diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-02-12 01:13:46 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-02-12 01:13:46 (GMT) |
commit | 0f6b319105b7e4305bc5ac1c5091f8a55be9b545 (patch) | |
tree | 24916212a2e49bf623f6a6f265c5643128c204fb | |
parent | c633ce4346fa04584e5168b77924ca6a42601435 (diff) | |
parent | 86372d8d9bf081b2a1ab2df7942f41309b1842fa (diff) | |
download | Qt-0f6b319105b7e4305bc5ac1c5091f8a55be9b545.zip Qt-0f6b319105b7e4305bc5ac1c5091f8a55be9b545.tar.gz Qt-0f6b319105b7e4305bc5ac1c5091f8a55be9b545.tar.bz2 |
Merge branch 'master' of scm.dev.nokia.troll.no:qt/mobility-staging into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/mobility-staging: (165 commits)
Add 'We mean it.' header.
Use provided typedef for QNetworkConfigurationPrivatePointer.
Fix public includes.
Document networkSessionOnline() signal and mark as internal.
Tag new classes as since 4.7.
Fix documentation.
Remove debug.
Update copyright year to 2010.
We don't need to migrate cached replies.
Fix after reworking to use signals/slots.
Remove debug.
Rename and remove unused private slots.
Add comments to private state enums.
Revert "(ODBC) Use wchar_t instead of assuming 2 bytes."
Move check for range header support to before deleting backend.
Don't try to migrate finished or aborted requests.
Clarify TemporaryNetworkFailureError docs.
Remove functions used for testing.
Connect signals between QNAM and QNetworkReplyImpl.
Fix networkAccessEnabled implementation.
...
477 files changed, 25039 insertions, 4122 deletions
diff --git a/bin/createpackage.pl b/bin/createpackage.pl index a748ba5..5738aeb 100755 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -95,10 +95,10 @@ Example with certfile: # This is comment line, also the empty lines are ignored rd.cer;rd-key.pem .\\cert\\mycert.cer;.\\cert\\mykey.key;yourpassword - X:\\QtS60\\selfsigned.cer;X:\\QtS60\\selfsigned.key + X:\\QtS60\\s60installs\\selfsigned.cer;X:\\QtS60\\s60installs\\selfsigned.key If no certificate and key files are provided, either a RnD certificate or -a self-signed certificate from Qt installation root directory is used. +a self-signed certificate from QtDir\\src\\s60installs directory is used. ============================================================================================== ENDUSAGESTRING @@ -149,8 +149,10 @@ $pkgoutputbasename = lc($pkgoutputbasename); # Store output file names to variables my $pkgoutput = lc($pkgoutputbasename.".pkg"); -my $unsigned_sis_name = $pkgoutputbasename."_unsigned.sis"; -my $signed_sis_name = $pkgoutputbasename.".sis"; +my $sisoutputbasename = lc($pkgoutputbasename); +$sisoutputbasename =~ s/_$targetplatform//g; +my $unsigned_sis_name = $sisoutputbasename."_unsigned.sis"; +my $signed_sis_name = $sisoutputbasename.".sis"; # Store some utility variables my $scriptpath = dirname(__FILE__); @@ -261,7 +263,11 @@ system ("signsis $unsigned_sis_name $signed_sis_name $certificate $key $passphra # Check if creating signed SIS Succeeded stat($signed_sis_name); if( -e _ ) { - print ("\nSuccessfully created $signed_sis_name using certificate: $certtext!\n"); + my $targetInsert = ""; + if ($targetplatform ne "-") { + $targetInsert = "for $targetplatform "; + } + print ("\nSuccessfully created $signed_sis_name ${targetInsert}using certificate: $certtext!\n"); # Sign with additional certificates & keys for my $row ( @certificates ) { diff --git a/config.tests/mac/corewlan/corewlan.pro b/config.tests/mac/corewlan/corewlan.pro new file mode 100644 index 0000000..8451af3 --- /dev/null +++ b/config.tests/mac/corewlan/corewlan.pro @@ -0,0 +1,3 @@ +SOURCES = corewlantest.mm +LIBS += -framework CoreWLAN -framework Foundation +CONFIG -= app_bundle qt diff --git a/config.tests/mac/corewlan/corewlantest.mm b/config.tests/mac/corewlan/corewlantest.mm new file mode 100644 index 0000000..3a29d84 --- /dev/null +++ b/config.tests/mac/corewlan/corewlantest.mm @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <CoreWLAN/CoreWLAN.h> +#include <CoreWLAN/CWInterface.h> + +int main() +{ + [CWInterface interfaceWithName:@"en2"]; + return 0; +} diff --git a/config.tests/unix/networkmanager/main.cpp b/config.tests/unix/networkmanager/main.cpp new file mode 100644 index 0000000..7b91ae0 --- /dev/null +++ b/config.tests/unix/networkmanager/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#if defined(QT_NO_DBUS) +#error Qt is not configured with DBus support. +#endif + +#include <NetworkManager/NetworkManager.h> + +int main(int argc, char** argv) +{ + return 0; +} diff --git a/config.tests/unix/networkmanager/networkmanager.pro b/config.tests/unix/networkmanager/networkmanager.pro new file mode 100644 index 0000000..c41204f --- /dev/null +++ b/config.tests/unix/networkmanager/networkmanager.pro @@ -0,0 +1,3 @@ +SOURCES = main.cpp +CONFIG -= qt dylib +mac:CONFIG -= app_bundle @@ -782,6 +782,8 @@ OPT_HELP= CFG_SILENT=no CFG_GRAPHICS_SYSTEM=default CFG_ALSA=auto +CFG_NETWORKMANAGER=auto +CFG_COREWLAN=auto # initalize variables used for installation QT_INSTALL_PREFIX= @@ -5407,6 +5409,14 @@ if [ "$PLATFORM_MAC" = "yes" ]; then # Always enable Phonon (unless it was explicitly disabled) CFG_PHONON=yes fi + + if [ "$CFG_COREWLAN" = "auto" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/mac/corewlan "CoreWlan" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_COREWLAN=yes + else + CFG_COREWLAN=no + fi + fi fi # QWS @@ -5861,6 +5871,14 @@ if [ "$CFG_ALSA" = "auto" ]; then fi fi +if [ "$CFG_NETWORKMANAGER" = "auto" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/networkmanager "NetworkManager" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_NETWORKMANAGER=yes + else + CFG_NETWORKMANAGER=no + fi +fi + if [ -f "$relpath/src/declarative/declarative.pro" ]; then if [ "$CFG_DECLARATIVE" = "auto" ]; then CFG_DECLARATIVE=yes @@ -6344,6 +6362,14 @@ if [ "$CFG_ALSA" = "yes" ]; then QT_CONFIG="$QT_CONFIG alsa" fi +if [ "$CFG_NETWORKMANAGER" = "yes" ]; then + QT_CONFIG="$QT_CONFIG networkmanager" +fi + +if [ "$CFG_COREWLAN" = "yes" ]; then + QT_CONFIG="$QT_CONFIG corewlan" +fi + # # Some Qt modules are too advanced in C++ for some old compilers # Detect here the platforms where they are known to work. @@ -7047,6 +7073,8 @@ fi [ "$CFG_XRANDR" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XRANDR" [ "$CFG_XINPUT" = "runtime" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_RUNTIME_XINPUT" [ "$CFG_ALSA" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_ALSA" +[ "$CFG_NETWORKMANAGER" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_NETWORKMANAGER" +[ "$CFG_COREWLAN" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_COREWLAN" # sort QCONFIG_FLAGS for neatness if we can [ '!' -z "$AWK" ] && QCONFIG_FLAGS=`echo $QCONFIG_FLAGS | $AWK '{ gsub(" ", "\n"); print }' | sort | uniq` @@ -7382,162 +7410,162 @@ fi if [ "$OPT_VERBOSE" = "yes" ]; then if echo '\c' | grep '\c' >/dev/null; then - echo -n "qmake vars .......... " + echo -n "qmake vars ............. " else - echo "qmake vars .......... \c" + echo "qmake vars ............. \c" fi cat "$QMAKE_VARS_FILE" | tr '\n' ' ' - echo "qmake switches ...... $QMAKE_SWITCHES" + echo "qmake switches ......... $QMAKE_SWITCHES" fi -[ "$CFG_INCREMENTAL" = "yes" ] && [ '!' -z "$INCREMENTAL" ] && echo "Incremental ......... $INCREMENTAL" -echo "Build ............... $CFG_BUILD_PARTS" -echo "Configuration ....... $QMAKE_CONFIG $QT_CONFIG" +[ "$CFG_INCREMENTAL" = "yes" ] && [ '!' -z "$INCREMENTAL" ] && echo "Incremental ............ $INCREMENTAL" +echo "Build .................. $CFG_BUILD_PARTS" +echo "Configuration .......... $QMAKE_CONFIG $QT_CONFIG" if [ "$CFG_DEBUG_RELEASE" = "yes" ]; then - echo "Debug ............... yes (combined)" + echo "Debug .................. yes (combined)" if [ "$CFG_DEBUG" = "yes" ]; then - echo "Default Link ........ debug" + echo "Default Link ........... debug" else - echo "Default Link ........ release" + echo "Default Link ........... release" fi else - echo "Debug ............... $CFG_DEBUG" -fi -echo "Qt 3 compatibility .. $CFG_QT3SUPPORT" -[ "$CFG_DBUS" = "no" ] && echo "QtDBus module ....... no" -[ "$CFG_DBUS" = "yes" ] && echo "QtDBus module ....... yes (run-time)" -[ "$CFG_DBUS" = "linked" ] && echo "QtDBus module ....... yes (linked)" -echo "QtConcurrent code.... $CFG_CONCURRENT" -echo "QtScript module ..... $CFG_SCRIPT" -echo "QtScriptTools module $CFG_SCRIPTTOOLS" -echo "QtXmlPatterns module $CFG_XMLPATTERNS" -echo "Phonon module ....... $CFG_PHONON" -echo "Multimedia module ... $CFG_MULTIMEDIA" -echo "SVG module .......... $CFG_SVG" -echo "WebKit module ....... $CFG_WEBKIT" + echo "Debug .................. $CFG_DEBUG" +fi +echo "Qt 3 compatibility ..... $CFG_QT3SUPPORT" +[ "$CFG_DBUS" = "no" ] && echo "QtDBus module .......... no" +[ "$CFG_DBUS" = "yes" ] && echo "QtDBus module .......... yes (run-time)" +[ "$CFG_DBUS" = "linked" ] && echo "QtDBus module .......... yes (linked)" +echo "QtConcurrent code ...... $CFG_CONCURRENT" +echo "QtScript module ........ $CFG_SCRIPT" +echo "QtScriptTools module ... $CFG_SCRIPTTOOLS" +echo "QtXmlPatterns module ... $CFG_XMLPATTERNS" +echo "Phonon module .......... $CFG_PHONON" +echo "Multimedia module ...... $CFG_MULTIMEDIA" +echo "SVG module ............. $CFG_SVG" +echo "WebKit module .......... $CFG_WEBKIT" if [ "$CFG_WEBKIT" = "yes" ]; then if [ "$CFG_JAVASCRIPTCORE_JIT" = "auto" ]; then - echo "JavaScriptCore JIT .. To be decided by JavaScriptCore" + echo "JavaScriptCore JIT ..... To be decided by JavaScriptCore" else - echo "JavaScriptCore JIT .. $CFG_JAVASCRIPTCORE_JIT" + echo "JavaScriptCore JIT ..... $CFG_JAVASCRIPTCORE_JIT" fi fi -echo "Declarative module .. $CFG_DECLARATIVE" -echo "STL support ......... $CFG_STL" -echo "PCH support ......... $CFG_PRECOMPILE" -echo "MMX/3DNOW/SSE/SSE2.. ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}" +echo "Declarative module ..... $CFG_DECLARATIVE" +echo "STL support ............ $CFG_STL" +echo "PCH support ............ $CFG_PRECOMPILE" +echo "MMX/3DNOW/SSE/SSE2 ..... ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}" if [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]; then - echo "iWMMXt support ...... ${CFG_IWMMXT}" - echo "NEON support ........ ${CFG_NEON}" -fi -[ "${PLATFORM_QWS}" != "yes" ] && echo "Graphics System ..... $CFG_GRAPHICS_SYSTEM" -echo "IPv6 support ........ $CFG_IPV6" -echo "IPv6 ifname support . $CFG_IPV6IFNAME" -echo "getaddrinfo support . $CFG_GETADDRINFO" -echo "getifaddrs support .. $CFG_GETIFADDRS" -echo "Accessibility ....... $CFG_ACCESSIBILITY" -echo "NIS support ......... $CFG_NIS" -echo "CUPS support ........ $CFG_CUPS" -echo "Iconv support ....... $CFG_ICONV" -echo "Glib support ........ $CFG_GLIB" -echo "GStreamer support ... $CFG_GSTREAMER" -echo "Large File support .. $CFG_LARGEFILE" -echo "GIF support ......... $CFG_GIF" + echo "iWMMXt support ......... ${CFG_IWMMXT}" + echo "NEON support ........... ${CFG_NEON}" +fi +[ "${PLATFORM_QWS}" != "yes" ] && echo "Graphics System ........ $CFG_GRAPHICS_SYSTEM" +echo "IPv6 support ........... $CFG_IPV6" +echo "IPv6 ifname support .... $CFG_IPV6IFNAME" +echo "getaddrinfo support .... $CFG_GETADDRINFO" +echo "getifaddrs support ..... $CFG_GETIFADDRS" +echo "Accessibility .......... $CFG_ACCESSIBILITY" +echo "NIS support ............ $CFG_NIS" +echo "CUPS support ........... $CFG_CUPS" +echo "Iconv support .......... $CFG_ICONV" +echo "Glib support ........... $CFG_GLIB" +echo "GStreamer support ...... $CFG_GSTREAMER" +echo "Large File support ..... $CFG_LARGEFILE" +echo "GIF support ............ $CFG_GIF" if [ "$CFG_TIFF" = "no" ]; then - echo "TIFF support ........ $CFG_TIFF" + echo "TIFF support ........... $CFG_TIFF" else - echo "TIFF support ........ $CFG_TIFF ($CFG_LIBTIFF)" + echo "TIFF support ........... $CFG_TIFF ($CFG_LIBTIFF)" fi if [ "$CFG_JPEG" = "no" ]; then - echo "JPEG support ........ $CFG_JPEG" + echo "JPEG support ........... $CFG_JPEG" else - echo "JPEG support ........ $CFG_JPEG ($CFG_LIBJPEG)" + echo "JPEG support ........... $CFG_JPEG ($CFG_LIBJPEG)" fi if [ "$CFG_PNG" = "no" ]; then - echo "PNG support ......... $CFG_PNG" + echo "PNG support ............ $CFG_PNG" else - echo "PNG support ......... $CFG_PNG ($CFG_LIBPNG)" + echo "PNG support ............ $CFG_PNG ($CFG_LIBPNG)" fi if [ "$CFG_MNG" = "no" ]; then - echo "MNG support ......... $CFG_MNG" + echo "MNG support ............ $CFG_MNG" else - echo "MNG support ......... $CFG_MNG ($CFG_LIBMNG)" + echo "MNG support ............ $CFG_MNG ($CFG_LIBMNG)" fi -echo "zlib support ........ $CFG_ZLIB" -echo "Session management .. $CFG_SM" +echo "zlib support ........... $CFG_ZLIB" +echo "Session management ..... $CFG_SM" if [ "$PLATFORM_QWS" = "yes" ]; then - echo "Embedded support .... $CFG_EMBEDDED" + echo "Embedded support ....... $CFG_EMBEDDED" if [ "$CFG_QWS_FREETYPE" = "auto" ]; then - echo "Freetype2 support ... $CFG_QWS_FREETYPE ($CFG_LIBFREETYPE)" + echo "Freetype2 support ...... $CFG_QWS_FREETYPE ($CFG_LIBFREETYPE)" else - echo "Freetype2 support ... $CFG_QWS_FREETYPE" + echo "Freetype2 support ...... $CFG_QWS_FREETYPE" fi # Normalize the decoration output first CFG_GFX_ON=`echo ${CFG_GFX_ON}` CFG_GFX_PLUGIN=`echo ${CFG_GFX_PLUGIN}` - echo "Graphics (qt) ....... ${CFG_GFX_ON}" - echo "Graphics (plugin) ... ${CFG_GFX_PLUGIN}" + echo "Graphics (qt) .......... ${CFG_GFX_ON}" + echo "Graphics (plugin) ...... ${CFG_GFX_PLUGIN}" CFG_DECORATION_ON=`echo ${CFG_DECORATION_ON}` CFG_DECORATION_PLUGIN=`echo ${CFG_DECORATION_PLUGIN}` - echo "Decorations (qt) .... $CFG_DECORATION_ON" - echo "Decorations (plugin) $CFG_DECORATION_PLUGIN" + echo "Decorations (qt) ....... $CFG_DECORATION_ON" + echo "Decorations (plugin) ... $CFG_DECORATION_PLUGIN" CFG_KBD_ON=`echo ${CFG_KBD_ON}` CFG_KBD_PLUGIN=`echo ${CFG_KBD_PLUGIN}` - echo "Keyboard driver (qt). ${CFG_KBD_ON}" - echo "Keyboard driver (plugin) ${CFG_KBD_PLUGIN}" + echo "Keyboard driver (qt) ... ${CFG_KBD_ON}" + echo "Keyboard driver (plugin) .. ${CFG_KBD_PLUGIN}" CFG_MOUSE_ON=`echo ${CFG_MOUSE_ON}` CFG_MOUSE_PLUGIN=`echo ${CFG_MOUSE_PLUGIN}` - echo "Mouse driver (qt) ... $CFG_MOUSE_ON" - echo "Mouse driver (plugin) $CFG_MOUSE_PLUGIN" + echo "Mouse driver (qt) ...... $CFG_MOUSE_ON" + echo "Mouse driver (plugin) .. $CFG_MOUSE_PLUGIN" fi if [ "$CFG_OPENGL" = "desktop" ]; then - echo "OpenGL support ...... yes (Desktop OpenGL)" + echo "OpenGL support ......... yes (Desktop OpenGL)" elif [ "$CFG_OPENGL" = "es1" ]; then - echo "OpenGL support ...... yes (OpenGL ES 1.x Common profile)" + echo "OpenGL support ......... yes (OpenGL ES 1.x Common profile)" elif [ "$CFG_OPENGL" = "es2" ]; then - echo "OpenGL support ...... yes (OpenGL ES 2.x)" + echo "OpenGL support ......... yes (OpenGL ES 2.x)" else - echo "OpenGL support ...... no" + echo "OpenGL support ......... no" fi if [ "$CFG_EGL" != "no" ]; then if [ "$CFG_EGL_GLES_INCLUDES" != "no" ]; then - echo "EGL support ......... yes <GLES/egl.h>" + echo "EGL support ............ yes <GLES/egl.h>" else - echo "EGL support ......... yes <EGL/egl.h>" + echo "EGL support ............ yes <EGL/egl.h>" fi fi if [ "$CFG_OPENVG" ]; then if [ "$CFG_OPENVG_SHIVA" = "yes" ]; then - echo "OpenVG support ...... ShivaVG" + echo "OpenVG support ......... ShivaVG" else - echo "OpenVG support ...... $CFG_OPENVG" + echo "OpenVG support ......... $CFG_OPENVG" fi fi if [ "$PLATFORM_X11" = "yes" ]; then - echo "NAS sound support ... $CFG_NAS" - echo "XShape support ...... $CFG_XSHAPE" - echo "XSync support ....... $CFG_XSYNC" - echo "Xinerama support .... $CFG_XINERAMA" - echo "Xcursor support ..... $CFG_XCURSOR" - echo "Xfixes support ...... $CFG_XFIXES" - echo "Xrandr support ...... $CFG_XRANDR" - echo "Xrender support ..... $CFG_XRENDER" - echo "Xi support .......... $CFG_XINPUT" - echo "MIT-SHM support ..... $CFG_MITSHM" - echo "FontConfig support .. $CFG_FONTCONFIG" - echo "XKB Support ......... $CFG_XKB" - echo "immodule support .... $CFG_IM" - echo "GTK theme support ... $CFG_QGTKSTYLE" -fi -[ "$CFG_SQL_mysql" != "no" ] && echo "MySQL support ....... $CFG_SQL_mysql" -[ "$CFG_SQL_psql" != "no" ] && echo "PostgreSQL support .. $CFG_SQL_psql" -[ "$CFG_SQL_odbc" != "no" ] && echo "ODBC support ........ $CFG_SQL_odbc" -[ "$CFG_SQL_oci" != "no" ] && echo "OCI support ......... $CFG_SQL_oci" -[ "$CFG_SQL_tds" != "no" ] && echo "TDS support ......... $CFG_SQL_tds" -[ "$CFG_SQL_db2" != "no" ] && echo "DB2 support ......... $CFG_SQL_db2" -[ "$CFG_SQL_ibase" != "no" ] && echo "InterBase support ... $CFG_SQL_ibase" -[ "$CFG_SQL_sqlite2" != "no" ] && echo "SQLite 2 support .... $CFG_SQL_sqlite2" -[ "$CFG_SQL_sqlite" != "no" ] && echo "SQLite support ...... $CFG_SQL_sqlite ($CFG_SQLITE)" + echo "NAS sound support ...... $CFG_NAS" + echo "XShape support ......... $CFG_XSHAPE" + echo "XSync support .......... $CFG_XSYNC" + echo "Xinerama support ....... $CFG_XINERAMA" + echo "Xcursor support ........ $CFG_XCURSOR" + echo "Xfixes support ......... $CFG_XFIXES" + echo "Xrandr support ......... $CFG_XRANDR" + echo "Xrender support ........ $CFG_XRENDER" + echo "Xi support ............. $CFG_XINPUT" + echo "MIT-SHM support ........ $CFG_MITSHM" + echo "FontConfig support ..... $CFG_FONTCONFIG" + echo "XKB Support ............ $CFG_XKB" + echo "immodule support ....... $CFG_IM" + echo "GTK theme support ...... $CFG_QGTKSTYLE" +fi +[ "$CFG_SQL_mysql" != "no" ] && echo "MySQL support .......... $CFG_SQL_mysql" +[ "$CFG_SQL_psql" != "no" ] && echo "PostgreSQL support ..... $CFG_SQL_psql" +[ "$CFG_SQL_odbc" != "no" ] && echo "ODBC support ........... $CFG_SQL_odbc" +[ "$CFG_SQL_oci" != "no" ] && echo "OCI support ............ $CFG_SQL_oci" +[ "$CFG_SQL_tds" != "no" ] && echo "TDS support ............ $CFG_SQL_tds" +[ "$CFG_SQL_db2" != "no" ] && echo "DB2 support ............ $CFG_SQL_db2" +[ "$CFG_SQL_ibase" != "no" ] && echo "InterBase support ...... $CFG_SQL_ibase" +[ "$CFG_SQL_sqlite2" != "no" ] && echo "SQLite 2 support ....... $CFG_SQL_sqlite2" +[ "$CFG_SQL_sqlite" != "no" ] && echo "SQLite support ......... $CFG_SQL_sqlite ($CFG_SQLITE)" OPENSSL_LINKAGE="" if [ "$CFG_OPENSSL" = "yes" ]; then @@ -7545,11 +7573,15 @@ if [ "$CFG_OPENSSL" = "yes" ]; then elif [ "$CFG_OPENSSL" = "linked" ]; then OPENSSL_LINKAGE="(linked)" fi -echo "OpenSSL support ..... $CFG_OPENSSL $OPENSSL_LINKAGE" -echo "Alsa support ........ $CFG_ALSA" +echo "OpenSSL support ........ $CFG_OPENSSL $OPENSSL_LINKAGE" +echo "Alsa support ........... $CFG_ALSA" +echo "NetworkManager support . $CFG_NETWORKMANAGER" +if [ "$PLATFORM_MAC" = "yes" ]; then + echo "CoreWlan support ....... $CFG_COREWLAN" +fi echo -[ "$CFG_PTMALLOC" != "no" ] && echo "Use ptmalloc ........ $CFG_PTMALLOC" +[ "$CFG_PTMALLOC" != "no" ] && echo "Use ptmalloc ........... $CFG_PTMALLOC" # complain about not being able to use dynamic plugins if we are using a static build if [ "$CFG_SHARED" = "no" ]; then diff --git a/demos/browser/browser.pro b/demos/browser/browser.pro index a42aa60..f038c61 100644 --- a/demos/browser/browser.pro +++ b/demos/browser/browser.pro @@ -6,8 +6,6 @@ CONFIG += qt warn_on contains(QT_BUILD_PARTS, tools):!embedded: CONFIG += uitools else: DEFINES += QT_NO_UITOOLS -release:DEFINES+=QT_NO_DEBUG_OUTPUT QT_NO_WARNING_OUTPUT - FORMS += \ addbookmarkdialog.ui \ bookmarks.ui \ diff --git a/demos/browser/networkaccessmanager.cpp b/demos/browser/networkaccessmanager.cpp index b0b00a2..70a9305 100644 --- a/demos/browser/networkaccessmanager.cpp +++ b/demos/browser/networkaccessmanager.cpp @@ -112,8 +112,9 @@ void NetworkAccessManager::requestFinished(QNetworkReply *reply) double pctCached = (double(requestFinishedFromCacheCount) * 100.0/ double(requestFinishedCount)); double pctPipelined = (double(requestFinishedPipelinedCount) * 100.0/ double(requestFinishedCount)); double pctSecure = (double(requestFinishedSecureCount) * 100.0/ double(requestFinishedCount)); +#ifdef QT_DEBUG qDebug("STATS [%lli requests total] [%3.2f%% from cache] [%3.2f%% pipelined] [%3.2f%% SSL/TLS]", requestFinishedCount, pctCached, pctPipelined, pctSecure); - +#endif } void NetworkAccessManager::loadSettings() diff --git a/demos/browser/webview.cpp b/demos/browser/webview.cpp index 1a7e38a..2f9b3e6 100644 --- a/demos/browser/webview.cpp +++ b/demos/browser/webview.cpp @@ -143,11 +143,19 @@ QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QS void WebPage::handleUnsupportedContent(QNetworkReply *reply) { - if (reply->error() == QNetworkReply::NoError) { - BrowserApplication::downloadManager()->handleUnsupportedContent(reply); + QString errorString = reply->errorString(); + + if (m_loadingUrl != reply->url()) { + // sub resource of this page + qWarning() << "Resource" << reply->url().toEncoded() << "has unknown Content-Type, will be ignored."; + reply->deleteLater(); return; } + if (reply->error() == QNetworkReply::NoError && !reply->header(QNetworkRequest::ContentTypeHeader).isValid()) { + errorString = "Unknown Content-Type"; + } + QFile file(QLatin1String(":/notfound.html")); bool isOpened = file.open(QIODevice::ReadOnly); Q_ASSERT(isOpened); @@ -156,7 +164,7 @@ void WebPage::handleUnsupportedContent(QNetworkReply *reply) QString title = tr("Error loading page: %1").arg(reply->url().toString()); QString html = QString(QLatin1String(file.readAll())) .arg(title) - .arg(reply->errorString()) + .arg(errorString) .arg(reply->url().toString()); QBuffer imageBuffer; diff --git a/dist/changes-4.6.2 b/dist/changes-4.6.2 index aaaaacc..657aafc 100644 --- a/dist/changes-4.6.2 +++ b/dist/changes-4.6.2 @@ -16,22 +16,6 @@ Qt Bug Tracker: http://bugreports.qt.nokia.com Task Tracker: http://qt.nokia.com/developer/task-tracker Merge Request: http://qt.gitorious.org -**************************************************************************** -* General * -**************************************************************************** - -New features ------------- - - - SomeClass, SomeOtherClass - * New classes for foo, bar and baz - -Optimizations -------------- - - - Optimized foo in QSomeClass - * See list of Important Behavior Changes below - **************************************************************************** * Library * @@ -42,98 +26,88 @@ QtCore - QAtomicPointer * [QTBUG-7356] Fixed a compilation failure when using the Intel - compiler on IA-64 - + compiler on IA-64 - QFile * Fixed double-buffering issue when opening files in buffered mode. - * [QTBUG-7285] QFile::remove would fail if an unrelated operation on the - same instance had been previously failed. This manisfested itself in - QTemporaryFile failing to auto-remove files and QFile::copy leaving + * [QTBUG-7285] QFile::remove would() fail if an unrelated operation on the + same instance had been previously failed. This manifested itself in + QTemporaryFile failing to auto-remove files and QFile::copy() leaving temporary files behind in certain situations. - - QFSFileEngine - * Fix typo that made realpath() not being used - + * Fix typo that made realpath() not be used. - QIODevice - * Optimized readAll() - + * Optimized readAll(). - QReadWriteLock - * [MR 426] Fixed documentation - + * [MR 426] Fixed documentation. - QXmlStreamWriter - * [QTBUG-6893] Fixed adding extra Byte Order Marks when writing to a xml file. + * [QTBUG-6893] Fixed adding extra Byte Order Marks when writing to a + .xml file. QtGui ----- + - QApplication + * [QTBUG-6098] Added a flag to avoid construction of application panes. + * [QTBUG-7029] Fixed a crash when re-creating QApplication object due + to a dangling gesture manager pointer. - QAbstractScrollArea - * [QTBUG-1760] Reverted horizontal scrolling with mouse wheel when vertical scrollbar is hidden - + * [QTBUG-1760] Reverted horizontal scrolling with mouse wheel when vertical + scrollbar is hidden - QBmpHandler - * [QTBUG-7530] Fixed an infinite loop that could occur when reading invalid BMP images. - + * [QTBUG-7530] Fixed an infinite loop that could occur when reading invalid + BMP images. - QGraphicsEffect * [QTBUG-6901] Fixed performance problem when translating items with graphics effects. - - QImage * [QTBUG-7231] Avoid an unnecessary copy in QImage::scaled(). - - - QPDFEngine - * [QTBUG-7249] Fixed the encoding of the Tile and Creator tags in the PDF engine. - - - QApplication - * [QTBUG-6098] Added a flag to avoid construction of application panes. - QInputContext - * [QTBUG-7439] Avoided the loss of preedit text when losing focus on Symbian. - - * [QT-2629] Implemented event filter functions for Symbian. - * [QTBUG-7029] Fixed a crash when re-creating QApplication object due to a - dangling gesture manager pointer. - * [QTBUG-7198] Setting a style sheet could break the checkbox position in item views. - * [QTBUG-7253] Fixed wrong stroke clipping with the raster engine when using a QPen - with a style other than SolidLine. - - - * [MR 2077] Integrated merge request 2077 + * [QTBUG-7439] Avoided the loss of preedit text when losing focus on + Symbian. + - QPDFEngine + * [QTBUG-7249] Fixed the encoding of the Tile and Creator tags in the PDF + engine. + - [QT-2629] Implemented event filter functions for Symbian. + - [QTBUG-7198] Setting a style sheet could break the checkbox position in + item views. + - [QTBUG-7253] Fixed wrong stroke clipping with the raster engine when using + a QPen with a style other than SolidLine. QtDBus ------ - QDBusConnection - * [QT-2307] Fixed sending of D-Bus method calls with QDBus::BlockWithGui + * [QT-2307] Fixed sending of D-Bus method calls with QDBus::BlockWithGui. QtNetwork --------- - QNetworkAccessManager * Optimizations - * HTTP: Get rid of QAbstractSocket warnings that were sometimes displayed - * HTTP: setReadBufferSize() of the QNetworkReply finally is working on all layers - * [QTBUG-7713] HTTP: Fix bug related to re-sending a request + * HTTP: Get rid of QAbstractSocket warnings that were sometimes displayed. + * HTTP: setReadBufferSize() of the QNetworkReply finally is working on all + layers. + * [QTBUG-7713] HTTP: Fix bug related to re-sending a request. * [QTBUG-7060] Fixed an issue with parsing of HTTP headers like - "private, max-age=300" - + "private, max-age=300". - QSslCertificate - * [QTBUG-6466] Fix issuerInfo() and subjectInfo() - + * [QTBUG-6466] Fix issuerInfo() and subjectInfo(). - QTcpSocket - * [QTBUG-7344] Fix performance degredation with write() on Windows - * [QTBUG-7316,QTBUG-7317] Also handle unknown errors from socket engine + * [QTBUG-7344] Fix performance degredation with write() on Windows. + * [QTBUG-7316,QTBUG-7317] Handle unknown errors from socket engine. QtOpenGL -------- - [QTBUG-7490] Better support for user-generated binary shaders. - - - QGLWidget - * [QTBUG-7213] Fixed QGLWidget::renderPixmap() on Windows. - - QGLPixelBuffer - * [QTBUG-7476] Fixed a crash under X11 when drawing QPixmaps to QGLPixelBuffers. - + * [QTBUG-7476] Fixed a crash under X11 when drawing QPixmaps to + QGLPixelBuffers. - QGL2PaintEngineEx * [QTBUG-7203] Reset the GL stencil mask, op and function in resetGLState(). + - QGLWidget + * [QTBUG-7213] Fixed QGLWidget::renderPixmap() on Windows. + QtOpenVG -------- @@ -141,137 +115,89 @@ QtOpenVG - [QTBUG-7791] Optimize single-rect IntersectClip in OpenVG using the scissor. - [QTBUG-7864] Use OpenVG scissor on 90/180/270 rotations and simple clips. -QtScript --------- - - - foo - * bar - -QtSql ------ - - - foo - * bar - -QtXml ------ - - - foo - * bar - QtMultimedia ------------ - QAudioInput - * [QTBUG-7044]: QAudioInput stopped working correctly after suspend()/resume() on linux. - -Qt Plugins ----------- - - - foo - * bar + * [QTBUG-7044]: QAudioInput stopped working correctly after + suspend()/resume() on linux. Examples -------- - QtMultimedia - * [MR 418] Fixed the example for QAudioOutput - + * [MR 418] Fixed the example for QAudioOutput. - WebKit - * [MR 2235] Added the framecapture example to the default build - -Third party components ----------------------- - - - Updated foo to version 2.3.9. - - - Updated bar to the latest version from baz.org. + * [MR 2235] Added the framecapture example to the default build. **************************************************************************** * Platform Specific Changes * **************************************************************************** -Qt for Unix (X11 and Mac OS X) ------------------------------- - - - - Qt for Linux/X11 ---------------- - * Fix a bug where QPixmap::serialNumber was not set on a transformed pixmap - in Qt/X11. - - * Fixed a crash when an input method tries to create a widget after the - application is destroyed. - - - [QTBUG-6952] Fixed a problem using NoButtons in spinbox with QGtkStyle - - [QTBUG-7504] Fixed missing focus rect on check- and radiobutton with - some GTK+ themes. - - [QTBUG-6522] Fixed missing menu separator in some GTK+ themes. - -Qt for Windows --------------- + - Fix a bug where QPixmap::serialNumber was not set on a transformed pixmap + in Qt/X11. + - Fixed a crash when an input method tries to create a widget after the + application is destroyed. + - [QTBUG-6952] Fixed a problem using NoButtons in spinbox with QGtkStyle. + - [QTBUG-7504] Fixed missing focus rect on check- and radiobutton with + some GTK+ themes. + - [QTBUG-6522] Fixed missing menu separator in some GTK+ themes. Qt for Mac OS X --------------- - [QTBUG-7832]: Restored missing margins around non-unified toolbars. - - [QTBUG-7312]: Menubar and dock disappear after hiding a fullscreen widget on Cocoa. - - [QTBUG-7481]: Re-added the Close button in QPrintPreviewDialog for Mac/Carbon. - - [QTBUG-7522]: Drawing fake buttons using QMacStyle+QStyleOptionViewItemV4 lead to crash. - - [QTBUG-7625]: Calling showFullScreen() then showNormal() on a widget results in top menu hiding. - - [QTBUG-7086]: QFileDialog now correctly responds to fileMode & acceptMode changes. - - [QTBUG-7162]: Fixed a crash in Designer when previewing a QMainWindow with native toolbar. - - [QTBUG-7305]: Fixed a crash when deleting QMainWindow with native toolbar on Cocoa. - - [QTBUG-6882]: Fixed a text layout issue with QHeaderView in right-to-left mode. - - -Qt for Embedded Linux ---------------------- - - - + - [QTBUG-7312]: Menubar and dock disappear after hiding a fullscreen widget + on Cocoa. + - [QTBUG-7481]: Re-added the Close button in QPrintPreviewDialog for + Mac/Carbon. + - [QTBUG-7522]: Drawing fake buttons using QMacStyle+QStyleOptionViewItemV4 + lead to crash. + - [QTBUG-7625]: Calling showFullScreen() then showNormal() on a widget results + in top menu hiding. + - [QTBUG-7086]: QFileDialog now correctly responds to fileMode & acceptMode + changes. + - [QTBUG-7162]: Fixed a crash in Designer when previewing a QMainWindow with + native toolbar. + - [QTBUG-7305]: Fixed a crash when deleting QMainWindow with native toolbar + on Cocoa. + - [QTBUG-6882]: Fixed a text layout issue with QHeaderView in right-to-left + mode. DirectFB -------- - * Fix a bug where QPixmap::serialNumber was not set on a transformed pixmap - in DirectFB. - * Reimplement QPixmapData::scroll for QDirectFBPixmapData which optimizes - QPixmap::scroll - * Fix a rendering issue for semi-transparent top level windows in DirectFB. - * Make it possible to fall back to the raster engine for stretch blits in - DirectFB using QT_NO_DIRECTFB_STRETCHBLIT - - - -Qt for Windows CE ------------------ - - + - Fix a bug where QPixmap::serialNumber was not set on a transformed pixmap + in DirectFB. + - Reimplement QPixmapData::scroll for QDirectFBPixmapData which optimizes + QPixmap::scroll. + - Fix a rendering issue for semi-transparent top level windows in DirectFB. + - Make it possible to fall back to the raster engine for stretch blits in + DirectFB using QT_NO_DIRECTFB_STRETCHBLIT. Qt for Symbian -------------- - * [QTBUG-6556] Improve the DEF file handling scheme, to allow simple enable/ - disable of DEF file usage (for use _during development only_ to decouple - the need to update the DEF files at the precise point that symbols are - removed, therefore allowing builds by CI systems to succeed even if symbols - have been removed. This does not remove the need to update the DEF files - before release. NOTE: Builds generated using this flag are not binary - compatible with previous versions of Qt.) - -- QProcess - * [QTBUG-7667] Fixed no-timeout case for QProcess::waitForFinished. - -- qmake - * [QTBUG-7695] Added support for ifdeffing for manufacturer in generated - pkg files. - * [QTBUG-7908] Smart installer package generation support - -- Patch_capabilities script + - [QTBUG-6556] Improve the DEF file handling scheme, to allow simple enable/ + disable of DEF file usage (for use _during development only_ to decouple + the need to update the DEF files at the precise point that symbols are + removed, therefore allowing builds by CI systems to succeed even if symbols + have been removed. This does not remove the need to update the DEF files + before release. NOTE: Builds generated using this flag are not binary + compatible with previous versions of Qt.) + - QProcess + * [QTBUG-7667] Fixed no-timeout case for QProcess::waitForFinished. + - qmake + * [QTBUG-7695] Added support for ifdeffing for manufacturer in generated + pkg files. + * [QTBUG-7908] Smart installer package generation support. + - Patch_capabilities script * Added support for embedded sis name/uid patching. - -- Qt deployment - * [QTBUG-7518] Backup and restore support for Qt libs + - Qt deployment + * [QTBUG-7518] Backup and restore support for Qt libs. **************************************************************************** @@ -279,28 +205,22 @@ Qt for Symbian **************************************************************************** - Designer - * [QTBUG-6965] Enabled editing seconds of QDateTime-type properties + * [QTBUG-6965] Enabled editing seconds of QDateTime-type properties. * [QTBUG-6757] Fixed bug where selection handles would be affected by a style sheet set on the main form. - uic3 * [QTBUG-7404] Added option to preserve layout names set by Qt 3 Designer. - - qdoc3 - * bar - - - Linguist - * baz - **************************************************************************** * Important Behavior Changes * **************************************************************************** - QNetworkAccessManager cache - * QNetworkAccessManager will no longer return expired pages, as - stated in the documentation - * The behaviour of PreferCache and PreferNetwork modes now match - the documentation more closely + * QNetworkAccessManager will no longer return expired pages, as + stated in the documentation + * The behaviour of PreferCache and PreferNetwork modes now match + the documentation more closely - QUrl * QUrl will now accept hostnames ending in dot and will not treat diff --git a/doc/src/deployment/deployment.qdoc b/doc/src/deployment/deployment.qdoc index 51383da..16718f3 100644 --- a/doc/src/deployment/deployment.qdoc +++ b/doc/src/deployment/deployment.qdoc @@ -961,14 +961,14 @@ \title Deploying an Application on Mac OS X - Starting with version 4.5, Qt now includes a \l {macdeploy}{deployment tool} - that automates the prodecures described in this document. - - This documentation will describe how to create a bundle, and how - to make sure that the application will find the resources it needs - at run-time. We will demonstrate the procedures in terms of - deploying the \l {tools/plugandpaint}{Plug & Paint} application - that is provided in Qt's examples directory. + Beginning with Qt 4.5, a \l {macdeploy}{deployment tool} is + included that automates the prodecures described here. + + This document describes how to create a bundle and how to make + sure that the application will find the resources it needs at + run-time. We demonstrate the procedures in terms of deploying the + \l {tools/plugandpaint}{Plug & Paint} application that is provided + in Qt's examples directory. \tableofcontents @@ -1378,63 +1378,38 @@ \section2 Mac OS X Version Dependencies - Qt 4.2 has been designed to be built and deployed on Mac OS X 10.3 - up until the current version as of this writing, Mac OS X 10.4 and - all their minor releases. Qt achieves this by using "weak - linking." This means that Qt tests if a function added in newer - versions of Mac OS X is available on the computer it is running on - before it uses it. This results in getting access to newer - features when running on newer versions of OS X while still - remaining compatible on older versions. + From Qt 4.6, Mac OS X 10.3 (Panther) is no longer supported. Qt + 4.6 applications can be built and deployed on Mac OS X 10.4 + (Tiger) and higher. This is achieved using \e{weak linking}. In + \e{weak linking}, Qt tests whether a function added in a newer + version of Mac OS X is available on the computer it is running + on. This allows Qt to use newer features, when it runs on a newer + version of OS X, while remaining compatible on the older versions. For more information about cross development issues on Mac OS X, see \l {http://developer.apple.com/documentation/DeveloperTools/Conceptual/cross_development/index.html}{Apple's Developer Website}. - Since the linker is set to be compatible with all OS X version, you have to - change the \c MACOSX_DEPLOYMENT_TARGET environment variable to get weak - linking to work for your application. You can add: + Since the linker is set to be compatible with all OS X versions, + you must change the \c MACOSX_DEPLOYMENT_TARGET environment + variable to get \e{weak linking} to work for your application. You + can add: \snippet doc/src/snippets/code/doc_src_deployment.qdoc 51 - to your .pro file and qmake will take care of this for you. - - However, there is a bit of a wrinkle to keep in mind when your are - deploying. Mac OS X 10.4 ("Tiger") ships GCC 4.0 as its default - compiler. This is also the GCC compiler we use for building the - binary Qt package. If you use GCC 4.0 to build your application, - it will link against a dynamic libstdc++ that is only available on - Mac OS X 10.4 and Mac OS X 10.3.9. The application will refuse to - run on older versions of the operating system. + to your .pro file, and qmake will take care of this for you. For more information about C++ runtime environment, see \l {http://developer.apple.com/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/index.html}{Apple's Developer Website} - If you want to deploy to versions of Mac OS X earlier than 10.3.9, - you must build with GCC 3.3 which is the default on Mac OS X - 10.3. GCC 3.3 is also available on the Mac OS X 10.4 "Xcode Tools" - CD and as a download for earlier versions of Mac OS X from Apple - (\l {https://connect.apple.com/}{connect.apple.com}). You can use - Apple's \c gcc_select(1) command line tool to switch the default - complier on your system. - \section3 Deploying Phonon Applications on Mac OS X \list - \o If you build your Phonon application on Tiger, it will work on - Tiger, Leopard and Panther. - \o If you build your application on Leopard, it will \bold not work - on Panther unless you rename the libraries with the following command - after you have built your application: - - \snippet doc/src/snippets/code/doc_src_deployment.qdoc 51a - This command must be invoked in the directory where - \c{libphonon_qt7.dylib} is located, usually in - \c{yourapp.app/Contents/plugins/phonon_backend/}. - \o The \l {macdeploy}{deployment tool} will perform this step for you. + \o If you build your Qt 4.6 Phonon application on OS X 10.4 + (Tiger), it will run on OS X 10.4 and higher. - \o If you are using Leopard, but would like to build your application + \o If you are using Leopard but would like to build your application against Tiger, you can use: \snippet doc/src/snippets/code/doc_src_deployment.qdoc 51b @@ -1442,12 +1417,13 @@ \section2 Architecture Dependencies - The Qt for Mac OS X libraries, tools, and examples can be built "universal" - (i.e. they run natively on both Intel and PowerPC machines). This - is accomplished by passing \c -universal on the \c configure line - of the source package, and requires that you use GCC 4.0.x. On - PowerPC hardware you will need to pass the universal SDK as a - command line argument to the Qt configure command. For example: + The Qt for Mac OS X libraries, tools, and examples can be built + "universal" (i.e. they run natively on both Intel and PowerPC + machines). This is accomplished by passing \c -universal on the + \c configure line of the source package, and requires that you use + GCC 4.0.x. On PowerPC hardware you will need to pass the universal + SDK as a command line argument to the Qt configure command. For + example: \snippet doc/src/snippets/code/doc_src_deployment.qdoc 52 @@ -1571,28 +1547,22 @@ By default \c .pkg file generated by \c qmake adds support for all S60 3rd edition FP1, S60 3rd edition FP2 and S60 5th edition devices. - As a last step we will instruct qmake to generate smart installer \c .pkg file by defining - the UID of the installation package. The UID needs to be different than the application UID, - and should be reserved via normal Symbian mechanisms. You can use a random UID starting with - \c 0xE for testing purposes: - - \snippet doc/src/snippets/code/doc_src_deployment.qdoc 58 - Now we are ready to compile the application and create the application deployment file. Run \c qmake to create Symbian specific makefiles, resources (\.rss) and deployment packaging files (\c .pkg). And do build to create the application binaries and resources. - \snippet doc/src/snippets/code/doc_src_deployment.qdoc 59 + \snippet doc/src/snippets/code/doc_src_deployment.qdoc 58 If everything compiled and linked without any errors, we are now ready to create - an application package (\c wiggly.sis): + an application installation package (\c wiggly_installer.sis). - \snippet doc/src/snippets/code/doc_src_deployment.qdoc 60 + If you haven't done so already, download the latest release of the Smart Installer + from \l{http://get.qt.nokia.com/nokiasmartinstaller/}, and install it on top of the Qt package - Now you can create the smart installer package for the application: + Then use this command to create the installer sis package: - \snippet doc/src/snippets/code/doc_src_deployment.qdoc 61 + \snippet doc/src/snippets/code/doc_src_deployment.qdoc 59 If all binaries and dependencies were found, you should now have a self signed \c wiggly_installer.sis ready to be installed on a device. The smart installer diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index 638c2da..ea902a2 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -677,7 +677,7 @@ If you are using pre-built binaries, follow the instructions given in the \snippet doc/src/snippets/code/doc_src_installation.qdoc 30 - This will create a self-signed \c fluidlauncher_armv5_urel.sis and + This will create a self-signed \c fluidlauncher.sis and install it to your device. To run the demos on the emulator simply navigate to the directory of the demo diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index b64d67b..9c9b743 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -285,6 +285,9 @@ \section1 General Information + Qt 4.6 applications can only be deployed on Mac OS X 10.4 (Tiger) + and higher. + Qt 4.4 and Qt 4.5 development is only supported on Mac OS X 10.4 and up. Applications built against these version of Qt can be deployed on Mac OS X 10.3, but cannot be developed on that version of the operating system due diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc index 427f45a..5cebee3 100644 --- a/doc/src/platforms/symbian-introduction.qdoc +++ b/doc/src/platforms/symbian-introduction.qdoc @@ -127,6 +127,11 @@ \row \o \c run \o Run the application on the emulator. \row \o \c runonphone \o Run the application on a device. \row \o \c sis \o Create signed \c .sis file for project. + \row \o \c installer_sis \o Create signed \l{Smart Installer}{smart installer} + \c .sis file for project. + Smart installer will attempt to download + missing dependencies in addition to + just installing the application. \endtable The following lines perform a debug build for the emulator @@ -137,6 +142,14 @@ To work on your project in Carbide, simply import the \c .pro file by right clicking on the project explorer and executing "Import...". + \section2 Smart Installer + + The Smart Installer makes sure that deployed applications have all the Qt dependencies + they need to run on a device. + + Download the latest release of the Smart Installer from \l{http://get.qt.nokia.com/nokiasmartinstaller/}, + and install it on top of the Qt package. + \section1 Installing your own applications To install your own applications on hardware, you need a signed \c .sis file. diff --git a/doc/src/snippets/code/doc_src_deployment.qdoc b/doc/src/snippets/code/doc_src_deployment.qdoc index 9c00681..3b0cda1 100644 --- a/doc/src/snippets/code/doc_src_deployment.qdoc +++ b/doc/src/snippets/code/doc_src_deployment.qdoc @@ -475,19 +475,10 @@ default_deployment.pkg_prerules += supported_platforms //! [57] //! [58] -DEPLOYMENT.installer_header = 0xE2345678 -//! [58] - -//! [59] qmake make release-gcce -//! [59] - -//! [60] -make sis -ren wiggly_release-gcce.sis wiggly.sis -//! [60] +//! [58] -//! [61] -createpackage wiggly_installer.pkg -//! [61]
\ No newline at end of file +//! [59] +make installer_sis +//! [59]
\ No newline at end of file diff --git a/examples/network/bearercloud/bearercloud.cpp b/examples/network/bearercloud/bearercloud.cpp new file mode 100644 index 0000000..27a296d --- /dev/null +++ b/examples/network/bearercloud/bearercloud.cpp @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bearercloud.h" +#include "cloud.h" + +#include <QGraphicsTextItem> +#include <QTimer> +#include <QDateTime> +#include <QHostInfo> + +#include <QDebug> + +#include <math.h> + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +//! [0] +BearerCloud::BearerCloud(QObject *parent) +: QGraphicsScene(parent), timerId(0) +{ + setSceneRect(-300, -300, 600, 600); + + qsrand(QDateTime::currentDateTime().toTime_t()); + + offset[QNetworkConfiguration::Active] = 2 * M_PI * qrand() / RAND_MAX; + offset[QNetworkConfiguration::Discovered] = offset[QNetworkConfiguration::Active] + M_PI / 6; + offset[QNetworkConfiguration::Defined] = offset[QNetworkConfiguration::Discovered] - M_PI / 6; + offset[QNetworkConfiguration::Undefined] = offset[QNetworkConfiguration::Undefined] + M_PI / 6; + + thisDevice = new QGraphicsTextItem(QHostInfo::localHostName()); + thisDevice->setData(0, QLatin1String("This Device")); + thisDevice->setPos(thisDevice->boundingRect().width() / -2, + thisDevice->boundingRect().height() / -2); + addItem(thisDevice); + + qreal radius = Cloud::getRadiusForState(QNetworkConfiguration::Active); + QGraphicsEllipseItem *orbit = new QGraphicsEllipseItem(-radius, -radius, 2*radius, 2*radius); + orbit->setPen(QColor(Qt::green)); + addItem(orbit); + radius = Cloud::getRadiusForState(QNetworkConfiguration::Discovered); + orbit = new QGraphicsEllipseItem(-radius, -radius, 2*radius, 2*radius); + orbit->setPen(QColor(Qt::blue)); + addItem(orbit); + radius = Cloud::getRadiusForState(QNetworkConfiguration::Defined); + orbit = new QGraphicsEllipseItem(-radius, -radius, 2*radius, 2*radius); + orbit->setPen(QColor(Qt::darkGray)); + addItem(orbit); + radius = Cloud::getRadiusForState(QNetworkConfiguration::Undefined); + orbit = new QGraphicsEllipseItem(-radius, -radius, 2*radius, 2*radius); + orbit->setPen(QColor(Qt::lightGray)); + addItem(orbit); + + connect(&manager, SIGNAL(configurationAdded(QNetworkConfiguration)), + this, SLOT(configurationAdded(QNetworkConfiguration))); + connect(&manager, SIGNAL(configurationRemoved(QNetworkConfiguration)), + this, SLOT(configurationRemoved(QNetworkConfiguration))); + connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)), + this, SLOT(configurationChanged(QNetworkConfiguration))); + + QTimer::singleShot(0, this, SLOT(updateConfigurations())); +} +//! [0] + +BearerCloud::~BearerCloud() +{ +} + +void BearerCloud::cloudMoved() +{ + if (!timerId) + timerId = startTimer(1000 / 25); +} + +void BearerCloud::timerEvent(QTimerEvent *) +{ + QList<Cloud *> clouds; + foreach (QGraphicsItem *item, items()) { + if (Cloud *cloud = qgraphicsitem_cast<Cloud *>(item)) + clouds << cloud; + } + + foreach (Cloud *cloud, clouds) + cloud->calculateForces(); + + bool cloudsMoved = false; + foreach (Cloud *cloud, clouds) + cloudsMoved |= cloud->advance(); + + if (!cloudsMoved) { + killTimer(timerId); + timerId = 0; + } +} + +//! [2] +void BearerCloud::configurationAdded(const QNetworkConfiguration &config) +{ + const QNetworkConfiguration::StateFlags state = config.state(); + + configStates.insert(state, config.identifier()); + + const qreal radius = Cloud::getRadiusForState(state); + const int count = configStates.count(state); + const qreal angle = 2 * M_PI / count; + + Cloud *item = new Cloud(config); + configurations.insert(config.identifier(), item); + + item->setPos(radius * cos((count-1) * angle + offset[state]), + radius * sin((count-1) * angle + offset[state])); + + addItem(item); + + cloudMoved(); +} +//! [2] + +//! [3] +void BearerCloud::configurationRemoved(const QNetworkConfiguration &config) +{ + foreach (const QNetworkConfiguration::StateFlags &state, configStates.uniqueKeys()) + configStates.remove(state, config.identifier()); + + Cloud *item = configurations.take(config.identifier()); + + item->setFinalScale(0.0); + item->setDeleteAfterAnimation(true); + + cloudMoved(); +} +//! [3] + +//! [4] +void BearerCloud::configurationChanged(const QNetworkConfiguration &config) +{ + foreach (const QNetworkConfiguration::StateFlags &state, configStates.uniqueKeys()) + configStates.remove(state, config.identifier()); + + configStates.insert(config.state(), config.identifier()); + + cloudMoved(); +} +//! [4] + +//! [1] +void BearerCloud::updateConfigurations() +{ + QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations(); + + while (!allConfigurations.isEmpty()) + configurationAdded(allConfigurations.takeFirst()); + + cloudMoved(); +} +//! [1] + diff --git a/examples/network/bearercloud/bearercloud.h b/examples/network/bearercloud/bearercloud.h new file mode 100644 index 0000000..f09cb53 --- /dev/null +++ b/examples/network/bearercloud/bearercloud.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qnetworkconfigmanager.h> + +#include <QGraphicsScene> +#include <QMap> +#include <QHash> + +QT_USE_NAMESPACE + +class Cloud; + +class BearerCloud : public QGraphicsScene +{ + Q_OBJECT + +public: + BearerCloud(QObject *parent = 0); + ~BearerCloud(); + + void cloudMoved(); + + void timerEvent(QTimerEvent *event); + +private Q_SLOTS: + void configurationAdded(const QNetworkConfiguration &config); + void configurationRemoved(const QNetworkConfiguration &config); + void configurationChanged(const QNetworkConfiguration &config); + void updateConfigurations(); + +private: + QNetworkConfigurationManager manager; + + QGraphicsTextItem *thisDevice; + QHash<QString, Cloud *> configurations; + + QMap<QNetworkConfiguration::StateFlags, qreal> offset; + QMultiMap<QNetworkConfiguration::StateFlags, QString> configStates; + + int timerId; +}; + diff --git a/examples/network/bearercloud/bearercloud.pro b/examples/network/bearercloud/bearercloud.pro new file mode 100644 index 0000000..c07626a --- /dev/null +++ b/examples/network/bearercloud/bearercloud.pro @@ -0,0 +1,16 @@ +HEADERS = bearercloud.h \ + cloud.h + +SOURCES = main.cpp \ + bearercloud.cpp \ + cloud.cpp + +RESOURCES = icons.qrc + +TARGET = bearercloud + +QT = core gui network svg + +CONFIG += console + +symbian:TARGET.CAPABILITY = NetworkServices ReadUserData diff --git a/examples/network/bearercloud/cloud.cpp b/examples/network/bearercloud/cloud.cpp new file mode 100644 index 0000000..81e13a6 --- /dev/null +++ b/examples/network/bearercloud/cloud.cpp @@ -0,0 +1,361 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "cloud.h" +#include "bearercloud.h" + +#include <qnetworksession.h> + +#include <QGraphicsTextItem> +#include <QGraphicsSvgItem> +#include <QGraphicsSceneMouseEvent> +#include <QSvgRenderer> +#include <QPainter> + +#include <QDebug> + +#include <math.h> + +static QMap<QString, QSvgRenderer *> svgCache; + +//! [0] +Cloud::Cloud(const QNetworkConfiguration &config, QGraphicsItem *parent) +: QGraphicsItem(parent), configuration(config), deleteAfterAnimation(false) +{ + session = new QNetworkSession(configuration, this); + connect(session, SIGNAL(newConfigurationActivated()), + this, SLOT(newConfigurationActivated())); + connect(session, SIGNAL(stateChanged(QNetworkSession::State)), + this, SLOT(stateChanged(QNetworkSession::State))); + + setFlag(ItemIsMovable); +#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)) + setFlag(ItemSendsGeometryChanges); +#endif + setZValue(1); + + icon = new QGraphicsSvgItem(this); + text = new QGraphicsTextItem(this); + + currentScale = 0; + finalScale = 1; + setTransform(QTransform::fromScale(currentScale, currentScale), false); + setOpacity(0); + + newConfigurationActivated(); +} +//! [0] + +Cloud::~Cloud() +{ +} + +void Cloud::setFinalScale(qreal factor) +{ + finalScale = factor; +} + +void Cloud::setDeleteAfterAnimation(bool deleteAfter) +{ + deleteAfterAnimation = deleteAfter; +} + +void Cloud::calculateForces() +{ + if (!scene() || scene()->mouseGrabberItem() == this) { + newPos = pos(); + return; + } + + // sum up all the forces push this item away + qreal xvel = 0; + qreal yvel = 0; + QLineF orbitForce; + foreach (QGraphicsItem *item, scene()->items()) { + // other clouds + Cloud *cloud = qgraphicsitem_cast<Cloud *>(item); + if (!cloud && item->data(0) != QLatin1String("This Device")) + continue; + + qreal factor = 1.0; + + QLineF line(cloud ? item->mapToScene(0, 0) : QPointF(0, 0), mapToScene(0, 0)); + if (item->data(0) == QLatin1String("This Device")) + orbitForce = line; + + if (cloud) + factor = cloud->currentScale; + + qreal dx = line.dx(); + qreal dy = line.dy(); + double l = 2.0 * (dx * dx + dy * dy); + if (l > 0) { + xvel += factor * dx * 200.0 / l; + yvel += factor * dy * 200.0 / l; + } + } + + // tendency to stay at a fixed orbit + qreal orbit = getRadiusForState(configuration.state()); + qreal distance = orbitForce.length(); + + QLineF unit = orbitForce.unitVector(); + + orbitForce.setLength(xvel * unit.dx() + yvel * unit.dy()); + + qreal w = 2 - exp(-pow(distance-orbit, 2)/(2 * 50)); + + if (distance < orbit) { + xvel += orbitForce.dx() * w; + yvel += orbitForce.dy() * w; + } else { + xvel -= orbitForce.dx() * w; + yvel -= orbitForce.dy() * w; + } + + if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1) + xvel = yvel = 0; + + QRectF sceneRect = scene()->sceneRect(); + newPos = pos() + QPointF(xvel, yvel); + newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)); + newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10)); +} + +bool Cloud::advance() +{ + static const qreal scaleDelta = 0.01; + + bool animated = false; + + if (currentScale < finalScale) { + animated = true; + currentScale = qMin<qreal>(currentScale + scaleDelta, finalScale); + setTransform(QTransform::fromScale(currentScale, currentScale), false); + } else if (currentScale > finalScale) { + animated = true; + currentScale = qMax<qreal>(currentScale - scaleDelta, finalScale); + setTransform(QTransform::fromScale(currentScale, currentScale), false); + } + + if (newPos != pos()) { + setPos(newPos); + animated = true; + } + + if (opacity() != finalOpacity) { + animated = true; + if (qAbs(finalScale - currentScale) > 0.0) { + // use scale as reference + setOpacity(opacity() + scaleDelta * (finalOpacity - opacity()) / + qAbs(finalScale - currentScale)); + } else { + setOpacity(finalOpacity); + } + } + + if (!animated && deleteAfterAnimation) + deleteLater(); + + return animated; +} + +QRectF Cloud::boundingRect() const +{ + return childrenBoundingRect(); +} + +void Cloud::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) +{ +} + +//! [4] +QVariant Cloud::itemChange(GraphicsItemChange change, const QVariant &value) +{ + switch (change) { + case ItemPositionHasChanged: + if (BearerCloud *bearercloud = qobject_cast<BearerCloud *>(scene())) + bearercloud->cloudMoved(); + default: + ; + }; + + return QGraphicsItem::itemChange(change, value); +} +//! [4] + +//! [3] +void Cloud::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + if (session->isOpen()) + session->close(); + else + session->open(); + + event->accept(); + } +} +//! [3] + +//! [2] +void Cloud::stateChanged(QNetworkSession::State state) +{ + if (configuration.name().isEmpty()) + finalOpacity = qreal(0.1); + else if (session->state() == QNetworkSession::NotAvailable) + finalOpacity = 0.5; + else + finalOpacity = 1.0; + + QString tooltip; + + if (configuration.name().isEmpty()) + tooltip += tr("<b>HIDDEN NETWORK</b><br>"); + else + tooltip += tr("<b>%1</b><br>").arg(configuration.name()); + + const QNetworkInterface interface = session->interface(); + if (interface.isValid()) + tooltip += tr("<br>Interface: %1").arg(interface.humanReadableName()); + tooltip += tr("<br>Id: %1").arg(configuration.identifier()); + + const QString bearerName = configuration.bearerName(); + if (!bearerName.isEmpty()) + tooltip += tr("<br>Bearer: %1").arg(bearerName); + + QString s = tr("<br>State: %1 (%2)"); + switch (state) { + case QNetworkSession::Invalid: + s = s.arg(tr("Invalid")); + break; + case QNetworkSession::NotAvailable: + s = s.arg(tr("Not Available")); + break; + case QNetworkSession::Connecting: + s = s.arg(tr("Connecting")); + break; + case QNetworkSession::Connected: + s = s.arg(tr("Connected")); + break; + case QNetworkSession::Closing: + s = s.arg(tr("Closing")); + break; + case QNetworkSession::Disconnected: + s = s.arg(tr("Disconnected")); + break; + case QNetworkSession::Roaming: + s = s.arg(tr("Roaming")); + break; + default: + s = s.arg(tr("Unknown")); + } + + if (session->isOpen()) + s = s.arg(tr("Open")); + else + s = s.arg(tr("Closed")); + + tooltip += s; + + tooltip += tr("<br><br>Active time: %1 seconds").arg(session->activeTime()); + tooltip += tr("<br>Received data: %1 bytes").arg(session->bytesReceived()); + tooltip += tr("<br>Sent data: %1 bytes").arg(session->bytesWritten()); + + setToolTip(tooltip); +} +//! [2] + +//! [1] +void Cloud::newConfigurationActivated() +{ + const QString bearerName = configuration.bearerName(); + if (!svgCache.contains(bearerName)) { + if (bearerName == QLatin1String("WLAN")) + svgCache.insert(bearerName, new QSvgRenderer(QLatin1String(":wlan.svg"))); + else if (bearerName == QLatin1String("Ethernet")) + svgCache.insert(bearerName, new QSvgRenderer(QLatin1String(":lan.svg"))); + else + svgCache.insert(bearerName, new QSvgRenderer(QLatin1String(":unknown.svg"))); + } + + icon->setSharedRenderer(svgCache[bearerName]); + + if (configuration.name().isEmpty()) { + text->setPlainText(tr("HIDDEN NETWORK")); + } else { + if (configuration.type() == QNetworkConfiguration::ServiceNetwork) + text->setHtml("<b>" + configuration.name() + "</b>"); + else + text->setPlainText(configuration.name()); + } + + const qreal height = icon->boundingRect().height() + text->boundingRect().height(); + + icon->setPos(icon->boundingRect().width() / -2, height / -2); + + text->setPos(text->boundingRect().width() / -2, + height / 2 - text->boundingRect().height()); + + stateChanged(session->state()); +} +//! [1] + +qreal Cloud::getRadiusForState(QNetworkConfiguration::StateFlags state) +{ + switch (state) { + case QNetworkConfiguration::Active: + return 100; + break; + case QNetworkConfiguration::Discovered: + return 150; + break; + case QNetworkConfiguration::Defined: + return 200; + break; + case QNetworkConfiguration::Undefined: + return 250; + break; + default: + return 300; + } +} + diff --git a/examples/network/bearercloud/cloud.h b/examples/network/bearercloud/cloud.h new file mode 100644 index 0000000..38f8aff --- /dev/null +++ b/examples/network/bearercloud/cloud.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qnetworkconfiguration.h> +#include <qnetworksession.h> + +#include <QGraphicsItem> +QT_USE_NAMESPACE + +QT_BEGIN_NAMESPACE +class QGraphicsTextItem; +class QGraphicsSvgItem; +QT_END_NAMESPACE + +class Cloud : public QObject, public QGraphicsItem +{ + Q_OBJECT + Q_INTERFACES(QGraphicsItem) + +public: + Cloud(const QNetworkConfiguration &config, QGraphicsItem *parent = 0); + ~Cloud(); + + enum { Type = UserType + 1 }; + int type() const { return Type; } + + void setFinalScale(qreal factor); + void setDeleteAfterAnimation(bool deleteAfter); + + void calculateForces(); + + bool advance(); + QRectF boundingRect() const; + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); + + static qreal getRadiusForState(QNetworkConfiguration::StateFlags state); + +protected: + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + +private Q_SLOTS: + void stateChanged(QNetworkSession::State state); + void newConfigurationActivated(); + +private: + QNetworkConfiguration configuration; + QNetworkSession *session; + + QGraphicsTextItem *text; + QGraphicsSvgItem *icon; + + qreal finalOpacity; + qreal finalScale; + qreal currentScale; + + QPointF newPos; + + bool deleteAfterAnimation; +}; + diff --git a/examples/network/bearercloud/icons.qrc b/examples/network/bearercloud/icons.qrc new file mode 100644 index 0000000..84a8939 --- /dev/null +++ b/examples/network/bearercloud/icons.qrc @@ -0,0 +1,7 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>wlan.svg</file> + <file>lan.svg</file> + <file>unknown.svg</file> +</qresource> +</RCC> diff --git a/examples/network/bearercloud/lan.svg b/examples/network/bearercloud/lan.svg new file mode 100644 index 0000000..3cce805 --- /dev/null +++ b/examples/network/bearercloud/lan.svg @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="25.000002" + height="9.6406126" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + version="1.0" + sodipodi:docname="lan.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="19.416667" + inkscape:cx="15.244635" + inkscape:cy="11.639485" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1459" + inkscape:window-height="964" + inkscape:window-x="453" + inkscape:window-y="166" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-4.0978193e-8,-19.359387)"> + <text + xml:space="preserve" + style="font-size:13.99289513px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="-1.1205248" + y="29" + id="text3239"><tspan + sodipodi:role="line" + id="tspan3241" + x="-1.1205248" + y="29">LAN</tspan></text> + </g> +</svg> diff --git a/examples/network/bearercloud/main.cpp b/examples/network/bearercloud/main.cpp new file mode 100644 index 0000000..86ef46f --- /dev/null +++ b/examples/network/bearercloud/main.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bearercloud.h" + +#include <QApplication> +#include <QGraphicsView> + +class CloudView : public QGraphicsView +{ + Q_OBJECT + +public: + CloudView(QGraphicsScene *scene); + ~CloudView() { } + +protected: + void resizeEvent(QResizeEvent *) { + fitInView(sceneRect(), Qt::KeepAspectRatio); + } +#ifdef Q_OS_WINCE + void hideEvent(QHideEvent *) { + qApp->quit(); + } +#endif +}; + +CloudView::CloudView(QGraphicsScene *scene) +: QGraphicsView(scene) +{ + setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing | + QPainter::SmoothPixmapTransform); +#if defined (Q_OS_SYMBIAN) || defined (Q_OS_WINCE) + setWindowState(Qt::WindowMaximized); +#endif +} + +#include "main.moc" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + BearerCloud bearerCloud; + + CloudView view(&bearerCloud); + view.show(); + + return app.exec(); +} + diff --git a/examples/network/bearercloud/unknown.svg b/examples/network/bearercloud/unknown.svg new file mode 100644 index 0000000..fd10298 --- /dev/null +++ b/examples/network/bearercloud/unknown.svg @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="25" + height="9.0681238" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + version="1.0" + sodipodi:docname="unknown.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="19.416667" + inkscape:cx="15.244635" + inkscape:cy="11.639485" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1459" + inkscape:window-height="964" + inkscape:window-x="453" + inkscape:window-y="166" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-6.891787e-8,-19.931876)"> + <text + xml:space="preserve" + style="font-size:13.16195393px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="-1.0539845" + y="29" + id="text3239"><tspan + sodipodi:role="line" + id="tspan3241" + x="-1.0539845" + y="29">NET</tspan></text> + </g> +</svg> diff --git a/examples/network/bearercloud/wlan.svg b/examples/network/bearercloud/wlan.svg new file mode 100644 index 0000000..8b86089 --- /dev/null +++ b/examples/network/bearercloud/wlan.svg @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="27" + height="29" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + version="1.0" + sodipodi:docname="wlan.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="19.416667" + inkscape:cx="23.665236" + inkscape:cy="11.639485" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1912" + inkscape:window-height="1130" + inkscape:window-x="0" + inkscape:window-y="0" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + id="g6334" + transform="translate(1.0000001,0)"> + <path + id="path2393" + d="M 12.500248,9.499893 L 12.500248,28.500095" + style="fill:none;fill-rule:evenodd;stroke:#3bb3ff;stroke-width:0.99981093;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + sodipodi:open="true" + sodipodi:end="4.1887902" + sodipodi:start="2.0943951" + transform="matrix(1.0216765,0,0,1.0324764,0.4493163,-22.692096)" + d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513" + sodipodi:ry="3.9141631" + sodipodi:rx="3.9141631" + sodipodi:cy="30.695278" + sodipodi:cx="10.815451" + id="path3171" + style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.97365081;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" /> + <path + sodipodi:open="true" + sodipodi:end="4.1887902" + sodipodi:start="2.0943951" + transform="matrix(1.6055152,0,0,1.6224868,-7.5798083,-40.80263)" + d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513" + sodipodi:ry="3.9141631" + sodipodi:rx="3.9141631" + sodipodi:cy="30.695278" + sodipodi:cx="10.815451" + id="path3175" + style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.61958688;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" /> + <path + sodipodi:open="true" + sodipodi:end="4.1887902" + sodipodi:start="2.0943951" + transform="matrix(2.4812855,0,0,2.5075146,-17.62358,-67.968804)" + d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513" + sodipodi:ry="3.9141631" + sodipodi:rx="3.9141631" + sodipodi:cy="30.695278" + sodipodi:cx="10.815451" + id="path3177" + style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.40090355;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" /> + <path + sodipodi:open="true" + sodipodi:end="4.1887902" + sodipodi:start="2.0943951" + transform="matrix(-1.0216765,0,0,1.0324764,24.550388,-22.692096)" + d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513" + sodipodi:ry="3.9141631" + sodipodi:rx="3.9141631" + sodipodi:cy="30.695278" + sodipodi:cx="10.815451" + id="path3179" + style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.97365081;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" /> + <path + sodipodi:open="true" + sodipodi:end="4.1887902" + sodipodi:start="2.0943951" + transform="matrix(-1.6055152,0,0,1.6224868,32.580246,-40.80263)" + d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513" + sodipodi:ry="3.9141631" + sodipodi:rx="3.9141631" + sodipodi:cy="30.695278" + sodipodi:cx="10.815451" + id="path3181" + style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.61958688;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" /> + <path + sodipodi:open="true" + sodipodi:end="4.1887902" + sodipodi:start="2.0943951" + transform="matrix(-2.4812855,0,0,2.5075146,42.623143,-67.968804)" + d="M 8.8583691,34.085043 A 3.9141631,3.9141631 0 0 1 8.8583691,27.305513" + sodipodi:ry="3.9141631" + sodipodi:rx="3.9141631" + sodipodi:cy="30.695278" + sodipodi:cx="10.815451" + id="path3183" + style="fill:none;fill-opacity:0;stroke:#3bb3ff;stroke-width:0.40090355;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" /> + </g> + </g> +</svg> diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp new file mode 100644 index 0000000..5b2bad1 --- /dev/null +++ b/examples/network/bearermonitor/bearermonitor.cpp @@ -0,0 +1,395 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bearermonitor.h" +#include "sessionwidget.h" + +#include <QDebug> + +#ifdef Q_OS_WIN +#include <winsock2.h> +#undef interface + +#ifndef NS_NLA +#define NS_NLA 15 +#endif +#endif + +BearerMonitor::BearerMonitor(QWidget *parent) +: QWidget(parent) +{ + setupUi(this); + delete tabWidget->currentWidget(); + sessionGroup->hide(); +#if defined (Q_OS_SYMBIAN) || defined(Q_OS_WINCE) + setWindowState(Qt::WindowMaximized); +#endif + updateConfigurations(); + + onlineStateChanged(!manager.allConfigurations(QNetworkConfiguration::Active).isEmpty()); + + QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration(); + for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) { + QTreeWidgetItem *item = treeWidget->topLevelItem(i); + + if (item->data(0, Qt::UserRole).toString() == defaultConfiguration.identifier()) { + treeWidget->setCurrentItem(item); + showConfigurationFor(item); + break; + } + } + + connect(&manager, SIGNAL(configurationAdded(const QNetworkConfiguration&)), + this, SLOT(configurationAdded(const QNetworkConfiguration&))); + connect(&manager, SIGNAL(configurationRemoved(const QNetworkConfiguration&)), + this, SLOT(configurationRemoved(const QNetworkConfiguration&))); + connect(&manager, SIGNAL(configurationChanged(const QNetworkConfiguration&)), + this, SLOT(configurationChanged(const QNetworkConfiguration))); + connect(&manager, SIGNAL(updateCompleted()), this, SLOT(updateConfigurations())); + connect(&manager, SIGNAL(onlineStateChanged(bool)), this ,SLOT(onlineStateChanged(bool))); + +#ifdef Q_OS_WIN + connect(registerButton, SIGNAL(clicked()), this, SLOT(registerNetwork())); + connect(unregisterButton, SIGNAL(clicked()), this, SLOT(unregisterNetwork())); +#else + nlaGroup->hide(); +#endif + + connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), + this, SLOT(createSessionFor(QTreeWidgetItem*))); + + connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), + this, SLOT(showConfigurationFor(QTreeWidgetItem*))); + + connect(newSessionButton, SIGNAL(clicked()), + this, SLOT(createNewSession())); + connect(deleteSessionButton, SIGNAL(clicked()), + this, SLOT(deleteSession())); + + connect(scanButton, SIGNAL(clicked()), + this, SLOT(performScan())); +} + +BearerMonitor::~BearerMonitor() +{ +} + +static void updateItem(QTreeWidgetItem *item, const QNetworkConfiguration &config) +{ + item->setText(0, config.name()); + item->setData(0, Qt::UserRole, config.identifier()); + + QFont font = item->font(1); + font.setBold((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active); + item->setFont(0, font); +} + +void BearerMonitor::configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent) +{ + QTreeWidgetItem *item = new QTreeWidgetItem; + updateItem(item, config); + + if (parent) + parent->addChild(item); + else + treeWidget->addTopLevelItem(item); + + if (config.type() == QNetworkConfiguration::ServiceNetwork) { + foreach (const QNetworkConfiguration &child, config.children()) + configurationAdded(child, item); + } +} + +void BearerMonitor::configurationRemoved(const QNetworkConfiguration &config) +{ + for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) { + QTreeWidgetItem *item = treeWidget->topLevelItem(i); + + if (item->data(0, Qt::UserRole).toString() == config.identifier()) { + delete item; + break; + } + } +} + +void BearerMonitor::configurationChanged(const QNetworkConfiguration &config) +{ + for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) { + QTreeWidgetItem *item = treeWidget->topLevelItem(i); + + if (item->data(0, Qt::UserRole).toString() == config.identifier()) { + updateItem(item, config); + + if (config.type() == QNetworkConfiguration::ServiceNetwork) + updateSnapConfiguration(item, config); + + if (item == treeWidget->currentItem()) + showConfigurationFor(item); + + break; + } + } +} + +void BearerMonitor::updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap) +{ + QMap<QString, QTreeWidgetItem *> itemMap; + for (int i = 0; i < parent->childCount(); ++i) { + QTreeWidgetItem *item = parent->child(i); + itemMap.insert(item->data(0, Qt::UserRole).toString(), item); + } + + QList<QNetworkConfiguration> allConfigurations = snap.children(); + + while (!allConfigurations.isEmpty()) { + QNetworkConfiguration config = allConfigurations.takeFirst(); + + QTreeWidgetItem *item = itemMap.take(config.identifier()); + if (item) { + updateItem(item, config); + + if (config.type() == QNetworkConfiguration::ServiceNetwork) + updateSnapConfiguration(item, config); + } else { + configurationAdded(config, parent); + } + } + + foreach (const QString &id, itemMap.keys()) + delete itemMap.value(id); + + itemMap.clear(); +} + +void BearerMonitor::updateConfigurations() +{ + progressBar->hide(); + scanButton->show(); + + QList<QTreeWidgetItem *> items = treeWidget->findItems(QLatin1String("*"), Qt::MatchWildcard); + QMap<QString, QTreeWidgetItem *> itemMap; + while (!items.isEmpty()) { + QTreeWidgetItem *item = items.takeFirst(); + itemMap.insert(item->data(0, Qt::UserRole).toString(), item); + } + + QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations(); + + while (!allConfigurations.isEmpty()) { + QNetworkConfiguration config = allConfigurations.takeFirst(); + + QTreeWidgetItem *item = itemMap.take(config.identifier()); + if (item) { + updateItem(item, config); + + if (config.type() == QNetworkConfiguration::ServiceNetwork) + updateSnapConfiguration(item, config); + } else { + configurationAdded(config); + } + } + + foreach (const QString &id, itemMap.keys()) + delete itemMap.value(id); +} + +void BearerMonitor::onlineStateChanged(bool isOnline) +{ + if (isOnline) + onlineState->setText(tr("Online")); + else + onlineState->setText(tr("Offline")); +} + +#ifdef Q_OS_WIN +void BearerMonitor::registerNetwork() +{ + QTreeWidgetItem *item = treeWidget->currentItem(); + + QNetworkConfiguration configuration = + manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString()); + + const QString name = configuration.name(); + + qDebug() << "Registering" << name << "with system"; + + WSAQUERYSET networkInfo; + memset(&networkInfo, 0, sizeof(networkInfo)); + networkInfo.dwSize = sizeof(networkInfo); + networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16(); + networkInfo.dwNameSpace = NS_NLA; + + if (WSASetService(&networkInfo, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR) + qDebug() << "WSASetService(RNRSERVICE_REGISTER) returned" << WSAGetLastError(); +} + +void BearerMonitor::unregisterNetwork() +{ + QTreeWidgetItem *item = treeWidget->currentItem(); + + QNetworkConfiguration configuration = + manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString()); + + const QString name = configuration.name(); + + qDebug() << "Unregistering" << name << "with system"; + + WSAQUERYSET networkInfo; + memset(&networkInfo, 0, sizeof(networkInfo)); + networkInfo.dwSize = sizeof(networkInfo); + networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16(); + networkInfo.dwNameSpace = NS_NLA; + + if (WSASetService(&networkInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR) + qDebug() << "WSASetService(RNRSERVICE_DELETE) returned" << WSAGetLastError(); +} +#endif + +void BearerMonitor::showConfigurationFor(QTreeWidgetItem *item) +{ + QString identifier; + + if (item) + identifier = item->data(0, Qt::UserRole).toString(); + + QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier); + + switch (conf.state()) { + case QNetworkConfiguration::Active: + configurationState->setText(tr("Active")); + break; + case QNetworkConfiguration::Discovered: + configurationState->setText(tr("Discovered")); + break; + case QNetworkConfiguration::Defined: + configurationState->setText(tr("Defined")); + break; + case QNetworkConfiguration::Undefined: + configurationState->setText(tr("Undefined")); + break; + default: + configurationState->setText(QString()); + } + + switch (conf.type()) { + case QNetworkConfiguration::InternetAccessPoint: + configurationType->setText(tr("Internet Access Point")); + break; + case QNetworkConfiguration::ServiceNetwork: + configurationType->setText(tr("Service Network")); + break; + case QNetworkConfiguration::UserChoice: + configurationType->setText(tr("User Choice")); + break; + case QNetworkConfiguration::Invalid: + configurationType->setText(tr("Invalid")); + break; + default: + configurationType->setText(QString()); + } + + switch (conf.purpose()) { + case QNetworkConfiguration::UnknownPurpose: + configurationPurpose->setText(tr("Unknown")); + break; + case QNetworkConfiguration::PublicPurpose: + configurationPurpose->setText(tr("Public")); + break; + case QNetworkConfiguration::PrivatePurpose: + configurationPurpose->setText(tr("Private")); + break; + case QNetworkConfiguration::ServiceSpecificPurpose: + configurationPurpose->setText(tr("Service Specific")); + break; + default: + configurationPurpose->setText(QString()); + } + + configurationIdentifier->setText(conf.identifier()); + + configurationRoaming->setText(conf.isRoamingAvailable() ? tr("Available") : tr("Not available")); + + configurationChildren->setText(QString::number(conf.children().count())); + + configurationName->setText(conf.name()); +} + +void BearerMonitor::createSessionFor(QTreeWidgetItem *item) +{ + const QString identifier = item->data(0, Qt::UserRole).toString(); + + QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier); + + SessionWidget *session = new SessionWidget(conf); + + tabWidget->addTab(session, conf.name()); + + sessionGroup->show(); + + sessionWidgets.append(session); +} + +void BearerMonitor::createNewSession() +{ + QTreeWidgetItem *item = treeWidget->currentItem(); + + createSessionFor(item); +} + +void BearerMonitor::deleteSession() +{ + SessionWidget *session = qobject_cast<SessionWidget *>(tabWidget->currentWidget()); + if (session) { + sessionWidgets.removeAll(session); + + delete session; + + if (tabWidget->count() == 0) + sessionGroup->hide(); + } +} + +void BearerMonitor::performScan() +{ + scanButton->hide(); + progressBar->show(); + manager.updateConfigurations(); +} diff --git a/examples/network/bearermonitor/bearermonitor.h b/examples/network/bearermonitor/bearermonitor.h new file mode 100644 index 0000000..d7025dd --- /dev/null +++ b/examples/network/bearermonitor/bearermonitor.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BEARERMONITOR_H +#define BEARERMONITOR_H + +#include <qnetworkconfigmanager.h> +#include <qnetworksession.h> +#if defined (Q_OS_SYMBIAN) || defined(Q_OS_WINCE) +#include "ui_bearermonitor_240_320.h" +#else +#include "ui_bearermonitor_640_480.h" +#endif + +QT_USE_NAMESPACE + +class SessionWidget; + +class BearerMonitor : public QWidget, public Ui_BearerMonitor +{ + Q_OBJECT + +public: + BearerMonitor(QWidget *parent = 0); + ~BearerMonitor(); + +private slots: + void configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent = 0); + void configurationRemoved(const QNetworkConfiguration &config); + void configurationChanged(const QNetworkConfiguration &config); + void updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap); + void updateConfigurations(); + + void onlineStateChanged(bool isOnline); + +#ifdef Q_OS_WIN + void registerNetwork(); + void unregisterNetwork(); +#endif + + void showConfigurationFor(QTreeWidgetItem *item); + + void createSessionFor(QTreeWidgetItem *item); + void createNewSession(); + void deleteSession(); + + void performScan(); + +private: + QNetworkConfigurationManager manager; + QList<SessionWidget *> sessionWidgets; +}; + +#endif //BEARERMONITOR_H diff --git a/examples/network/bearermonitor/bearermonitor.pro b/examples/network/bearermonitor/bearermonitor.pro new file mode 100644 index 0000000..4b86187 --- /dev/null +++ b/examples/network/bearermonitor/bearermonitor.pro @@ -0,0 +1,26 @@ +HEADERS = sessionwidget.h \ + bearermonitor.h + +SOURCES = main.cpp \ + bearermonitor.cpp \ + sessionwidget.cpp + +FORMS = bearermonitor_240_320.ui \ + bearermonitor_640_480.ui \ + sessionwidget.ui + +TARGET = bearermonitor + +QT = core gui network + +win32 { + !wince* { + LIBS += -lWs2_32 + } else { + LIBS += -lWs2 + } +} + +CONFIG += console + +symbian:TARGET.CAPABILITY = NetworkServices ReadUserData diff --git a/examples/network/bearermonitor/bearermonitor_240_320.ui b/examples/network/bearermonitor/bearermonitor_240_320.ui new file mode 100644 index 0000000..ce9c2d1 --- /dev/null +++ b/examples/network/bearermonitor/bearermonitor_240_320.ui @@ -0,0 +1,420 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>BearerMonitor</class> + <widget class="QWidget" name="BearerMonitor"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>240</width> + <height>320</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>-274</y> + <width>206</width> + <height>576</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QGroupBox" name="systemState"> + <property name="title"> + <string>System State</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="onlineStateLayout"> + <item> + <widget class="QLabel" name="onlineStateLabel"> + <property name="text"> + <string>Online State:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="onlineState"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Configurations</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_9"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="configurationNameLayout"> + <item> + <widget class="QLabel" name="configurationNameLabel"> + <property name="text"> + <string>Name:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationStateLayout"> + <item> + <widget class="QLabel" name="configurationStateLabel"> + <property name="text"> + <string>State:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationState"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationTypeLayout"> + <item> + <widget class="QLabel" name="configurationTypeLabel"> + <property name="text"> + <string>Type:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationType"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Invalid</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationPurposeLayout"> + <item> + <widget class="QLabel" name="configurationPurposeLabel"> + <property name="text"> + <string>Purpose:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationPurpose"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Unknown</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationIdentifierLayout"> + <item> + <widget class="QLabel" name="configurationIdentifierLabel"> + <property name="text"> + <string>Identifier:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationIdentifier"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationRoamingLayout"> + <item> + <widget class="QLabel" name="configurationRoamingLabel"> + <property name="text"> + <string>Roaming:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationRoaming"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationChildrenLayout"> + <item> + <widget class="QLabel" name="configurationChildrenLabel"> + <property name="text"> + <string>Children:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationChildren"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="nlaGroup"> + <property name="title"> + <string>Network Location Awareness</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="registerButton"> + <property name="text"> + <string>Register</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="unregisterButton"> + <property name="text"> + <string>Unregister</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QPushButton" name="newSessionButton"> + <property name="text"> + <string>New Session</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="deleteSessionButton"> + <property name="text"> + <string>Delete Session</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="scanButton"> + <property name="text"> + <string>Scan</string> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="maximum"> + <number>0</number> + </property> + <property name="value"> + <number>-1</number> + </property> + <property name="textVisible"> + <bool>false</bool> + </property> + <property name="invertedAppearance"> + <bool>false</bool> + </property> + <property name="format"> + <string>%p%</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QTreeWidget" name="treeWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <attribute name="headerVisible"> + <bool>false</bool> + </attribute> + <column> + <property name="text"> + <string>1</string> + </property> + </column> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="sessionGroup"> + <property name="title"> + <string>Sessions</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>Session 1</string> + </attribute> + </widget> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/examples/network/bearermonitor/bearermonitor_640_480.ui b/examples/network/bearermonitor/bearermonitor_640_480.ui new file mode 100644 index 0000000..941eaa0 --- /dev/null +++ b/examples/network/bearermonitor/bearermonitor_640_480.ui @@ -0,0 +1,386 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>BearerMonitor</class> + <widget class="QWidget" name="BearerMonitor"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>640</width> + <height>515</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QGroupBox" name="systemState"> + <property name="title"> + <string>System State</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="onlineStateLayout"> + <item> + <widget class="QLabel" name="onlineStateLabel"> + <property name="text"> + <string>Online State:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="onlineState"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Configurations</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_9"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QTreeWidget" name="treeWidget"> + <attribute name="headerVisible"> + <bool>false</bool> + </attribute> + <column> + <property name="text"> + <string>1</string> + </property> + </column> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="configurationNameLayout"> + <item> + <widget class="QLabel" name="configurationNameLabel"> + <property name="text"> + <string>Name:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationStateLayout"> + <item> + <widget class="QLabel" name="configurationStateLabel"> + <property name="text"> + <string>State:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationState"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationTypeLayout"> + <item> + <widget class="QLabel" name="configurationTypeLabel"> + <property name="text"> + <string>Type:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationType"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Invalid</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationPurposeLayout"> + <item> + <widget class="QLabel" name="configurationPurposeLabel"> + <property name="text"> + <string>Purpose:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationPurpose"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Unknown</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationIdentifierLayout"> + <item> + <widget class="QLabel" name="configurationIdentifierLabel"> + <property name="text"> + <string>Identifier:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationIdentifier"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationRoamingLayout"> + <item> + <widget class="QLabel" name="configurationRoamingLabel"> + <property name="text"> + <string>Roaming:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationRoaming"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationChildrenLayout"> + <item> + <widget class="QLabel" name="configurationChildrenLabel"> + <property name="text"> + <string>Children:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configurationChildren"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="nlaGroup"> + <property name="title"> + <string>Network Location Awareness</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="registerButton"> + <property name="text"> + <string>Register</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="unregisterButton"> + <property name="text"> + <string>Unregister</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QPushButton" name="newSessionButton"> + <property name="text"> + <string>New Session</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="deleteSessionButton"> + <property name="text"> + <string>Delete Session</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="scanButton"> + <property name="text"> + <string>Scan</string> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="maximum"> + <number>0</number> + </property> + <property name="value"> + <number>-1</number> + </property> + <property name="textVisible"> + <bool>false</bool> + </property> + <property name="invertedAppearance"> + <bool>false</bool> + </property> + <property name="format"> + <string>%p%</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <widget class="QGroupBox" name="sessionGroup"> + <property name="title"> + <string>Sessions</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>Session 1</string> + </attribute> + </widget> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/examples/network/bearermonitor/main.cpp b/examples/network/bearermonitor/main.cpp new file mode 100644 index 0000000..b7ac4fe --- /dev/null +++ b/examples/network/bearermonitor/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> + +#include "bearermonitor.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + BearerMonitor monitor; + monitor.show(); + + return app.exec(); +} + diff --git a/examples/network/bearermonitor/sessionwidget.cpp b/examples/network/bearermonitor/sessionwidget.cpp new file mode 100644 index 0000000..46ffb20 --- /dev/null +++ b/examples/network/bearermonitor/sessionwidget.cpp @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sessionwidget.h" +#include "qnetworkconfigmanager.h" + +SessionWidget::SessionWidget(const QNetworkConfiguration &config, QWidget *parent) +: QWidget(parent), statsTimer(-1) +{ + setupUi(this); + + session = new QNetworkSession(config, this); + + connect(session, SIGNAL(stateChanged(QNetworkSession::State)), + this, SLOT(updateSession())); + connect(session, SIGNAL(error(QNetworkSession::SessionError)), + this, SLOT(updateSession())); + + updateSession(); + + sessionId->setText(QString("0x%1").arg(qulonglong(session), 8, 16, QChar('0'))); + + configuration->setText(session->configuration().name()); + + connect(openSessionButton, SIGNAL(clicked()), + this, SLOT(openSession())); + connect(openSyncSessionButton, SIGNAL(clicked()), + this, SLOT(openSyncSession())); + connect(closeSessionButton, SIGNAL(clicked()), + this, SLOT(closeSession())); + connect(stopSessionButton, SIGNAL(clicked()), + this, SLOT(stopSession())); +} + +SessionWidget::~SessionWidget() +{ + delete session; +} + +void SessionWidget::timerEvent(QTimerEvent *e) +{ + if (e->timerId() == statsTimer) { + rxData->setText(QString::number(session->bytesReceived())); + txData->setText(QString::number(session->bytesWritten())); + activeTime->setText(QString::number(session->activeTime())); + } +} + +void SessionWidget::updateSession() +{ + updateSessionState(session->state()); + updateSessionError(session->error()); + + if (session->state() == QNetworkSession::Connected) + statsTimer = startTimer(1000); + else + killTimer(statsTimer); + + if (session->configuration().type() == QNetworkConfiguration::InternetAccessPoint) + bearer->setText(session->configuration().bearerName()); + else { + QNetworkConfigurationManager mgr; + QNetworkConfiguration c = mgr.configurationFromIdentifier(session->sessionProperty("ActiveConfiguration").toString()); + bearer->setText(c.bearerName()); + } + + interfaceName->setText(session->interface().humanReadableName()); + interfaceGuid->setText(session->interface().name()); +} + +void SessionWidget::openSession() +{ + session->open(); + updateSession(); +} + +void SessionWidget::openSyncSession() +{ + session->open(); + session->waitForOpened(); + updateSession(); +} + +void SessionWidget::closeSession() +{ + session->close(); + updateSession(); +} + +void SessionWidget::stopSession() +{ + session->stop(); + updateSession(); +} + +void SessionWidget::updateSessionState(QNetworkSession::State state) +{ + QString s = tr("%1 (%2)"); + + switch (state) { + case QNetworkSession::Invalid: + s = s.arg(tr("Invalid")); + break; + case QNetworkSession::NotAvailable: + s = s.arg(tr("Not Available")); + break; + case QNetworkSession::Connecting: + s = s.arg(tr("Connecting")); + break; + case QNetworkSession::Connected: + s = s.arg(tr("Connected")); + break; + case QNetworkSession::Closing: + s = s.arg(tr("Closing")); + break; + case QNetworkSession::Disconnected: + s = s.arg(tr("Disconnected")); + break; + case QNetworkSession::Roaming: + s = s.arg(tr("Roaming")); + break; + default: + s = s.arg(tr("Unknown")); + } + + if (session->isOpen()) + s = s.arg(tr("Open")); + else + s = s.arg(tr("Closed")); + + sessionState->setText(s); +} + +void SessionWidget::updateSessionError(QNetworkSession::SessionError error) +{ + lastError->setText(QString::number(error)); + errorString->setText(session->errorString()); +} + diff --git a/examples/network/bearermonitor/sessionwidget.h b/examples/network/bearermonitor/sessionwidget.h new file mode 100644 index 0000000..cc9c067 --- /dev/null +++ b/examples/network/bearermonitor/sessionwidget.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SESSIONWIDGET_H +#define SESSIONWIDGET_H + +#include "ui_sessionwidget.h" + +#include <qnetworksession.h> + +QT_USE_NAMESPACE + +class SessionWidget : public QWidget, public Ui_SessionWidget +{ + Q_OBJECT + +public: + SessionWidget(const QNetworkConfiguration &config, QWidget *parent = 0); + ~SessionWidget(); + + void timerEvent(QTimerEvent *); + +private: + void updateSessionState(QNetworkSession::State state); + void updateSessionError(QNetworkSession::SessionError error); + +private Q_SLOTS: + void openSession(); + void openSyncSession(); + void closeSession(); + void stopSession(); + void updateSession(); + +private: + QNetworkSession *session; + int statsTimer; +}; + +#endif + diff --git a/examples/network/bearermonitor/sessionwidget.ui b/examples/network/bearermonitor/sessionwidget.ui new file mode 100644 index 0000000..45135f5 --- /dev/null +++ b/examples/network/bearermonitor/sessionwidget.ui @@ -0,0 +1,307 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SessionWidget</class> + <widget class="QWidget" name="SessionWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>340</width> + <height>276</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="sessionIdLayout"> + <item> + <widget class="QLabel" name="sessionIdLabel"> + <property name="text"> + <string>Session ID:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="sessionId"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="sessionStateLayout"> + <item> + <widget class="QLabel" name="sessionStateLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Session State:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="sessionState"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Invalid</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="configurationLayout"> + <item> + <widget class="QLabel" name="configurationLabel"> + <property name="text"> + <string>Configuration:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="configuration"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="bearerLayout"> + <item> + <widget class="QLabel" name="bearerLabel"> + <property name="text"> + <string>Bearer:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="bearer"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="interfaceNameLayout"> + <item> + <widget class="QLabel" name="interfaceNameLabel"> + <property name="text"> + <string>Interface Name:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="interfaceName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="interfaceGuidLayout"> + <item> + <widget class="QLabel" name="interfaceGuidLabel"> + <property name="text"> + <string>Interface GUID:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="interfaceGuid"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="lastErrorLayout"> + <item> + <widget class="QLabel" name="lastErrorLabel"> + <property name="text"> + <string>Last Error:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lastError"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="errorStringLayout"> + <item> + <widget class="QLabel" name="errorStringLabel"> + <property name="text"> + <string>Error String</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="errorString"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="rxData"> + <property name="text"> + <string>0</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="txData"> + <property name="text"> + <string>0</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Active Time:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="activeTime"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>0 seconds</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="openSessionButton"> + <property name="text"> + <string>Open</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="openSyncSessionButton"> + <property name="text"> + <string>Blocking Open</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPushButton" name="closeSessionButton"> + <property name="text"> + <string>Close</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="stopSessionButton"> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/examples/network/network.pro b/examples/network/network.pro index c5a97fb..bd632b8 100644 --- a/examples/network/network.pro +++ b/examples/network/network.pro @@ -11,7 +11,9 @@ SUBDIRS = blockingfortuneclient \ loopback \ threadedfortuneserver \ googlesuggest \ - torrent + torrent \ + bearercloud \ + bearermonitor # no QProcess !vxworks:!qnx:SUBDIRS += network-chat diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 42ce1bc..e4b7dae 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -97,7 +97,7 @@ equals(MOC_DIR, .) { } #auto depend on moc -unix:!no_mocdepend { +unix:!symbian:!no_mocdepend { moc_source.depends += $$first(QMAKE_MOC) moc_header.depends += $$first(QMAKE_MOC) !contains(TARGET, moc) { #auto build moc diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 7ccce00..7279a4c 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -207,7 +207,7 @@ QString generate_uid(const QString& target) return tmp; } - unsigned long hash = 5381; + quint32 hash = 5381; int c; for (int i = 0; i < target.size(); ++i) { diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 5e27af5..ee7a1dd 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -94,7 +94,9 @@ #define MMP_END_RESOURCE "END" #define SIS_TARGET "sis" +#define INSTALLER_SIS_TARGET "installer_sis" #define OK_SIS_TARGET "ok_sis" +#define OK_INSTALLER_SIS_TARGET "ok_installer_sis" #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg" #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache" @@ -302,6 +304,9 @@ void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile, Deployme QTextStream t(&pkgFile); QString installerSisHeader = project->values("DEPLOYMENT.installer_header").join("\n"); + if (installerSisHeader.isEmpty()) + installerSisHeader = "0xA000D7CE"; // Use default self-signable UID if not defined + QString wrapperStreamBuffer; QTextStream tw(&wrapperStreamBuffer); @@ -524,7 +529,7 @@ void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile, Deployme twf << "\"" << currentPath << "/" << sisName << "\" - \"c:\\adm\\" << sisName << "\"" << endl; QString bootStrapPath = QLibraryInfo::location(QLibraryInfo::PrefixPath); - bootStrapPath.append("/bootstrap.sis"); + bootStrapPath.append("/smartinstaller.sis"); QFileInfo fi(fileInfo(bootStrapPath)); twf << "@\"" << fi.absoluteFilePath() << "\",(0x2002CCCD)" << endl; } @@ -1908,8 +1913,34 @@ void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) t << pkgcommand << endl; t << endl; + QString sisName = fixedTarget; + sisName += ".sis"; + + t << sisName << ":" << endl; + t << "\t$(MAKE) -s -f $(MAKEFILE) " SIS_TARGET << endl << endl; + + t << INSTALLER_SIS_TARGET ": " << sisName << endl; + siscommand = QString("\t$(if $(wildcard %1_installer.%2)," \ + "$(MAKE) -s -f $(MAKEFILE) %3," \ + "$(MAKE) -s -f $(MAKEFILE) %4)") + .arg(fixedTarget) + .arg("pkg") + .arg(OK_INSTALLER_SIS_TARGET) + .arg(FAIL_SIS_NOPKG_TARGET); + t << siscommand << endl; + t << endl; + + t << OK_INSTALLER_SIS_TARGET ": " << endl; + + pkgcommand = QString("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_installer.%2 - " \ + "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") + .arg(fixedTarget) + .arg("pkg"); + t << pkgcommand << endl; + t << endl; + t << FAIL_SIS_NOPKG_TARGET ":" << endl; - t << "\t$(error PKG file does not exist, 'SIS' target is only supported for executables or projects with DEPLOYMENT statement)" << endl; + t << "\t$(error PKG file does not exist, '" SIS_TARGET "' and '" INSTALLER_SIS_TARGET "' target are only supported for executables or projects with DEPLOYMENT statement)" << endl; t << endl; t << FAIL_SIS_NOCACHE_TARGET ":" << endl; diff --git a/qmake/qmake.pro b/qmake/qmake.pro index 560aee9..00dcbce 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -17,9 +17,15 @@ VPATH += $$QT_SOURCE_TREE/src/corelib/global \ $$QT_SOURCE_TREE/src/corelib/kernel \ $$QT_SOURCE_TREE/src/corelib/codecs \ $$QT_SOURCE_TREE/src/corelib/plugin \ - $$QT_SOURCE_TREE/src/corelib/xml \ - $$QT_SOURCE_TREE/src/corelib/io -INCPATH += generators generators/unix generators/win32 generators/mac generators/symbian \ - $$QT_SOURCE_TREE/include $$QT_SOURCE_TREE/include/QtCore + $$QT_SOURCE_TREE/src/corelib/xml \ + $$QT_SOURCE_TREE/src/corelib/io +INCPATH += generators \ + generators/unix \ + generators/win32 \ + generators/mac \ + generators/symbian \ + $$QT_SOURCE_TREE/include \ + $$QT_SOURCE_TREE/include/QtCore \ + $$QT_SOURCE_TREE/qmake include(qmake.pri) diff --git a/src/3rdparty/s60/eiksoftkeyimage.h b/src/3rdparty/s60/eiksoftkeyimage.h index 84f6108a..a658421 100644 --- a/src/3rdparty/s60/eiksoftkeyimage.h +++ b/src/3rdparty/s60/eiksoftkeyimage.h @@ -39,23 +39,6 @@ ** ****************************************************************************/ -/* -* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Changes cba button's label to image. -* -*/ - #ifndef EIKSOFTKEYIMAGE_H #define EIKSOFTKEYIMAGE_H diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index b943840..6446773 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,16 @@ +2010-02-09 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Laszlo Gombos. + + [Qt] use nanval() for Symbian as nonInlineNaN + https://bugs.webkit.org/show_bug.cgi?id=34170 + + numeric_limits<double>::quiet_NaN is broken in Symbian + causing NaN to be evaluated as a number. + + * runtime/JSValue.cpp: + (JSC::nonInlineNaN): + 2010-01-07 Norbert Leser <norbert.leser@nokia.com> Reviewed by NOBODY (OOPS!). diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp index 699c1cd..bafb85b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp @@ -174,7 +174,11 @@ uint32_t toUInt32SlowCase(double d, bool& ok) NEVER_INLINE double nonInlineNaN() { +#if PLATFORM(SYMBIAN) + return nanval(); +#else return std::numeric_limits<double>::quiet_NaN(); +#endif } } // namespace JSC diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 4348cbc..cc0e04f 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - da5d96a26e80162027bc95ce7e5725fe4b277ff7 + ffae5e11181a3961193fa21ea405851cad714d4b diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 1f6f290..61c2227 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,15 @@ +2010-01-14 Diego Gonzalez <diego.gonzalez@openbossa.org> + + Reviewed by Kenneth Christiansen. + + [Qt] Missing fileSystemPath() method in Qt KURL implementation + https://bugs.webkit.org/show_bug.cgi?id=33614 + + No new tests. + + * platform/qt/KURLQt.cpp: + (WebCore::KURL::fileSystemPath): + 2010-02-01 Andreas Kling <andreas.kling@nokia.com> Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp index 0763fe0..1f62006 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp @@ -95,8 +95,10 @@ KURL::operator QUrl() const String KURL::fileSystemPath() const { - notImplemented(); - return String(); + if (!isValid() || !protocolIs("file")) + return String(); + + return String(path()); } } diff --git a/src/corelib/arch/sparc/arch.pri b/src/corelib/arch/sparc/arch.pri index 3113dd3..9bb3a88 100644 --- a/src/corelib/arch/sparc/arch.pri +++ b/src/corelib/arch/sparc/arch.pri @@ -1,7 +1,7 @@ # # SPARC architecture # -*-64 { +*-64* { SOURCES += $$QT_ARCH_CPP/qatomic64.s } else { diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index 445565a..4cc7912 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -681,7 +681,7 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con int u; const QChar* ucp = in; unsigned char* rp = (unsigned char *)r.data(); - const unsigned char* rmp = (const unsigned char *)reverseMap->data(); + const unsigned char* rmp = (const unsigned char *)reverseMap->constData(); int rmsize = (int) reverseMap->size(); while(i--) { diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 43ea1c8..1c607a6 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -79,7 +79,7 @@ # endif #endif // QT_NO_CODECS #include "qlocale.h" -#include "private/qmutexpool_p.h" +#include "qmutex.h" #include <stdlib.h> #include <ctype.h> @@ -659,13 +659,13 @@ static void setupLocaleMapper() #endif } - -static void setup() -{ #ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&all)); +Q_GLOBAL_STATIC_WITH_ARGS(QMutex, textCodecsMutex, (QMutex::Recursive)); #endif +// textCodecsMutex need to be locked to enter this function +static void setup() +{ if (all) return; @@ -903,8 +903,6 @@ QTextCodec::ConverterState::~ConverterState() */ /*! - \nonreentrant - Constructs a QTextCodec, and gives it the highest precedence. The QTextCodec should always be constructed on the heap (i.e. with \c new). Qt takes ownership and will delete it when the application @@ -912,6 +910,9 @@ QTextCodec::ConverterState::~ConverterState() */ QTextCodec::QTextCodec() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); all->prepend(this); } @@ -929,8 +930,12 @@ QTextCodec::~QTextCodec() if (!destroying_is_ok) qWarning("QTextCodec::~QTextCodec: Called by application"); #endif - if (all) + if (all) { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif all->removeAll(this); + } } /*! @@ -951,6 +956,9 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) if (name.isEmpty()) return 0; +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); for (int i = 0; i < all->size(); ++i) { @@ -973,6 +981,9 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) */ QTextCodec* QTextCodec::codecForMib(int mib) { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map @@ -1001,6 +1012,9 @@ QTextCodec* QTextCodec::codecForMib(int mib) */ QList<QByteArray> QTextCodec::availableCodecs() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); QList<QByteArray> codecs; @@ -1008,6 +1022,11 @@ QList<QByteArray> QTextCodec::availableCodecs() codecs += all->at(i)->name(); codecs += all->at(i)->aliases(); } + +#ifndef QT_NO_THREAD + locker.unlock(); +#endif + #ifndef QT_NO_TEXTCODECPLUGIN QFactoryLoader *l = loader(); QStringList keys = l->keys(); @@ -1031,11 +1050,19 @@ QList<QByteArray> QTextCodec::availableCodecs() */ QList<int> QTextCodec::availableMibs() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); QList<int> codecs; for (int i = 0; i < all->size(); ++i) codecs += all->at(i)->mibEnum(); + +#ifndef QT_NO_THREAD + locker.unlock(); +#endif + #ifndef QT_NO_TEXTCODECPLUGIN QFactoryLoader *l = loader(); QStringList keys = l->keys(); @@ -1082,6 +1109,9 @@ QTextCodec* QTextCodec::codecForLocale() if (localeMapper) return localeMapper; +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); return localeMapper; diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b4e19d1..39c41c4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1392,7 +1392,8 @@ QGraphicsItem::~QGraphicsItem() } delete d_ptr->transformData; - qt_dataStore()->data.remove(this); + if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore()) + dataStore->data.remove(this); } /*! diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index ac1d303..bf6eb8d 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -104,6 +104,15 @@ QT_BEGIN_NAMESPACE static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1); +static void qt_cleanup_icon_cache(); +typedef QCache<QString, QIcon> IconCache; +Q_GLOBAL_STATIC_WITH_INITIALIZER(IconCache, qtIconCache, qAddPostRoutine(qt_cleanup_icon_cache)) + +static void qt_cleanup_icon_cache() +{ + qtIconCache()->clear(); +} + QIconPrivate::QIconPrivate() : engine(0), ref(1), serialNum(serialNumCounter.fetchAndAddRelaxed(1)), @@ -963,15 +972,13 @@ QString QIcon::themeName() */ QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback) { - static QCache <QString, QIcon> iconCache; - QIcon icon; - if (iconCache.contains(name)) { - icon = *iconCache.object(name); + if (qtIconCache()->contains(name)) { + icon = *qtIconCache()->object(name); } else { QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name)); - iconCache.insert(name, cachedIcon); + qtIconCache()->insert(name, cachedIcon); icon = *cachedIcon; } diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index c9e015c..9320cfc 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -263,25 +263,37 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, device->seek(pos); } - if (!handler && !testFormat.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) { + if (!handler && !testFormat.isEmpty() && !ignoresFormatAndExtension) { // check if any plugin supports the format (they are not allowed to // read from the device yet). const qint64 pos = device ? device->pos() : 0; - for (int i = 0; i < keys.size(); ++i) { - if (i != suffixPluginIndex) { - QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i))); - if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { + + if (autoDetectImageFormat) { + for (int i = 0; i < keys.size(); ++i) { + if (i != suffixPluginIndex) { + QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i))); + if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { #ifdef QIMAGEREADER_DEBUG - qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format"; + qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format"; #endif - handler = plugin->create(device, testFormat); - break; + handler = plugin->create(device, testFormat); + break; + } } } + } else { + QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(QLatin1String(testFormat))); + if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { +#ifdef QIMAGEREADER_DEBUG + qDebug() << "QImageReader::createReadHandler: the" << testFormat << "plugin can read this format"; +#endif + handler = plugin->create(device, testFormat); + } } if (device && !device->isSequential()) device->seek(pos); } + #endif // QT_NO_LIBRARY // if we don't have a handler yet, check if we have built-in support for diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 37a6a18..2792e45 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -422,6 +422,9 @@ void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const Q if(d->kernelWidth<=0 || d->kernelHeight <= 0) return; + if (src.isNull()) + return; + QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; QPixmapConvolutionFilter *convolutionFilter = static_cast<QPixmapConvolutionFilter*>(filter); @@ -710,7 +713,8 @@ void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transp radius *= qreal(0.5); Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied - || img.format() == QImage::Format_RGB32); + || img.format() == QImage::Format_RGB32 + || img.format() == QImage::Format_Indexed8); // choose the alpha such that pixels at radius distance from a fully // saturated pixel will have an alpha component of no greater than @@ -902,6 +906,9 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap if (!painter->isActive()) return; + if (src.isNull()) + return; + QRectF srcRect = rect; if (srcRect.isNull()) srcRect = src.rect(); @@ -1082,6 +1089,10 @@ void QPixmapColorizeFilter::setStrength(qreal strength) void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const { Q_D(const QPixmapColorizeFilter); + + if (src.isNull()) + return; + QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; QPixmapColorizeFilter *colorizeFilter = static_cast<QPixmapColorizeFilter*>(filter); @@ -1312,6 +1323,10 @@ void QPixmapDropShadowFilter::draw(QPainter *p, const QRectF &src) const { Q_D(const QPixmapDropShadowFilter); + + if (px.isNull()) + return; + QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ? static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0; QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter); diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 19b1e8c..b2def39 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -2160,7 +2160,7 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand) } else { if (flowPositions.isEmpty()) return; - const int max = flowPositions.count() - 1; + const int max = scrollValueMap.count() - 1; if (vertical && flow() == QListView::TopToBottom && dy != 0) { int currentValue = qBound(0, verticalValue, max); int previousValue = qBound(0, currentValue + dy, max); diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 3fba833..25c98c5 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -2168,6 +2168,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event } if (wheel_deltaX || wheel_deltaY) { +#ifndef QT_NO_WHEELEVENT if (wheel_deltaX) { QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal); QApplication::sendSpontaneousEvent(widget, &qwe); @@ -2190,6 +2191,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event handled_event = false; } } +#endif // QT_NO_WHEELEVENT } else { #ifdef QMAC_SPEAK_TO_ME const int speak_keys = Qt::AltModifier | Qt::ShiftModifier; @@ -2764,6 +2766,7 @@ int QApplication::keyboardInputInterval() return QApplicationPrivate::keyboard_input_time; } +#ifndef QT_NO_WHEELEVENT void QApplication::setWheelScrollLines(int n) { QApplicationPrivate::wheel_scroll_lines = n; @@ -2773,6 +2776,7 @@ int QApplication::wheelScrollLines() { return QApplicationPrivate::wheel_scroll_lines; } +#endif void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) { @@ -2935,9 +2939,11 @@ bool QApplicationPrivate::qt_mac_apply_settings() QApplication::cursorFlashTime()).toInt(); QApplication::setCursorFlashTime(num); +#ifndef QT_NO_WHEELEVENT num = settings.value(QLatin1String("wheelScrollLines"), QApplication::wheelScrollLines()).toInt(); QApplication::setWheelScrollLines(num); +#endif QString colorspec = settings.value(QLatin1String("colorSpec"), QVariant(QLatin1String("default"))).toString(); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index d19d86e..e0a6103 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -427,7 +427,9 @@ public: static int cursor_flash_time; static int mouse_double_click_time; static int keyboard_input_time; +#ifndef QT_NO_WHEELEVENT static int wheel_scroll_lines; +#endif static bool animate_ui; static bool animate_menu; diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 87de602..3e2e6f6 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -809,12 +809,15 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const void QSymbianControl::Draw(const TRect& controlRect) const { // Set flag to avoid calling DrawNow in window surface - QWExtra *extra = qwidget->d_func()->extraData(); - if (extra && !extra->inExpose) { - extra->inExpose = true; + QWidget *window = qwidget->window(); + Q_ASSERT(window); + QTLWExtra *topExtra = window->d_func()->maybeTopData(); + Q_ASSERT(topExtra); + if (!topExtra->inExpose) { + topExtra->inExpose = true; QRect exposeRect = qt_TRect2QRect(controlRect); qwidget->d_func()->syncBackingStore(exposeRect); - extra->inExpose = false; + topExtra->inExpose = false; } QWindowSurface *surface = qwidget->windowSurface(); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 3355272..0a4869b 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -928,7 +928,11 @@ const QString qt_reg_winclass(QWidget *w) // register window class uint style; bool icon; QString cname; - if (flags & Qt::MSWindowsOwnDC) { + if (qt_widget_private(w)->isGLWidget) { + cname = QLatin1String("QGLWidget"); + style = CS_DBLCLKS; + icon = true; + } else if (flags & Qt::MSWindowsOwnDC) { cname = QLatin1String("QWidgetOwnDC"); style = CS_DBLCLKS; #ifndef Q_WS_WINCE @@ -1021,7 +1025,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class } wc.hCursor = 0; #ifndef Q_WS_WINCE - wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); + wc.hbrBackground = qt_widget_private(w)->isGLWidget ? 0 : (HBRUSH)GetSysColorBrush(COLOR_WINDOW); #else wc.hbrBackground = 0; #endif @@ -3616,13 +3620,19 @@ bool QETWidget::translatePaintEvent(const MSG &msg) return true; setAttribute(Qt::WA_PendingUpdate, false); - const QRegion dirtyInBackingStore(qt_dirtyRegion(this)); - // Make sure the invalidated region contains the region we're about to repaint. - // BeginPaint will set the clip to the invalidated region and it is impossible - // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient - // as it may return an invalid context (especially on Windows Vista). - if (!dirtyInBackingStore.isEmpty()) - InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false); + + if (d_func()->isGLWidget) { + if (d_func()->usesDoubleBufferedGLContext) + InvalidateRect(internalWinId(), 0, false); + } else { + const QRegion dirtyInBackingStore(qt_dirtyRegion(this)); + // Make sure the invalidated region contains the region we're about to repaint. + // BeginPaint will set the clip to the invalidated region and it is impossible + // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient + // as it may return an invalid context (especially on Windows Vista). + if (!dirtyInBackingStore.isEmpty()) + InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false); + } PAINTSTRUCT ps; d_func()->hd = BeginPaint(internalWinId(), &ps); diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 667db39..34865b5 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -949,10 +949,12 @@ bool QApplicationPrivate::x11_apply_settings() QApplication::cursorFlashTime()).toInt(); QApplication::setCursorFlashTime(num); +#ifndef QT_NO_WHEELEVENT num = settings.value(QLatin1String("wheelScrollLines"), QApplication::wheelScrollLines()).toInt(); QApplication::setWheelScrollLines(num); +#endif QString colorspec = settings.value(QLatin1String("colorSpec"), QVariant(QLatin1String("default"))).toString(); @@ -4406,8 +4408,10 @@ bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta, QWidget* popup = qApp->activePopupWidget(); if (popup && window() != popup) popup->close(); +#ifndef QT_NO_WHEELEVENT QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient); if (QApplication::sendSpontaneousEvent(widget, &e)) +#endif return true; } @@ -4418,8 +4422,10 @@ bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta, QWidget* popup = qApp->activePopupWidget(); if (popup && widget != popup) popup->hide(); +#ifndef QT_NO_WHEELEVENT QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient); if (QApplication::sendSpontaneousEvent(widget, &e)) +#endif return true; } return false; @@ -5318,6 +5324,7 @@ int QApplication::keyboardInputInterval() return QApplicationPrivate::keyboard_input_time; } +#ifndef QT_NO_WHEELEVENT void QApplication::setWheelScrollLines(int n) { QApplicationPrivate::wheel_scroll_lines = n; @@ -5327,6 +5334,7 @@ int QApplication::wheelScrollLines() { return QApplicationPrivate::wheel_scroll_lines; } +#endif void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) { diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp index f3a971d..49a6cc8 100644 --- a/src/gui/kernel/qclipboard_mac.cpp +++ b/src/gui/kernel/qclipboard_mac.cpp @@ -388,6 +388,18 @@ QMacPasteboard::setMimeData(QMimeData *mime_src) clear_helper(); QStringList formats = mime_src->formats(); +#ifdef QT_MAC_USE_COCOA + // QMimeData sub classes reimplementing the formats() might not expose the + // temporary "application/x-qt-mime-type-name" mimetype. So check the existence + // of this mime type while doing drag and drop. + QString dummyMimeType(QLatin1String("application/x-qt-mime-type-name")); + if (!formats.contains(dummyMimeType)) { + QByteArray dummyType = mime_src->data(dummyMimeType); + if (!dummyType.isEmpty()) { + formats.append(dummyMimeType); + } + } +#endif for(int f = 0; f < formats.size(); ++f) { QString mimeType = formats.at(f); for (QList<QMacPasteboardMime *>::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) { diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 70c78c8..873fb7e 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -786,6 +786,7 @@ extern "C" { deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120); } +#ifndef QT_NO_WHEELEVENT if (deltaX != 0) { QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal); qt_sendSpontaneousEvent(widgetToGetMouse, &qwe); @@ -826,6 +827,8 @@ extern "C" { wheelOK = qwe2.isAccepted(); } } +#endif //QT_NO_WHEELEVENT + if (!wheelOK) { return [super scrollWheel:theEvent]; } @@ -1362,7 +1365,7 @@ Qt::DropAction QDragManager::drag(QDrag *o) // setup the data QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND); - dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray()); + dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy")); dragBoard.setMimeData(dragPrivate()->data); // create the image diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index 70574e7..4e6c847 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -360,6 +360,13 @@ QList<int> QKeyMapperPrivate::possibleKeysXKB(QKeyEvent *event) if (code && code < 0xfffe) code = QChar(code).toUpper().unicode(); + + if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) { + // map shift+tab to shift+backtab + code = Qt::Key_Backtab; + text = QString(); + } + if (code == baseCode) continue; @@ -448,6 +455,13 @@ QList<int> QKeyMapperPrivate::possibleKeysCore(QKeyEvent *event) if (code && code < 0xfffe) code = QChar(code).toUpper().unicode(); + + if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) { + // map shift+tab to shift+backtab + code = Qt::Key_Backtab; + text = QString(); + } + if (code == baseCode) continue; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 2e951b6..1e92507 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -192,6 +192,7 @@ QWidgetPrivate::QWidgetPrivate(int version) , inDirtyList(0) , isScrolled(0) , isMoved(0) + , isGLWidget(0) , usesDoubleBufferedGLContext(0) #if defined(Q_WS_X11) , picture(0) @@ -200,7 +201,6 @@ QWidgetPrivate::QWidgetPrivate(int version) , nativeGesturePanEnabled(0) #elif defined(Q_WS_MAC) , needWindowChange(0) - , isGLWidget(0) , window_event(0) , qd_hd(0) #endif diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index ff8f276..75b4c12 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -174,6 +174,8 @@ struct QTLWExtra { #ifndef QT_NO_QWS_MANAGER QWSManager *qwsManager; #endif +#elif defined(Q_OS_SYMBIAN) + uint inExpose : 1; // Prevents drawing recursion #endif }; @@ -230,7 +232,6 @@ struct QWExtra { #endif #elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian uint activated : 1; // RWindowBase::Activated has been called - uint inExpose : 1; // Prevents drawing recursion /** * Defines the behaviour of QSymbianControl::Draw. @@ -685,6 +686,7 @@ public: uint inDirtyList : 1; uint isScrolled : 1; uint isMoved : 1; + uint isGLWidget : 1; uint usesDoubleBufferedGLContext : 1; // *************************** Platform specific ************************************ @@ -716,7 +718,6 @@ public: #elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC // This is new stuff uint needWindowChange : 1; - uint isGLWidget : 1; // Each wiget keeps a list of all its child and grandchild OpenGL widgets. // This list is used to update the gl context whenever a parent and a granparent diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index a844430..ebd289c 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -878,6 +878,7 @@ void QWidgetPrivate::registerDropSite(bool /* on */) void QWidgetPrivate::createTLSysExtra() { extra->topextra->backingStore = 0; + extra->topextra->inExpose = 0; } void QWidgetPrivate::deleteTLSysExtra() @@ -891,7 +892,6 @@ void QWidgetPrivate::createSysExtra() extra->activated = 0; extra->nativePaintMode = QWExtra::Default; extra->receiveNativePaintEvents = 0; - extra->inExpose = 0; } void QWidgetPrivate::deleteSysExtra() diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 660a2a8..7a3da20 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1267,32 +1267,28 @@ static const uint L2CacheLineLengthInInts = L2CacheLineLength/sizeof(uint); result = 0 d = d * cia */ +#define comp_func_Clear_impl(dest, length, const_alpha)\ +{\ + if (const_alpha == 255) {\ + QT_MEMFILL_UINT(dest, length, 0);\ + } else {\ + int ialpha = 255 - const_alpha;\ + PRELOAD_INIT(dest)\ + for (int i = 0; i < length; ++i) {\ + PRELOAD_COND(dest)\ + dest[i] = BYTE_MUL(dest[i], ialpha);\ + }\ + }\ +} + static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) { - if (const_alpha == 255) { - QT_MEMFILL_UINT(dest, length, 0); - } else { - int ialpha = 255 - const_alpha; - PRELOAD_INIT(dest) - for (int i = 0; i < length; ++i) { - PRELOAD_COND(dest) - dest[i] = BYTE_MUL(dest[i], ialpha); - } - } + comp_func_Clear_impl(dest, length, const_alpha); } static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) { - if (const_alpha == 255) { - QT_MEMFILL_UINT(dest, length, 0); - } else { - int ialpha = 255 - const_alpha; - PRELOAD_INIT(dest) - for (int i = 0; i < length; ++i) { - PRELOAD_COND(dest) - dest[i] = BYTE_MUL(dest[i], ialpha); - } - } + comp_func_Clear_impl(dest, length, const_alpha); } /* diff --git a/src/gui/painting/qdrawhelper_mmx_p.h b/src/gui/painting/qdrawhelper_mmx_p.h index 8482262..59b3804 100644 --- a/src/gui/painting/qdrawhelper_mmx_p.h +++ b/src/gui/painting/qdrawhelper_mmx_p.h @@ -146,36 +146,30 @@ struct QMMXCommonIntrinsics result = 0 d = d * cia */ +#define comp_func_Clear_impl(dest, length, const_alpha)\ +{\ + if (const_alpha == 255) {\ + qt_memfill(static_cast<quint32*>(dest), quint32(0), length);\ + } else {\ + C_FF; C_80; C_00;\ + m64 ia = MM::negate(MM::load_alpha(const_alpha));\ + for (int i = 0; i < length; ++i) {\ + dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));\ + }\ + MM::end();\ + }\ +} + template <class MM> static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) { - if (!length) - return; - - if (const_alpha == 255) { - qt_memfill(static_cast<quint32*>(dest), quint32(0), length); - } else { - C_FF; C_80; C_00; - m64 ia = MM::negate(MM::load_alpha(const_alpha)); - for (int i = 0; i < length; ++i) { - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia)); - } - } - MM::end(); + comp_func_Clear_impl(dest, length, const_alpha); } template <class MM> static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) { - if (const_alpha == 255) { - qt_memfill(static_cast<quint32*>(dest), quint32(0), length); - } else { - C_FF; C_80; C_00; - m64 ia = MM::negate(MM::load_alpha(const_alpha)); - for (int i = 0; i < length; ++i) - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia)); - } - MM::end(); + comp_func_Clear_impl(dest, length, const_alpha); } /* @@ -246,7 +240,10 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le C_FF; C_80; C_00; if (const_alpha == 255) { for (int i = 0; i < length; ++i) { - if ((0xff000000 & src[i]) == 0xff000000) { + const uint alphaMaskedSource = 0xff000000 & src[i]; + if (alphaMaskedSource == 0) + continue; + if (alphaMaskedSource == 0xff000000) { dest[i] = src[i]; } else { m64 s = MM::load(src[i]); @@ -257,6 +254,8 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le } else { m64 ca = MM::load_alpha(const_alpha); for (int i = 0; i < length; ++i) { + if ((0xff000000 & src[i]) == 0) + continue; m64 s = MM::byte_mul(MM::load(src[i]), ca); m64 ia = MM::negate(MM::alpha(s)); dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia))); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 6c47aac..cb0db4f 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -1549,6 +1549,9 @@ template<> inline void qt_memfill(quint8 *dest, quint8 color, int count) template <class T> inline void qt_memfill(T *dest, T value, int count) { + if (!count) + return; + int n = (count + 7) / 8; switch (count & 0x07) { diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 147491e..da48fcb 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1989,6 +1989,9 @@ void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRect } XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh); restore_clip = true; + } else if (mono_dst && !mono_src) { + QBitmap bitmap(pixmap); + XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y); } else { XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y); } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index bf12c6b..270144b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -38,6 +38,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + // QtCore #include <qdebug.h> #include <qmath.h> @@ -1986,12 +1987,25 @@ QPaintEngine *QPainter::paintEngine() const endNativePainting(). Note that only the states the underlying paint engine changes will be reset - to their respective default states. If, for example, the OpenGL polygon - mode is changed by the user inside a beginNativePaint()/endNativePainting() - block, it will not be reset to the default state by endNativePainting(). + to their respective default states. The states we reset may change from + release to release. The following states are currently reset in the OpenGL + 2 engine: + + \list + \i blending is disabled + \i the depth, stencil and scissor tests are disabled + \i the active texture unit is reset to 0 + \i the depth mask, depth function and the clear depth are reset to their + default values + \i the stencil mask, stencil operation and stencil function are reset to + their default values + \i the current color is reset to solid white + \endlist - Here is an example that shows intermixing of painter commands - and raw OpenGL commands: + If, for example, the OpenGL polygon mode is changed by the user inside a + beginNativePaint()/endNativePainting() block, it will not be reset to the + default state by endNativePainting(). Here is an example that shows + intermixing of painter commands and raw OpenGL commands: \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21 diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index b41dc2c..6cbf3d9 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -145,12 +145,15 @@ QImage* QS60WindowSurface::buffer(const QWidget *widget) void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &) { - QWExtra *extra = widget->d_func()->extraData(); - if (extra && !extra->inExpose) { - extra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again + QWidget *window = widget->window(); + Q_ASSERT(window); + QTLWExtra *topExtra = window->d_func()->maybeTopData(); + Q_ASSERT(topExtra); + if (!topExtra->inExpose) { + topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again TRect tr = qt_QRect2TRect(region.boundingRect()); widget->winId()->DrawNow(tr); - extra->inExpose = false; + topExtra->inExpose = false; } } diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index bbd35f1..dd9e69e 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -629,8 +629,9 @@ QFontEngineData::~QFontEngineData() Returns the name of the font within the underlying window system. - Only on X11 when Qt was built without FontConfig support the XLFD (X Logical Font Description) - is returned; otherwise an empty string. + On X11, this function will return an empty string if Qt is built with + FontConfig support; otherwise the XLFD (X Logical Font Description) is + returned. Using the return value of this function is usually \e not \e portable. diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index 9dd4af7..3ea084b 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -44,7 +44,7 @@ #include "qglobal.h" #include <private/qapplication_p.h> #include "qimage.h" -#include "qt_s60_p.h" +#include <private/qt_s60_p.h> #include <e32base.h> #include <e32std.h> diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 26c7c1e..af91603 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1331,7 +1331,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition QTextLine l(line, d); const QScriptLine &sl = d->lines[line]; - const qreal x = position.x() + l.cursorToX(cursorPosition); + qreal x = position.x() + l.cursorToX(cursorPosition); int itm = d->findItem(cursorPosition - 1); QFixed base = sl.base(); @@ -1350,6 +1350,10 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition && (p->transform().type() > QTransform::TxTranslate); if (toggleAntialiasing) p->setRenderHint(QPainter::Antialiasing); +#if defined(QT_MAC_USE_COCOA) + // Always draw the cursor aligned to pixel boundary. + x = qRound(x); +#endif p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush()); if (toggleAntialiasing) p->setRenderHint(QPainter::Antialiasing, false); diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h index b881f68..e8bf197 100644 --- a/src/gui/util/qsystemtrayicon_p.h +++ b/src/gui/util/qsystemtrayicon_p.h @@ -164,7 +164,9 @@ protected: bool x11Event(XEvent *event); void mousePressEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *event); +#endif bool event(QEvent *e); private: diff --git a/src/gui/util/qsystemtrayicon_x11.cpp b/src/gui/util/qsystemtrayicon_x11.cpp index a645050..82b4325 100644 --- a/src/gui/util/qsystemtrayicon_x11.cpp +++ b/src/gui/util/qsystemtrayicon_x11.cpp @@ -308,10 +308,12 @@ void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev) emit q->activated(QSystemTrayIcon::DoubleClick); } +#ifndef QT_NO_WHEELEVENT void QSystemTrayIconSys::wheelEvent(QWheelEvent *e) { QApplication::sendEvent(q, e); } +#endif bool QSystemTrayIconSys::event(QEvent *e) { diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp index 73c17db..4bd7b5a 100644 --- a/src/gui/widgets/qabstractslider.cpp +++ b/src/gui/widgets/qabstractslider.cpp @@ -705,7 +705,11 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb // Calculate how many lines to scroll. Depending on what delta is (and // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can // only scroll whole lines, so we keep the reminder until next event. - qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * effectiveSingleStep(); + qreal stepsToScrollF = +#ifndef QT_NO_WHEELEVENT + QApplication::wheelScrollLines() * +#endif + offset * effectiveSingleStep(); // Check if wheel changed direction since last event: if (offset_accumulated != 0 && (offset / offset_accumulated) < 0) offset_accumulated = 0; diff --git a/src/gui/widgets/qabstractspinbox.h b/src/gui/widgets/qabstractspinbox.h index 059943a..6c062c0 100644 --- a/src/gui/widgets/qabstractspinbox.h +++ b/src/gui/widgets/qabstractspinbox.h @@ -137,7 +137,9 @@ protected: void resizeEvent(QResizeEvent *event); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *event); +#endif void focusInEvent(QFocusEvent *event); void focusOutEvent(QFocusEvent *event); void contextMenuEvent(QContextMenuEvent *event); diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index f332d31..9b19a66 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -245,7 +245,9 @@ protected: void mouseReleaseEvent(QMouseEvent *e); void keyPressEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *e); +#endif void contextMenuEvent(QContextMenuEvent *e); void inputMethodEvent(QInputMethodEvent *); QVariant inputMethodQuery(Qt::InputMethodQuery) const; diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index b0a64ea..db099e8 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -1371,6 +1371,8 @@ bool QLineControl::processEvent(QEvent* ev) processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break; #ifndef QT_NO_SHORTCUT case QEvent::ShortcutOverride:{ + if (isReadOnly()) + return false; QKeyEvent* ke = static_cast<QKeyEvent*>(ev); if (ke == QKeySequence::Copy || ke == QKeySequence::Paste diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h index 28bd859..a040afa 100644 --- a/src/gui/widgets/qmenu.h +++ b/src/gui/widgets/qmenu.h @@ -162,7 +162,9 @@ protected: void mouseReleaseEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *); +#endif void enterEvent(QEvent *); void leaveEvent(QEvent *); void hideEvent(QHideEvent *); diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp index 3eed3a9..4eff260 100644 --- a/src/gui/widgets/qscrollbar.cpp +++ b/src/gui/widgets/qscrollbar.cpp @@ -521,6 +521,7 @@ bool QScrollBar::event(QEvent *event) if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) d_func()->updateHoverControl(he->pos()); break; +#ifndef QT_NO_WHEELEVENT case QEvent::Wheel: { // override wheel event without adding virtual function override QWheelEvent *ev = static_cast<QWheelEvent *>(event); @@ -537,6 +538,7 @@ bool QScrollBar::event(QEvent *event) event->accept(); return true; } +#endif default: break; } diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 70a301d..5bd972c 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -305,9 +305,12 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() while (socket->bytesAvailable()) { QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState; switch (state) { - case QHttpNetworkReplyPrivate::NothingDoneState: - case QHttpNetworkReplyPrivate::ReadingStatusState: { + case QHttpNetworkReplyPrivate::NothingDoneState: { + // only eat whitespace on the first call eatWhitespace(); + state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState; + } + case QHttpNetworkReplyPrivate::ReadingStatusState: { qint64 statusBytes = reply->d_func()->readStatus(socket); if (statusBytes == -1 && reconnectAttempts <= 0) { // too many errors reading/receiving/parsing the status, close the socket and emit error diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index a5223d1..512c045 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -423,13 +423,26 @@ int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteA qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) { + if (fragment.isEmpty()) { + // reserve bytes for the status line. This is better than always append() which reallocs the byte array + fragment.reserve(32); + } + qint64 bytes = 0; char c; + qint64 haveRead = 0; + + do { + haveRead = socket->read(&c, 1); + if (haveRead == -1) + return -1; // unexpected EOF + else if (haveRead == 0) + break; // read more later + + bytes++; - while (socket->bytesAvailable()) { // allow both CRLF & LF (only) line endings - if (socket->peek(&c, 1) == 1 && c == '\n') { - bytes += socket->read(&c, 1); // read the "n" + if (c == '\n') { // remove the CR at the end if (fragment.endsWith('\r')) { fragment.truncate(fragment.length()-1); @@ -442,11 +455,6 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) } break; } else { - c = 0; - int haveRead = socket->read(&c, 1); - if (haveRead == -1) - return -1; - bytes += haveRead; fragment.append(c); } @@ -456,8 +464,7 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) fragment.clear(); return -1; } - - } + } while (haveRead == 1); return bytes; } @@ -500,20 +507,41 @@ bool QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status) qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) { + if (fragment.isEmpty()) { + // according to http://dev.opera.com/articles/view/mama-http-headers/ the average size of the header + // block is 381 bytes. + // reserve bytes. This is better than always append() which reallocs the byte array. + fragment.reserve(512); + } + qint64 bytes = 0; char c = 0; bool allHeaders = false; - while (!allHeaders && socket->bytesAvailable()) { - if (socket->peek(&c, 1) == 1 && c == '\n') { - // check for possible header endings. As per HTTP rfc, - // the header endings will be marked by CRLFCRLF. But - // we will allow CRLFLF, LFLF & CRLFCRLF - if (fragment.endsWith("\n\r") || fragment.endsWith('\n')) - allHeaders = true; + qint64 haveRead = 0; + do { + haveRead = socket->read(&c, 1); + if (haveRead == 0) { + // read more later + break; + } else if (haveRead == -1) { + // connection broke down + return -1; + } else { + fragment.append(c); + bytes++; + + if (c == '\n') { + // check for possible header endings. As per HTTP rfc, + // the header endings will be marked by CRLFCRLF. But + // we will allow CRLFCRLF, CRLFLF, LFLF + if (fragment.endsWith("\r\n\r\n") + || fragment.endsWith("\r\n\n") + || fragment.endsWith("\n\n")) + allHeaders = true; + } } - bytes += socket->read(&c, 1); - fragment.append(c); - } + } while (!allHeaders && haveRead > 0); + // we received all headers now parse them if (allHeaders) { parseHeader(fragment); diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 8ac64d2..1d23cdc 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -49,6 +49,7 @@ #include "qnetworkaccesscachebackend_p.h" #include "qabstractnetworkcache.h" +#include "qhostinfo.h" #include "private/qnoncontiguousbytedevice_p.h" @@ -341,4 +342,35 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors) #endif } +/*! + Starts the backend. Returns true if the backend is started. Returns false if the backend + could not be started due to an unopened or roaming session. The caller should recall this + function once the session has been opened or the roaming process has finished. +*/ +bool QNetworkAccessBackend::start() +{ + if (!manager->networkSession) { + open(); + return true; + } + + // This is not ideal. + const QString host = reply->url.host(); + if (host == QLatin1String("localhost") || + QHostAddress(host) == QHostAddress::LocalHost || + QHostAddress(host) == QHostAddress::LocalHostIPv6) { + // Don't need an open session for localhost access. + open(); + return true; + } + + if (manager->networkSession->isOpen() && + manager->networkSession->state() == QNetworkSession::Connected) { + open(); + return true; + } + + return false; +} + QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h index 43d993c..830ec7e 100644 --- a/src/network/access/qnetworkaccessbackend_p.h +++ b/src/network/access/qnetworkaccessbackend_p.h @@ -54,6 +54,7 @@ // #include "qnetworkreplyimpl_p.h" +#include "QtNetwork/qnetworksession.h" #include "QtCore/qobject.h" QT_BEGIN_NAMESPACE @@ -111,6 +112,7 @@ public: // socket). virtual void open() = 0; + virtual bool start(); virtual void closeDownstreamChannel() = 0; virtual bool waitForDownstreamReadyRead(int msecs) = 0; @@ -190,6 +192,7 @@ private: friend class QNetworkAccessManager; friend class QNetworkAccessManagerPrivate; friend class QNetworkAccessBackendUploadIODevice; + friend class QNetworkReplyImplPrivate; QNetworkAccessManagerPrivate *manager; QNetworkReplyImplPrivate *reply; }; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index e16aedc..9a351dc 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -59,6 +59,8 @@ #include "QtCore/qvector.h" #include "QtNetwork/qauthenticator.h" #include "QtNetwork/qsslconfiguration.h" +#include "QtNetwork/qnetworkconfigmanager.h" +#include "QtNetwork/qnetworksession.h" QT_BEGIN_NAMESPACE @@ -160,6 +162,43 @@ static void ensureInitialized() */ /*! + \property QNetworkAccessManager::networkAccess + \brief states whether network access is enabled or disabled through this network access + manager. + + \since 4.7 + + Network access is enabled by default. + + When network access is disabled the network access manager will not process any new network + requests, all such requests will fail with an error. Requests with URLs with the file:// scheme + will still be processed. + + This property can be used to enable and disable network access for all clients of a single + network access manager instance. +*/ + +/*! + \fn void QNetworkAccessManager::networkAccessChanged(bool enabled) + + This signal is emitted when the value of the \l networkAccess property changes. If \a enabled + is true new requests that access the network will be processed; otherwise new network requests + that require network access will fail with an error. +*/ + +/*! + \fn void QNetworkAccessManager::networkSessionOnline() + + \since 4.7 + + \internal + + This signal is emitted when the status of the network session changes into a usable state. + It is used to signal QNetworkReply's to start or migrate their network operation once the + network session has been opened / roamed. +*/ + +/*! \fn void QNetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator) This signal is emitted whenever a proxy requests authentication @@ -346,6 +385,9 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) : QObject(*new QNetworkAccessManagerPrivate, parent) { ensureInitialized(); + + QNetworkConfigurationManager manager; + d_func()->createSession(manager.defaultConfiguration()); } /*! @@ -665,6 +707,85 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ } /*! + \since 4.7 + + Sets the network configuration that will be used when creating a network session to \a config. + + \sa configuration() +*/ +void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config) +{ + d_func()->createSession(config); +} + +/*! + \since 4.7 + + Returns the network configuration. + + \sa setConfiguration() +*/ +QNetworkConfiguration QNetworkAccessManager::configuration() const +{ + Q_D(const QNetworkAccessManager); + + if (d->networkSession) + return d->networkSession->configuration(); + else + return QNetworkConfiguration(); +} + +/*! + \since 4.7 + + Returns the current active network configuration. + + \sa configuration() +*/ +QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const +{ + Q_D(const QNetworkAccessManager); + + if (d->networkSession) { + QNetworkConfigurationManager manager; + + return manager.configurationFromIdentifier( + d->networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString()); + } else { + return QNetworkConfiguration(); + } +} + +/*! + \since 4.7 + + Enables network access via this QNetworkAccessManager if \a enabled is true; otherwise disables + access. +*/ +void QNetworkAccessManager::setNetworkAccessEnabled(bool enabled) +{ + Q_D(QNetworkAccessManager); + + if (d->networkAccessEnabled != enabled) { + d->networkAccessEnabled = enabled; + emit networkAccessChanged(enabled); + } +} + +/*! + \since 4.7 + + Returns true if network access via this QNetworkAccessManager is enabled; otherwise returns + false. +*/ +bool QNetworkAccessManager::networkAccessEnabled() const +{ + Q_D(const QNetworkAccessManager); + + return d->networkAccessEnabled; +} + +/*! Returns a new QNetworkReply object to handle the operation \a op and request \a req. The device \a outgoingData is always 0 for Get and Head requests, but is the value passed to post() and put() in @@ -693,6 +814,13 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera return new QFileNetworkReply(this, req, op); } + // Return a disabled network reply if network access is disabled. + // Except if the scheme is empty or file://. + if (!d->networkAccessEnabled && !(req.url().scheme() == QLatin1String("file") || + req.url().scheme().isEmpty())) { + return new QDisabledNetworkReply(this, req, op); + } + QNetworkRequest request = req; if (!request.header(QNetworkRequest::ContentLengthHeader).isValid() && outgoingData && !outgoingData->isSequential()) { @@ -709,6 +837,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // first step: create the reply QUrl url = request.url(); QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); + if (req.url().scheme() != QLatin1String("file") && !req.url().scheme().isEmpty()) + connect(this, SIGNAL(networkSessionOnline()), reply, SLOT(_q_networkSessionOnline())); QNetworkReplyImplPrivate *priv = reply->d_func(); priv->manager = this; @@ -743,6 +873,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera void QNetworkAccessManagerPrivate::_q_replyFinished() { Q_Q(QNetworkAccessManager); + QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender()); if (reply) emit q->finished(reply); @@ -998,6 +1129,45 @@ QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate() { } +void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &config) +{ + Q_Q(QNetworkAccessManager); + + if (networkSession) + delete networkSession; + + if (!config.isValid()) { + networkSession = 0; + return; + } + + networkSession = new QNetworkSession(config, q); + + QObject::connect(networkSession, SIGNAL(opened()), q, SIGNAL(networkSessionOnline())); + QObject::connect(networkSession, SIGNAL(newConfigurationActivated()), + q, SLOT(_q_networkSessionNewConfigurationActivated())); + QObject::connect(networkSession, + SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)), + q, + SLOT(_q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool))); +} + +void QNetworkAccessManagerPrivate::_q_networkSessionNewConfigurationActivated() +{ + Q_Q(QNetworkAccessManager); + + networkSession->accept(); + + emit q->networkSessionOnline(); +} + +void QNetworkAccessManagerPrivate::_q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &, bool) +{ + Q_Q(QNetworkAccessManager); + + networkSession->migrate(); +} + QT_END_NAMESPACE #include "moc_qnetworkaccessmanager.cpp" diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index d2fe527..6fdb678 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -62,12 +62,16 @@ class QNetworkReply; class QNetworkProxy; class QNetworkProxyFactory; class QSslError; +class QNetworkConfiguration; class QNetworkReplyImplPrivate; class QNetworkAccessManagerPrivate; class Q_NETWORK_EXPORT QNetworkAccessManager: public QObject { Q_OBJECT + + Q_PROPERTY(bool networkAccess READ networkAccessEnabled WRITE setNetworkAccessEnabled NOTIFY networkAccessChanged) + public: enum Operation { HeadOperation = 1, @@ -103,6 +107,13 @@ public: QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data); QNetworkReply *deleteResource(const QNetworkRequest &request); + void setConfiguration(const QNetworkConfiguration &config); + QNetworkConfiguration configuration() const; + QNetworkConfiguration activeConfiguration() const; + + void setNetworkAccessEnabled(bool enabled); + bool networkAccessEnabled() const; + Q_SIGNALS: #ifndef QT_NO_NETWORKPROXY void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); @@ -113,6 +124,10 @@ Q_SIGNALS: void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors); #endif + void networkSessionOnline(); + + void networkAccessChanged(bool enabled); + protected: virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0); @@ -122,6 +137,8 @@ private: Q_DECLARE_PRIVATE(QNetworkAccessManager) Q_PRIVATE_SLOT(d_func(), void _q_replyFinished()) Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>)) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionNewConfigurationActivated()) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool)) }; QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 1749373..568894c 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -65,6 +65,7 @@ class QAuthenticator; class QAbstractNetworkCache; class QNetworkAuthenticationCredential; class QNetworkCookieJar; +class QNetworkSession; class QNetworkAccessManagerPrivate: public QObjectPrivate { @@ -74,7 +75,9 @@ public: #ifndef QT_NO_NETWORKPROXY proxyFactory(0), #endif - cookieJarCreated(false) + cookieJarCreated(false), + networkSession(0), + networkAccessEnabled(true) { } ~QNetworkAccessManagerPrivate(); @@ -99,6 +102,12 @@ public: QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request); + void createSession(const QNetworkConfiguration &config); + + void _q_networkSessionNewConfigurationActivated(); + void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config, + bool isSeamless); + // this is the cache for storing downloaded files QAbstractNetworkCache *networkCache; @@ -112,6 +121,8 @@ public: bool cookieJarCreated; + QNetworkSession *networkSession; + bool networkAccessEnabled; // this cache can be used by individual backends to cache e.g. their TCP connections to a server // and use the connections for multiple requests. diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h index f34396f..3cc4cee 100644 --- a/src/network/access/qnetworkcookie.h +++ b/src/network/access/qnetworkcookie.h @@ -114,7 +114,7 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug, const QNetworkCookie &); QT_END_NAMESPACE // ### Qt5 remove this include -#include "qnetworkcookiejar.h" +#include <QtNetwork/QNetworkCookieJar> Q_DECLARE_METATYPE(QNetworkCookie) Q_DECLARE_METATYPE(QList<QNetworkCookie>) diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h index 813bf3e..8086f38 100644 --- a/src/network/access/qnetworkcookiejar.h +++ b/src/network/access/qnetworkcookiejar.h @@ -46,7 +46,7 @@ #include <QtCore/QUrl> // ### Qt5 remove this include -#include "qnetworkcookie.h" +#include <QtNetwork/QNetworkCookie> QT_BEGIN_HEADER diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 15748fe..c8b8c1f 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -125,6 +125,11 @@ QNetworkReplyPrivate::QNetworkReplyPrivate() encrypted channel could not be established. The sslErrors() signal should have been emitted. + \value TemporaryNetworkFailureError the connection was broken due + to disconnection from the network, however the system has initiated + roaming to another access point. The request should be resubmitted + and will be processed as soon as the connection is re-established. + \value ProxyConnectionRefusedError the connection to the proxy server was refused (the proxy server is not accepting requests) diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h index 5db4985..acb7379 100644 --- a/src/network/access/qnetworkreply.h +++ b/src/network/access/qnetworkreply.h @@ -77,6 +77,7 @@ public: TimeoutError, OperationCanceledError, SslHandshakeFailedError, + TemporaryNetworkFailureError, UnknownNetworkError = 99, // proxy errors (101-199): diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 59c7d76..7f66b25 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -47,6 +47,7 @@ #include "QtCore/qdatetime.h" #include "QtNetwork/qsslconfiguration.h" #include "qnetworkaccesshttpbackend_p.h" +#include "qnetworkaccessmanager_p.h" #include <QtCore/QCoreApplication> @@ -57,7 +58,7 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate() copyDevice(0), cacheEnabled(false), cacheSaveDevice(0), notificationHandlingPaused(false), - bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1), + bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1), preMigrationDownloaded(-1), httpStatusCode(0), state(Idle) { @@ -82,7 +83,24 @@ void QNetworkReplyImplPrivate::_q_startOperation() return; } - backend->open(); + if (!backend->start()) { + // backend failed to start because the session state is not Connected. + // QNetworkAccessManager will call reply->backend->start() again for us when the session + // state changes. + state = WaitingForSession; + + QNetworkSession *session = manager->d_func()->networkSession; + + if (session) { + if (!session->isOpen()) + session->open(); + } else { + qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); + } + + return; + } + if (state != Finished) { if (operation == QNetworkAccessManager::GetOperation) pendingNotifications.append(NotifyDownstreamReadyWrite); @@ -134,6 +152,8 @@ void QNetworkReplyImplPrivate::_q_copyReadyRead() lastBytesDownloaded = bytesDownloaded; QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); + if (preMigrationDownloaded != Q_INT64_C(-1)) + totalSize = totalSize.toLongLong() + preMigrationDownloaded; pauseNotificationHandling(); emit q->downloadProgress(bytesDownloaded, totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); @@ -206,6 +226,26 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingData() } } +void QNetworkReplyImplPrivate::_q_networkSessionOnline() +{ + Q_Q(QNetworkReplyImpl); + + switch (state) { + case QNetworkReplyImplPrivate::Buffering: + case QNetworkReplyImplPrivate::Working: + case QNetworkReplyImplPrivate::Reconnecting: + // Migrate existing downloads to new network connection. + migrateBackend(); + break; + case QNetworkReplyImplPrivate::WaitingForSession: + // Start waiting requests. + QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); + break; + default: + ; + } +} + void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *data) { @@ -457,6 +497,17 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) QPointer<QNetworkReplyImpl> qq = q; QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); + if (totalSize.isNull()) { + RawHeadersList::ConstIterator it = findRawHeader("Content-Range"); + if (it != rawHeaders.constEnd()) { + int index = it->second.lastIndexOf('/'); + if (index != -1) + totalSize = it->second.mid(index + 1).toLongLong() - preMigrationDownloaded; + } + } + + if (preMigrationDownloaded != Q_INT64_C(-1)) + totalSize = totalSize.toLongLong() + preMigrationDownloaded; pauseNotificationHandling(); emit q->downloadProgress(bytesDownloaded, totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); @@ -498,14 +549,39 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data) void QNetworkReplyImplPrivate::finished() { Q_Q(QNetworkReplyImpl); - if (state == Finished || state == Aborted) + + if (state == Finished || state == Aborted || state == WaitingForSession) return; + pauseNotificationHandling(); + QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); + if (preMigrationDownloaded != Q_INT64_C(-1)) + totalSize = totalSize.toLongLong() + preMigrationDownloaded; + QNetworkSession *session = manager->d_func()->networkSession; + if (session && session->state() == QNetworkSession::Roaming && + state == Working && errorCode != QNetworkReply::OperationCanceledError) { + // only content with a known size will fail with a temporary network failure error + if (!totalSize.isNull()) { + if (bytesDownloaded != totalSize) { + if (migrateBackend()) { + // either we are migrating or the request is finished/aborted + if (state == Reconnecting || state == WaitingForSession) { + resumeNotificationHandling(); + return; // exit early if we are migrating. + } + } else { + error(QNetworkReply::TemporaryNetworkFailureError, + q->tr("Temporary network failure.")); + } + } + } + } + resumeNotificationHandling(); + state = Finished; pendingNotifications.clear(); pauseNotificationHandling(); - QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); if (totalSize.isNull() || totalSize == -1) { emit q->downloadProgress(bytesDownloaded, bytesDownloaded); } @@ -514,7 +590,9 @@ void QNetworkReplyImplPrivate::finished() emit q->uploadProgress(0, 0); resumeNotificationHandling(); - completeCacheSave(); + // if we don't know the total size of or we received everything save the cache + if (totalSize.isNull() || totalSize == -1 || bytesDownloaded == totalSize) + completeCacheSave(); // note: might not be a good idea, since users could decide to delete us // which would delete the backend too... @@ -722,6 +800,89 @@ bool QNetworkReplyImpl::event(QEvent *e) return QObject::event(e); } +/* + Migrates the backend of the QNetworkReply to a new network connection if required. Returns + true if the reply is migrated or it is not required; otherwise returns false. +*/ +bool QNetworkReplyImplPrivate::migrateBackend() +{ + Q_Q(QNetworkReplyImpl); + + // Network reply is already finished or aborted, don't need to migrate. + if (state == Finished || state == Aborted) + return true; + + // Resume only supported by http backend, not migrating. + if (!qobject_cast<QNetworkAccessHttpBackend *>(backend)) + return false; + + // Request has outgoing data, not migrating. + if (outgoingData) + return false; + + // Request is serviced from the cache, don't need to migrate. + if (copyDevice) + return true; + + // Range header is not supported by server/resource, can't migrate. + RawHeadersList::ConstIterator it = findRawHeader("Accept-Ranges"); + if (it == rawHeaders.constEnd() || it->second == "none") + return false; + + state = QNetworkReplyImplPrivate::Reconnecting; + + if (backend) { + delete backend; + backend = 0; + } + + cookedHeaders.clear(); + rawHeaders.clear(); + + preMigrationDownloaded = bytesDownloaded; + + request.setRawHeader("Range", "bytes=" + QByteArray::number(preMigrationDownloaded) + '-'); + + backend = manager->d_func()->findBackend(operation, request); + + if (backend) { + backend->setParent(q); + backend->reply = this; + } + + if (qobject_cast<QNetworkAccessHttpBackend *>(backend)) { + _q_startOperation(); + } else { + QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); + } + + return true; +} + +QDisabledNetworkReply::QDisabledNetworkReply(QObject *parent, + const QNetworkRequest &req, + QNetworkAccessManager::Operation op) +: QNetworkReply(parent) +{ + setRequest(req); + setUrl(req.url()); + setOperation(op); + + qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError"); + + QString msg = QCoreApplication::translate("QNetworkAccessManager", + "Network access is disabled."); + setError(UnknownNetworkError, msg); + + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, UnknownNetworkError)); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); +} + +QDisabledNetworkReply::~QDisabledNetworkReply() +{ +} + QT_END_NAMESPACE #include "moc_qnetworkreplyimpl_p.cpp" diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index 168e5cf..ec413cc 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -98,6 +98,7 @@ public: Q_PRIVATE_SLOT(d_func(), void _q_copyReadChannelFinished()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionOnline()) }; class QNetworkReplyImplPrivate: public QNetworkReplyPrivate @@ -110,11 +111,13 @@ public: }; enum State { - Idle, - Buffering, - Working, - Finished, - Aborted + Idle, // The reply is idle. + Buffering, // The reply is buffering outgoing data. + Working, // The reply is uploading/downloading data. + Finished, // The reply has finished. + Aborted, // The reply has been aborted. + WaitingForSession, // The reply is waiting for the session to open before connecting. + Reconnecting // The reply will reconnect to once roaming has completed. }; typedef QQueue<InternalNotifications> NotificationQueue; @@ -128,6 +131,7 @@ public: void _q_copyReadChannelFinished(); void _q_bufferOutgoingData(); void _q_bufferOutgoingDataFinished(); + void _q_networkSessionOnline(); void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData); @@ -161,6 +165,8 @@ public: QIODevice *copyDevice; QAbstractNetworkCache *networkCache() const; + bool migrateBackend(); + bool cacheEnabled; QIODevice *cacheSaveDevice; @@ -177,6 +183,7 @@ public: qint64 bytesDownloaded; qint64 lastBytesDownloaded; qint64 bytesUploaded; + qint64 preMigrationDownloaded; QString httpReasonPhrase; int httpStatusCode; @@ -186,6 +193,20 @@ public: Q_DECLARE_PUBLIC(QNetworkReplyImpl) }; +class QDisabledNetworkReply : public QNetworkReply +{ + Q_OBJECT + +public: + QDisabledNetworkReply(QObject *parent, const QNetworkRequest &req, + const QNetworkAccessManager::Operation op); + ~QDisabledNetworkReply(); + + void abort() { } +protected: + qint64 readData(char *, qint64) { return -1; } +}; + QT_END_NAMESPACE #endif diff --git a/src/network/bearer/bearer.pri b/src/network/bearer/bearer.pri new file mode 100644 index 0000000..44e97fd --- /dev/null +++ b/src/network/bearer/bearer.pri @@ -0,0 +1,18 @@ +# Qt network bearer management module + +HEADERS += bearer/qnetworkconfiguration.h \ + bearer/qnetworksession.h \ + bearer/qnetworkconfigmanager.h \ + bearer/qnetworkconfigmanager_p.h \ + bearer/qnetworkconfiguration_p.h \ + bearer/qnetworksession_p.h \ + bearer/qbearerengine_p.h \ + bearer/qbearerplugin_p.h + +SOURCES += bearer/qnetworksession.cpp \ + bearer/qnetworkconfigmanager.cpp \ + bearer/qnetworkconfiguration.cpp \ + bearer/qnetworkconfigmanager_p.cpp \ + bearer/qbearerengine.cpp \ + bearer/qbearerplugin.cpp + diff --git a/src/network/bearer/qbearerengine.cpp b/src/network/bearer/qbearerengine.cpp new file mode 100644 index 0000000..bd2ca6c --- /dev/null +++ b/src/network/bearer/qbearerengine.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbearerengine_p.h" + +QT_BEGIN_NAMESPACE + +QBearerEngine::QBearerEngine(QObject *parent) +: QObject(parent) +{ +} + +QBearerEngine::~QBearerEngine() +{ + foreach (const QString &oldIface, snapConfigurations.keys()) { + QNetworkConfigurationPrivatePointer priv = snapConfigurations.take(oldIface); + priv->isValid = false; + priv->id.clear(); + } + + foreach (const QString &oldIface, accessPointConfigurations.keys()) { + QNetworkConfigurationPrivatePointer priv = accessPointConfigurations.take(oldIface); + priv->isValid = false; + priv->id.clear(); + } + + foreach (const QString &oldIface, userChoiceConfigurations.keys()) { + QNetworkConfigurationPrivatePointer priv = userChoiceConfigurations.take(oldIface); + priv->isValid = false; + priv->id.clear(); + } +} + +#include "moc_qbearerengine_p.cpp" + +QT_END_NAMESPACE diff --git a/src/network/bearer/qbearerengine_p.h b/src/network/bearer/qbearerengine_p.h new file mode 100644 index 0000000..7e96877 --- /dev/null +++ b/src/network/bearer/qbearerengine_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBEARERENGINE_P_H +#define QBEARERENGINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qnetworkconfiguration_p.h" +#include "qnetworksession.h" +#include "qnetworkconfigmanager.h" + +#include <QtCore/qobject.h> +#include <QtCore/qglobal.h> +#include <QtCore/qlist.h> +#include <QtCore/qstring.h> +#include <QtCore/qhash.h> +#include <QtCore/qsharedpointer.h> + +QT_BEGIN_NAMESPACE + +class QNetworkConfiguration; + +class Q_NETWORK_EXPORT QBearerEngine : public QObject +{ + Q_OBJECT + +public: + QBearerEngine(QObject *parent = 0); + virtual ~QBearerEngine(); + + virtual bool hasIdentifier(const QString &id) = 0; + + virtual void requestUpdate() = 0; + + virtual QNetworkConfigurationManager::Capabilities capabilities() const = 0; + + virtual QNetworkSessionPrivate *createSessionBackend() = 0; + + virtual QNetworkConfigurationPrivatePointer defaultConfiguration() = 0; + +public: + //this table contains an up to date list of all configs at any time. + //it must be updated if configurations change, are added/removed or + //the members of ServiceNetworks change + QHash<QString, QNetworkConfigurationPrivatePointer> accessPointConfigurations; + QHash<QString, QNetworkConfigurationPrivatePointer> snapConfigurations; + QHash<QString, QNetworkConfigurationPrivatePointer> userChoiceConfigurations; + +Q_SIGNALS: + void configurationAdded(QNetworkConfigurationPrivatePointer config); + void configurationRemoved(QNetworkConfigurationPrivatePointer config); + void configurationChanged(QNetworkConfigurationPrivatePointer config); + + void updateCompleted(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/network/bearer/qbearerplugin.cpp b/src/network/bearer/qbearerplugin.cpp new file mode 100644 index 0000000..4509fd0 --- /dev/null +++ b/src/network/bearer/qbearerplugin.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbearerplugin_p.h" + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +QBearerEnginePlugin::QBearerEnginePlugin(QObject *parent) +: QObject(parent) +{ +} + +QBearerEnginePlugin::~QBearerEnginePlugin() +{ +} + +QT_END_NAMESPACE diff --git a/src/network/bearer/qbearerplugin_p.h b/src/network/bearer/qbearerplugin_p.h new file mode 100644 index 0000000..36709c2 --- /dev/null +++ b/src/network/bearer/qbearerplugin_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBEARERPLUGIN_P_H +#define QBEARERPLUGIN_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qbearerengine_p.h" + +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Network) + +struct Q_NETWORK_EXPORT QBearerEngineFactoryInterface : public QFactoryInterface +{ + virtual QBearerEngine *create(const QString &key = QString()) const = 0; +}; + +#define QBearerEngineFactoryInterface_iid "com.trolltech.Qt.QBearerEngineFactoryInterface" +Q_DECLARE_INTERFACE(QBearerEngineFactoryInterface, QBearerEngineFactoryInterface_iid) + +class Q_NETWORK_EXPORT QBearerEnginePlugin : public QObject, public QBearerEngineFactoryInterface +{ + Q_OBJECT + Q_INTERFACES(QBearerEngineFactoryInterface:QFactoryInterface) + +public: + explicit QBearerEnginePlugin(QObject *parent = 0); + virtual ~QBearerEnginePlugin(); + + virtual QStringList keys() const = 0; + virtual QBearerEngine *create(const QString &key = QString()) const = 0; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif + diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp new file mode 100644 index 0000000..8ca2537 --- /dev/null +++ b/src/network/bearer/qnetworkconfigmanager.cpp @@ -0,0 +1,348 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworkconfigmanager.h" + +#include "qnetworkconfigmanager_p.h" +#include "qbearerengine_p.h" + +#include <QtCore/qstringlist.h> + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC(QNetworkConfigurationManagerPrivate, connManager); + +QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate() +{ + return connManager(); +} + +/*! + \class QNetworkConfigurationManager + + \brief The QNetworkConfigurationManager class manages the network configurations provided + by the system. + + \since 4.7 + + \inmodule QtNetwork + \ingroup bearer + + QNetworkConfigurationManager provides access to the network configurations known to the system and + enables applications to detect the system capabilities (with regards to network sessions) at runtime. + + A QNetworkConfiguration abstracts a set of configuration options describing how a + network interface has to be configured to connect to a particular target network. + QNetworkConfigurationManager maintains and updates the global list of + QNetworkConfigurations. Applications can access and filter this list via + allConfigurations(). If a new configuration is added or an existing one is removed or changed + the configurationAdded(), configurationRemoved() and configurationChanged() signals are emitted + respectively. + + The defaultConfiguration() can be used when intending to immediately create a new + network session without caring about the particular configuration. It returns + a \l QNetworkConfiguration::Discovered configuration. If there are not any + discovered ones an invalid configuration is returned. + + Some configuration updates may require some time to perform updates. A WLAN scan is + such an example. Unless the platform performs internal updates it may be required to + manually trigger configuration updates via QNetworkConfigurationManager::updateConfigurations(). + The completion of the update process is indicted by emitting the updateCompleted() + signal. The update process ensures that every existing QNetworkConfiguration instance + is updated. There is no need to ask for a renewed configuration list via allConfigurations(). + + \sa QNetworkConfiguration +*/ + +/*! + \fn void QNetworkConfigurationManager::configurationAdded(const QNetworkConfiguration& config) + + This signal is emitted whenever a new network configuration is added to the system. The new + configuration is specified by \a config. +*/ + +/*! + \fn void QNetworkConfigurationManager::configurationRemoved(const QNetworkConfiguration& configuration) + + This signal is emitted when a configuration is about to be removed from the system. The removed + \a configuration is invalid but retains name and identifier. +*/ + +/*! + \fn void QNetworkConfigurationManager::updateCompleted() + + This signal is emitted when the configuration update has been completed. Such an update can + be initiated via \l updateConfigurations(). +*/ + +/*! \fn void QNetworkConfigurationManager::configurationChanged(const QNetworkConfiguration& config) + + This signal is emitted when the \l {QNetworkConfiguration::state()}{state} of \a config changes. +*/ + +/*! + \fn void QNetworkConfigurationManager::onlineStateChanged(bool isOnline) + + This signal is emitted when the device changes from online to offline mode or vice versa. + \a isOnline represents the new state of the device. + + The state is considered to be online for as long as + \l{allConfigurations()}{allConfigurations}(QNetworkConfiguration::Active) returns a list with + at least one entry. +*/ + +/*! + \enum QNetworkConfigurationManager::Capability + + Specifies the system capabilities of the bearer API. The possible values are: + + \value CanStartAndStopInterfaces Network sessions and their underlying access points can be + started and stopped. If this flag is not set QNetworkSession + can only monitor but not influence the state of access points. + On some platforms this feature may require elevated user + permissions. This option is platform specific and may not + always be available. + \value DirectConnectionRouting Network sessions and their sockets can be bound to a + particular network interface. Any packet that passes through + the socket goes to the specified network interface and thus + disregards standard routing table entries. This may be useful + when two interfaces can reach overlapping IP ranges or an + application has specific needs in regards to target networks. + This option is platform specific and may not always be + available. + \value SystemSessionSupport If this flag is set the underlying platform ensures that a + network interface is not shut down until the last network + session has been \l{QNetworkSession::close()}{closed()}. This + works across multiple processes. If the platform session + support is missing this API can only ensure the above behavior + for network sessions within the same process. + In general mobile platforms (such as Symbian/S60) have such + support whereas most desktop platform lack this capability. + \value ApplicationLevelRoaming The system gives applications control over the systems roaming + behavior. Applications can initiate roaming (in case the + current link is not suitable) and are consulted if the system + has identified a more suitable access point. + \value ForcedRoaming The system disconnects an existing access point and reconnects + via a more suitable one. The application does not have any + control over this process and has to reconnect its active + sockets. + \value DataStatistics If this flag is set QNetworkSession can provide statistics + about transmitted and received data. +*/ + +/*! + Constructs a QNetworkConfigurationManager with the given \a parent. +*/ +QNetworkConfigurationManager::QNetworkConfigurationManager( QObject* parent ) + : QObject(parent) +{ + QNetworkConfigurationManagerPrivate* priv = connManager(); + connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)), + this, SIGNAL(configurationAdded(QNetworkConfiguration))); + connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)), + this, SIGNAL(configurationRemoved(QNetworkConfiguration))); + connect(priv, SIGNAL(configurationUpdateComplete()), + this, SIGNAL(updateCompleted())); + connect(priv, SIGNAL(onlineStateChanged(bool)), + this, SIGNAL(onlineStateChanged(bool))); + connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)), + this, SIGNAL(configurationChanged(QNetworkConfiguration))); +} + +/*! + Frees the resources associated with the QNetworkConfigurationManager object. +*/ +QNetworkConfigurationManager::~QNetworkConfigurationManager() +{ +} + + +/*! + Returns the default configuration to be used. This function always returns a discovered + configuration; otherwise an invalid configuration. + + In some cases it may be required to call updateConfigurations() and wait for the + updateCompleted() signal before calling this function. + + \sa allConfigurations() +*/ +QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const +{ + return connManager()->defaultConfiguration(); +} + +/*! + Returns the list of configurations which comply with the given \a filter. + + By default this function returns all (defined and undefined) configurations. + + A wireless network with a particular SSID may only be accessible in a + certain area despite the fact that the system has a valid configuration + for it. Therefore the filter flag may be used to limit the list to + discovered and possibly connected configurations only. + + If \a filter is set to zero this function returns all possible configurations. + + Note that this function returns the states for all configurations as they are known at + the time of this function call. If for instance a configuration of type WLAN is defined + the system may have to perform a WLAN scan in order to determine whether it is + actually available. To obtain the most accurate state updateConfigurations() should + be used to update each configuration's state. Note that such an update may require + some time. It's completion is signalled by updateCompleted(). In the absence of a + configuration update this function returns the best estimate at the time of the call. +*/ +QList<QNetworkConfiguration> QNetworkConfigurationManager::allConfigurations(QNetworkConfiguration::StateFlags filter) const +{ + QList<QNetworkConfiguration> result; + QNetworkConfigurationManagerPrivate* conPriv = connManager(); + + foreach (QBearerEngine *engine, conPriv->sessionEngines) { + QStringList cpsIdents = engine->accessPointConfigurations.keys(); + + //find all InternetAccessPoints + foreach (const QString &ii, cpsIdents) { + QNetworkConfigurationPrivatePointer p = engine->accessPointConfigurations.value(ii); + if ((p->state & filter) == filter) { + QNetworkConfiguration pt; + pt.d = engine->accessPointConfigurations.value(ii); + result << pt; + } + } + + //find all service networks + cpsIdents = engine->snapConfigurations.keys(); + foreach (const QString &ii, cpsIdents) { + QNetworkConfigurationPrivatePointer p = engine->snapConfigurations.value(ii); + if ((p->state & filter) == filter) { + QNetworkConfiguration pt; + pt.d = engine->snapConfigurations.value(ii); + result << pt; + } + } + } + + return result; +} + +/*! + Returns the QNetworkConfiguration for \a identifier; otherwise returns an + invalid QNetworkConfiguration. + + \sa QNetworkConfiguration::identifier() +*/ +QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString& identifier) const +{ + QNetworkConfigurationManagerPrivate* conPriv = connManager(); + + QNetworkConfiguration item; + + foreach (QBearerEngine *engine, conPriv->sessionEngines) { + if (engine->accessPointConfigurations.contains(identifier)) + item.d = engine->accessPointConfigurations.value(identifier); + else if (engine->snapConfigurations.contains(identifier)) + item.d = engine->snapConfigurations.value(identifier); + else if (engine->userChoiceConfigurations.contains(identifier)) + item.d = engine->userChoiceConfigurations.value(identifier); + else + continue; + + return item; + } + + return item; +} + +/*! + Returns true if the system is considered to be connected to another device via an active + network interface; otherwise returns false. + + This is equivalent to the following code snippet: + + \code + QNetworkConfigurationManager mgr; + QList<QNetworkConfiguration> activeConfigs = mgr.allConfigurations(QNetworkConfiguration::Active) + if (activeConfigs.count() > 0) + Q_ASSERT(mgr.isOnline()) + else + Q_ASSERT(!mgr.isOnline()) + \endcode + + \sa onlineStateChanged() +*/ +bool QNetworkConfigurationManager::isOnline() const +{ + QNetworkConfigurationManagerPrivate* conPriv = connManager(); + Q_UNUSED(conPriv); + QList<QNetworkConfiguration> activeConfigs = allConfigurations(QNetworkConfiguration::Active); + return activeConfigs.count() > 0; +} + +/*! + Returns the capabilities supported by the current platform. +*/ +QNetworkConfigurationManager::Capabilities QNetworkConfigurationManager::capabilities() const +{ + return connManager()->capFlags; +} + +/*! + Initiates an update of all configurations. This may be used to initiate WLAN scans or other + time consuming updates which may be required to obtain the correct state for configurations. + + This call is asynchronous. On completion of this update the updateCompleted() signal is + emitted. If new configurations are discovered or old ones were removed or changed the update + process may trigger the emission of one or multiple configurationAdded(), + configurationRemoved() and configurationChanged() signals. + + If a configuration state changes as a result of this update all existing QNetworkConfiguration + instances are updated automatically. + + \sa allConfigurations() +*/ +void QNetworkConfigurationManager::updateConfigurations() +{ + connManager()->performAsyncConfigurationUpdate(); +} + +#include "moc_qnetworkconfigmanager.cpp" + +QT_END_NAMESPACE + diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h new file mode 100644 index 0000000..a34e456 --- /dev/null +++ b/src/network/bearer/qnetworkconfigmanager.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKCONFIGURATIONMANAGER_H +#define QNETWORKCONFIGURATIONMANAGER_H + +#include <QtCore/qobject.h> +#include <QtNetwork/qnetworkconfiguration.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QNetworkConfigurationManagerPrivate; +class Q_NETWORK_EXPORT QNetworkConfigurationManager : public QObject +{ + Q_OBJECT + +public: + + enum Capability { + CanStartAndStopInterfaces = 0x00000001, + DirectConnectionRouting = 0x00000002, + SystemSessionSupport = 0x00000004, + ApplicationLevelRoaming = 0x00000008, + ForcedRoaming = 0x00000010, + DataStatistics = 0x00000020 + }; + + Q_DECLARE_FLAGS(Capabilities, Capability) + + QNetworkConfigurationManager( QObject* parent = 0 ); + virtual ~QNetworkConfigurationManager(); + + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkConfiguration defaultConfiguration() const; + QList<QNetworkConfiguration> allConfigurations(QNetworkConfiguration::StateFlags flags = 0) const; + QNetworkConfiguration configurationFromIdentifier(const QString& identifier) const; + void updateConfigurations(); + + bool isOnline() const; + +Q_SIGNALS: + void configurationAdded(const QNetworkConfiguration& config); + void configurationRemoved(const QNetworkConfiguration& config); + void configurationChanged(const QNetworkConfiguration& config); + void onlineStateChanged(bool isOnline); + void updateCompleted(); + +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkConfigurationManager::Capabilities) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QNETWORKCONFIGURATIONMANAGER_H + diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp new file mode 100644 index 0000000..01a85a5 --- /dev/null +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -0,0 +1,306 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworkconfigmanager_p.h" +#include "qbearerplugin_p.h" + +#include <QtCore/private/qfactoryloader_p.h> + +#include <QtCore/qdebug.h> +#include <QtCore/qtimer.h> +#include <QtCore/qstringlist.h> + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QBearerEngineFactoryInterface_iid, QLatin1String("/bearer"))) + +QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() +{ + while (!sessionEngines.isEmpty()) + delete sessionEngines.takeFirst(); +} + +void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurationPrivatePointer ptr) +{ + if (!firstUpdate) { + QNetworkConfiguration item; + item.d = ptr; + emit configurationAdded(item); + } + + if (ptr->state == QNetworkConfiguration::Active) { + onlineConfigurations.insert(ptr); + if (!firstUpdate && onlineConfigurations.count() == 1) + emit onlineStateChanged(true); + } +} + +void QNetworkConfigurationManagerPrivate::configurationRemoved(QNetworkConfigurationPrivatePointer ptr) +{ + ptr->isValid = false; + + if (!firstUpdate) { + QNetworkConfiguration item; + item.d = ptr; + emit configurationRemoved(item); + } + + onlineConfigurations.remove(ptr); + if (!firstUpdate && onlineConfigurations.isEmpty()) + emit onlineStateChanged(false); +} + +void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigurationPrivatePointer ptr) +{ + if (!firstUpdate) { + QNetworkConfiguration item; + item.d = ptr; + emit configurationChanged(item); + } + + bool previous = !onlineConfigurations.isEmpty(); + + if (ptr->state == QNetworkConfiguration::Active) + onlineConfigurations.insert(ptr); + else + onlineConfigurations.remove(ptr); + + bool online = !onlineConfigurations.isEmpty(); + + if (!firstUpdate && online != previous) + emit onlineStateChanged(online); +} + +void QNetworkConfigurationManagerPrivate::updateInternetServiceConfiguration() +{ +#if 0 + if (!generic->snapConfigurations.contains(QLatin1String("Internet Service Network"))) { + QNetworkConfigurationPrivate *serviceNetwork = new QNetworkConfigurationPrivate; + serviceNetwork->name = tr("Internet"); + serviceNetwork->isValid = true; + serviceNetwork->id = QLatin1String("Internet Service Network"); + serviceNetwork->state = QNetworkConfiguration::Defined; + serviceNetwork->type = QNetworkConfiguration::ServiceNetwork; + + QNetworkConfigurationPrivatePointer ptr(serviceNetwork); + + generic->snapConfigurations.insert(serviceNetwork->id, ptr); + + if (!firstUpdate) { + QNetworkConfiguration item; + item.d = ptr; + emit configurationAdded(item); + } + } + + QNetworkConfigurationPrivatePointer ptr = + generic->snapConfigurations.value(QLatin1String("Internet Service Network")); + + QList<QNetworkConfigurationPrivatePointer> serviceNetworkMembers; + + QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i = + generic->accessPointConfigurations.constBegin(); + + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Defined; + while (i != generic->accessPointConfigurations.constEnd()) { + QNetworkConfigurationPrivatePointer child = i.value(); + + if (child.data()->internet && ((child.data()->state & QNetworkConfiguration::Defined) + == QNetworkConfiguration::Defined)) { + serviceNetworkMembers.append(child); + + state |= child.data()->state; + } + + ++i; + } + + + if (ptr.data()->state != state || ptr.data()->serviceNetworkMembers != serviceNetworkMembers) { + ptr.data()->state = state; + ptr.data()->serviceNetworkMembers = serviceNetworkMembers; + + QNetworkConfiguration item; + item.d = ptr; + emit configurationChanged(item); + } +#endif +} + +void QNetworkConfigurationManagerPrivate::updateConfigurations() +{ + if (firstUpdate) { + updating = false; + + QFactoryLoader *l = loader(); + + QBearerEngine *generic = 0; + + foreach (const QString &key, l->keys()) { + QBearerEnginePlugin *plugin = qobject_cast<QBearerEnginePlugin *>(l->instance(key)); + if (plugin) { + QBearerEngine *engine = plugin->create(key); + if (!engine) + continue; + + if (key == QLatin1String("generic")) + generic = engine; + else + sessionEngines.append(engine); + + connect(engine, SIGNAL(updateCompleted()), + this, SLOT(updateConfigurations())); + connect(engine, SIGNAL(configurationAdded(QNetworkConfigurationPrivatePointer)), + this, SLOT(configurationAdded(QNetworkConfigurationPrivatePointer))); + connect(engine, SIGNAL(configurationRemoved(QNetworkConfigurationPrivatePointer)), + this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer))); + connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)), + this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer))); + + capFlags |= engine->capabilities(); + } + } + + if (generic) + sessionEngines.append(generic); + } + + QBearerEngine *engine = qobject_cast<QBearerEngine *>(sender()); + if (!updatingEngines.isEmpty() && engine) { + int index = sessionEngines.indexOf(engine); + if (index >= 0) + updatingEngines.remove(index); + } + + if (updating && updatingEngines.isEmpty()) { + updating = false; + emit configurationUpdateComplete(); + } + + if (firstUpdate) + firstUpdate = false; +} + +/*! + Returns the default configuration of the first plugin, if one exists; otherwise returns an + invalid configuration. + + \internal +*/ +QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() +{ + foreach (QBearerEngine *engine, sessionEngines) { + QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration(); + + if (ptr) { + QNetworkConfiguration config; + config.d = ptr; + return config; + } + } + + // Engines don't have a default configuration. + + // Return first active snap + QNetworkConfigurationPrivatePointer firstDiscovered; + + foreach (QBearerEngine *engine, sessionEngines) { + foreach (const QString &id, engine->snapConfigurations.keys()) { + QNetworkConfigurationPrivatePointer ptr = engine->snapConfigurations.value(id); + + if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + QNetworkConfiguration config; + config.d = ptr; + return config; + } else if ((ptr->state & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + firstDiscovered = ptr; + } + } + } + + // No Active SNAPs return first Discovered SNAP. + if (firstDiscovered) { + QNetworkConfiguration config; + config.d = firstDiscovered; + return config; + } + + // No Active or Discovered SNAPs, do same for InternetAccessPoints. + firstDiscovered.reset(); + + foreach (QBearerEngine *engine, sessionEngines) { + foreach (const QString &id, engine->accessPointConfigurations.keys()) { + QNetworkConfigurationPrivatePointer ptr = engine->accessPointConfigurations.value(id); + + if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + QNetworkConfiguration config; + config.d = ptr; + return config; + } else if ((ptr->state & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + firstDiscovered = ptr; + } + } + } + + // No Active InternetAccessPoint return first Discovered InternetAccessPoint. + if (firstDiscovered) { + QNetworkConfiguration config; + config.d = firstDiscovered; + return config; + } + + return QNetworkConfiguration(); +} + +void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() +{ + updating = true; + + for (int i = 0; i < sessionEngines.count(); ++i) { + updatingEngines.insert(i); + sessionEngines.at(i)->requestUpdate(); + } +} + +QT_END_NAMESPACE diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h new file mode 100644 index 0000000..f6603ce --- /dev/null +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKCONFIGURATIONMANAGERPRIVATE_H +#define QNETWORKCONFIGURATIONMANAGERPRIVATE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qnetworkconfigmanager.h" +#include "qnetworkconfiguration_p.h" + +QT_BEGIN_NAMESPACE + +class QBearerEngine; + +class QNetworkConfigurationManagerPrivate : public QObject +{ + Q_OBJECT +public: + QNetworkConfigurationManagerPrivate() + : QObject(0), capFlags(0), firstUpdate(true) + { + updateConfigurations(); + } + + virtual ~QNetworkConfigurationManagerPrivate(); + + QNetworkConfiguration defaultConfiguration(); + + QNetworkConfigurationManager::Capabilities capFlags; + + void performAsyncConfigurationUpdate(); + + bool firstUpdate; + +public slots: + void updateConfigurations(); + +Q_SIGNALS: + void configurationAdded(const QNetworkConfiguration& config); + void configurationRemoved(const QNetworkConfiguration& config); + void configurationUpdateComplete(); + void configurationChanged(const QNetworkConfiguration& config); + void onlineStateChanged(bool isOnline); + +private: + void updateInternetServiceConfiguration(); + + void abort(); + +public: + QList<QBearerEngine *> sessionEngines; + +private: + QSet<QNetworkConfigurationPrivatePointer> onlineConfigurations; + + bool updating; + QSet<int> updatingEngines; + +private Q_SLOTS: + void configurationAdded(QNetworkConfigurationPrivatePointer ptr); + void configurationRemoved(QNetworkConfigurationPrivatePointer ptr); + void configurationChanged(QNetworkConfigurationPrivatePointer ptr); +}; + +Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate(); + +QT_END_NAMESPACE + +#endif //QNETWORKCONFIGURATIONMANAGERPRIVATE_H diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp new file mode 100644 index 0000000..8c11d9c --- /dev/null +++ b/src/network/bearer/qnetworkconfiguration.cpp @@ -0,0 +1,396 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworkconfiguration.h" + +#include "qnetworkconfiguration_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QNetworkConfiguration + + \brief The QNetworkConfiguration class provides an abstraction of one or more access point configurations. + + \since 4.7 + + \inmodule QtNetwork + \ingroup bearer + + QNetworkConfiguration encapsulates a single access point or service network. + In most cases a single access point configuration can be mapped to one network + interface. However a single network interface may not always map to only one + access point configuration. Multiple configurations for the same + network device may enable multiple access points. An example + device that could exhibit such a configuration might be a + Smartphone which allows the user to manage multiple WLAN + configurations while the device itself has only one WLAN network device. + + The QNetworkConfiguration also supports the concept of service networks. + This concept allows the grouping of multiple access point configurations + into one entity. Such a group is called service network and can be + beneficial in cases whereby a network session to a + particular destination network is required (e.g. a company network). + When using a service network the user doesn't usually care which one of the + connectivity options is chosen (e.g. corporate WLAN or VPN via GPRS) + as long as he can reach the company's target server. Depending + on the current position and time some of the access points that make + up the service network may not even be available. Furthermore + automated access point roaming can be enabled which enables the device + to change the network interface configuration dynamically while maintaining + the applications connection to the target network. It allows adaption + to the changing environment and may enable optimization with regards to + cost, speed or other network parameters. + + Special configurations of type UserChoice provide a placeholder configuration which is + resolved to an actual network configuration by the platform when a + \l {QNetworkSession}{session} is \l {QNetworkSession::open()}{opened}. Not all platforms + support the concept of a user choice configuration. + + \section1 Configuration states + + The list of available configurations can be obtained via + QNetworkConfigurationManager::allConfigurations(). A configuration can have + multiple states. The \l Defined configuration state indicates that the configuration + is stored on the device. However the configuration is not yet ready to be activated + as e.g. a WLAN may not be available at the current time. + + The \l Discovered state implies that the configuration is \l Defined and + the outside conditions are such that the configuration can be used immediately + to open a new network session. An example of such an outside condition may be + that the Ethernet cable is actually connected to the device or that the WLAN + with the specified SSID is in range. + + The \l Active state implies that the configuration is \l Discovered. A configuration + in this state is currently being used by an application. The underlying network + interface has a valid IP configuration and can transfer IP packets between the + device and the target network. + + The \l Undefined state indicates that the system has knowledge of possible target + networks but cannot actually use that knowledge to connect to it. An example + for such a state could be an encrypted WLAN that has been discovered + but the user hasn't actually saved a configuration including the required password + which would allow the device to connect to it. + + Depending on the type of configuration some states are transient in nature. A GPRS/UMTS + connection may almost always be \l Discovered if the GSM/UMTS network is available. + However if the GSM/UMTS network looses the connection the associated configuration may change its state + from \l Discovered to \l Defined as well. A similar use case might be triggered by + WLAN availability. QNetworkConfigurationManager::updateConfigurations() can be used to + manually trigger updates of states. Note that some platforms do not require such updates + as they implicitly change the state once it has been discovered. If the state of a + configuration changes all related QNetworkConfiguration instances change their state automatically. + + \sa QNetworkSession, QNetworkConfigurationManager +*/ + +/*! + \enum QNetworkConfiguration::Type + + This enum describes the type of configuration. + + \value InternetAccessPoint The configuration specifies the details for a single access point. + Note that configurations of type InternetAccessPoint may be part + of other QNetworkConfigurations of type ServiceNetwork. + \value ServiceNetwork The configuration is based on a group of QNetworkConfigurations of + type InternetAccessPoint. All group members can reach the same + target network. This type of configuration is a mandatory + requirement for roaming enabled network sessions. On some + platforms this form of configuration may also be called Service + Network Access Point (SNAP). + \value UserChoice The configuration is a placeholder which will be resolved to an + actual configuration by the platform when a session is opened. Depending + on the platform the selection may generate a popup dialog asking the user + for his preferred choice. + \value Invalid The configuration is invalid. +*/ + +/*! + \enum QNetworkConfiguration::StateFlag + + Specifies the configuration states. + + \value Undefined This state is used for transient configurations such as newly discovered + WLANs for which the user has not actually created a configuration yet. + \value Defined Defined configurations are known to the system but are not immediately + usable (e.g. a configured WLAN is not within range or the Ethernet cable + is currently not plugged into the machine). + \value Discovered A discovered configuration can be immediately used to create a new + QNetworkSession. An example of a discovered configuration could be a WLAN + which is within in range. If the device moves out of range the discovered + flag is dropped. A second example is a GPRS configuration which generally + remains discovered for as long as the phone has network coverage. A + configuration that has this state is also in state + QNetworkConfiguration::Defined. If the configuration is a service network + this flag is set if at least one of the underlying access points + configurations has the Discovered state. + \value Active The configuration is currently used by an open network session + (see \l QNetworkSession::isOpen()). However this does not mean that the + current process is the entity that created the open session. It merely + indicates that if a new QNetworkSession were to be constructed based on + this configuration \l QNetworkSession::state() would return + \l QNetworkSession::Connected. This state implies the + QNetworkConfiguration::Discovered state. +*/ + +/*! + \enum QNetworkConfiguration::Purpose + + Specifies the purpose of the configuration. + + \value UnknownPurpose The configuration doesn't specify any purpose. This is the default value. + \value PublicPurpose The configuration can be used for general purpose internet access. + \value PrivatePurpose The configuration is suitable to access a private network such as an office Intranet. + \value ServiceSpecificPurpose The configuration can be used for operator specific services (e.g. + receiving MMS messages or content streaming). +*/ + +/*! + Constructs an invalid configuration object. + + \sa isValid() +*/ +QNetworkConfiguration::QNetworkConfiguration() + : d(0) +{ +} + +/*! + Creates a copy of the QNetworkConfiguration object contained in \a other. +*/ +QNetworkConfiguration::QNetworkConfiguration(const QNetworkConfiguration& other) + : d(other.d) +{ +} + +/*! + Copies the content of the QNetworkConfiguration object contained in \a other into this one. +*/ +QNetworkConfiguration& QNetworkConfiguration::operator=(const QNetworkConfiguration& other) +{ + d = other.d; + return *this; +} + +/*! + Frees the resources associated with the QNetworkConfiguration object. +*/ +QNetworkConfiguration::~QNetworkConfiguration() +{ +} + +/*! + Returns true, if this configuration is the same as the \a other + configuration given; otherwise returns false. +*/ +bool QNetworkConfiguration::operator==(const QNetworkConfiguration& other) const +{ + if (!d) + return !other.d; + + if (!other.d) + return false; + + return (d == other.d); +} + +/*! + \fn bool QNetworkConfiguration::operator!=(const QNetworkConfiguration& other) const + + Returns true if this configuration is not the same as the \a other + configuration given; otherwise returns false. +*/ + +/*! + Returns the user visible name of this configuration. + + The name may either be the name of the underlying access point or the + name for service network that this configuration represents. +*/ +QString QNetworkConfiguration::name() const +{ + return d ? d->name : QString(); +} + +/*! + Returns the unique and platform specific identifier for this network configuration; + otherwise an empty string. +*/ +QString QNetworkConfiguration::identifier() const +{ + return d ? d->id : QString(); +} + +/*! + Returns the type of the configuration. + + A configuration can represent a single access point configuration or + a set of access point configurations. Such a set is called service network. + A configuration that is based on a service network can potentially support + roaming of network sessions. +*/ +QNetworkConfiguration::Type QNetworkConfiguration::type() const +{ + return d ? d->type : QNetworkConfiguration::Invalid; +} + +/*! + Returns true if this QNetworkConfiguration object is valid. + A configuration may become invalid if the user deletes the configuration or + the configuration was default-constructed. + + The addition and removal of configurations can be monitored via the + QNetworkConfigurationManager. + + \sa QNetworkConfigurationManager +*/ +bool QNetworkConfiguration::isValid() const +{ + return d ? d->isValid : false; +} + +/*! + Returns the current state of the configuration. +*/ +QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const +{ + return d ? d->state : QNetworkConfiguration::Undefined; +} + +/*! + Returns the purpose of this configuration. + + The purpose field may be used to programmatically determine the + purpose of a configuration. Such information is usually part of the + access point or service network meta data. +*/ +QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const +{ + return d ? d->purpose : QNetworkConfiguration::UnknownPurpose; +} + +/*! + Returns true if this configuration supports roaming; otherwise false. +*/ +bool QNetworkConfiguration::isRoamingAvailable() const +{ + return d ? d->roamingSupported : false; +} + +/*! + Returns all sub configurations of this network configuration. + Only network configurations of type \l ServiceNetwork can have children. Otherwise + this function returns an empty list. +*/ +QList<QNetworkConfiguration> QNetworkConfiguration::children() const +{ + QList<QNetworkConfiguration> results; + if (type() != QNetworkConfiguration::ServiceNetwork || !isValid() ) + return results; + + QMutableListIterator<QNetworkConfigurationPrivatePointer> iter(d->serviceNetworkMembers); + while(iter.hasNext()) { + QNetworkConfigurationPrivatePointer p = iter.next(); + //if we have an invalid member get rid of it -> was deleted earlier on + if (!p->isValid) + iter.remove(); + + QNetworkConfiguration item; + item.d = p; + results << item; + } + + return results; +} + +/*! + Returns the type of bearer. The string is not translated and + therefore can not be shown to the user. The subsequent table presents the currently known + bearer types: + + \table + \header + \o Value + \o Description + \row + \o Unknown + \o The session is based on an unknown or unspecified bearer type. + \row + \o Ethernet + \o The session is based on Ethernet. + \row + \o WLAN + \o The session is based on Wireless LAN. + \row + \o 2G + \o The session uses CSD, GPRS, HSCSD, EDGE or cdmaOne. + \row + \o CDMA2000 + \o The session uses CDMA. + \row + \o WCDMA + \o The session uses W-CDMA/UMTS. + \row + \o HSPA + \o The session uses High Speed Packet Access. + \row + \o Bluetooth + \o The session uses Bluetooth. + \row + \o WiMAX + \o The session uses WiMAX. + \endtable + + This function returns an empty string if this is an invalid configuration, + a network configuration of type \l QNetworkConfiguration::ServiceNetwork or + \l QNetworkConfiguration::UserChoice. +*/ +QString QNetworkConfiguration::bearerName() const +{ + if (!isValid()) + return QString(); + + return d->bearerName(); +} + + +QT_END_NAMESPACE + diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h new file mode 100644 index 0000000..8d45cf6 --- /dev/null +++ b/src/network/bearer/qnetworkconfiguration.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKCONFIGURATION_H +#define QNETWORKCONFIGURATION_H + +#include <QtCore/qglobal.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> +#include <QtCore/qlist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QNetworkConfigurationPrivate; +class Q_NETWORK_EXPORT QNetworkConfiguration +{ +public: + QNetworkConfiguration(); + QNetworkConfiguration(const QNetworkConfiguration& other); + QNetworkConfiguration &operator=(const QNetworkConfiguration& other); + ~QNetworkConfiguration(); + + bool operator==(const QNetworkConfiguration& cp) const; + inline bool operator!=(const QNetworkConfiguration& cp) const + { return !operator==(cp); } + + enum Type { + InternetAccessPoint = 0, + ServiceNetwork, + UserChoice, + Invalid + }; + + enum Purpose { + UnknownPurpose = 0, + PublicPurpose, + PrivatePurpose, + ServiceSpecificPurpose + }; + + enum StateFlag { + Undefined = 0x0000001, + Defined = 0x0000002, + Discovered = 0x0000006, + Active = 0x000000e + }; + + Q_DECLARE_FLAGS(StateFlags, StateFlag) + + StateFlags state() const; + Type type() const; + Purpose purpose() const; + QString bearerName() const; + QString identifier() const; + bool isRoamingAvailable() const; + QList<QNetworkConfiguration> children() const; + + QString name() const; + bool isValid() const; + +private: + friend class QNetworkConfigurationPrivate; + friend class QNetworkConfigurationManager; + friend class QNetworkConfigurationManagerPrivate; + friend class QNetworkSessionPrivate; + QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QNETWORKCONFIGURATION_H diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h new file mode 100644 index 0000000..6b40946 --- /dev/null +++ b/src/network/bearer/qnetworkconfiguration_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKCONFIGURATIONPRIVATE_H +#define QNETWORKCONFIGURATIONPRIVATE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qnetworkconfiguration.h" +#include <QtCore/qshareddata.h> +#include <QtNetwork/QNetworkInterface> + +QT_BEGIN_NAMESPACE + +typedef QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationPrivatePointer; +class QNetworkConfigurationPrivate : public QSharedData +{ +public: + QNetworkConfigurationPrivate () + : isValid(false), type(QNetworkConfiguration::Invalid), + roamingSupported(false), purpose(QNetworkConfiguration::UnknownPurpose), internet(false) + { + } + + ~QNetworkConfigurationPrivate() + { + //release pointers to member configurations + serviceNetworkMembers.clear(); + } + + virtual QString bearerName() const + { + return bearer; + } + + QString bearer; + + QString name; + + bool isValid; + QString id; + QNetworkConfiguration::StateFlags state; + QNetworkConfiguration::Type type; + bool roamingSupported; + QNetworkConfiguration::Purpose purpose; + + bool internet; + + QList<QNetworkConfigurationPrivatePointer> serviceNetworkMembers; + +private: + + // disallow detaching + QNetworkConfigurationPrivate &operator=(const QNetworkConfigurationPrivate &other); + QNetworkConfigurationPrivate(const QNetworkConfigurationPrivate &other); +}; + +QT_END_NAMESPACE + +#endif //QNETWORKCONFIGURATIONPRIVATE_H diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp new file mode 100644 index 0000000..3e77354 --- /dev/null +++ b/src/network/bearer/qnetworksession.cpp @@ -0,0 +1,684 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QEventLoop> +#include <QTimer> + +#include "qnetworksession.h" +#include "qbearerengine_p.h" +#include "qnetworkconfigmanager_p.h" +#include "qnetworksession_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QNetworkSession + + \brief The QNetworkSession class provides control over the system's access points + and enables session management for cases when multiple clients access the same access point. + + \since 4.7 + + \inmodule QtNetwork + \ingroup bearer + + A QNetworkSession enables control over the system's network interfaces. The session's configuration + parameter are determined via the QNetworkConfiguration object to which it is bound. Depending on the + type of the session (single access point or service network) a session may be linked to one or more + network interfaces. By means of \l{open()}{opening} and \l{close()}{closing} of network sessions + a developer can start and stop the systems network interfaces. If the configuration represents + multiple access points (see \l QNetworkConfiguration::ServiceNetwork) more advanced features such as roaming may be supported. + + QNetworkSession supports session management within the same process and depending on the platform's + capabilities may support out-of-process sessions. If the same + network configuration is used by multiple open sessions the underlying network interface is only terminated once + the last session has been closed. + + \section1 Roaming + + Applications may connect to the preferredConfigurationChanged() signal in order to + receive notifications when a more suitable access point becomes available. + In response to this signal the application must either initiate the roaming via migrate() + or ignore() the new access point. Once the session has roamed the + newConfigurationActivated() signal is emitted. The application may now test the + carrier and must either accept() or reject() it. The session will return to the previous + access point if the roaming was rejected. The subsequent state diagram depicts the required + state transitions. + + \image roaming-states.png + + Some platforms may distinguish forced roaming and application level roaming (ALR). + ALR implies that the application controls (via migrate(), ignore(), accept() and reject()) + whether a network session can roam from one access point to the next. Such control is useful + if the application maintains stateful socket connections and wants to control the transition from + one interface to the next. Forced roaming implies that the system automatically roams to the next network without + consulting the application. This has the advantage that the application can make use of roaming features + without actually being aware of it. It is expected that the application detects that the underlying + socket is broken and automatically reconnects via the new network link. + + If the platform supports both modes of roaming, an application indicates its preference + by connecting to the preferredConfigurationChanged() signal. Connecting to this signal means that + the application wants to take control over the roaming behavior and therefore implies application + level roaming. If the client does not connect to the preferredConfigurationChanged(), forced roaming + is used. If forced roaming is not supported the network session will not roam by default. + + Some applications may want to suppress any form of roaming altogether. Possible use cases may be + high priority downloads or remote services which cannot handle a roaming enabled client. Clients + can suppress roaming by connecting to the preferredConfigurationChanged() signal and answer each + signal emission with ignore(). + + \sa QNetworkConfiguration, QNetworkConfigurationManager +*/ + +/*! + \enum QNetworkSession::State + + This enum describes the connectivity state of the session. If the session is based on a + single access point configuration the state of the session is the same as the state of the + associated network interface. + + \value Invalid The session is invalid due to an invalid configuration. This may + happen due to a removed access point or a configuration that was + invalid to begin with. + \value NotAvailable The session is based on a defined but not yet discovered QNetworkConfiguration + (see \l QNetworkConfiguration::StateFlag). + \value Connecting The network session is being established. + \value Connected The network session is connected. If the current process wishes to use this session + it has to register its interest by calling open(). A network session + is considered to be ready for socket operations if it isOpen() and connected. + \value Closing The network session is in the process of being shut down. + \value Disconnected The network session is not connected. The associated QNetworkConfiguration + has the state QNetworkConfiguration::Discovered. + \value Roaming The network session is roaming from one access point to another + access point. +*/ + +/*! + \enum QNetworkSession::SessionError + + This enum describes the session errors that can occur. + + \value UnknownSessionError An unidentified error occurred. + \value SessionAbortedError The session was aborted by the user or system. + \value RoamingError The session cannot roam to a new configuration. + \value OperationNotSupportedError The operation is not supported for current configuration. + \value InvalidConfigurationError The operation cannot currently be performed for the + current configuration. +*/ + +/*! + \fn void QNetworkSession::stateChanged(QNetworkSession::State state) + + This signal is emitted whenever the state of the network session changes. + The \a state parameter is the new state. + + \sa state() +*/ + +/*! + \fn void QNetworkSession::error(QNetworkSession::SessionError error) + + This signal is emitted after an error occurred. The \a error parameter + describes the error that occurred. + + \sa error(), errorString() +*/ + +/*! + \fn void QNetworkSession::preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless) + + This signal is emitted when the preferred configuration/access point for the + session changes. Only sessions which are based on service network configurations + may emit this signal. \a config can be used to determine access point specific + details such as proxy settings and \a isSeamless indicates whether roaming will + break the sessions IP address. + + As a consequence to this signal the application must either start the roaming process + by calling migrate() or choose to ignore() the new access point. + + If the roaming process is non-seamless the IP address will change which means that + a socket becomes invalid. However seamless mobility can ensure that the local IP address + does not change. This is achieved by using a virtual IP address which is bound to the actual + link address. During the roaming process the virtual address is attached to the new link + address. + + Some platforms may support the concept of Forced Roaming and Application Level Roaming (ALR). + Forced roaming implies that the platform may simply roam to a new configuration without + consulting applications. It is up to the application to detect the link layer loss and reestablish + its sockets. In contrast ALR provides the opportunity to prevent the system from roaming. + If this session is based on a configuration that supports roaming the application can choose + whether it wants to be consulted (ALR use case) by connecting to this signal. For as long as this signal + connection remains the session remains registered as a roaming stakeholder; otherwise roaming will + be enforced by the platform. + + \sa migrate(), ignore(), QNetworkConfiguration::isRoamingAvailable() +*/ + +/*! + \fn void QNetworkSession::newConfigurationActivated() + + This signal is emitted once the session has roamed to the new access point. + The application may reopen its socket and test the suitability of the new network link. + Subsequently it must either accept() or reject() the new access point. + + \sa accept(), reject() +*/ + +/*! + \fn void QNetworkSession::opened() + + This signal is emitted when the network session has been opened. + + The underlying network interface will not be shut down as long as the session remains open. + Note that this feature is dependent on \l{QNetworkConfigurationManager::SystemSessionSupport}{system wide session support}. +*/ + +/*! + \fn void QNetworkSession::closed() + + This signal is emitted when the network session has been closed. +*/ + +/*! + Constructs a session based on \a connectionConfig with the given \a parent. + + \sa QNetworkConfiguration +*/ +QNetworkSession::QNetworkSession(const QNetworkConfiguration& connectionConfig, QObject* parent) +: QObject(parent), d(0) +{ + foreach (QBearerEngine *engine, qNetworkConfigurationManagerPrivate()->sessionEngines) { + if (engine->hasIdentifier(connectionConfig.identifier())) { + d = engine->createSessionBackend(); + d->q = this; + d->publicConfig = connectionConfig; + d->syncStateWithInterface(); + connect(d, SIGNAL(quitPendingWaitsForOpened()), this, SIGNAL(opened())); + connect(d, SIGNAL(error(QNetworkSession::SessionError)), + this, SIGNAL(error(QNetworkSession::SessionError))); + connect(d, SIGNAL(stateChanged(QNetworkSession::State)), + this, SIGNAL(stateChanged(QNetworkSession::State))); + connect(d, SIGNAL(closed()), this, SIGNAL(closed())); + connect(d, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)), + this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))); + connect(d, SIGNAL(newConfigurationActivated()), + this, SIGNAL(newConfigurationActivated())); + break; + } + } +} + +/*! + Frees the resources associated with the QNetworkSession object. +*/ +QNetworkSession::~QNetworkSession() +{ + delete d; +} + +/*! + Creates an open session which increases the session counter on the underlying network interface. + The system will not terminate a network interface until the session reference counter reaches zero. + Therefore an open session allows an application to register its use of the interface. + + As a result of calling open() the interface will be started if it is not connected/up yet. + Some platforms may not provide support for out-of-process sessions. On such platforms the session + counter ignores any sessions held by another process. The platform capabilities can be + detected via QNetworkConfigurationManager::capabilities(). + + Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired + by connecting to the stateChanged(), opened() or error() signals. + + It is not a requirement to open a session in order to monitor the underlying network interface. + + \sa close(), stop(), isOpen() +*/ +void QNetworkSession::open() +{ + if (d) + d->open(); +} + +/*! + Waits until the session has been opened, up to \a msecs milliseconds. If the session has been opened, this + function returns true; otherwise it returns false. In the case where it returns false, you can call error() + to determine the cause of the error. + + The following example waits up to one second for the session to be opened: + + \code + session->open(); + if (session->waitForOpened(1000)) + qDebug("Open!"); + \endcode + + If \a msecs is -1, this function will not time out. + + \sa open(), error() +*/ +bool QNetworkSession::waitForOpened(int msecs) +{ + if (!d) + return false; + + if (d->isOpen) + return true; + + if (d->state != Connecting) + return false; + + QEventLoop* loop = new QEventLoop(this); + QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()), + loop, SLOT(quit())); + + //final call + if (msecs>=0) + QTimer::singleShot(msecs, loop, SLOT(quit())); + + loop->exec(); + loop->disconnect(); + loop->deleteLater(); + + return d->isOpen; +} + +/*! + Decreases the session counter on the associated network configuration. If the session counter reaches zero + the active network interface is shut down. This also means that state() will only change from \l Connected to + \l Disconnected if the current session was the last open session. + + If the platform does not support out-of-process sessions calling this function does not stop the + interface. In this case \l{stop()} has to be used to force a shut down. + The platform capabilities can be detected via QNetworkConfigurationManager::capabilities(). + + Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired + by connecting to the stateChanged(), opened() or error() signals. + + \sa open(), stop(), isOpen() +*/ +void QNetworkSession::close() +{ + if (d) + d->close(); +} + +/*! + Invalidates all open sessions against the network interface and therefore stops the + underlying network interface. This function always changes the session's state() flag to + \l Disconnected. + + On Symbian platform, a 'NetworkControl' capability is required for + full interface-level stop (without the capability, only the current session is stopped). + + \sa open(), close() +*/ +void QNetworkSession::stop() +{ + if (d) + d->stop(); +} + +/*! + Returns the QNetworkConfiguration that this network session object is based on. + + \sa QNetworkConfiguration +*/ +QNetworkConfiguration QNetworkSession::configuration() const +{ + return d ? d->publicConfig : QNetworkConfiguration(); +} + +/*! + Returns the network interface that is used by this session. + + This function only returns a valid QNetworkInterface when this session is \l Connected. + + The returned interface may change as a result of a roaming process. + + Note: this function does not work in Symbian emulator due to the way the + connectivity is emulated on Windows. + + \sa state() +*/ +QNetworkInterface QNetworkSession::interface() const +{ + return d ? d->currentInterface() : QNetworkInterface(); +} + +/*! + Returns true if this session is open. If the number of all open sessions is greater than + zero the underlying network interface will remain connected/up. + + The session can be controlled via open() and close(). +*/ +bool QNetworkSession::isOpen() const +{ + return d ? d->isOpen : false; +} + +/*! + Returns the state of the session. + + If the session is based on a single access point configuration the state of the + session is the same as the state of the associated network interface. Therefore + a network session object can be used to monitor network interfaces. + + A \l QNetworkConfiguration::ServiceNetwork based session summarizes the state of all its children + and therefore returns the \l Connected state if at least one of the service network's + \l {QNetworkConfiguration::children()}{children()} configurations is active. + + Note that it is not required to hold an open session in order to obtain the network interface state. + A connected but closed session may be used to monitor network interfaces whereas an open and connected + session object may prevent the network interface from being shut down. + + \sa error(), stateChanged() +*/ +QNetworkSession::State QNetworkSession::state() const +{ + return d ? d->state : QNetworkSession::Invalid; +} + +/*! + Returns the type of error that last occurred. + + \sa state(), errorString() +*/ +QNetworkSession::SessionError QNetworkSession::error() const +{ + return d ? d->error() : InvalidConfigurationError; +} + +/*! + Returns a human-readable description of the last device error that + occurred. + + \sa error() +*/ +QString QNetworkSession::errorString() const +{ + return d ? d->errorString() : tr("Invalid configuration."); +} + +/*! + Returns the value for property \a key. + + A network session can have properties attached which may describe the session in more details. + This function can be used to gain access to those properties. + + The following property keys are guaranteed to be specified on all platforms: + + \table + \header + \o Key \o Description + \row + \o ActiveConfiguration + \o If the session \l isOpen() this property returns the identifier of the + QNetworkConfiguration that is used by this session; otherwise an empty string. + + The main purpose of this key is to determine which Internet access point is used + if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}. + The following code snippet highlights the difference: + \code + QNetworkConfigurationManager mgr; + QNetworkConfiguration ap = mgr.defaultConfiguration(); + QNetworkSession* session = new QNetworkSession(ap); + ... //code activates session + + QString ident = session->sessionProperty("ActiveConfiguration").toString(); + if ( ap.type() == QNetworkConfiguration::ServiceNetwork ) { + Q_ASSERT( ap.identifier() != ident ); + Q_ASSERT( ap.children().contains( mgr.configurationFromIdentifier(ident) ) ); + } else if ( ap.type() == QNetworkConfiguration::InternetAccessPoint ) { + Q_ASSERT( ap.identifier() == ident ); + } + \endcode + \row + \o UserChoiceConfiguration + \o If the session \l isOpen() and is bound to a QNetworkConfiguration of type + UserChoice, this property returns the identifier of the QNetworkConfiguration that the + configuration resolved to when \l open() was called; otherwise an empty string. + + The purpose of this key is to determine the real QNetworkConfiguration that the + session is using. This key is different to \i ActiveConfiguration in that + this key may return an identifier for either a + \l {QNetworkConfiguration::ServiceNetwork}{service network} or a + \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations + whereas \i ActiveConfiguration always returns identifiers to + \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations. + \row + \o ConnectInBackground + \o Setting this property to \i true before calling \l open() implies that the connection attempt + is made but if no connection can be established, the user is not connsulted and asked to select + a suitable connection. This property is not set by default and support for it depends on the platform. + \endtable +*/ +QVariant QNetworkSession::sessionProperty(const QString& key) const +{ + if (!d) + return QVariant(); + + if (!d->publicConfig.isValid()) + return QVariant(); + + if (key == QLatin1String("ActiveConfiguration")) { + if (!d->isOpen) + return QString(); + else + return d->activeConfig.identifier(); + } + + if (key == QLatin1String("UserChoiceConfiguration")) { + if (!d->isOpen || d->publicConfig.type() != QNetworkConfiguration::UserChoice) + return QString(); + + if (d->serviceConfig.isValid()) + return d->serviceConfig.identifier(); + else + return d->activeConfig.identifier(); + } + + return d->sessionProperty(key); +} + +/*! + Sets the property \a value on the session. The property is identified using + \a key. Removing an already set property can be achieved by passing an + invalid QVariant. + + Note that the \i UserChoiceConfiguration and \i ActiveConfiguration + properties are read only and cannot be changed using this method. +*/ +void QNetworkSession::setSessionProperty(const QString& key, const QVariant& value) +{ + if (!d) + return; + + if (key == QLatin1String("ActiveConfiguration") || + key == QLatin1String("UserChoiceConfiguration")) { + return; + } + + d->setSessionProperty(key, value); +} + +/*! + Instructs the session to roam to the new access point. The old access point remains active + until the application calls accept(). + + The newConfigurationActivated() signal is emitted once roaming has been completed. + + \sa accept() +*/ +void QNetworkSession::migrate() +{ + if (d) + d->migrate(); +} + +/*! + This function indicates that the application does not wish to roam the session. + + \sa migrate() +*/ +void QNetworkSession::ignore() +{ + // Needed on at least Symbian platform: the roaming must be explicitly + // ignore()'d or migrate()'d + if (d) + d->ignore(); +} + +/*! + Instructs the session to permanently accept the new access point. Once this function + has been called the session may not return to the old access point. + + The old access point may be closed in the process if there are no other network sessions for it. + Therefore any open socket that still uses the old access point + may become unusable and should be closed before completing the migration. +*/ +void QNetworkSession::accept() +{ + if (d) + d->accept(); +} + +/*! + The new access point is not suitable for the application. By calling this function the + session returns to the previous access point/configuration. This action may invalidate + any socket that has been created via the not desired access point. + + \sa accept() +*/ +void QNetworkSession::reject() +{ + if (d) + d->reject(); +} + + +/*! + Returns the amount of data sent in bytes; otherwise 0. + + This field value includes the usage across all open network + sessions which use the same network interface. + + If the session is based on a service network configuration the number of + sent bytes across all active member configurations are returned. + + This function may not always be supported on all platforms and returns + 0. The platform capability can be detected via QNetworkConfigurationManager::DataStatistics. +*/ +quint64 QNetworkSession::bytesWritten() const +{ + return d ? d->bytesWritten() : Q_UINT64_C(0); +} + +/*! + Returns the amount of data received in bytes; otherwise 0. + + This field value includes the usage across all open network + sessions which use the same network interface. + + If the session is based on a service network configuration the number of + sent bytes across all active member configurations are returned. + + This function may not always be supported on all platforms and returns + 0. The platform capability can be detected via QNetworkConfigurationManager::DataStatistics. +*/ +quint64 QNetworkSession::bytesReceived() const +{ + return d ? d->bytesReceived() : Q_UINT64_C(0); +} + +/*! + Returns the number of seconds that the session has been active. +*/ +quint64 QNetworkSession::activeTime() const +{ + return d ? d->activeTime() : Q_UINT64_C(0); +} + +/*! + \internal + + This function is required to detect whether the client wants to control + the roaming process. If he connects to preferredConfigurationChanged() signal + he intends to influence it. Otherwise QNetworkSession always roams + without registering this session as a stakeholder in the roaming process. + + For more details check the Forced vs ALR roaming section in the QNetworkSession + class description. +*/ +void QNetworkSession::connectNotify(const char *signal) +{ + QObject::connectNotify(signal); + //check for preferredConfigurationChanged() signal connect notification + //This is not required on all platforms + if (!d) + return; + + if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0) + d->setALREnabled(true); +} + +/*! + \internal + + This function is called when the client disconnects from the preferredConfigurationChanged() + signal. + + \sa connectNotify() +*/ +void QNetworkSession::disconnectNotify(const char *signal) +{ + QObject::disconnectNotify(signal); + //check for preferredConfigurationChanged() signal disconnect notification + //This is not required on all platforms + if (!d) + return; + + if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0) + d->setALREnabled(false); +} + +#include "moc_qnetworksession.cpp" + +QT_END_NAMESPACE diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h new file mode 100644 index 0000000..3c8d913 --- /dev/null +++ b/src/network/bearer/qnetworksession.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKSESSION_H +#define QNETWORKSESSION_H + +#include <QtCore/qobject.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> +#include <QtNetwork/qnetworkinterface.h> +#include <QtCore/qvariant.h> +#include <QtNetwork/qnetworkconfiguration.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QNetworkSessionPrivate; +class Q_NETWORK_EXPORT QNetworkSession : public QObject +{ + Q_OBJECT +public: + enum State { + Invalid = 0, + NotAvailable, + Connecting, + Connected, + Closing, + Disconnected, + Roaming + }; + + enum SessionError { + UnknownSessionError = 0, + SessionAbortedError, + RoamingError, + OperationNotSupportedError, + InvalidConfigurationError + }; + + QNetworkSession(const QNetworkConfiguration& connConfig, QObject* parent =0); + virtual ~QNetworkSession(); + + bool isOpen() const; + QNetworkConfiguration configuration() const; + QNetworkInterface interface() const; + + State state() const; + SessionError error() const; + QString errorString() const; + QVariant sessionProperty(const QString& key) const; + void setSessionProperty(const QString& key, const QVariant& value); + + quint64 bytesWritten() const; + quint64 bytesReceived() const; + quint64 activeTime() const; + + bool waitForOpened(int msecs = 30000); + +public Q_SLOTS: + void open(); + void close(); + void stop(); + + //roaming related slots + void migrate(); + void ignore(); + void accept(); + void reject(); + + +Q_SIGNALS: + void stateChanged(QNetworkSession::State); + void opened(); + void closed(); + void error(QNetworkSession::SessionError); + void preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless); + void newConfigurationActivated(); + +protected: + virtual void connectNotify(const char *signal); + virtual void disconnectNotify(const char *signal); + +private: + QNetworkSessionPrivate* d; + friend class QNetworkSessionPrivate; + }; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QNETWORKSESSION_H diff --git a/src/network/bearer/qnetworksession_p.h b/src/network/bearer/qnetworksession_p.h new file mode 100644 index 0000000..76691b3 --- /dev/null +++ b/src/network/bearer/qnetworksession_p.h @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKSESSIONPRIVATE_H +#define QNETWORKSESSIONPRIVATE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qnetworksession.h" +#include "qnetworkconfiguration_p.h" + +#include <QNetworkInterface> + +QT_BEGIN_NAMESPACE + +class Q_NETWORK_EXPORT QNetworkSessionPrivate : public QObject +{ + Q_OBJECT + + friend class QNetworkSession; + +public: + QNetworkSessionPrivate() + : state(QNetworkSession::Invalid), isOpen(false) + { + } + + virtual ~QNetworkSessionPrivate() + { + } + + //called by QNetworkSession constructor and ensures + //that the state is immediately updated (w/o actually opening + //a session). Also this function should take care of + //notification hooks to discover future state changes. + virtual void syncStateWithInterface() = 0; + + virtual QNetworkInterface currentInterface() const = 0; + virtual QVariant sessionProperty(const QString& key) const = 0; + virtual void setSessionProperty(const QString& key, const QVariant& value) = 0; + + virtual void open() = 0; + virtual void close() = 0; + virtual void stop() = 0; + + virtual void setALREnabled(bool /*enabled*/) { } + virtual void migrate() = 0; + virtual void accept() = 0; + virtual void ignore() = 0; + virtual void reject() = 0; + + virtual QString errorString() const = 0; //must return translated string + virtual QNetworkSession::SessionError error() const = 0; + + virtual quint64 bytesWritten() const = 0; + virtual quint64 bytesReceived() const = 0; + virtual quint64 activeTime() const = 0; + +protected: + inline QNetworkConfigurationPrivatePointer privateConfiguration(const QNetworkConfiguration &config) const + { + return config.d; + } + + inline void setPrivateConfiguration(QNetworkConfiguration &config, + QNetworkConfigurationPrivatePointer ptr) const + { + config.d = ptr; + } + +Q_SIGNALS: + //releases any pending waitForOpened() calls + void quitPendingWaitsForOpened(); + + void error(QNetworkSession::SessionError error); + void stateChanged(QNetworkSession::State state); + void closed(); + void newConfigurationActivated(); + void preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless); + +protected: + // The config set on QNetworkSession. + QNetworkConfiguration publicConfig; + + // If publicConfig is a ServiceNetwork this is a copy of publicConfig. + // If publicConfig is an UserChoice that is resolved to a ServiceNetwork this is the actual + // ServiceNetwork configuration. + QNetworkConfiguration serviceConfig; + + // This is the actual active configuration currently in use by the session. + // Either a copy of publicConfig or one of serviceConfig.children(). + QNetworkConfiguration activeConfig; + + QNetworkSession::State state; + bool isOpen; + + QNetworkSession *q; +}; + +QT_END_NAMESPACE + +#endif //QNETWORKSESSIONPRIVATE_H + diff --git a/src/network/network.pro b/src/network/network.pro index e890b94..8582d8a 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -17,6 +17,7 @@ unix:QMAKE_PKGCONFIG_REQUIRES = QtCore include(../qbase.pri) include(access/access.pri) +include(bearer/bearer.pri) include(kernel/kernel.pri) include(socket/socket.pri) include(ssl/ssl.pri) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 3e5c4fc..cfcbbf8 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -99,6 +99,10 @@ QT_BEGIN_NAMESPACE QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs; #endif +#ifdef Q_WS_X11 +extern const QX11Info *qt_x11Info(const QPaintDevice *pd); +#endif + struct QGLThreadContext { QGLContext *context; }; @@ -2448,7 +2452,10 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, #if defined(Q_WS_X11) // Try to use texture_from_pixmap - if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType) { + const QX11Info *xinfo = qt_x11Info(paintDevice); + if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType + && xinfo && xinfo->screen() == pixmap.x11Info().screen()) + { texture = bindTextureFromNativePixmap(pd, key, options); if (texture) { texture->options |= QGLContext::MemoryManagedBindOption; diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index c01575b..4d7532e 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -951,8 +951,6 @@ void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget) break; current = current->parentWidget(); } - - isGLWidget = 1; } bool QGLWidgetPrivate::renderCxPm(QPixmap*) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 18fc9c2..efd2090 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -173,7 +173,9 @@ public: #if defined(Q_WS_X11) && defined(QT_OPENGL_ES) , eglSurfaceWindowId(0) #endif - {} + { + isGLWidget = 1; + } ~QGLWidgetPrivate() {} diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp index 5b34cbb..32a42a2 100644 --- a/src/opengl/qglpixelbuffer_x11.cpp +++ b/src/opengl/qglpixelbuffer_x11.cpp @@ -181,7 +181,11 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge qt_format_to_attrib_list(f, attribs); - GLXFBConfig *configs = glXChooseFBConfig(X11->display, X11->defaultScreen, attribs, &num_configs); + int screen = X11->defaultScreen; + if (shareWidget) + screen = shareWidget->x11Info().screen(); + + GLXFBConfig *configs = glXChooseFBConfig(X11->display, screen, attribs, &num_configs); if (configs && num_configs) { int res; glXGetFBConfigAttrib(X11->display, configs[0], GLX_LEVEL, &res); diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 37bb7c0..d5a11d9 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -394,6 +394,7 @@ void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTe static bool hookAdded = false; if (!hookAdded) { QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(pixmapDestroyed); + QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(pixmapDestroyed); hookAdded = true; } diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro new file mode 100644 index 0000000..95c9851 --- /dev/null +++ b/src/plugins/bearer/bearer.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs + +!maemo:contains(QT_CONFIG, dbus):contains(QT_CONFIG, networkmanager):SUBDIRS += networkmanager +win32:SUBDIRS += nla +win32:!wince*:SUBDIRS += nativewifi +macx:SUBDIRS += corewlan +symbian:SUBDIRS += symbian +maemo6:contains(QT_CONFIG, dbus):SUBDIRS += icd + +isEmpty(SUBDIRS):SUBDIRS += generic diff --git a/src/plugins/bearer/corewlan/corewlan.pro b/src/plugins/bearer/corewlan/corewlan.pro new file mode 100644 index 0000000..50c72b2 --- /dev/null +++ b/src/plugins/bearer/corewlan/corewlan.pro @@ -0,0 +1,24 @@ +TARGET = qcorewlanbearer +include(../../qpluginbase.pri) + +QT += network +LIBS += -framework Foundation -framework SystemConfiguration + +contains(QT_CONFIG, corewlan) { + isEmpty(QMAKE_MAC_SDK)|contains(QMAKE_MAC_SDK, "/Developer/SDKs/MacOSX10.6.sdk") { + LIBS += -framework CoreWLAN + DEFINES += MAC_SDK_10_6 + } +} + +HEADERS += qcorewlanengine.h \ + ../qnetworksession_impl.h \ + ../qbearerengine_impl.h + +SOURCES += main.cpp \ + qcorewlanengine.mm \ + ../qnetworksession_impl.cpp + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer +target.path += $$[QT_INSTALL_PLUGINS]/bearer +INSTALLS += target diff --git a/src/plugins/bearer/corewlan/main.cpp b/src/plugins/bearer/corewlan/main.cpp new file mode 100644 index 0000000..5be8c0e --- /dev/null +++ b/src/plugins/bearer/corewlan/main.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcorewlanengine.h" + +#include <QtNetwork/private/qbearerplugin_p.h> + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QCoreWlanEnginePlugin : public QBearerEnginePlugin +{ +public: + QCoreWlanEnginePlugin(); + ~QCoreWlanEnginePlugin(); + + QStringList keys() const; + QBearerEngine *create(const QString &key) const; +}; + +QCoreWlanEnginePlugin::QCoreWlanEnginePlugin() +{ +} + +QCoreWlanEnginePlugin::~QCoreWlanEnginePlugin() +{ +} + +QStringList QCoreWlanEnginePlugin::keys() const +{ + return QStringList() << QLatin1String("corewlan"); +} + +QBearerEngine *QCoreWlanEnginePlugin::create(const QString &key) const +{ + if (key == QLatin1String("corewlan")) + return new QCoreWlanEngine; + else + return 0; +} + +Q_EXPORT_STATIC_PLUGIN(QCoreWlanEnginePlugin) +Q_EXPORT_PLUGIN2(qcorewlanbearer, QCoreWlanEnginePlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h new file mode 100644 index 0000000..54f2027 --- /dev/null +++ b/src/plugins/bearer/corewlan/qcorewlanengine.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOREWLANENGINE_H +#define QCOREWLANENGINE_H + +#include "../qbearerengine_impl.h" + +#include <QMap> +#include <QTimer> + +QT_BEGIN_NAMESPACE + +class QNetworkConfigurationPrivate; + +class QCoreWlanEngine : public QBearerEngineImpl +{ + Q_OBJECT + +public: + QCoreWlanEngine(QObject *parent = 0); + ~QCoreWlanEngine(); + + QString getInterfaceFromId(const QString &id); + bool hasIdentifier(const QString &id); + + QString bearerName(const QString &id); + + void connectToId(const QString &id); + void disconnectFromId(const QString &id); + + void requestUpdate(); + + QNetworkSession::State sessionStateForId(const QString &id); + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkSessionPrivate *createSessionBackend(); + + QNetworkConfigurationPrivatePointer defaultConfiguration(); + + static bool getAllScInterfaces(); + +private Q_SLOTS: + void doRequestUpdate(); + +private: + bool isWifiReady(const QString &dev); + QMap<QString, QString> configurationInterface; + QTimer pollTimer; + QStringList scanForSsids(const QString &interfaceName); + + bool isKnownSsid(const QString &interfaceName, const QString &ssid); + QList<QNetworkConfigurationPrivate *> foundConfigurations; + +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm new file mode 100644 index 0000000..fff65e4 --- /dev/null +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -0,0 +1,531 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcorewlanengine.h" +#include "../qnetworksession_impl.h" + +#include <QtNetwork/private/qnetworkconfiguration_p.h> + +#include <QtCore/qthread.h> +#include <QtCore/qmutex.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qstringlist.h> + +#include <QtCore/qdebug.h> + +#if defined(MAC_SDK_10_6) //not much functionality without this +#include <CoreWLAN/CoreWLAN.h> +#include <CoreWLAN/CWInterface.h> +#include <CoreWLAN/CWNetwork.h> +#include <CoreWLAN/CWNetwork.h> +#endif + +#include <Foundation/NSEnumerator.h> +#include <Foundation/NSKeyValueObserving.h> +#include <Foundation/NSAutoreleasePool.h> + +#include <SystemConfiguration/SCNetworkConfiguration.h> +QMap <QString, QString> networkInterfaces; + +QT_BEGIN_NAMESPACE + +inline QString cfstringRefToQstring(CFStringRef cfStringRef) { +// return QString([cfStringRef UTF8String]); + QString retVal; + CFIndex maxLength = 2 * CFStringGetLength(cfStringRef) + 1/*zero term*/; // max UTF8 + char *cstring = new char[maxLength]; + if (CFStringGetCString(CFStringRef(cfStringRef), cstring, maxLength, kCFStringEncodingUTF8)) { + retVal = QString::fromUtf8(cstring); + } + delete[] cstring; + return retVal; +} + +inline CFStringRef qstringToCFStringRef(const QString &string) +{ + return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(string.unicode()), + string.length()); +} + +inline NSString *qstringToNSString(const QString &qstr) +{ return [reinterpret_cast<const NSString *>(qstringToCFStringRef(qstr)) autorelease]; } + +inline QString nsstringToQString(const NSString *nsstr) +{ return cfstringRefToQstring(reinterpret_cast<const CFStringRef>(nsstr)); } + +inline QStringList nsarrayToQStringList(void *nsarray) +{ + QStringList result; + NSArray *array = static_cast<NSArray *>(nsarray); + for (NSUInteger i=0; i<[array count]; ++i) + result << nsstringToQString([array objectAtIndex:i]); + return result; +} + +static QString qGetInterfaceType(const QString &interfaceString) +{ + return networkInterfaces.value(interfaceString, QLatin1String("Unknown")); +} + +QCoreWlanEngine::QCoreWlanEngine(QObject *parent) +: QBearerEngineImpl(parent) +{ + connect(&pollTimer, SIGNAL(timeout()), this, SLOT(doRequestUpdate())); + pollTimer.setInterval(10000); + doRequestUpdate(); +} + +QCoreWlanEngine::~QCoreWlanEngine() +{ + while (!foundConfigurations.isEmpty()) + delete foundConfigurations.takeFirst(); +} + +QString QCoreWlanEngine::getInterfaceFromId(const QString &id) +{ + return configurationInterface.value(id); +} + +bool QCoreWlanEngine::hasIdentifier(const QString &id) +{ + return configurationInterface.contains(id); +} + +void QCoreWlanEngine::connectToId(const QString &id) +{ + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QString interfaceString = getInterfaceFromId(id); + + if(networkInterfaces.value(interfaceString) == "WLAN") { +#if defined(MAC_SDK_10_6) + CWInterface *wifiInterface = [CWInterface interfaceWithName: qstringToNSString(interfaceString)]; + CWConfiguration *userConfig = [ wifiInterface configuration]; + + NSSet *remNets = [userConfig rememberedNetworks]; //CWWirelessProfile + + NSEnumerator *enumerator = [remNets objectEnumerator]; + CWWirelessProfile *wProfile; + NSUInteger index=0; + CWNetwork *apNetwork; + NSDictionary *parametersDict; + NSArray* apArray; + + CW8021XProfile *user8021XProfile; + NSError *err; + NSMutableDictionary *params; + + while ((wProfile = [enumerator nextObject])) { //CWWirelessProfile + + if(id == nsstringToQString([wProfile ssid])) { + user8021XProfile = nil; + user8021XProfile = [ wProfile user8021XProfile]; + + err = nil; + params = [NSMutableDictionary dictionaryWithCapacity:0]; + + if(user8021XProfile) { + [params setValue: user8021XProfile forKey:kCWAssocKey8021XProfile]; + } else { + [params setValue: [wProfile passphrase] forKey: kCWAssocKeyPassphrase]; + } + + parametersDict = nil; + apArray = [NSMutableArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:parametersDict error:&err]]; + + if(!err) { + + for(uint row=0; row < [apArray count]; row++ ) { + apNetwork = [apArray objectAtIndex:row]; + if([[apNetwork ssid] compare:[wProfile ssid]] == NSOrderedSame) { + + bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err]; + + if(!result) { + qWarning() <<"ERROR"<< nsstringToQString([err localizedDescription ]); + emit connectionError(id, ConnectError); + } else { + [apNetwork release]; + [autoreleasepool release]; + return; + } + } + } + } + } + index++; + } + [apNetwork release]; + + emit connectionError(id, InterfaceLookupError); +#endif + } else { + // not wifi + } + emit connectionError(id, OperationNotSupported); + [autoreleasepool release]; +} + +void QCoreWlanEngine::disconnectFromId(const QString &id) +{ + QString interfaceString = getInterfaceFromId(id); + if(networkInterfaces.value(getInterfaceFromId(id)) == "WLAN") { //wifi only for now +#if defined(MAC_SDK_10_6) + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + CWInterface *wifiInterface = [CWInterface interfaceWithName: qstringToNSString(interfaceString)]; + [wifiInterface disassociate]; + if([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) { + emit connectionError(id, DisconnectionError); + } + [autoreleasepool release]; + return; +#endif + } else { + + } + emit connectionError(id, OperationNotSupported); +} + +void QCoreWlanEngine::requestUpdate() +{ + pollTimer.stop(); + QTimer::singleShot(0, this, SLOT(doRequestUpdate())); +} + +void QCoreWlanEngine::doRequestUpdate() +{ + getAllScInterfaces(); + + QStringList previous = accessPointConfigurations.keys(); + + QMapIterator<QString, QString> i(networkInterfaces); + while (i.hasNext()) { + i.next(); + if (i.value() == QLatin1String("WLAN")) { + QStringList added = scanForSsids(i.key()); + while (!added.isEmpty()) { + previous.removeAll(added.takeFirst()); + } + } + + QNetworkInterface interface = QNetworkInterface::interfaceFromName(i.key()); + + if (!interface.isValid()) + continue; + + uint identifier; + if (interface.index()) + identifier = qHash(QLatin1String("corewlan:") + QString::number(interface.index())); + else + identifier = qHash(QLatin1String("corewlan:") + interface.hardwareAddress()); + + const QString id = QString::number(identifier); + + previous.removeAll(id); + + QString name = interface.humanReadableName(); + if (name.isEmpty()) + name = interface.name(); + + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; + + if (interface.flags() && QNetworkInterface::IsRunning) + state = QNetworkConfiguration::Defined; + + if (!interface.addressEntries().isEmpty()) + state = QNetworkConfiguration::Active; + + if (accessPointConfigurations.contains(id)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + + bool changed = false; + + if (!ptr->isValid) { + ptr->isValid = true; + changed = true; + } + + if (ptr->name != name) { + ptr->name = name; + changed = true; + } + + if (ptr->id != id) { + ptr->id = id; + changed = true; + } + + if (ptr->state != state) { + ptr->state = state; + changed = true; + } + + if (changed) + emit configurationChanged(ptr); + } else { + QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); + + ptr->name = name; + ptr->isValid = true; + ptr->id = id; + ptr->state = state; + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->bearer = qGetInterfaceType(interface.name()); + + accessPointConfigurations.insert(id, ptr); + configurationInterface.insert(id, interface.name()); + + emit configurationAdded(ptr); + } + } + + while (!previous.isEmpty()) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(previous.takeFirst()); + + configurationInterface.remove(ptr->id); + emit configurationRemoved(ptr); + } + + pollTimer.start(); + + emit updateCompleted(); +} + +QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) +{ + QStringList found; + +#if defined(MAC_SDK_10_6) + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + + CWInterface *currentInterface = [CWInterface interfaceWithName:qstringToNSString(interfaceName)]; + NSError *err = nil; + NSDictionary *parametersDict = nil; + NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err]; + + CWNetwork *apNetwork; + if (!err) { + for(uint row=0; row < [apArray count]; row++ ) { + NSAutoreleasePool *looppool = [[NSAutoreleasePool alloc] init]; + + apNetwork = [apArray objectAtIndex:row]; + + const QString networkSsid = nsstringToQString([apNetwork ssid]); + + const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); + found.append(id); + + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; + + if ([currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) { + if (networkSsid == nsstringToQString([currentInterface ssid])) + state = QNetworkConfiguration::Active; + } else { + if (isKnownSsid(interfaceName, networkSsid)) + state = QNetworkConfiguration::Discovered; + else + state = QNetworkConfiguration::Defined; + } + + if (accessPointConfigurations.contains(id)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + + bool changed = false; + + if (!ptr->isValid) { + ptr->isValid = true; + changed = true; + } + + if (ptr->name != networkSsid) { + ptr->name = networkSsid; + changed = true; + } + + if (ptr->id != id) { + ptr->id = id; + changed = true; + } + + if (ptr->state != state) { + ptr->state = state; + changed = true; + } + + if (changed) + emit configurationChanged(ptr); + } else { + QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); + + ptr->name = networkSsid; + ptr->isValid = true; + ptr->id = id; + ptr->state = state; + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->bearer = QLatin1String("WLAN"); + + accessPointConfigurations.insert(id, ptr); + configurationInterface.insert(id, interfaceName); + + emit configurationAdded(ptr); + } + [looppool release]; + } + } else { + qWarning() << "ERROR scanning for ssids" << nsstringToQString([err localizedDescription]) + <<nsstringToQString([err domain]); + } + + [autoreleasepool drain]; +#else + Q_UNUSED(interfaceName); +#endif + return found; +} + +bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName) +{ +#if defined(MAC_SDK_10_6) + CWInterface *defaultInterface = [CWInterface interfaceWithName: qstringToNSString(wifiDeviceName)]; + if([defaultInterface power]) + return true; +#else + Q_UNUSED(wifiDeviceName); +#endif + return false; +} + +bool QCoreWlanEngine::isKnownSsid(const QString &interfaceName, const QString &ssid) +{ +#if defined(MAC_SDK_10_6) + CWInterface *wifiInterface = [CWInterface interfaceWithName: qstringToNSString(interfaceName)]; + CWConfiguration *userConfig = [wifiInterface configuration]; + NSSet *remNets = [userConfig rememberedNetworks]; + for (CWWirelessProfile *wProfile in remNets) { + if(ssid == nsstringToQString([wProfile ssid])) + return true; + } +#else + Q_UNUSED(interfaceName); + Q_UNUSED(ssid); +#endif + return false; +} + +bool QCoreWlanEngine::getAllScInterfaces() +{ + networkInterfaces.clear(); + NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + + CFArrayRef interfaces = SCNetworkInterfaceCopyAll(); + if (interfaces != NULL) { + CFIndex interfaceCount; + CFIndex interfaceIndex; + interfaceCount = CFArrayGetCount(interfaces); + for (interfaceIndex = 0; interfaceIndex < interfaceCount; interfaceIndex++) { + NSAutoreleasePool *looppool = [[NSAutoreleasePool alloc] init]; + + CFStringRef bsdName; + CFTypeRef thisInterface = CFArrayGetValueAtIndex(interfaces, interfaceIndex); + bsdName = SCNetworkInterfaceGetBSDName((SCNetworkInterfaceRef)thisInterface); + QString interfaceName = cfstringRefToQstring(bsdName); + QString typeStr; + CFStringRef type = SCNetworkInterfaceGetInterfaceType((SCNetworkInterfaceRef)thisInterface); + if ( CFEqual(type, kSCNetworkInterfaceTypeIEEE80211)) { + typeStr = "WLAN"; +// } else if (CFEqual(type, kSCNetworkInterfaceTypeBluetooth)) { +// typeStr = "Bluetooth"; + } else if(CFEqual(type, kSCNetworkInterfaceTypeEthernet)) { + typeStr = "Ethernet"; + } else if(CFEqual(type, kSCNetworkInterfaceTypeFireWire)) { + typeStr = "Ethernet"; //ok a bit fudged + } + if(!networkInterfaces.contains(interfaceName) && !typeStr.isEmpty()) { + networkInterfaces.insert(interfaceName,typeStr); + } + [looppool release]; + } + } + CFRelease(interfaces); + + [autoreleasepool drain]; + return true; +} + +QNetworkSession::State QCoreWlanEngine::sessionStateForId(const QString &id) +{ + 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; +} + +QNetworkSessionPrivate *QCoreWlanEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl; +} + +QNetworkConfigurationPrivatePointer QCoreWlanEngine::defaultConfiguration() +{ + return QNetworkConfigurationPrivatePointer(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/generic/generic.pro b/src/plugins/bearer/generic/generic.pro new file mode 100644 index 0000000..1d141fd --- /dev/null +++ b/src/plugins/bearer/generic/generic.pro @@ -0,0 +1,16 @@ +TARGET = qgenericbearer +include(../../qpluginbase.pri) + +QT += network + +HEADERS += qgenericengine.h \ + ../qnetworksession_impl.h \ + ../qbearerengine_impl.h \ + ../platformdefs_win.h +SOURCES += qgenericengine.cpp \ + ../qnetworksession_impl.cpp \ + main.cpp + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer +target.path += $$[QT_INSTALL_PLUGINS]/bearer +INSTALLS += target diff --git a/src/plugins/bearer/generic/main.cpp b/src/plugins/bearer/generic/main.cpp new file mode 100644 index 0000000..ba85d93 --- /dev/null +++ b/src/plugins/bearer/generic/main.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgenericengine.h" + +#include <QtNetwork/private/qbearerplugin_p.h> + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QGenericEnginePlugin : public QBearerEnginePlugin +{ +public: + QGenericEnginePlugin(); + ~QGenericEnginePlugin(); + + QStringList keys() const; + QBearerEngine *create(const QString &key) const; +}; + +QGenericEnginePlugin::QGenericEnginePlugin() +{ +} + +QGenericEnginePlugin::~QGenericEnginePlugin() +{ +} + +QStringList QGenericEnginePlugin::keys() const +{ + return QStringList() << QLatin1String("generic"); +} + +QBearerEngine *QGenericEnginePlugin::create(const QString &key) const +{ + if (key == QLatin1String("generic")) + return new QGenericEngine; + else + return 0; +} + +Q_EXPORT_STATIC_PLUGIN(QGenericEnginePlugin) +Q_EXPORT_PLUGIN2(qgenericbearer, QGenericEnginePlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp new file mode 100644 index 0000000..dba2c08 --- /dev/null +++ b/src/plugins/bearer/generic/qgenericengine.cpp @@ -0,0 +1,323 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgenericengine.h" +#include "../qnetworksession_impl.h" + +#include <QtNetwork/private/qnetworkconfiguration_p.h> + +#include <QtCore/qthread.h> +#include <QtCore/qmutex.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qstringlist.h> + +#include <QtCore/qdebug.h> + +#ifdef Q_OS_WIN +#include "../platformdefs_win.h" +#endif + +#ifdef Q_OS_LINUX +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <net/if.h> +#include <net/if_arp.h> +#endif + + +static QString qGetInterfaceType(const QString &interface) +{ +#ifdef Q_OS_WIN32 + unsigned long oid; + DWORD bytesWritten; + + NDIS_MEDIUM medium; + NDIS_PHYSICAL_MEDIUM physicalMedium; + + HANDLE handle = CreateFile((TCHAR *)QString("\\\\.\\%1").arg(interface).utf16(), 0, + FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if (handle == INVALID_HANDLE_VALUE) + return QLatin1String("Unknown"); + + oid = OID_GEN_MEDIA_SUPPORTED; + bytesWritten = 0; + bool result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid), + &medium, sizeof(medium), &bytesWritten, 0); + if (!result) { + CloseHandle(handle); + return QLatin1String("Unknown"); + } + + oid = OID_GEN_PHYSICAL_MEDIUM; + bytesWritten = 0; + result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid), + &physicalMedium, sizeof(physicalMedium), &bytesWritten, 0); + if (!result) { + CloseHandle(handle); + + if (medium == NdisMedium802_3) + return QLatin1String("Ethernet"); + else + return QLatin1String("Unknown"); + } + + CloseHandle(handle); + + if (medium == NdisMedium802_3) { + switch (physicalMedium) { + case NdisPhysicalMediumWirelessLan: + return QLatin1String("WLAN"); + case NdisPhysicalMediumBluetooth: + return QLatin1String("Bluetooth"); + case NdisPhysicalMediumWiMax: + return QLatin1String("WiMAX"); + default: +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Physical Medium" << physicalMedium; +#endif + return QLatin1String("Ethernet"); + } + } + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << medium << physicalMedium; +#endif +#elif defined(Q_OS_LINUX) + int sock = socket(AF_INET, SOCK_DGRAM, 0); + + ifreq request; + strncpy(request.ifr_name, interface.toLocal8Bit().data(), sizeof(request.ifr_name)); + if (ioctl(sock, SIOCGIFHWADDR, &request) >= 0) { + switch (request.ifr_hwaddr.sa_family) { + case ARPHRD_ETHER: + return QLatin1String("Ethernet"); + } + } + + close(sock); +#else + Q_UNUSED(interface); +#endif + + return QLatin1String("Unknown"); +} + +QGenericEngine::QGenericEngine(QObject *parent) +: QBearerEngineImpl(parent) +{ + connect(&pollTimer, SIGNAL(timeout()), this, SLOT(doRequestUpdate())); + pollTimer.setInterval(10000); + doRequestUpdate(); +} + +QGenericEngine::~QGenericEngine() +{ +} + +QString QGenericEngine::getInterfaceFromId(const QString &id) +{ + return configurationInterface.value(id); +} + +bool QGenericEngine::hasIdentifier(const QString &id) +{ + return configurationInterface.contains(id); +} + +void QGenericEngine::connectToId(const QString &id) +{ + emit connectionError(id, OperationNotSupported); +} + +void QGenericEngine::disconnectFromId(const QString &id) +{ + emit connectionError(id, OperationNotSupported); +} + +void QGenericEngine::requestUpdate() +{ + pollTimer.stop(); + QTimer::singleShot(0, this, SLOT(doRequestUpdate())); +} + +void QGenericEngine::doRequestUpdate() +{ + // Immediately after connecting with a wireless access point + // QNetworkInterface::allInterfaces() will sometimes return an empty list. Calling it again a + // second time results in a non-empty list. If we loose interfaces we will end up removing + // network configurations which will break current sessions. + QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces(); + if (interfaces.isEmpty()) + interfaces = QNetworkInterface::allInterfaces(); + + QStringList previous = accessPointConfigurations.keys(); + + // create configuration for each interface + while (!interfaces.isEmpty()) { + QNetworkInterface interface = interfaces.takeFirst(); + + if (!interface.isValid()) + continue; + + // ignore loopback interface + if (interface.flags() & QNetworkInterface::IsLoopBack) + continue; + + // ignore WLAN interface handled in seperate engine + if (qGetInterfaceType(interface.name()) == QLatin1String("WLAN")) + continue; + + uint identifier; + if (interface.index()) + identifier = qHash(QLatin1String("generic:") + QString::number(interface.index())); + else + identifier = qHash(QLatin1String("generic:") + interface.hardwareAddress()); + + const QString id = QString::number(identifier); + + previous.removeAll(id); + + QString name = interface.humanReadableName(); + if (name.isEmpty()) + name = interface.name(); + + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Discovered; + if (interface.flags() & QNetworkInterface::IsUp) + state |= QNetworkConfiguration::Active; + + if (accessPointConfigurations.contains(id)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + + bool changed = false; + + if (!ptr->isValid) { + ptr->isValid = true; + changed = true; + } + + if (ptr->name != name) { + ptr->name = name; + changed = true; + } + + if (ptr->id != id) { + ptr->id = id; + changed = true; + } + + if (ptr->state != state) { + ptr->state = state; + changed = true; + } + + if (changed) + emit configurationChanged(ptr); + } else { + QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); + + ptr->name = name; + ptr->isValid = true; + ptr->id = id; + ptr->state = state; + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->bearer = qGetInterfaceType(interface.name()); + + accessPointConfigurations.insert(id, ptr); + configurationInterface.insert(id, interface.name()); + + emit configurationAdded(ptr); + } + } + + while (!previous.isEmpty()) { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.take(previous.takeFirst()); + + configurationInterface.remove(ptr->id); + emit configurationRemoved(ptr); + } + + pollTimer.start(); + + emit updateCompleted(); +} + +QNetworkSession::State QGenericEngine::sessionStateForId(const QString &id) +{ + 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 QGenericEngine::capabilities() const +{ + return QNetworkConfigurationManager::ForcedRoaming; +} + +QNetworkSessionPrivate *QGenericEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl; +} + +QNetworkConfigurationPrivatePointer QGenericEngine::defaultConfiguration() +{ + return QNetworkConfigurationPrivatePointer(); +} + +QT_END_NAMESPACE + diff --git a/src/plugins/bearer/generic/qgenericengine.h b/src/plugins/bearer/generic/qgenericengine.h new file mode 100644 index 0000000..cd9a976 --- /dev/null +++ b/src/plugins/bearer/generic/qgenericengine.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGENERICENGINE_H +#define QGENERICENGINE_H + +#include "../qbearerengine_impl.h" + +#include <QMap> +#include <QTimer> + +QT_BEGIN_NAMESPACE + +class QNetworkConfigurationPrivate; +class QNetworkSessionPrivate; + +class QGenericEngine : public QBearerEngineImpl +{ + Q_OBJECT + +public: + QGenericEngine(QObject *parent = 0); + ~QGenericEngine(); + + QString getInterfaceFromId(const QString &id); + bool hasIdentifier(const QString &id); + + QString bearerName(const QString &id); + + void connectToId(const QString &id); + void disconnectFromId(const QString &id); + + void requestUpdate(); + + QNetworkSession::State sessionStateForId(const QString &id); + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkSessionPrivate *createSessionBackend(); + + QNetworkConfigurationPrivatePointer defaultConfiguration(); + +private Q_SLOTS: + void doRequestUpdate(); + +private: + QMap<QString, QString> configurationInterface; + QTimer pollTimer; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/plugins/bearer/icd/icd.pro b/src/plugins/bearer/icd/icd.pro new file mode 100644 index 0000000..5eaf5af --- /dev/null +++ b/src/plugins/bearer/icd/icd.pro @@ -0,0 +1,22 @@ +TARGET = qicdbearer +include(../../qpluginbase.pri) + +QT += network dbus + +CONFIG += link_pkgconfig +PKGCONFIG += glib-2.0 dbus-glib-1 gconf-2.0 osso-ic conninet + +HEADERS += qicdengine.h \ + monitor.h \ + qnetworksession_impl.h + +SOURCES += main.cpp \ + qicdengine.cpp \ + monitor.cpp \ + qnetworksession_impl.cpp + +#DEFINES += BEARER_MANAGEMENT_DEBUG + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer +target.path += $$[QT_INSTALL_PLUGINS]/bearer +INSTALLS += target diff --git a/tests/benchmarks/qtwidgets/mainwindow.h b/src/plugins/bearer/icd/main.cpp index 8a4521a..b131ccb 100644 --- a/tests/benchmarks/qtwidgets/mainwindow.h +++ b/src/plugins/bearer/icd/main.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -38,43 +38,47 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H -#include <QWidget> -#include <QWhatsThis> -#include "ui_standard.h" -#include "ui_advanced.h" -#include "ui_system.h" +#include "qicdengine.h" -class StyleWidget : public QWidget -{ - Q_OBJECT +#include <QtNetwork/private/qbearerengine_p.h> + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE +class QIcdEnginePlugin : public QBearerEnginePlugin +{ public: - StyleWidget(QWidget *parent = 0, Qt::WFlags f = 0); - ~StyleWidget(); + QIcdEnginePlugin(); + ~QIcdEnginePlugin(); -public slots: - void onWhatsThis() { QWhatsThis::enterWhatsThisMode(); } + QStringList keys() const; + QBearerEngine *create(const QString &key) const; +}; -private: - void addComboBoxItems(); - void addListItems(); - void addTextEdit(); - void setupOtherWidgets(); - void setupButtons(); - void addTreeItems(); - void addTreeListItems(); +QIcdEnginePlugin::QIcdEnginePlugin() +{ +} - Ui::Standard m_staWidget; - Ui::Advanced m_advWidget; - Ui::System m_sysWidget; +QIcdEnginePlugin::~QIcdEnginePlugin() +{ +} - QIcon m_small1; - QIcon m_small2; - QIcon m_big; -}; +QStringList QIcdEnginePlugin::keys() const +{ + return QStringList() << QLatin1String("icd"); +} + +QBearerEngine *QIcdEnginePlugin::create(const QString &key) const +{ + if (key == QLatin1String("icd")) + return new QIcdEngine; + else + return 0; +} -#endif //MAINWINDOW_H +Q_EXPORT_STATIC_PLUGIN(QIcdEnginePlugin) +Q_EXPORT_PLUGIN2(qicdbearer, QIcdEnginePlugin) +QT_END_NAMESPACE diff --git a/src/plugins/bearer/icd/monitor.cpp b/src/plugins/bearer/icd/monitor.cpp new file mode 100644 index 0000000..0ff45d2 --- /dev/null +++ b/src/plugins/bearer/icd/monitor.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "monitor.h" +#include "qicdengine.h" + +#include <wlancond.h> +#include <libicd-network-wlan-dev.h> +#include <maemo_icd.h> +#include <iapconf.h> + +#define IAP "/system/osso/connectivity/IAP" + +static int iap_prefix_len; + +/* Notify func that is called when IAP is added or deleted */ +void notify_iap(GConfClient *, guint, GConfEntry *entry, gpointer user_data) +{ + const char *key = gconf_entry_get_key(entry); + if (key && g_str_has_prefix(key, IAP)) { + IapMonitor *ptr = (IapMonitor *)user_data; + if (gconf_entry_get_value(entry)) { + ptr->iapAdded(key, entry); + } else { + ptr->iapDeleted(key, entry); + } + } +} + + +void IapMonitor::setup(QIcdEngine *d_ptr) +{ + if (first_call) { + d = d_ptr; + iap_prefix_len = strlen(IAP); + iap = new Maemo::IAPMonitor(notify_iap, (gpointer)this); + first_call = false; + } +} + + +void IapMonitor::cleanup() +{ + if (!first_call) { + delete iap; + timers.removeAll(); + first_call = true; + } +} + + +void IapMonitor::iapAdded(const char *key, GConfEntry * /*entry*/) +{ + //qDebug("Notify called for added element: %s=%s", + // gconf_entry_get_key(entry), gconf_value_to_string(gconf_entry_get_value(entry))); + + /* We cannot know when the IAP is fully added to gconf, so a timer is + * installed instead. When the timer expires we hope that IAP is added ok. + */ + QString iap_id = QString(key + iap_prefix_len + 1).section('/',0,0); + timers.add(iap_id, d); +} + + +void IapMonitor::iapDeleted(const char *key, GConfEntry * /*entry*/) +{ + //qDebug("Notify called for deleted element: %s", gconf_entry_get_key(entry)); + + /* We are only interested in IAP deletions so we skip the config entries + */ + if (strstr(key + iap_prefix_len + 1, "/")) { + //qDebug("Deleting IAP config %s", key+iap_prefix_len); + return; + } + + QString iap_id = key + iap_prefix_len + 1; + d->deleteConfiguration(iap_id); +} diff --git a/src/plugins/bearer/icd/monitor.h b/src/plugins/bearer/icd/monitor.h new file mode 100644 index 0000000..82b0f36 --- /dev/null +++ b/src/plugins/bearer/icd/monitor.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MONITOR_H +#define MONITOR_H + +#include <QtCore/qhash.h> +#include <QtCore/qtimer.h> + +#include <gconf/gconf.h> +#include <gconf/gconf-client.h> + +#include <iapmonitor.h> + +class QIcdEngine; + +/* The IapAddTimer is a helper class that makes sure we update + * the configuration only after all gconf additions to certain + * iap are finished (after a certain timeout) + */ +class _IapAddTimer : public QObject +{ + Q_OBJECT + +public: + _IapAddTimer() {} + ~_IapAddTimer() + { + if (timer.isActive()) { + QObject::disconnect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.stop(); + } + } + + void add(QString& iap_id, QIcdEngine *d); + + QString iap_id; + QTimer timer; + QIcdEngine *d; + +public Q_SLOTS: + void timeout(); +}; + +class IapAddTimer { + QHash<QString, _IapAddTimer* > timers; + +public: + IapAddTimer() {} + ~IapAddTimer() {} + + void add(QString& iap_id, QIcdEngine *d); + void del(QString& iap_id); + void removeAll(); +}; + +class IapMonitor +{ +public: + IapMonitor() : first_call(true) { } + friend void notify_iap(GConfClient *, guint, + GConfEntry *entry, gpointer user_data); + + void setup(QIcdEngine *d); + void cleanup(); + +private: + bool first_call; + + void iapAdded(const char *key, GConfEntry *entry); + void iapDeleted(const char *key, GConfEntry *entry); + + Maemo::IAPMonitor *iap; + QIcdEngine *d; + IapAddTimer timers; +}; + +#endif // MONITOR_H diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp new file mode 100644 index 0000000..3233eda --- /dev/null +++ b/src/plugins/bearer/icd/qicdengine.cpp @@ -0,0 +1,416 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qicdengine.h" +#include "monitor.h" +#include "qnetworksession_impl.h" + +#include <libicd-network-wlan-dev.h> +#include <maemo_icd.h> +#include <iapconf.h> + +QT_BEGIN_NAMESPACE + +IcdNetworkConfigurationPrivate::IcdNetworkConfigurationPrivate() +: network_attrs(0), service_attrs(0) +{ +} + +IcdNetworkConfigurationPrivate::~IcdNetworkConfigurationPrivate() +{ +} + +QString IcdNetworkConfigurationPrivate::bearerName() const +{ + if (iap_type == QLatin1String("WLAN_INFRA") || + iap_type == QLatin1String("WLAN_ADHOC")) { + return QLatin1String("WLAN"); + } else if (iap_type == QLatin1String("GPRS")) { + return QLatin1String("HSPA"); + } else { + return iap_type; + } +} + +static inline QString network_attrs_to_security(uint network_attrs) +{ + uint cap = 0; + nwattr2cap(network_attrs, &cap); /* from libicd-network-wlan-dev.h */ + if (cap & WLANCOND_OPEN) + return "NONE"; + else if (cap & WLANCOND_WEP) + return "WEP"; + else if (cap & WLANCOND_WPA_PSK) + return "WPA_PSK"; + else if (cap & WLANCOND_WPA_EAP) + return "WPA_EAP"; + return ""; +} + +QIcdEngine::QIcdEngine(QObject *parent) +: QBearerEngine(parent), iapMonitor(new IapMonitor) +{ + /* Turn on IAP monitoring */ + iapMonitor->setup(this); + + doRequestUpdate(); +} + +QIcdEngine::~QIcdEngine() +{ +} + +bool QIcdEngine::hasIdentifier(const QString &id) +{ + return accessPointConfigurations.contains(id) || + snapConfigurations.contains(id) || + userChoiceConfigurations.contains(id); +} + +void QIcdEngine::requestUpdate() +{ + QTimer::singleShot(0, this, SLOT(doRequestUpdate())); +} + +static uint32_t getNetworkAttrs(bool is_iap_id, + QString& iap_id, + QString& iap_type, + QString security_method) +{ + guint network_attr = 0; + dbus_uint32_t cap = 0; + + if (iap_type == "WLAN_INFRA") + cap |= WLANCOND_INFRA; + else if (iap_type == "WLAN_ADHOC") + cap |= WLANCOND_ADHOC; + + if (security_method.isEmpty() && (cap & (WLANCOND_INFRA | WLANCOND_ADHOC))) { + Maemo::IAPConf saved_ap(iap_id); + security_method = saved_ap.value("wlan_security").toString(); + } + + if (!security_method.isEmpty()) { + if (security_method == "WEP") + cap |= WLANCOND_WEP; + else if (security_method == "WPA_PSK") + cap |= WLANCOND_WPA_PSK; + else if (security_method == "WPA_EAP") + cap |= WLANCOND_WPA_EAP; + else if (security_method == "NONE") + cap |= WLANCOND_OPEN; + + if (cap & (WLANCOND_WPA_PSK | WLANCOND_WPA_EAP)) { + Maemo::IAPConf saved_iap(iap_id); + bool wpa2_only = saved_iap.value("EAP_wpa2_only_mode").toBool(); + if (wpa2_only) { + cap |= WLANCOND_WPA2; + } + } + } + + cap2nwattr(cap, &network_attr); + if (is_iap_id) + network_attr |= ICD_NW_ATTR_IAPNAME; + + return (uint32_t)network_attr; +} + +void QIcdEngine::doRequestUpdate() +{ + QStringList previous = accessPointConfigurations.keys(); + + /* All the scanned access points */ + QList<Maemo::IcdScanResult> scanned; + + /* We create a default configuration which is a pseudo config */ + if (!userChoiceConfigurations.contains(OSSO_IAP_ANY)) { + QNetworkConfigurationPrivatePointer ptr(new IcdNetworkConfigurationPrivate); + + ptr->name = QLatin1String("UserChoice"); + ptr->state = QNetworkConfiguration::Discovered; + ptr->isValid = true; + ptr->id = OSSO_IAP_ANY; + ptr->type = QNetworkConfiguration::UserChoice; + ptr->purpose = QNetworkConfiguration::UnknownPurpose; + ptr->roamingSupported = false; + + userChoiceConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); + } + + /* We return currently configured IAPs in the first run and do the WLAN + * scan in subsequent runs. + */ + QList<QString> all_iaps; + Maemo::IAPConf::getAll(all_iaps); + + foreach (QString escaped_iap_id, all_iaps) { + QByteArray ssid; + + /* The key that is returned by getAll() needs to be unescaped */ + gchar *unescaped_id = gconf_unescape_key(escaped_iap_id.toUtf8().data(), -1); + QString iap_id = QString((char *)unescaped_id); + g_free(unescaped_id); + + previous.removeAll(iap_id); + + Maemo::IAPConf saved_ap(iap_id); + bool is_temporary = saved_ap.value("temporary").toBool(); + if (is_temporary) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "is temporary, skipping it."; +#endif + continue; + } + + QString iap_type = saved_ap.value("type").toString(); + if (iap_type.startsWith("WLAN")) { + ssid = saved_ap.value("wlan_ssid").toByteArray(); + if (ssid.isEmpty()) { + qWarning() << "Cannot get ssid for" << iap_id; + continue; + } + + QString security_method = saved_ap.value("wlan_security").toString(); + } else if (iap_type.isEmpty()) { + qWarning() << "IAP" << iap_id << "network type is not set! Skipping it"; + continue; + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "network type is" << iap_type; +#endif + ssid.clear(); + } + + if (!accessPointConfigurations.contains(iap_id)) { + IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; + + cpPriv->name = saved_ap.value("name").toString(); + if (cpPriv->name.isEmpty()) + if (!ssid.isEmpty() && ssid.size() > 0) + cpPriv->name = ssid.data(); + else + cpPriv->name = iap_id; + cpPriv->isValid = true; + cpPriv->id = iap_id; + cpPriv->network_id = ssid; + cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); + cpPriv->iap_type = iap_type; + cpPriv->service_id = saved_ap.value("service_id").toString(); + cpPriv->service_type = saved_ap.value("service_type").toString(); + cpPriv->type = QNetworkConfiguration::InternetAccessPoint; + cpPriv->state = QNetworkConfiguration::Defined; + + QNetworkConfigurationPrivatePointer ptr(cpPriv); + accessPointConfigurations.insert(iap_id, ptr); + emit configurationAdded(ptr); + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, name: %s, ssid: %s, added to known list", + iap_id.toAscii().data(), ptr->name.toAscii().data(), + !ssid.isEmpty() ? ssid.data() : "-"); +#endif + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, ssid: %s, already exists in the known list", + iap_id.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); +#endif + } + } + + if (sender()) { + QStringList scannedNetworkTypes; + QStringList networkTypesToScan; + QString error; + Maemo::Icd icd(ICD_SHORT_SCAN_TIMEOUT); + + scannedNetworkTypes = icd.scan(ICD_SCAN_REQUEST_ACTIVE, + networkTypesToScan, + scanned, + error); + if (!error.isEmpty()) { + qWarning() << "Network scanning failed" << error; + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + if (!scanned.isEmpty()) + qDebug() << "Scan returned" << scanned.size() << "networks"; + else + qDebug() << "Scan returned nothing."; +#endif + } + } + + /* This is skipped in the first update as scanned size is zero */ + if (!scanned.isEmpty()) { + for (int i=0; i<scanned.size(); ++i) { + const Maemo::IcdScanResult ap = scanned.at(i); + + QByteArray scanned_ssid = ap.scan.network_id; + + if (ap.scan.network_attrs & ICD_NW_ATTR_IAPNAME) { + /* The network_id is IAP id, so the IAP is a known one */ + QString iapid = ap.scan.network_id.data(); + + previous.removeAll(iapid); + + if (accessPointConfigurations.contains(iapid)) { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.value(iapid); + + bool changed = false; + + if (!ptr->isValid) { + ptr->isValid = true; + changed = true; + } + + if (ptr->state != QNetworkConfiguration::Discovered) { + ptr->state = QNetworkConfiguration::Discovered; + changed = true; + } + + toIcdConfig(ptr)->network_attrs = ap.scan.network_attrs; + toIcdConfig(ptr)->service_id = ap.scan.service_id; + toIcdConfig(ptr)->service_type = ap.scan.service_type; + toIcdConfig(ptr)->service_attrs = ap.scan.service_attrs; + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, ssid: %s, discovered", + iapid.toAscii().data(), scanned_ssid.data()); +#endif + + if (changed) + emit configurationChanged(ptr); + + if (!ap.scan.network_type.startsWith("WLAN")) + continue; // not a wlan AP + } + } else { + IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; + + QString hrs = scanned_ssid.data(); + + cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name; + cpPriv->isValid = true; + // Note: id is now ssid, it should be set to IAP id if the IAP is saved + cpPriv->id = scanned_ssid.data(); + cpPriv->network_id = scanned_ssid; + cpPriv->iap_type = ap.scan.network_type; + if (cpPriv->iap_type.isEmpty()) + cpPriv->iap_type = QLatin1String("WLAN"); + cpPriv->network_attrs = ap.scan.network_attrs; + cpPriv->service_id = ap.scan.service_id; + cpPriv->service_type = ap.scan.service_type; + cpPriv->service_attrs = ap.scan.service_attrs; + + cpPriv->type = QNetworkConfiguration::InternetAccessPoint; + cpPriv->state = QNetworkConfiguration::Undefined; + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP with network id" << cpPriv->id << "was found in the scan."; +#endif + + previous.removeAll(cpPriv->id); + + QNetworkConfigurationPrivatePointer ptr(cpPriv); + accessPointConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); + } + } + } + + while (!previous.isEmpty()) { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.take(previous.takeFirst()); + + emit configurationRemoved(ptr); + } + + if (sender()) + emit updateCompleted(); +} + +void QIcdEngine::deleteConfiguration(const QString &iap_id) +{ + /* Called when IAPs are deleted in gconf, in this case we do not scan + * or read all the IAPs from gconf because it might take too much power + * (multiple applications would need to scan and read all IAPs from gconf) + */ + if (accessPointConfigurations.contains(iap_id)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(iap_id); + + if (ptr) { + ptr->isValid = false; +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "was removed from storage."; +#endif + + emit configurationRemoved(ptr); + } else { + qWarning("Configuration not found for IAP %s", iap_id.toAscii().data()); + } + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("IAP: %s, already missing from the known list", iap_id.toAscii().data()); +#endif + } +} + +QNetworkConfigurationManager::Capabilities QIcdEngine::capabilities() const +{ + return QNetworkConfigurationManager::CanStartAndStopInterfaces | + QNetworkConfigurationManager::DataStatistics | + QNetworkConfigurationManager::ForcedRoaming; +} + +QNetworkSessionPrivate *QIcdEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl(this); +} + +QNetworkConfigurationPrivatePointer QIcdEngine::defaultConfiguration() +{ + // Here we just return [ANY] request to icd and let the icd decide which IAP to connect. + return userChoiceConfigurations.value(OSSO_IAP_ANY); +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/icd/qicdengine.h b/src/plugins/bearer/icd/qicdengine.h new file mode 100644 index 0000000..30b5711 --- /dev/null +++ b/src/plugins/bearer/icd/qicdengine.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QICDENGINE_H +#define QICDENGINE_H + +#include <QtNetwork/private/qbearerengine_p.h> + +QT_BEGIN_NAMESPACE + +class QNetworkConfigurationPrivate; +class IapMonitor; + +class IcdNetworkConfigurationPrivate : public QNetworkConfigurationPrivate +{ +public: + IcdNetworkConfigurationPrivate(); + ~IcdNetworkConfigurationPrivate(); + + QString bearerName() const; + + // In Maemo the id field (defined in QNetworkConfigurationPrivate) + // is the IAP id (which typically is UUID) + QByteArray network_id; // typically WLAN ssid or similar + QString iap_type; // is this one WLAN or GPRS + + // Network attributes for this IAP, this is the value returned by icd and + // passed to it when connecting. + uint32_t network_attrs; + + QString service_type; + QString service_id; + uint32_t service_attrs; +}; + +inline IcdNetworkConfigurationPrivate *toIcdConfig(QNetworkConfigurationPrivatePointer ptr) +{ + return static_cast<IcdNetworkConfigurationPrivate *>(ptr.data()); +} + +class QIcdEngine : public QBearerEngine +{ + Q_OBJECT + + friend class QNetworkSessionPrivateImpl; + +public: + QIcdEngine(QObject *parent = 0); + ~QIcdEngine(); + + bool hasIdentifier(const QString &id); + + void requestUpdate(); + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkSessionPrivate *createSessionBackend(); + + QNetworkConfigurationPrivatePointer defaultConfiguration(); + + void deleteConfiguration(const QString &iap_id); + +private: + inline void addSessionConfiguration(QNetworkConfigurationPrivatePointer ptr) + { + accessPointConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); + } + + inline void changedSessionConfiguration(QNetworkConfigurationPrivatePointer ptr) + { + emit configurationChanged(ptr); + } + +private Q_SLOTS: + void doRequestUpdate(); + +private: + IapMonitor *iapMonitor; +}; + +QT_END_NAMESPACE + +#endif // QICDENGINE_H diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp new file mode 100644 index 0000000..6cc4a1d --- /dev/null +++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp @@ -0,0 +1,1105 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworksession_impl.h" +#include "qicdengine.h" + +#include <QHash> + +#include <dbus/dbus.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include <maemo_icd.h> +#include <iapconf.h> + +#include <sys/types.h> +#include <ifaddrs.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +QT_BEGIN_NAMESPACE + +static QHash<QString, QVariant> properties; + +static QString get_network_interface(); +static DBusConnection *dbus_connection; +static DBusHandlerResult signal_handler(DBusConnection *connection, + DBusMessage *message, + void *user_data); + +#define ICD_DBUS_MATCH "type='signal'," \ + "interface='" ICD_DBUS_INTERFACE "'," \ + "path='" ICD_DBUS_PATH "'" + + +static inline DBusConnection *get_dbus_conn(DBusError *error) +{ + DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM, error); +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Listening to bus" << dbus_bus_get_unique_name(conn); +#endif + + return conn; +} + + +/* Helper class that monitors the Icd status messages and + * can change the IAP status accordingly. This is a singleton. + */ +class IcdListener : public QObject +{ + Q_OBJECT + +public: + IcdListener() : first_call(true) { } + friend DBusHandlerResult signal_handler(DBusConnection *connection, + DBusMessage *message, + void *user_data); + void setup(QNetworkSessionPrivateImpl *d); + void cleanup(); + void cleanupSession(QNetworkSessionPrivateImpl *ptr); + + enum IapConnectionStatus { + /* The IAP was connected */ + CONNECTED = 0, + /* The IAP was disconnected */ + DISCONNECTED, + /* The IAP is disconnecting */ + DISCONNECTING, + /* The IAP has a network address, but is not yet fully connected */ + NETWORK_UP + }; + +private: + void icdSignalReceived(QString&, QString&, QString&); + bool first_call; + QHash<QString, QNetworkSessionPrivateImpl *> sessions; +}; + +Q_GLOBAL_STATIC(IcdListener, icdListener); + + +static DBusHandlerResult signal_handler(DBusConnection *, + DBusMessage *message, + void *user_data) +{ + if (dbus_message_is_signal(message, + ICD_DBUS_INTERFACE, + ICD_STATUS_CHANGED_SIG)) { + + IcdListener *icd = (IcdListener *)user_data; + DBusError error; + dbus_error_init(&error); + + char *iap_id = 0; + char *network_type = 0; + char *state = 0; + + if (dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &iap_id, + DBUS_TYPE_STRING, &network_type, + DBUS_TYPE_STRING, &state, + DBUS_TYPE_INVALID) == FALSE) { + qWarning() << QString("Failed to parse icd status signal: %1").arg(error.message); + } else { + QString _iap_id(iap_id); + QString _network_type(network_type); + QString _state(state); + + icd->icdSignalReceived(_iap_id, _network_type, _state); + } + + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + + +void IcdListener::setup(QNetworkSessionPrivateImpl *d) +{ + if (first_call) { + // We use the old Icd dbus interface like in ConIC + DBusError error; + dbus_error_init(&error); + + dbus_connection = get_dbus_conn(&error); + if (dbus_error_is_set(&error)) { + qWarning() << "Cannot get dbus connection."; + dbus_error_free(&error); + return; + } + + static struct DBusObjectPathVTable icd_vtable; + icd_vtable.message_function = signal_handler; + + dbus_bus_add_match(dbus_connection, ICD_DBUS_MATCH, &error); + if (dbus_error_is_set(&error)) { + qWarning() << "Cannot add match" << ICD_DBUS_MATCH; + dbus_error_free(&error); + return; + } + + if (dbus_connection_register_object_path(dbus_connection, + ICD_DBUS_PATH, + &icd_vtable, + (void*)this) == FALSE) { + qWarning() << "Cannot register dbus signal handler, interface"<< ICD_DBUS_INTERFACE << "path" << ICD_DBUS_PATH; + dbus_error_free(&error); + return; + } + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Listening" << ICD_STATUS_CHANGED_SIG << "signal from" << ICD_DBUS_SERVICE; +#endif + first_call = false; + dbus_error_free(&error); + } + + QString id = d->activeConfig.identifier(); + if (!sessions.contains(id)) { + QNetworkSessionPrivateImpl *ptr = d; + sessions.insert(id, ptr); + } +} + + +void IcdListener::icdSignalReceived(QString& iap_id, +#ifdef BEARER_MANAGEMENT_DEBUG + QString& network_type, +#else + QString&, +#endif + QString& state) +{ + if (iap_id == OSSO_IAP_SCAN) // icd sends scan status signals which we will ignore + return; + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Status received:" << iap_id << "type" << network_type << "state" << state; +#endif + + if (!sessions.contains(iap_id)) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "No session for IAP" << iap_id; +#endif + return; + } + + QNetworkSessionPrivateImpl *session = sessions.value(iap_id); + QNetworkConfiguration ap_conf = + QNetworkConfigurationManager().configurationFromIdentifier(iap_id); + if (!ap_conf.isValid()) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Unknown IAP" << iap_id; +#endif + return; + } + + IapConnectionStatus status; + + if (state == "IDLE") { + status = DISCONNECTED; + } else if (state == "CONNECTED") { + status = CONNECTED; + } else if (state == "NETWORKUP") { + status = NETWORK_UP; + } else { + //qDebug() << "Unknown state" << state; + return; + } + + if (status == DISCONNECTED) { + if (ap_conf.state() == QNetworkConfiguration::Active) { + /* The IAP was just disconnected by Icd */ + session->updateState(QNetworkSession::Disconnected); + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Got a network disconnect when in state" << ap_conf.state(); +#endif + } + } else if (status == CONNECTED) { + /* The IAP was just connected by Icd */ + session->updateState(QNetworkSession::Connected); + session->updateIdentifier(iap_id); + + if (session->publicConfig.identifier() == OSSO_IAP_ANY) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "connected when connecting to" << OSSO_IAP_ANY; +#endif + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "IAP" << iap_id << "connected"; +#endif + } + } + + return; +} + + +void IcdListener::cleanup() +{ + if (!first_call) { + dbus_bus_remove_match(dbus_connection, ICD_DBUS_MATCH, NULL); + dbus_connection_unref(dbus_connection); + } +} + + +void IcdListener::cleanupSession(QNetworkSessionPrivateImpl *ptr) +{ + if (ptr->publicConfig.type() == QNetworkConfiguration::UserChoice) + (void)sessions.take(ptr->activeConfig.identifier()); + else + (void)sessions.take(ptr->publicConfig.identifier()); +} + + +void QNetworkSessionPrivateImpl::cleanupSession(void) +{ + icdListener()->cleanupSession(this); +} + + +void QNetworkSessionPrivateImpl::updateState(QNetworkSession::State newState) +{ + if (newState == state) + return; + + state = newState; + + if (state == QNetworkSession::Disconnected) { + isOpen = false; + currentNetworkInterface.clear(); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + privateConfiguration(activeConfig)->state = QNetworkConfiguration::Defined; + privateConfiguration(publicConfig)->state = QNetworkConfiguration::Defined; + + } else if (state == QNetworkSession::Connected) { + isOpen = true; + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + privateConfiguration(activeConfig)->state = QNetworkConfiguration::Active; + privateConfiguration(activeConfig)->type = QNetworkConfiguration::InternetAccessPoint; + } + privateConfiguration(publicConfig)->state = QNetworkConfiguration::Active; + } + + emit stateChanged(newState); +} + + +void QNetworkSessionPrivateImpl::updateIdentifier(QString &newId) +{ + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + toIcdConfig(privateConfiguration(activeConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME; + privateConfiguration(activeConfig)->id = newId; + } else { + toIcdConfig(privateConfiguration(publicConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME; + if (privateConfiguration(publicConfig)->id != newId) { + qWarning() << "Your config id changed from" << privateConfiguration(publicConfig)->id + << "to" << newId; + privateConfiguration(publicConfig)->id = newId; + } + } +} + + +quint64 QNetworkSessionPrivateImpl::getStatistics(bool sent) const +{ + /* This could be also implemented by using the Maemo::Icd::statistics() + * that gets the statistics data for a specific IAP. Change if + * necessary. + */ + Maemo::Icd icd; + QList<Maemo::IcdStatisticsResult> stats_results; + quint64 counter_rx = 0, counter_tx = 0; + + if (!icd.statistics(stats_results)) { + return 0; + } + + foreach (Maemo::IcdStatisticsResult res, stats_results) { + if (res.params.network_attrs & ICD_NW_ATTR_IAPNAME) { + /* network_id is the IAP UUID */ + if (QString(res.params.network_id.data()) == activeConfig.identifier()) { + counter_tx = res.bytes_sent; + counter_rx = res.bytes_received; + } + } else { + /* We probably will never get to this branch */ + if (res.params.network_id == toIcdConfig(privateConfiguration(activeConfig))->network_id) { + counter_tx = res.bytes_sent; + counter_rx = res.bytes_received; + } + } + } + + if (sent) + return counter_tx; + else + return counter_rx; +} + + +quint64 QNetworkSessionPrivateImpl::bytesWritten() const +{ + return getStatistics(true); +} + +quint64 QNetworkSessionPrivateImpl::bytesReceived() const +{ + return getStatistics(false); +} + +quint64 QNetworkSessionPrivateImpl::activeTime() const +{ + if (startTime.isNull()) { + return 0; + } + return startTime.secsTo(QDateTime::currentDateTime()); +} + + +QNetworkConfiguration& QNetworkSessionPrivateImpl::copyConfig(QNetworkConfiguration &fromConfig, + QNetworkConfiguration &toConfig, + bool deepCopy) +{ + IcdNetworkConfigurationPrivate *cpPriv; + if (deepCopy) { + cpPriv = new IcdNetworkConfigurationPrivate; + setPrivateConfiguration(toConfig, QNetworkConfigurationPrivatePointer(cpPriv)); + } else { + cpPriv = toIcdConfig(privateConfiguration(toConfig)); + } + + cpPriv->name = privateConfiguration(fromConfig)->name; + cpPriv->isValid = privateConfiguration(fromConfig)->isValid; + // Note that we do not copy id field here as the publicConfig does + // not contain a valid IAP id. + cpPriv->state = privateConfiguration(fromConfig)->state; + cpPriv->type = privateConfiguration(fromConfig)->type; + cpPriv->roamingSupported = privateConfiguration(fromConfig)->roamingSupported; + cpPriv->purpose = privateConfiguration(fromConfig)->purpose; + cpPriv->network_id = toIcdConfig(privateConfiguration(fromConfig))->network_id; + cpPriv->iap_type = toIcdConfig(privateConfiguration(fromConfig))->iap_type; + cpPriv->network_attrs = toIcdConfig(privateConfiguration(fromConfig))->network_attrs; + cpPriv->service_type = toIcdConfig(privateConfiguration(fromConfig))->service_type; + cpPriv->service_id = toIcdConfig(privateConfiguration(fromConfig))->service_id; + cpPriv->service_attrs = toIcdConfig(privateConfiguration(fromConfig))->service_attrs; + + return toConfig; +} + + +/* This is called by QNetworkSession constructor and it updates the current + * state of the configuration. + */ +void QNetworkSessionPrivateImpl::syncStateWithInterface() +{ + /* Start to listen Icd status messages. */ + icdListener()->setup(this); + + /* Initially we are not active although the configuration might be in + * connected state. + */ + isOpen = false; + opened = false; + + connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged())); + + connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)), + this, SLOT(configurationChanged(QNetworkConfiguration))); + + state = QNetworkSession::Invalid; + lastError = QNetworkSession::UnknownSessionError; + + switch (publicConfig.type()) { + case QNetworkConfiguration::InternetAccessPoint: + activeConfig = publicConfig; + break; + case QNetworkConfiguration::ServiceNetwork: + serviceConfig = publicConfig; + break; + case QNetworkConfiguration::UserChoice: + // active config will contain correct data after open() has succeeded + copyConfig(publicConfig, activeConfig); + + /* We create new configuration that holds the actual configuration + * returned by icd. This way publicConfig still contains the + * original user specified configuration. + * + * Note that the new activeConfig configuration is not inserted + * to configurationManager as manager class will get the newly + * connected configuration from gconf when the IAP is saved. + * This configuration manager update is done by IapMonitor class. + * If the ANY connection fails in open(), then the configuration + * data is not saved to gconf and will not be added to + * configuration manager IAP list. + */ +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug()<<"New configuration created for" << publicConfig.identifier(); +#endif + break; + default: + /* Invalid configuration, no point continuing */ + return; + } + + if (!activeConfig.isValid()) + return; + + /* Get the initial state from icd */ + Maemo::Icd icd; + QList<Maemo::IcdStateResult> state_results; + + /* Update the active config from first connection, this is ok as icd + * supports only one connection anyway. + */ + if (icd.state(state_results) && !state_results.isEmpty()) { + + /* If we did not get full state back, then we are not + * connected and can skip the next part. + */ + if (!(state_results.first().params.network_attrs == 0 && + state_results.first().params.network_id.isEmpty())) { + + /* If we try to connect to specific IAP and we get results back + * that tell the icd is actually connected to another IAP, + * then do not update current state etc. + */ + if (publicConfig.type() == QNetworkConfiguration::UserChoice || + privateConfiguration(publicConfig)->id == state_results.first().params.network_id) { + + switch (state_results.first().state) { + case ICD_STATE_DISCONNECTED: + state = QNetworkSession::Disconnected; + if (privateConfiguration(activeConfig)) + privateConfiguration(activeConfig)->isValid = true; + break; + case ICD_STATE_CONNECTING: + state = QNetworkSession::Connecting; + if (privateConfiguration(activeConfig)) + privateConfiguration(activeConfig)->isValid = true; + break; + case ICD_STATE_CONNECTED: + { + if (!state_results.first().error.isEmpty()) + break; + + const QString id = state_results.first().params.network_id; + + QNetworkConfiguration config = manager.configurationFromIdentifier(id); + if (config.isValid()) { + //we don't want the copied data if the config is already known by the manager + //just reuse it so that existing references to the old data get the same update + setPrivateConfiguration(activeConfig, privateConfiguration(config)); + } + + QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); + + state = QNetworkSession::Connected; + toIcdConfig(ptr)->network_id = state_results.first().params.network_id; + ptr->id = toIcdConfig(ptr)->network_id; + toIcdConfig(ptr)->network_attrs = state_results.first().params.network_attrs; + toIcdConfig(ptr)->iap_type = state_results.first().params.network_type; + toIcdConfig(ptr)->service_type = state_results.first().params.service_type; + toIcdConfig(ptr)->service_id = state_results.first().params.service_id; + toIcdConfig(ptr)->service_attrs = state_results.first().params.service_attrs; + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->state = QNetworkConfiguration::Active; + ptr->isValid = true; + currentNetworkInterface = get_network_interface(); + + Maemo::IAPConf iap_name(privateConfiguration(activeConfig)->id); + QString name_value = iap_name.value("name").toString(); + if (!name_value.isEmpty()) + privateConfiguration(activeConfig)->name = name_value; + else + privateConfiguration(activeConfig)->name = privateConfiguration(activeConfig)->id; + + + // Add the new active configuration to manager or update the old config + if (!(engine->accessPointConfigurations.contains(privateConfiguration(activeConfig)->id))) + engine->addSessionConfiguration(privateConfiguration(activeConfig)); + else + engine->changedSessionConfiguration(privateConfiguration(activeConfig)); + } + break; + + case ICD_STATE_DISCONNECTING: + state = QNetworkSession::Closing; + if (privateConfiguration(activeConfig)) + privateConfiguration(activeConfig)->isValid = true; + break; + default: + break; + } + } + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "status_req tells icd is not connected"; +#endif + } + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "status_req did not return any results from icd"; +#endif + } + + networkConfigurationsChanged(); +} + + +void QNetworkSessionPrivateImpl::networkConfigurationsChanged() +{ + if (serviceConfig.isValid()) + updateStateFromServiceNetwork(); + else + updateStateFromActiveConfig(); +} + + +void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork() +{ + QNetworkSession::State oldState = state; + + foreach (const QNetworkConfiguration &config, serviceConfig.children()) { + if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) + continue; + + if (activeConfig != config) { + activeConfig = config; + emit newConfigurationActivated(); + } + + state = QNetworkSession::Connected; + if (state != oldState) + emit stateChanged(state); + + return; + } + + if (serviceConfig.children().isEmpty()) + state = QNetworkSession::NotAvailable; + else + state = QNetworkSession::Disconnected; + + if (state != oldState) + emit stateChanged(state); +} + + +void QNetworkSessionPrivateImpl::clearConfiguration(QNetworkConfiguration &config) +{ + toIcdConfig(privateConfiguration(config))->network_id.clear(); + toIcdConfig(privateConfiguration(config))->iap_type.clear(); + toIcdConfig(privateConfiguration(config))->network_attrs = 0; + toIcdConfig(privateConfiguration(config))->service_type.clear(); + toIcdConfig(privateConfiguration(config))->service_id.clear(); + toIcdConfig(privateConfiguration(config))->service_attrs = 0; +} + + +void QNetworkSessionPrivateImpl::updateStateFromActiveConfig() +{ + QNetworkSession::State oldState = state; + + bool newActive = false; + + if (!privateConfiguration(activeConfig)) + return; + + if (!activeConfig.isValid()) { + state = QNetworkSession::Invalid; + clearConfiguration(activeConfig); + } else if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + state = QNetworkSession::Connected; + newActive = opened; + } else if ((activeConfig.state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) { + state = QNetworkSession::Disconnected; + } else if ((activeConfig.state() & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) { + state = QNetworkSession::NotAvailable; + } else if ((activeConfig.state() & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined) { + state = QNetworkSession::NotAvailable; + //clearConfiguration(activeConfig); + } + + bool oldActive = isOpen; + isOpen = newActive; + + if (!oldActive && isOpen) + emit quitPendingWaitsForOpened(); + + if (oldActive && !isOpen) + emit closed(); + + if (oldState != state) { + emit stateChanged(state); + + if (state == QNetworkSession::Disconnected) { +#ifdef BEARER_MANAGEMENT_DEBUG + //qDebug()<<"session aborted error emitted for"<<activeConfig.identifier(); +#endif + lastError = QNetworkSession::SessionAbortedError; + emit QNetworkSessionPrivate::error(lastError); + } + } + +#ifdef BEARER_MANAGEMENT_DEBUG + //qDebug()<<"oldState ="<<oldState<<" state ="<<state<<" oldActive ="<<oldActive<<" newActive ="<<newActive<<" opened ="<<opened; +#endif +} + + +void QNetworkSessionPrivateImpl::configurationChanged(const QNetworkConfiguration &config) +{ + if (serviceConfig.isValid() && (config == serviceConfig || config == activeConfig)) + updateStateFromServiceNetwork(); + else if (config == activeConfig) + updateStateFromActiveConfig(); +} + + +static QString get_network_interface() +{ + Maemo::Icd icd; + QList<Maemo::IcdAddressInfoResult> addr_results; + uint ret; + QString iface; + + ret = icd.addrinfo(addr_results); + if (ret == 0) { + /* No results */ +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Cannot get addrinfo from icd, are you connected or is icd running?"; +#endif + return iface; + } + + const char *address = addr_results.first().ip_info.first().address.toAscii().constData(); + struct in_addr addr; + if (inet_aton(address, &addr) == 0) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "address" << address << "invalid"; +#endif + return iface; + } + + struct ifaddrs *ifaddr, *ifa; + int family; + + if (getifaddrs(&ifaddr) == -1) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "getifaddrs() failed"; +#endif + return iface; + } + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + family = ifa->ifa_addr->sa_family; + if (family != AF_INET) { + continue; /* Currently only IPv4 is supported by icd dbus interface */ + } + if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == addr.s_addr) { + iface = QString(ifa->ifa_name); + break; + } + } + + freeifaddrs(ifaddr); + return iface; +} + + +void QNetworkSessionPrivateImpl::open() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else if (!isOpen) { + + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + /* Caller is trying to connect to default IAP. + * At this time we will not know the IAP details so we just + * connect and update the active config when the IAP is + * connected. + */ + opened = true; + state = QNetworkSession::Connecting; + emit stateChanged(state); + QTimer::singleShot(0, this, SLOT(do_open())); + return; + } + + /* User is connecting to one specific IAP. If that IAP is not + * in discovered state we cannot continue. + */ + if ((activeConfig.state() & QNetworkConfiguration::Discovered) != + QNetworkConfiguration::Discovered) { + lastError =QNetworkSession::InvalidConfigurationError; + emit QNetworkSessionPrivate::error(lastError); + return; + } + opened = true; + + if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) { + state = QNetworkSession::Connecting; + emit stateChanged(state); + + QTimer::singleShot(0, this, SLOT(do_open())); + return; + } + + isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active; + if (isOpen) + emit quitPendingWaitsForOpened(); + } else { + /* We seem to be active so inform caller */ + emit quitPendingWaitsForOpened(); + } +} + + +void QNetworkSessionPrivateImpl::do_open() +{ + icd_connection_flags flags = connectFlags; + bool st; + QString result; + QString iap = publicConfig.identifier(); + + if (state == QNetworkSession::Connected) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Already connected to" << activeConfig.identifier(); +#endif + emit stateChanged(QNetworkSession::Connected); + emit quitPendingWaitsForOpened(); + return; + } + + Maemo::IcdConnectResult connect_result; + Maemo::Icd icd(ICD_LONG_CONNECT_TIMEOUT); + QNetworkConfiguration config; + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + config = activeConfig; + else + config = publicConfig; + + if (iap == OSSO_IAP_ANY) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "connecting to default IAP" << iap; +#endif + st = icd.connect(flags, connect_result); + + } else { + + QList<Maemo::ConnectParams> params; + Maemo::ConnectParams param; + param.connect.service_type = toIcdConfig(privateConfiguration(config))->service_type; + param.connect.service_attrs = toIcdConfig(privateConfiguration(config))->service_attrs; + param.connect.service_id = toIcdConfig(privateConfiguration(config))->service_id; + param.connect.network_type = toIcdConfig(privateConfiguration(config))->iap_type; + param.connect.network_attrs = toIcdConfig(privateConfiguration(config))->network_attrs; + if (toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME) + param.connect.network_id = QByteArray(iap.toLatin1()); + else + param.connect.network_id = toIcdConfig(privateConfiguration(config))->network_id; + params.append(param); + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s", + param.connect.network_id.data(), + param.connect.network_type.toAscii().constData(), + param.connect.network_attrs, + param.connect.service_type.toAscii().constData(), + param.connect.service_attrs, + param.connect.service_id.toAscii().constData()); +#endif + st = icd.connect(flags, params, connect_result); + } + + if (st) { + result = connect_result.connect.network_id.data(); + QString connected_iap = result; + + if (connected_iap.isEmpty()) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "connect to"<< iap << "failed, result is empty"; +#endif + updateState(QNetworkSession::Disconnected); + emit quitPendingWaitsForOpened(); + emit QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + cleanupAnyConfiguration(); + return; + } + + /* If the user tried to connect to some specific connection (foo) + * and we were already connected to some other connection (bar), + * then we cannot activate this session although icd has a valid + * connection to somewhere. + */ + if ((publicConfig.type() != QNetworkConfiguration::UserChoice) && + (connected_iap != config.identifier())) { + updateState(QNetworkSession::Disconnected); + emit quitPendingWaitsForOpened(); + emit QNetworkSessionPrivate::error(QNetworkSession::InvalidConfigurationError); + return; + } + + + /* Did we connect to non saved IAP? */ + if (!(toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME)) { + /* Because the connection succeeded, the IAP is now known. + */ + toIcdConfig(privateConfiguration(config))->network_attrs |= ICD_NW_ATTR_IAPNAME; + privateConfiguration(config)->id = connected_iap; + } + + /* User might have changed the IAP name when a new IAP was saved */ + Maemo::IAPConf iap_name(privateConfiguration(config)->id); + QString name = iap_name.value("name").toString(); + if (!name.isEmpty()) + privateConfiguration(config)->name = name; + + toIcdConfig(privateConfiguration(config))->iap_type = connect_result.connect.network_type; + + privateConfiguration(config)->isValid = true; + privateConfiguration(config)->state = QNetworkConfiguration::Active; + privateConfiguration(config)->type = QNetworkConfiguration::InternetAccessPoint; + + startTime = QDateTime::currentDateTime(); + updateState(QNetworkSession::Connected); + + currentNetworkInterface = get_network_interface(); + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "connected to" << result << config.name() << "at" << currentNetworkInterface; +#endif + + /* We first check if the configuration already exists in the manager + * and if it is not found there, we then insert it. Note that this + * is only done for user choice config only because it can be missing + * from config manager list. + */ + + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + if (!engine->accessPointConfigurations.contains(result)) { + engine->addSessionConfiguration(privateConfiguration(config)); + } else { + QNetworkConfigurationPrivatePointer priv = + engine->accessPointConfigurations.value(result); + QNetworkConfiguration reference; + setPrivateConfiguration(reference, priv); + copyConfig(config, reference, false); + config = reference; + activeConfig = reference; + engine->changedSessionConfiguration(privateConfiguration(config)); + } + } + + emit quitPendingWaitsForOpened(); + + } else { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "connect to"<< iap << "failed, status:" << connect_result.status; +#endif + updateState(QNetworkSession::Disconnected); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) + cleanupAnyConfiguration(); + emit quitPendingWaitsForOpened(); + emit QNetworkSessionPrivate::error(QNetworkSession::UnknownSessionError); + } +} + + +void QNetworkSessionPrivateImpl::cleanupAnyConfiguration() +{ +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug()<<"Removing configuration created for" << activeConfig.identifier(); +#endif + activeConfig = publicConfig; +} + + +void QNetworkSessionPrivateImpl::close() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else if (isOpen) { + opened = false; + isOpen = false; + emit closed(); + } +} + + +void QNetworkSessionPrivateImpl::stop() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else { + if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + state = QNetworkSession::Closing; + emit stateChanged(state); + + Maemo::Icd icd; +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "stopping session" << publicConfig.identifier(); +#endif + icd.disconnect(ICD_CONNECTION_FLAG_APPLICATION_EVENT); + startTime = QDateTime(); + + /* Note that the state will go disconnected in + * updateStateFromActiveConfig() which gets called after + * configurationChanged is emitted (below). + */ + + privateConfiguration(activeConfig)->state = QNetworkConfiguration::Discovered; + engine->changedSessionConfiguration(privateConfiguration(activeConfig)); + + opened = false; + isOpen = false; + + } else { + opened = false; + isOpen = false; + emit closed(); + } + } +} + + +void QNetworkSessionPrivateImpl::migrate() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + + +void QNetworkSessionPrivateImpl::accept() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + + +void QNetworkSessionPrivateImpl::ignore() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + + +void QNetworkSessionPrivateImpl::reject() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + + +QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const +{ + if (!publicConfig.isValid() || state != QNetworkSession::Connected) + return QNetworkInterface(); + + if (currentNetworkInterface.isEmpty()) + return QNetworkInterface(); + + return QNetworkInterface::interfaceFromName(currentNetworkInterface); +} + + +void QNetworkSessionPrivateImpl::setSessionProperty(const QString& key, const QVariant& value) +{ + if (value.isValid()) { + properties.insert(key, value); + + if (key == "ConnectInBackground") { + bool v = value.toBool(); + if (v) + connectFlags = ICD_CONNECTION_FLAG_APPLICATION_EVENT; + else + connectFlags = ICD_CONNECTION_FLAG_USER_EVENT; + } + } else { + properties.remove(key); + + /* Set default value when property is removed */ + if (key == "ConnectInBackground") + connectFlags = ICD_CONNECTION_FLAG_USER_EVENT; + } +} + + +QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& key) const +{ + return properties.value(key); +} + + +QString QNetworkSessionPrivateImpl::errorString() const +{ + QString errorStr; + switch(q->error()) { + case QNetworkSession::RoamingError: + errorStr = QObject::tr("Roaming error"); + break; + case QNetworkSession::SessionAbortedError: + errorStr = QObject::tr("Session aborted by user or system"); + break; + default: + case QNetworkSession::UnknownSessionError: + errorStr = QObject::tr("Unidentified Error"); + break; + } + return errorStr; +} + + +QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const +{ + return QNetworkSession::UnknownSessionError; +} + +#include "qnetworksession_impl.moc" + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/icd/qnetworksession_impl.h b/src/plugins/bearer/icd/qnetworksession_impl.h new file mode 100644 index 0000000..b7461dc --- /dev/null +++ b/src/plugins/bearer/icd/qnetworksession_impl.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKSESSION_IMPL_H +#define QNETWORKSESSION_IMPL_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the QLibrary class. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include <QtNetwork/private/qnetworksession_p.h> +#include <QtNetwork/qnetworkconfigmanager.h> + +//#include "qnetworkconfigmanager_maemo_p.h" +//#include "qnetworksession.h" + +//#include <qnetworksession.h> +//#include <QNetworkInterface> +#include <QtCore/qdatetime.h> + +#include <icd/dbus_api.h> + +QT_BEGIN_NAMESPACE + +class QIcdEngine; + +class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate +{ + Q_OBJECT + +public: + QNetworkSessionPrivateImpl(QIcdEngine *engine) + : engine(engine), connectFlags(ICD_CONNECTION_FLAG_USER_EVENT) + { + } + + ~QNetworkSessionPrivateImpl() + { + cleanupSession(); + } + + //called by QNetworkSession constructor and ensures + //that the state is immediately updated (w/o actually opening + //a session). Also this function should take care of + //notification hooks to discover future state changes. + void syncStateWithInterface(); + + QNetworkInterface currentInterface() const; + QVariant sessionProperty(const QString& key) const; + void setSessionProperty(const QString& key, const QVariant& value); + + void open(); + void close(); + void stop(); + + void migrate(); + void accept(); + void ignore(); + void reject(); + + QString errorString() const; //must return translated string + QNetworkSession::SessionError error() const; + + quint64 bytesWritten() const; + quint64 bytesReceived() const; + quint64 activeTime() const; + +private: + void updateStateFromServiceNetwork(); + void updateStateFromActiveConfig(); + +private Q_SLOTS: + void do_open(); + void networkConfigurationsChanged(); + void configurationChanged(const QNetworkConfiguration &config); + +private: + QNetworkConfigurationManager manager; + QIcdEngine *engine; + + QNetworkConfiguration& copyConfig(QNetworkConfiguration &fromConfig, QNetworkConfiguration &toConfig, bool deepCopy = true); + void clearConfiguration(QNetworkConfiguration &config); + void cleanupAnyConfiguration(); + + bool opened; + icd_connection_flags connectFlags; + + QNetworkSession::SessionError lastError; + + QDateTime startTime; + QString currentNetworkInterface; + friend class IcdListener; + void updateState(QNetworkSession::State); + void updateIdentifier(QString &newId); + quint64 getStatistics(bool sent) const; + void cleanupSession(void); +}; + +QT_END_NAMESPACE + +#endif //QNETWORKSESSIONPRIVATE_H + diff --git a/src/plugins/bearer/nativewifi/main.cpp b/src/plugins/bearer/nativewifi/main.cpp new file mode 100644 index 0000000..d77462e --- /dev/null +++ b/src/plugins/bearer/nativewifi/main.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnativewifiengine.h" +#include "platformdefs.h" + +#include <QtCore/qmutex.h> +#include <QtCore/private/qmutexpool_p.h> +#include <QtCore/qlibrary.h> + +#include <QtNetwork/private/qbearerplugin_p.h> + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +static void resolveLibrary() +{ + static volatile bool triedResolve = false; + + if (!triedResolve) { +#ifndef QT_NO_THREAD + QMutexLocker locker(QMutexPool::globalInstanceGet(&local_WlanOpenHandle)); +#endif + + if (!triedResolve) { + local_WlanOpenHandle = (WlanOpenHandleProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanOpenHandle"); + local_WlanRegisterNotification = (WlanRegisterNotificationProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanRegisterNotification"); + local_WlanEnumInterfaces = (WlanEnumInterfacesProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanEnumInterfaces"); + local_WlanGetAvailableNetworkList = (WlanGetAvailableNetworkListProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanGetAvailableNetworkList"); + local_WlanQueryInterface = (WlanQueryInterfaceProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanQueryInterface"); + local_WlanConnect = (WlanConnectProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanConnect"); + local_WlanDisconnect = (WlanDisconnectProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanDisconnect"); + local_WlanScan = (WlanScanProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanScan"); + local_WlanFreeMemory = (WlanFreeMemoryProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanFreeMemory"); + local_WlanCloseHandle = (WlanCloseHandleProto) + QLibrary::resolve(QLatin1String("wlanapi.dll"), "WlanCloseHandle"); + + triedResolve = true; + } + } +} + +class QNativeWifiEnginePlugin : public QBearerEnginePlugin +{ +public: + QNativeWifiEnginePlugin(); + ~QNativeWifiEnginePlugin(); + + QStringList keys() const; + QBearerEngine *create(const QString &key) const; +}; + +QNativeWifiEnginePlugin::QNativeWifiEnginePlugin() +{ +} + +QNativeWifiEnginePlugin::~QNativeWifiEnginePlugin() +{ +} + +QStringList QNativeWifiEnginePlugin::keys() const +{ + return QStringList() << QLatin1String("nativewifi"); +} + +QBearerEngine *QNativeWifiEnginePlugin::create(const QString &key) const +{ + if (key != QLatin1String("nativewifi")) + return 0; + + resolveLibrary(); + + // native wifi dll not available + if (!local_WlanOpenHandle) + return 0; + + QNativeWifiEngine *engine = new QNativeWifiEngine; + + // could not initialise subsystem + if (engine && !engine->available()) { + delete engine; + return 0; + } + + return engine; +} + +Q_EXPORT_STATIC_PLUGIN(QNativeWifiEnginePlugin) +Q_EXPORT_PLUGIN2(qnativewifibearer, QNativeWifiEnginePlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/nativewifi/nativewifi.pro b/src/plugins/bearer/nativewifi/nativewifi.pro new file mode 100644 index 0000000..f277a04 --- /dev/null +++ b/src/plugins/bearer/nativewifi/nativewifi.pro @@ -0,0 +1,17 @@ +TARGET = qnativewifibearer +include(../../qpluginbase.pri) + +QT += network + +HEADERS += qnativewifiengine.h \ + platformdefs.h \ + ../qnetworksession_impl.h \ + ../qbearerengine_impl.h + +SOURCES += main.cpp \ + qnativewifiengine.cpp \ + ../qnetworksession_impl.cpp + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer +target.path += $$[QT_INSTALL_PLUGINS]/bearer +INSTALLS += target diff --git a/src/plugins/bearer/nativewifi/platformdefs.h b/src/plugins/bearer/nativewifi/platformdefs.h new file mode 100644 index 0000000..57ae852 --- /dev/null +++ b/src/plugins/bearer/nativewifi/platformdefs.h @@ -0,0 +1,322 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLATFORMDEFS_H +#define PLATFORMDEFS_H + +#include <wtypes.h> +#undef interface + +#define WLAN_MAX_NAME_LENGTH 256 +#define WLAN_MAX_PHY_TYPE_NUMBER 8 +#define WLAN_NOTIFICATION_SOURCE_ALL 0x0000ffff +#define WLAN_AVAILABLE_NETWORK_CONNECTED 1 +#define WLAN_AVAILABLE_NETWORK_HAS_PROFILE 2 +#define DOT11_SSID_MAX_LENGTH 32 + +struct WLAN_NOTIFICATION_DATA { + DWORD NotificationSource; + DWORD NotificationCode; + GUID InterfaceGuid; + DWORD dwDataSize; + PVOID pData; +}; + +enum WLAN_INTERFACE_STATE { + wlan_interface_state_not_ready = 0, + wlan_interface_state_connected, + wlan_interface_state_ad_hoc_network_formed, + wlan_interface_state_disconnecting, + wlan_interface_state_disconnected, + wlan_interface_state_associating, + wlan_interface_state_discovering, + wlan_interface_state_authenticating +}; + +struct WLAN_INTERFACE_INFO { + GUID InterfaceGuid; + WCHAR strInterfaceDescription[WLAN_MAX_NAME_LENGTH]; + WLAN_INTERFACE_STATE isState; +}; + +struct WLAN_INTERFACE_INFO_LIST { + DWORD dwNumberOfItems; + DWORD dwIndex; + WLAN_INTERFACE_INFO InterfaceInfo[1]; +}; + +struct DOT11_SSID { + ULONG uSSIDLength; + UCHAR ucSSID[DOT11_SSID_MAX_LENGTH]; +}; + +struct NDIS_OBJECT_HEADER { + UCHAR Type; + UCHAR Revision; + USHORT Size; +}; + +typedef UCHAR DOT11_MAC_ADDRESS[6]; +struct DOT11_BSSID_LIST { + NDIS_OBJECT_HEADER Header; + ULONG uNumberOfEntries; + ULONG uTotalNumOfEntries; + DOT11_MAC_ADDRESS BSSIDs[1]; +}; + +enum DOT11_BSS_TYPE { + dot11_BSS_type_infrastructure = 1, + dot11_BSS_type_independent = 2, + dot11_BSS_type_any = 3 +}; + +enum DOT11_PHY_TYPE { + dot11_phy_type_unknown = 0, + dot11_phy_type_any = dot11_phy_type_unknown, + dot11_phy_type_fhss = 1, + dot11_phy_type_dsss = 2, + dot11_phy_type_irbaseband = 3, + dot11_phy_type_ofdm = 4, + dot11_phy_type_hrdsss = 5, + dot11_phy_type_erp = 6, + dot11_phy_type_ht = 7, + dot11_phy_type_IHV_start = 0x80000000, + dot11_phy_type_IHV_end = 0xffffffff +}; + +enum DOT11_AUTH_ALGORITHM { + DOT11_AUTH_ALGO_80211_OPEN = 1, + DOT11_AUTH_ALGO_80211_SHARED_KEY = 2, + DOT11_AUTH_ALGO_WPA = 3, + DOT11_AUTH_ALGO_WPA_PSK = 4, + DOT11_AUTH_ALGO_WPA_NONE = 5, + DOT11_AUTH_ALGO_RSNA = 6, + DOT11_AUTH_ALGO_RSNA_PSK = 7, + DOT11_AUTH_ALGO_IHV_START = 0x80000000, + DOT11_AUTH_ALGO_IHV_END = 0xffffffff +}; + +enum DOT11_CIPHER_ALGORITHM { + DOT11_CIPHER_ALGO_NONE = 0x00, + DOT11_CIPHER_ALGO_WEP40 = 0x01, + DOT11_CIPHER_ALGO_TKIP = 0x02, + DOT11_CIPHER_ALGO_CCMP = 0x04, + DOT11_CIPHER_ALGO_WEP104 = 0x05, + DOT11_CIPHER_ALGO_WPA_USE_GROUP = 0x100, + DOT11_CIPHER_ALGO_RSN_USE_GROUP = 0x100, + DOT11_CIPHER_ALGO_WEP = 0x101, + DOT11_CIPHER_ALGO_IHV_START = 0x80000000, + DOT11_CIPHER_ALGO_IHV_END = 0xffffffff +}; + +struct WLAN_AVAILABLE_NETWORK { + WCHAR strProfileName[WLAN_MAX_NAME_LENGTH]; + DOT11_SSID dot11Ssid; + DOT11_BSS_TYPE dot11BssType; + ULONG uNumberOfBssids; + BOOL bNetworkConnectable; + DWORD wlanNotConnectableReason; + ULONG uNumberOfPhyTypes; + DOT11_PHY_TYPE dot11PhyTypes[WLAN_MAX_PHY_TYPE_NUMBER]; + BOOL bMorePhyTypes; + ULONG wlanSignalQuality; + BOOL bSecurityEnabled; + DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm; + DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm; + DWORD dwFlags; + DWORD dwReserved; +}; + +struct WLAN_AVAILABLE_NETWORK_LIST { + DWORD dwNumberOfItems; + DWORD dwIndex; + WLAN_AVAILABLE_NETWORK Network[1]; +}; + +enum WLAN_INTF_OPCODE { + wlan_intf_opcode_autoconf_start = 0x000000000, + wlan_intf_opcode_autoconf_enabled, + wlan_intf_opcode_background_scan_enabled, + wlan_intf_opcode_media_streaming_mode, + wlan_intf_opcode_radio_state, + wlan_intf_opcode_bss_type, + wlan_intf_opcode_interface_state, + wlan_intf_opcode_current_connection, + wlan_intf_opcode_channel_number, + wlan_intf_opcode_supported_infrastructure_auth_cipher_pairs, + wlan_intf_opcode_supported_adhoc_auth_cipher_pairs, + wlan_intf_opcode_supported_country_or_region_string_list, + wlan_intf_opcode_current_operation_mode, + wlan_intf_opcode_supported_safe_mode, + wlan_intf_opcode_certified_safe_mode, + wlan_intf_opcode_autoconf_end = 0x0fffffff, + wlan_intf_opcode_msm_start = 0x10000100, + wlan_intf_opcode_statistics, + wlan_intf_opcode_rssi, + wlan_intf_opcode_msm_end = 0x1fffffff, + wlan_intf_opcode_security_start = 0x20010000, + wlan_intf_opcode_security_end = 0x2fffffff, + wlan_intf_opcode_ihv_start = 0x30000000, + wlan_intf_opcode_ihv_end = 0x3fffffff +}; + +enum WLAN_OPCODE_VALUE_TYPE { + wlan_opcode_value_type_query_only = 0, + wlan_opcode_value_type_set_by_group_policy, + wlan_opcode_value_type_set_by_user, + wlan_opcode_value_type_invalid +}; + +enum WLAN_CONNECTION_MODE { + wlan_connection_mode_profile = 0, + wlan_connection_mode_temporary_profile, + wlan_connection_mode_discovery_secure, + wlan_connection_mode_discovery_unsecure, + wlan_connection_mode_auto, + wlan_connection_mode_invalid +}; + +struct WLAN_CONNECTION_PARAMETERS { + WLAN_CONNECTION_MODE wlanConnectionMode; + LPCWSTR strProfile; + DOT11_SSID *pDot11Ssid; + DOT11_BSSID_LIST *pDesiredBssidList; + DOT11_BSS_TYPE dot11BssType; + DWORD dwFlags; +}; + +struct WLAN_RAW_DATA { + DWORD dwDataSize; + BYTE DataBlob[1]; +}; + +enum WLAN_NOTIFICATION_ACM { + wlan_notification_acm_start = 0, + wlan_notification_acm_autoconf_enabled, + wlan_notification_acm_autoconf_disabled, + wlan_notification_acm_background_scan_enabled, + wlan_notification_acm_background_scan_disabled, + wlan_notification_acm_bss_type_change, + wlan_notification_acm_power_setting_change, + wlan_notification_acm_scan_complete, + wlan_notification_acm_scan_fail, + wlan_notification_acm_connection_start, + wlan_notification_acm_connection_complete, + wlan_notification_acm_connection_attempt_fail, + wlan_notification_acm_filter_list_change, + wlan_notification_acm_interface_arrival, + wlan_notification_acm_interface_removal, + wlan_notification_acm_profile_change, + wlan_notification_acm_profile_name_change, + wlan_notification_acm_profiles_exhausted, + wlan_notification_acm_network_not_available, + wlan_notification_acm_network_available, + wlan_notification_acm_disconnecting, + wlan_notification_acm_disconnected, + wlan_notification_acm_adhoc_network_state_change, + wlan_notification_acm_end +}; + +struct WLAN_ASSOCIATION_ATTRIBUTES { + DOT11_SSID dot11Ssid; + DOT11_BSS_TYPE dot11BssType; + DOT11_MAC_ADDRESS dot11Bssid; + DOT11_PHY_TYPE dot11PhyType; + ULONG uDot11PhyIndex; + ULONG wlanSignalQuality; + ULONG ulRxRate; + ULONG ulTxRate; +}; + +struct WLAN_SECURITY_ATTRIBUTES { + BOOL bSecurityEnabled; + BOOL bOneXEnabled; + DOT11_AUTH_ALGORITHM dot11AuthAlgorithm; + DOT11_CIPHER_ALGORITHM dot11CipherAlgorithm; +}; + +struct WLAN_CONNECTION_ATTRIBUTES { + WLAN_INTERFACE_STATE isState; + WLAN_CONNECTION_MODE wlanConnectionMode; + WCHAR strProfileName[WLAN_MAX_NAME_LENGTH]; + WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes; + WLAN_SECURITY_ATTRIBUTES wlanSecurityAttributes; +}; + +typedef void (WINAPI *WLAN_NOTIFICATION_CALLBACK)(WLAN_NOTIFICATION_DATA *, PVOID); + +typedef DWORD (WINAPI *WlanOpenHandleProto) + (DWORD dwClientVersion, PVOID pReserved, PDWORD pdwNegotiatedVersion, PHANDLE phClientHandle); +typedef DWORD (WINAPI *WlanRegisterNotificationProto) + (HANDLE hClientHandle, DWORD dwNotifSource, BOOL bIgnoreDuplicate, + WLAN_NOTIFICATION_CALLBACK funcCallback, PVOID pCallbackContext, + PVOID pReserved, PDWORD pdwPrevNotifSource); +typedef DWORD (WINAPI *WlanEnumInterfacesProto) + (HANDLE hClientHandle, PVOID pReserved, WLAN_INTERFACE_INFO_LIST **ppInterfaceList); +typedef DWORD (WINAPI *WlanGetAvailableNetworkListProto) + (HANDLE hClientHandle, const GUID* pInterfaceGuid, DWORD dwFlags, PVOID pReserved, + WLAN_AVAILABLE_NETWORK_LIST **ppAvailableNetworkList); +typedef DWORD (WINAPI *WlanQueryInterfaceProto) + (HANDLE hClientHandle, const GUID *pInterfaceGuid, WLAN_INTF_OPCODE OpCode, PVOID pReserved, + PDWORD pdwDataSize, PVOID *ppData, WLAN_OPCODE_VALUE_TYPE *pWlanOpcodeValueType); +typedef DWORD (WINAPI *WlanConnectProto) + (HANDLE hClientHandle, const GUID *pInterfaceGuid, + const WLAN_CONNECTION_PARAMETERS *pConnectionParameters, PVOID pReserved); +typedef DWORD (WINAPI *WlanDisconnectProto) + (HANDLE hClientHandle, const GUID *pInterfaceGuid, PVOID pReserved); +typedef DWORD (WINAPI *WlanScanProto) + (HANDLE hClientHandle, const GUID *pInterfaceGuid, const DOT11_SSID *pDot11Ssid, + const WLAN_RAW_DATA *pIeData, PVOID pReserved); +typedef VOID (WINAPI *WlanFreeMemoryProto)(PVOID pMemory); +typedef DWORD (WINAPI *WlanCloseHandleProto)(HANDLE hClientHandle, PVOID pReserved); + +extern WlanOpenHandleProto local_WlanOpenHandle; +extern WlanRegisterNotificationProto local_WlanRegisterNotification; +extern WlanEnumInterfacesProto local_WlanEnumInterfaces; +extern WlanGetAvailableNetworkListProto local_WlanGetAvailableNetworkList; +extern WlanQueryInterfaceProto local_WlanQueryInterface; +extern WlanConnectProto local_WlanConnect; +extern WlanDisconnectProto local_WlanDisconnect; +extern WlanScanProto local_WlanScan; +extern WlanFreeMemoryProto local_WlanFreeMemory; +extern WlanCloseHandleProto local_WlanCloseHandle; + +#endif // PLATFORMDEFS_H diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp new file mode 100644 index 0000000..e4ab0aa --- /dev/null +++ b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp @@ -0,0 +1,481 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnativewifiengine.h" +#include "platformdefs.h" +#include "../qnetworksession_impl.h" + +#include <QtNetwork/private/qnetworkconfiguration_p.h> + +#include <QtCore/qstringlist.h> + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +WlanOpenHandleProto local_WlanOpenHandle = 0; +WlanRegisterNotificationProto local_WlanRegisterNotification = 0; +WlanEnumInterfacesProto local_WlanEnumInterfaces = 0; +WlanGetAvailableNetworkListProto local_WlanGetAvailableNetworkList = 0; +WlanQueryInterfaceProto local_WlanQueryInterface = 0; +WlanConnectProto local_WlanConnect = 0; +WlanDisconnectProto local_WlanDisconnect = 0; +WlanScanProto local_WlanScan = 0; +WlanFreeMemoryProto local_WlanFreeMemory = 0; +WlanCloseHandleProto local_WlanCloseHandle = 0; + +void qNotificationCallback(WLAN_NOTIFICATION_DATA *data, QNativeWifiEngine *d) +{ + Q_UNUSED(d); + + switch (data->NotificationCode) { + case wlan_notification_acm_connection_complete: + case wlan_notification_acm_disconnected: + QMetaObject::invokeMethod(d, "scanComplete", Qt::QueuedConnection); + break; + default: + ; + } +} + +QNativeWifiEngine::QNativeWifiEngine(QObject *parent) +: QBearerEngineImpl(parent), handle(0) +{ + DWORD clientVersion; + + DWORD result = local_WlanOpenHandle(1, 0, &clientVersion, &handle); + if (result != ERROR_SUCCESS) { + if (result != ERROR_SERVICE_NOT_ACTIVE) + qWarning("%s: WlanOpenHandle failed with error %ld\n", __FUNCTION__, result); + + return; + } + + result = local_WlanRegisterNotification(handle, WLAN_NOTIFICATION_SOURCE_ALL, true, + WLAN_NOTIFICATION_CALLBACK(qNotificationCallback), + this, 0, 0); + if (result != ERROR_SUCCESS) + qWarning("%s: WlanRegisterNotification failed with error %ld\n", __FUNCTION__, result); + + // On Windows XP SP2 and SP3 only connection and disconnection notifications are available. + // We need to poll for changes in available wireless networks. + connect(&pollTimer, SIGNAL(timeout()), this, SLOT(scanComplete())); + pollTimer.setInterval(10000); + scanComplete(); +} + +QNativeWifiEngine::~QNativeWifiEngine() +{ + local_WlanCloseHandle(handle, 0); +} + +void QNativeWifiEngine::scanComplete() +{ + QStringList previous = accessPointConfigurations.keys(); + + // enumerate interfaces + WLAN_INTERFACE_INFO_LIST *interfaceList; + DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result); + return; + } + + for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) { + const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i]; + + WLAN_AVAILABLE_NETWORK_LIST *networkList; + result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid, + 3, 0, &networkList); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n", + __FUNCTION__, result); + continue; + } + + QStringList seenNetworks; + + for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) { + WLAN_AVAILABLE_NETWORK &network = networkList->Network[j]; + + QString networkName; + + if (network.strProfileName[0] != 0) { + networkName = QString::fromWCharArray(network.strProfileName); + } else { + networkName = QByteArray(reinterpret_cast<char *>(network.dot11Ssid.ucSSID), + network.dot11Ssid.uSSIDLength); + } + + const QString id = QString::number(qHash(QLatin1String("WLAN:") + networkName)); + + previous.removeAll(id); + + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; + + if (!(network.dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE)) + state = QNetworkConfiguration::Undefined; + + if (network.strProfileName[0] != 0) { + if (network.bNetworkConnectable) { + if (network.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) + state = QNetworkConfiguration::Active; + else + state = QNetworkConfiguration::Discovered; + } else { + state = QNetworkConfiguration::Defined; + } + } + + if (seenNetworks.contains(networkName)) + continue; + else + seenNetworks.append(networkName); + + if (accessPointConfigurations.contains(id)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + + bool changed = false; + + if (!ptr->isValid) { + ptr->isValid = true; + changed = true; + } + + if (ptr->name != networkName) { + ptr->name = networkName; + changed = true; + } + + if (ptr->state != state) { + ptr->state = state; + changed = true; + } + + if (changed) + emit configurationChanged(ptr); + } else { + QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); + + ptr->name = networkName; + ptr->isValid = true; + ptr->id = id; + ptr->state = state; + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->bearer = QLatin1String("WLAN"); + + accessPointConfigurations.insert(id, ptr); + + emit configurationAdded(ptr); + } + } + + local_WlanFreeMemory(networkList); + } + + local_WlanFreeMemory(interfaceList); + + while (!previous.isEmpty()) { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.take(previous.takeFirst()); + + emit configurationRemoved(ptr); + } + + pollTimer.start(); + + emit updateCompleted(); +} + +QString QNativeWifiEngine::getInterfaceFromId(const QString &id) +{ + // enumerate interfaces + WLAN_INTERFACE_INFO_LIST *interfaceList; + DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result); + return QString(); + } + + for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) { + const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i]; + + DWORD dataSize; + WLAN_CONNECTION_ATTRIBUTES *connectionAttributes; + result = local_WlanQueryInterface(handle, &interface.InterfaceGuid, + wlan_intf_opcode_current_connection, 0, &dataSize, + reinterpret_cast<PVOID *>(&connectionAttributes), 0); + if (result != ERROR_SUCCESS) { + if (result != ERROR_INVALID_STATE) + qWarning("%s: WlanQueryInterface failed with error %ld\n", __FUNCTION__, result); + + continue; + } + + if (qHash(QLatin1String("WLAN:") + + QString::fromWCharArray(connectionAttributes->strProfileName)) == id.toUInt()) { + QString guid("{%1-%2-%3-%4%5-%6%7%8%9%10%11}"); + + guid = guid.arg(interface.InterfaceGuid.Data1, 8, 16, QChar('0')); + guid = guid.arg(interface.InterfaceGuid.Data2, 4, 16, QChar('0')); + guid = guid.arg(interface.InterfaceGuid.Data3, 4, 16, QChar('0')); + for (int i = 0; i < 8; ++i) + guid = guid.arg(interface.InterfaceGuid.Data4[i], 2, 16, QChar('0')); + + local_WlanFreeMemory(connectionAttributes); + local_WlanFreeMemory(interfaceList); + + return guid.toUpper(); + } + + local_WlanFreeMemory(connectionAttributes); + } + + local_WlanFreeMemory(interfaceList); + + return QString(); +} + +bool QNativeWifiEngine::hasIdentifier(const QString &id) +{ + // enumerate interfaces + WLAN_INTERFACE_INFO_LIST *interfaceList; + DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result); + return false; + } + + for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) { + const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i]; + + WLAN_AVAILABLE_NETWORK_LIST *networkList; + result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid, + 3, 0, &networkList); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n", + __FUNCTION__, result); + continue; + } + + for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) { + WLAN_AVAILABLE_NETWORK &network = networkList->Network[j]; + + QString networkName; + + if (network.strProfileName[0] != 0) { + networkName = QString::fromWCharArray(network.strProfileName); + } else { + networkName = QByteArray(reinterpret_cast<char *>(network.dot11Ssid.ucSSID), + network.dot11Ssid.uSSIDLength); + } + + if (qHash(QLatin1String("WLAN:") + networkName) == id.toUInt()) { + local_WlanFreeMemory(networkList); + local_WlanFreeMemory(interfaceList); + return true; + } + } + + local_WlanFreeMemory(networkList); + } + + local_WlanFreeMemory(interfaceList); + + return false; +} + +/*QString QNativeWifiEngine::bearerName(const QString &) +{ + return QLatin1String("WLAN"); +}*/ + +void QNativeWifiEngine::connectToId(const QString &id) +{ + WLAN_INTERFACE_INFO_LIST *interfaceList; + DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result); + emit connectionError(id, InterfaceLookupError); + return; + } + + QString profile; + + for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) { + const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i]; + + WLAN_AVAILABLE_NETWORK_LIST *networkList; + result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid, + 3, 0, &networkList); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanGetAvailableNetworkList failed with error %ld\n", + __FUNCTION__, result); + continue; + } + + for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) { + WLAN_AVAILABLE_NETWORK &network = networkList->Network[j]; + + profile = QString::fromWCharArray(network.strProfileName); + + if (qHash(QLatin1String("WLAN:") + profile) == id.toUInt()) + break; + else + profile.clear(); + } + + local_WlanFreeMemory(networkList); + + if (!profile.isEmpty()) { + WLAN_CONNECTION_PARAMETERS parameters; + parameters.wlanConnectionMode = wlan_connection_mode_profile; + parameters.strProfile = reinterpret_cast<LPCWSTR>(profile.utf16()); + parameters.pDot11Ssid = 0; + parameters.pDesiredBssidList = 0; + parameters.dot11BssType = dot11_BSS_type_any; + parameters.dwFlags = 0; + + DWORD result = local_WlanConnect(handle, &interface.InterfaceGuid, ¶meters, 0); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanConnect failed with error %ld\n", __FUNCTION__, result); + emit connectionError(id, ConnectError); + break; + } + + break; + } + } + + local_WlanFreeMemory(interfaceList); + + if (profile.isEmpty()) + emit connectionError(id, InterfaceLookupError); +} + +void QNativeWifiEngine::disconnectFromId(const QString &id) +{ + QString interface = getInterfaceFromId(id); + + if (interface.isEmpty()) { + emit connectionError(id, InterfaceLookupError); + return; + } + + QStringList split = interface.mid(1, interface.length() - 2).split('-'); + + GUID guid; + guid.Data1 = split.at(0).toUInt(0, 16); + guid.Data2 = split.at(1).toUShort(0, 16); + guid.Data3 = split.at(2).toUShort(0, 16); + guid.Data4[0] = split.at(3).left(2).toUShort(0, 16); + guid.Data4[1] = split.at(3).right(2).toUShort(0, 16); + for (int i = 0; i < 6; ++i) + guid.Data4[i + 2] = split.at(4).mid(i*2, 2).toUShort(0, 16); + + DWORD result = local_WlanDisconnect(handle, &guid, 0); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanDisconnect failed with error %ld\n", __FUNCTION__, result); + emit connectionError(id, DisconnectionError); + return; + } +} + +void QNativeWifiEngine::requestUpdate() +{ + // enumerate interfaces + WLAN_INTERFACE_INFO_LIST *interfaceList; + DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList); + if (result != ERROR_SUCCESS) { + qWarning("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result); + return; + } + + for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) { + result = local_WlanScan(handle, &interfaceList->InterfaceInfo[i].InterfaceGuid, 0, 0, 0); + if (result != ERROR_SUCCESS) + qWarning("%s: WlanScan failed with error %ld\n", __FUNCTION__, result); + } + + local_WlanFreeMemory(interfaceList); +} + +QNetworkSession::State QNativeWifiEngine::sessionStateForId(const QString &id) +{ + 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 QNativeWifiEngine::capabilities() const +{ + return QNetworkConfigurationManager::ForcedRoaming | + QNetworkConfigurationManager::CanStartAndStopInterfaces; +} + +QNetworkSessionPrivate *QNativeWifiEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl; +} + +QNetworkConfigurationPrivatePointer QNativeWifiEngine::defaultConfiguration() +{ + return QNetworkConfigurationPrivatePointer(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.h b/src/plugins/bearer/nativewifi/qnativewifiengine.h new file mode 100644 index 0000000..a9a9375 --- /dev/null +++ b/src/plugins/bearer/nativewifi/qnativewifiengine.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNATIVEWIFIENGINE_P_H +#define QNATIVEWIFIENGINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "../qbearerengine_impl.h" + +#include <QtCore/qtimer.h> + +QT_BEGIN_NAMESPACE + +class QNetworkConfigurationPrivate; +struct WLAN_NOTIFICATION_DATA; + +class QNativeWifiEngine : public QBearerEngineImpl +{ + Q_OBJECT + +public: + QNativeWifiEngine(QObject *parent = 0); + ~QNativeWifiEngine(); + + QString getInterfaceFromId(const QString &id); + bool hasIdentifier(const QString &id); + + //QString bearerName(const QString &id); + + void connectToId(const QString &id); + void disconnectFromId(const QString &id); + + void requestUpdate(); + + QNetworkSession::State sessionStateForId(const QString &id); + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkSessionPrivate *createSessionBackend(); + + QNetworkConfigurationPrivatePointer defaultConfiguration(); + + inline bool available() const { return handle != 0; } + +public Q_SLOTS: + void scanComplete(); + +private: + QTimer pollTimer; + + Qt::HANDLE handle; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/bearer/networkmanager/main.cpp b/src/plugins/bearer/networkmanager/main.cpp new file mode 100644 index 0000000..f62b847 --- /dev/null +++ b/src/plugins/bearer/networkmanager/main.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworkmanagerengine.h" + +#include <QtNetwork/private/qbearerplugin_p.h> + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QNetworkManagerEnginePlugin : public QBearerEnginePlugin +{ +public: + QNetworkManagerEnginePlugin(); + ~QNetworkManagerEnginePlugin(); + + QStringList keys() const; + QBearerEngine *create(const QString &key) const; +}; + +QNetworkManagerEnginePlugin::QNetworkManagerEnginePlugin() +{ +} + +QNetworkManagerEnginePlugin::~QNetworkManagerEnginePlugin() +{ +} + +QStringList QNetworkManagerEnginePlugin::keys() const +{ + return QStringList() << QLatin1String("networkmanager"); +} + +QBearerEngine *QNetworkManagerEnginePlugin::create(const QString &key) const +{ + if (key == QLatin1String("networkmanager")) + return new QNetworkManagerEngine; + else + return 0; +} + +Q_EXPORT_STATIC_PLUGIN(QNetworkManagerEnginePlugin) +Q_EXPORT_PLUGIN2(qnmbearer, QNetworkManagerEnginePlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/networkmanager/networkmanager.pro b/src/plugins/bearer/networkmanager/networkmanager.pro new file mode 100644 index 0000000..bf0d29a --- /dev/null +++ b/src/plugins/bearer/networkmanager/networkmanager.pro @@ -0,0 +1,20 @@ +TARGET = qnmbearer +include(../../qpluginbase.pri) + +QT += network dbus + +HEADERS += qnmdbushelper.h \ + qnetworkmanagerservice.h \ + qnetworkmanagerengine.h \ + ../qnetworksession_impl.h \ + ../qbearerengine_impl.h + +SOURCES += main.cpp \ + qnmdbushelper.cpp \ + qnetworkmanagerservice.cpp \ + qnetworkmanagerengine.cpp \ + ../qnetworksession_impl.cpp + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer +target.path += $$[QT_INSTALL_PLUGINS]/bearer +INSTALLS += target diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp new file mode 100644 index 0000000..3f3e1bd --- /dev/null +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -0,0 +1,789 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworkmanagerengine.h" +#include "qnetworkmanagerservice.h" +#include "../qnetworksession_impl.h" + +#include <QtNetwork/private/qnetworkconfiguration_p.h> + +#include <QtNetwork/qnetworksession.h> + +#include <QtCore/qdebug.h> + +#include <NetworkManager/NetworkManager.h> +#include <QtDBus> +#include <QDBusConnection> +#include <QDBusError> +#include <QDBusInterface> +#include <QDBusMessage> +#include <QDBusReply> + +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)) +{ + interface->setConnections(); + connect(interface, SIGNAL(deviceAdded(QDBusObjectPath)), + this, SLOT(deviceAdded(QDBusObjectPath))); + connect(interface, SIGNAL(deviceRemoved(QDBusObjectPath)), + this, SLOT(deviceRemoved(QDBusObjectPath))); +#if 0 + connect(interface, SIGNAL(stateChanged(const QString,quint32)), + this, SIGNAL(configurationsChanged())); +#endif + connect(interface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), + this, SLOT(activationFinished(QDBusPendingCallWatcher*))); + connect(interface, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)), + this, SLOT(interfacePropertiesChanged(QString,QMap<QString,QVariant>))); + + qDBusRegisterMetaType<QNmSettingsMap>(); + + systemSettings->setConnections(); + connect(systemSettings, SIGNAL(newConnection(QDBusObjectPath)), + this, SLOT(newConnection(QDBusObjectPath))); + + userSettings->setConnections(); + connect(userSettings, SIGNAL(newConnection(QDBusObjectPath)), + this, SLOT(newConnection(QDBusObjectPath))); + + // Get current list of access points. + foreach (const QDBusObjectPath &devicePath, interface->getDevices()) + deviceAdded(devicePath); + + // Get connections. + foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections()) + newConnection(settingsPath, systemSettings); + foreach (const QDBusObjectPath &settingsPath, userSettings->listConnections()) + newConnection(settingsPath, userSettings); + + // Get active connections. + foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + QNetworkManagerConnectionActive *activeConnection = + new QNetworkManagerConnectionActive(acPath.path()); + activeConnections.insert(acPath.path(), activeConnection); + + activeConnection->setConnections(); + connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)), + this, SLOT(activeConnectionPropertiesChanged(QString,QMap<QString,QVariant>))); + } +} + +QNetworkManagerEngine::~QNetworkManagerEngine() +{ +} + +void QNetworkManagerEngine::doRequestUpdate() +{ + emit updateCompleted(); +} + +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())); + + if (id == identifier) { + QList<QDBusObjectPath> devices = activeConnection.devices(); + + if (devices.isEmpty()) + continue; + + QNetworkManagerInterfaceDevice device(devices.at(0).path()); + return device.interface().name(); + } + } + + return QString(); +} + +bool QNetworkManagerEngine::hasIdentifier(const QString &id) +{ + 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; +} + +QString QNetworkManagerEngine::bearerName(const QString &id) +{ + QNetworkManagerSettingsConnection *connection = connectionFromId(id); + + if (!connection) + return QString(); + + QNmSettingsMap map = connection->getSettings(); + const QString connectionType = map.value("connection").value("type").toString(); + + if (connectionType == "802-3-ethernet") + return QLatin1String("Ethernet"); + else if (connectionType == "802-11-wireless") + return QLatin1String("WLAN"); + else if (connectionType == "gsm") + return QLatin1String("2G"); + else if (connectionType == "cdma") + return QLatin1String("CDMA2000"); + else + return QString(); +} + +void QNetworkManagerEngine::connectToId(const QString &id) +{ + QNetworkManagerSettingsConnection *connection = connectionFromId(id); + + if (!connection) + return; + + QNmSettingsMap map = connection->getSettings(); + const QString connectionType = map.value("connection").value("type").toString(); + + QString dbusDevicePath; + foreach (const QDBusObjectPath &devicePath, interface->getDevices()) { + QNetworkManagerInterfaceDevice device(devicePath.path()); + if (device.deviceType() == DEVICE_TYPE_802_3_ETHERNET && + connectionType == QLatin1String("802-3-ethernet")) { + dbusDevicePath = devicePath.path(); + break; + } else if (device.deviceType() == DEVICE_TYPE_802_11_WIRELESS && + connectionType == QLatin1String("802-11-wireless")) { + dbusDevicePath = devicePath.path(); + break; + } + } + + const QString service = connection->connectionInterface()->service(); + const QString settingsPath = connection->connectionInterface()->path(); + + interface->activateConnection(service, QDBusObjectPath(settingsPath), + QDBusObjectPath(dbusDevicePath), QDBusObjectPath("/")); +} + +void QNetworkManagerEngine::disconnectFromId(const QString &id) +{ + foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + QNetworkManagerConnectionActive activeConnection(acPath.path()); + + const QString identifier = QString::number(qHash(activeConnection.serviceName() + ' ' + + activeConnection.connection().path())); + + if (id == identifier && accessPointConfigurations.contains(id)) { + interface->deactivateConnection(acPath); + break; + } + } +} + +void QNetworkManagerEngine::requestUpdate() +{ + QTimer::singleShot(0, this, SLOT(doRequestUpdate())); +} + +void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, + const QMap<QString, QVariant> &properties) +{ + Q_UNUSED(path) + + QMapIterator<QString, QVariant> i(properties); + while (i.hasNext()) { + i.next(); + + if (i.key() == QLatin1String("ActiveConnections")) { + // Active connections changed, update configurations. + + QList<QDBusObjectPath> activeConnections = + qdbus_cast<QList<QDBusObjectPath> >(i.value().value<QDBusArgument>()); + + QStringList identifiers = accessPointConfigurations.keys(); + foreach (const QString &id, identifiers) + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + + QStringList priorActiveConnections = this->activeConnections.keys(); + + foreach (const QDBusObjectPath &acPath, activeConnections) { + priorActiveConnections.removeOne(acPath.path()); + QNetworkManagerConnectionActive *activeConnection = + this->activeConnections.value(acPath.path()); + if (!activeConnection) { + activeConnection = new QNetworkManagerConnectionActive(acPath.path()); + this->activeConnections.insert(acPath.path(), activeConnection); + + activeConnection->setConnections(); + connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)), + this, SLOT(activeConnectionPropertiesChanged(QString,QMap<QString,QVariant>))); + } + + const QString id = QString::number(qHash(activeConnection->serviceName() + ' ' + + activeConnection->connection().path())); + + identifiers.removeOne(id); + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + if (ptr) { + if (activeConnection->state() == 2 && + ptr->state != QNetworkConfiguration::Active) { + ptr->state = QNetworkConfiguration::Active; + emit configurationChanged(ptr); + } + } + } + + while (!priorActiveConnections.isEmpty()) + delete this->activeConnections.take(priorActiveConnections.takeFirst()); + + while (!identifiers.isEmpty()) { + // These configurations are not active + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.value(identifiers.takeFirst()); + + if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + ptr->state = QNetworkConfiguration::Discovered; + emit configurationChanged(ptr); + } + } + } + } +} + +void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &path, + const QMap<QString, QVariant> &properties) +{ + Q_UNUSED(properties) + + QNetworkManagerConnectionActive *activeConnection = activeConnections.value(path); + + if (!activeConnection) + return; + + const QString id = QString::number(qHash(activeConnection->serviceName() + ' ' + + activeConnection->connection().path())); + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + if (ptr) { + if (activeConnection->state() == 2 && + ptr->state != QNetworkConfiguration::Active) { + ptr->state = QNetworkConfiguration::Active; + emit configurationChanged(ptr); + } + } +} + +void QNetworkManagerEngine::devicePropertiesChanged(const QString &path, + const QMap<QString, QVariant> &properties) +{ +} + +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()); + wirelessDevices.insert(path.path(), wirelessDevice); + + 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<QString,QVariant>)), + this, SLOT(devicePropertiesChanged(QString,QMap<QString,QVariant>))); + + foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints()) + newAccessPoint(QString(), apPath); + } +} + +void QNetworkManagerEngine::deviceRemoved(const QDBusObjectPath &path) +{ + delete wirelessDevices.value(path.path()); +} + +void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, + QNetworkManagerSettings *settings) +{ + if (!settings) + settings = qobject_cast<QNetworkManagerSettings *>(sender()); + + if (!settings) + return; + + QNetworkManagerSettingsConnection *connection = + new QNetworkManagerSettingsConnection(settings->connectionInterface()->service(), + path.path()); + connections.append(connection); + + connect(connection, SIGNAL(removed(QString)), this, SLOT(removeConnection(QString))); + connect(connection, SIGNAL(updated(const QNmSettingsMap&)), + this, SLOT(updateConnection(const QNmSettingsMap&))); + + const QString service = connection->connectionInterface()->service(); + const QString settingsPath = connection->connectionInterface()->path(); + + QNetworkConfigurationPrivate *cpPriv = + parseConnection(service, settingsPath, connection->getSettings()); + + // Check if connection is active. + foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + QNetworkManagerConnectionActive activeConnection(acPath.path()); + + if (activeConnection.serviceName() == service && + activeConnection.connection().path() == settingsPath && + activeConnection.state() == 2) { + cpPriv->state |= QNetworkConfiguration::Active; + break; + } + } + + QNetworkConfigurationPrivatePointer ptr(cpPriv); + accessPointConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); +} + +void QNetworkManagerEngine::removeConnection(const QString &path) +{ + Q_UNUSED(path) + + QNetworkManagerSettingsConnection *connection = + qobject_cast<QNetworkManagerSettingsConnection *>(sender()); + if (!connection) + return; + + connections.removeAll(connection); + + const QString id = QString::number(qHash(connection->connectionInterface()->service() + ' ' + + connection->connectionInterface()->path())); + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id); + ptr->isValid = false; + emit configurationRemoved(ptr); +} + +void QNetworkManagerEngine::updateConnection(const QNmSettingsMap &settings) +{ + QNetworkManagerSettingsConnection *connection = + qobject_cast<QNetworkManagerSettingsConnection *>(sender()); + if (!connection) + return; + + const QString service = connection->connectionInterface()->service(); + const QString settingsPath = connection->connectionInterface()->path(); + + QNetworkConfigurationPrivate *cpPriv = parseConnection(service, settingsPath, settings); + + // Check if connection is active. + foreach (const QDBusObjectPath &acPath, interface->activeConnections()) { + QNetworkManagerConnectionActive activeConnection(acPath.path()); + + if (activeConnection.serviceName() == service && + activeConnection.connection().path() == settingsPath && + activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + cpPriv->state |= QNetworkConfiguration::Active; + break; + } + } + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id); + + ptr->isValid = cpPriv->isValid; + ptr->name = cpPriv->name; + ptr->id = cpPriv->id; + ptr->state = cpPriv->state; + + emit configurationChanged(ptr); + delete cpPriv; +} + +void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher) +{ + QDBusPendingReply<QDBusObjectPath> reply = *watcher; + if (!reply.isError()) { + QDBusObjectPath result = reply.value(); + + QNetworkManagerConnectionActive activeConnection(result.path()); + + const QString id = QString::number(qHash(activeConnection.serviceName() + ' ' + + activeConnection.connection().path())); + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + if (ptr) { + if (activeConnection.state() == 2 && + ptr->state != QNetworkConfiguration::Active) { + ptr->state = QNetworkConfiguration::Active; + emit configurationChanged(ptr); + } + } + } +} + +void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjectPath &objectPath) +{ + Q_UNUSED(path) + + QNetworkManagerInterfaceAccessPoint *accessPoint = + new QNetworkManagerInterfaceAccessPoint(objectPath.path()); + accessPoints.append(accessPoint); + + accessPoint->setConnections(); + connect(accessPoint, SIGNAL(propertiesChanged(QMap<QString,QVariant>)), + this, SLOT(updateAccessPoint(QMap<QString,QVariant>))); + + // Check if configuration for this SSID already exists. + for (int i = 0; i < accessPoints.count(); ++i) { + if (accessPoint != accessPoints.at(i) && + accessPoint->ssid() == accessPoints.at(i)->ssid()) { + return; + } + } + + // Check if configuration exists for connection. + if (!accessPoint->ssid().isEmpty()) { + 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)); + + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.value(connectionId); + ptr->state = QNetworkConfiguration::Discovered; + emit configurationChanged(ptr); + return; + } + } + } + + // New access point. + QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); + + ptr->name = accessPoint->ssid(); + ptr->isValid = true; + ptr->id = QString::number(qHash(objectPath.path())); + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->purpose = QNetworkConfiguration::PublicPurpose; + ptr->state = QNetworkConfiguration::Undefined; + ptr->bearer = QLatin1String("WLAN"); + + accessPointConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); +} + +void QNetworkManagerEngine::removeAccessPoint(const QString &path, + const QDBusObjectPath &objectPath) +{ + Q_UNUSED(path) + + for (int i = 0; i < accessPoints.count(); ++i) { + QNetworkManagerInterfaceAccessPoint *accessPoint = accessPoints.at(i); + + if (accessPoint->connectionInterface()->path() == objectPath.path()) { + accessPoints.removeOne(accessPoint); + + if (configuredAccessPoints.contains(accessPoint)) { + // find connection and change state to Defined + configuredAccessPoints.removeOne(accessPoint); + 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)); + + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.value(connectionId); + ptr->state = QNetworkConfiguration::Defined; + emit configurationChanged(ptr); + return; + } + } + } else { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.take(QString::number(qHash(objectPath.path()))); + + if (ptr) + emit configurationRemoved(ptr); + } + + delete accessPoint; + + break; + } + } +} + +void QNetworkManagerEngine::updateAccessPoint(const QMap<QString, QVariant> &map) +{ + Q_UNUSED(map) + + QNetworkManagerInterfaceAccessPoint *accessPoint = + qobject_cast<QNetworkManagerInterfaceAccessPoint *>(sender()); + if (!accessPoint) + return; + + 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)); + + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.value(connectionId); + ptr->state = QNetworkConfiguration::Discovered; + emit configurationChanged(ptr); + return; + } + } +} + +QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QString &service, + const QString &settingsPath, + const QNmSettingsMap &map) +{ + QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate; + cpPriv->name = map.value("connection").value("id").toString(); + cpPriv->isValid = true; + cpPriv->id = QString::number(qHash(service + ' ' + settingsPath)); + cpPriv->type = QNetworkConfiguration::InternetAccessPoint; + + cpPriv->purpose = QNetworkConfiguration::PublicPurpose; + + cpPriv->state = QNetworkConfiguration::Defined; + + const QString connectionType = map.value("connection").value("type").toString(); + + if (connectionType == QLatin1String("802-3-ethernet")) { + cpPriv->bearer = QLatin1String("Ethernet"); + + foreach (const QDBusObjectPath &devicePath, interface->getDevices()) { + QNetworkManagerInterfaceDevice device(devicePath.path()); + if (device.deviceType() == DEVICE_TYPE_802_3_ETHERNET) { + QNetworkManagerInterfaceDeviceWired wiredDevice(device.connectionInterface()->path()); + if (wiredDevice.carrier()) { + cpPriv->state |= QNetworkConfiguration::Discovered; + break; + } + + } + } + } else if (connectionType == QLatin1String("802-11-wireless")) { + cpPriv->bearer = QLatin1String("WLAN"); + + const QString connectionSsid = map.value("802-11-wireless").value("ssid").toString(); + + for (int i = 0; i < accessPoints.count(); ++i) { + if (connectionSsid == accessPoints.at(i)->ssid()) { + cpPriv->state |= QNetworkConfiguration::Discovered; + if (!configuredAccessPoints.contains(accessPoints.at(i))) { + configuredAccessPoints.append(accessPoints.at(i)); + + const QString accessPointId = + QString::number(qHash(accessPoints.at(i)->connectionInterface()->path())); + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.take(accessPointId); + emit configurationRemoved(ptr); + } + break; + } + } + } else if (connectionType == "gsm") { + cpPriv->bearer = QLatin1String("2G"); + } else if (connectionType == "cdma") { + cpPriv->bearer = QLatin1String("CDMA2000"); + } + + return cpPriv; +} + +QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const QString &id) 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 = QString::number(qHash(service + ' ' + settingsPath)); + + if (id == identifier) + return connection; + } + + return 0; +} + +QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &id) +{ + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + + if (!ptr) + return QNetworkSession::Invalid; + + if (!ptr->isValid) + return QNetworkSession::Invalid; + + foreach (const QString &acPath, activeConnections.keys()) { + QNetworkManagerConnectionActive *activeConnection = activeConnections.value(acPath); + + const QString identifier = QString::number(qHash(activeConnection->serviceName() + ' ' + + activeConnection->connection().path())); + + if (id == identifier) { + switch (activeConnection->state()) { + case 0: + return QNetworkSession::Disconnected; + case 1: + return QNetworkSession::Connecting; + case 2: + return QNetworkSession::Connected; + } + } + } + + 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; +} + +quint64 QNetworkManagerEngine::bytesWritten(const QString &id) +{ + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + const QString networkInterface = getInterfaceFromId(id); + if (!networkInterface.isEmpty()) { + const QString devFile = QLatin1String("/sys/class/net/") + + networkInterface + + QLatin1String("/statistics/tx_bytes"); + + quint64 result = Q_UINT64_C(0); + + QFile tx(devFile); + if (tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&tx); + in >> result; + tx.close(); + } + + return result; + } + } + + return Q_UINT64_C(0); +} + +quint64 QNetworkManagerEngine::bytesReceived(const QString &id) +{ + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + const QString networkInterface = getInterfaceFromId(id); + if (!networkInterface.isEmpty()) { + const QString devFile = QLatin1String("/sys/class/net/") + + networkInterface + + QLatin1String("/statistics/rx_bytes"); + + quint64 result = Q_UINT64_C(0); + + QFile tx(devFile); + if (tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&tx); + in >> result; + tx.close(); + } + + return result; + } + } + + return Q_UINT64_C(0); +} + +quint64 QNetworkManagerEngine::startTime(const QString &id) +{ + QNetworkManagerSettingsConnection *connection = connectionFromId(id); + if (connection) + return connection->getTimestamp(); + else + return Q_UINT64_C(0); +} + +QNetworkConfigurationManager::Capabilities QNetworkManagerEngine::capabilities() const +{ + return QNetworkConfigurationManager::ForcedRoaming | + QNetworkConfigurationManager::CanStartAndStopInterfaces; +} + +QNetworkSessionPrivate *QNetworkManagerEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl; +} + +QNetworkConfigurationPrivatePointer QNetworkManagerEngine::defaultConfiguration() +{ + return QNetworkConfigurationPrivatePointer(); +} + +QT_END_NAMESPACE + diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h new file mode 100644 index 0000000..70efc05 --- /dev/null +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKMANAGERENGINE_P_H +#define QNETWORKMANAGERENGINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the QLibrary class. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include "../qbearerengine_impl.h" + +#include "qnetworkmanagerservice.h" + +#include <QMap> +#include <QVariant> + +QT_BEGIN_NAMESPACE + +class QNetworkManagerEngine : public QBearerEngineImpl +{ + Q_OBJECT + +public: + QNetworkManagerEngine(QObject *parent = 0); + ~QNetworkManagerEngine(); + + QString getInterfaceFromId(const QString &id); + bool hasIdentifier(const QString &id); + + QString bearerName(const QString &id); + + void connectToId(const QString &id); + void disconnectFromId(const QString &id); + + void requestUpdate(); + + QNetworkSession::State sessionStateForId(const QString &id); + + quint64 bytesWritten(const QString &id); + quint64 bytesReceived(const QString &id); + quint64 startTime(const QString &id); + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkSessionPrivate *createSessionBackend(); + + QNetworkConfigurationPrivatePointer defaultConfiguration(); + +private Q_SLOTS: + void interfacePropertiesChanged(const QString &path, + const QMap<QString, QVariant> &properties); + void activeConnectionPropertiesChanged(const QString &path, + const QMap<QString, QVariant> &properties); + void devicePropertiesChanged(const QString &path, + const QMap<QString, QVariant> &properties); + + 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 activationFinished(QDBusPendingCallWatcher *watcher); + + void newAccessPoint(const QString &path, const QDBusObjectPath &objectPath); + void removeAccessPoint(const QString &path, const QDBusObjectPath &objectPath); + void updateAccessPoint(const QMap<QString, QVariant> &map); + + void doRequestUpdate(); + +private: + QNetworkConfigurationPrivate *parseConnection(const QString &service, + const QString &settingsPath, + const QNmSettingsMap &map); + QNetworkManagerSettingsConnection *connectionFromId(const QString &id) const; + +private: + QNetworkManagerInterface *interface; + QNetworkManagerSettings *systemSettings; + QNetworkManagerSettings *userSettings; + QHash<QString, QNetworkManagerInterfaceDeviceWireless *> wirelessDevices; + QHash<QString, QNetworkManagerConnectionActive *> activeConnections; + QList<QNetworkManagerSettingsConnection *> connections; + QList<QNetworkManagerInterfaceAccessPoint *> accessPoints; + QList<QNetworkManagerInterfaceAccessPoint *> configuredAccessPoints; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp new file mode 100644 index 0000000..f7fedbf --- /dev/null +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -0,0 +1,1047 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QObject> +#include <QList> +#include <QtDBus> +#include <QDBusConnection> +#include <QDBusError> +#include <QDBusInterface> +#include <QDBusMessage> +#include <QDBusReply> +#include <QDBusPendingCallWatcher> +#include <QDBusObjectPath> +#include <QDBusPendingCall> + +#include <NetworkManager/NetworkManager.h> + +#include "qnmdbushelper.h" +#include "qnetworkmanagerservice.h" + +//Q_DECLARE_METATYPE(QList<uint>) +QT_BEGIN_NAMESPACE + +static QDBusConnection dbusConnection = QDBusConnection::systemBus(); +//static QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbusConnection); + +class QNetworkManagerInterfacePrivate +{ +public: + QDBusInterface *connectionInterface; + bool valid; +}; + +QNetworkManagerInterface::QNetworkManagerInterface(QObject *parent) + : QObject(parent), nmDBusHelper(0) +{ + d = new QNetworkManagerInterfacePrivate(); + d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + dbusConnection); + if (!d->connectionInterface->isValid()) { + qWarning() << "Could not find NetworkManager"; + d->valid = false; + return; + } + d->valid = true; + nmDBusHelper = new QNmDBusHelper; + connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)), + this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>))); + connect(nmDBusHelper,SIGNAL(pathForStateChanged(const QString &, quint32)), + this, SIGNAL(stateChanged(const QString&, quint32))); + +} + +QNetworkManagerInterface::~QNetworkManagerInterface() +{ + if (nmDBusHelper) + delete nmDBusHelper; + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerInterface::isValid() +{ + return d->valid; +} + +bool QNetworkManagerInterface::setConnections() +{ + if(!isValid() ) + return false; + bool allOk = false; + if (!dbusConnection.connect(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "PropertiesChanged", + nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>)))) { + allOk = true; + } + if (!dbusConnection.connect(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "DeviceAdded", + this,SIGNAL(deviceAdded(QDBusObjectPath)))) { + allOk = true; + } + if (!dbusConnection.connect(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "DeviceRemoved", + this,SIGNAL(deviceRemoved(QDBusObjectPath)))) { + allOk = true; + } + + return allOk; +} + +QDBusInterface *QNetworkManagerInterface::connectionInterface() const +{ + return d->connectionInterface; +} + +QList <QDBusObjectPath> QNetworkManagerInterface::getDevices() const +{ + QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call("GetDevices"); + return reply.value(); +} + +void QNetworkManagerInterface::activateConnection( const QString &serviceName, + QDBusObjectPath connectionPath, + QDBusObjectPath devicePath, + QDBusObjectPath specificObject) +{ + QDBusPendingCall pendingCall = d->connectionInterface->asyncCall("ActivateConnection", + QVariant(serviceName), + QVariant::fromValue(connectionPath), + QVariant::fromValue(devicePath), + QVariant::fromValue(specificObject)); + + QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pendingCall, this); + connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SIGNAL(activationFinished(QDBusPendingCallWatcher*))); +} + +void QNetworkManagerInterface::deactivateConnection(QDBusObjectPath connectionPath) const +{ + d->connectionInterface->call("DeactivateConnection", QVariant::fromValue(connectionPath)); +} + +bool QNetworkManagerInterface::wirelessEnabled() const +{ + return d->connectionInterface->property("WirelessEnabled").toBool(); +} + +bool QNetworkManagerInterface::wirelessHardwareEnabled() const +{ + return d->connectionInterface->property("WirelessHardwareEnabled").toBool(); +} + +QList <QDBusObjectPath> QNetworkManagerInterface::activeConnections() const +{ + QVariant prop = d->connectionInterface->property("ActiveConnections"); + return prop.value<QList<QDBusObjectPath> >(); +} + +quint32 QNetworkManagerInterface::state() +{ + return d->connectionInterface->property("State").toUInt(); +} + +///////////// +class QNetworkManagerInterfaceAccessPointPrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + bool valid; +}; + +QNetworkManagerInterfaceAccessPoint::QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent) + : QObject(parent), nmDBusHelper(0) +{ + d = new QNetworkManagerInterfaceAccessPointPrivate(); + d->path = dbusPathName; + d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_ACCESS_POINT, + dbusConnection); + if (!d->connectionInterface->isValid()) { + d->valid = false; + qWarning() << "Could not find InterfaceAccessPoint"; + return; + } + d->valid = true; + +} + +QNetworkManagerInterfaceAccessPoint::~QNetworkManagerInterfaceAccessPoint() +{ + if (nmDBusHelper) + delete nmDBusHelper; + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerInterfaceAccessPoint::isValid() +{ + return d->valid; +} + +bool QNetworkManagerInterfaceAccessPoint::setConnections() +{ + if(!isValid() ) + return false; + + bool allOk = false; + if (nmDBusHelper) + delete nmDBusHelper; + nmDBusHelper = 0; + nmDBusHelper = new QNmDBusHelper; + connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)), + this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>))); + + if(dbusConnection.connect(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_ACCESS_POINT, + "PropertiesChanged", + nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>))) ) { + allOk = true; + + } + return allOk; +} + +QDBusInterface *QNetworkManagerInterfaceAccessPoint::connectionInterface() const +{ + return d->connectionInterface; +} + +quint32 QNetworkManagerInterfaceAccessPoint::flags() const +{ + return d->connectionInterface->property("Flags").toUInt(); +} + +quint32 QNetworkManagerInterfaceAccessPoint::wpaFlags() const +{ + return d->connectionInterface->property("WpaFlags").toUInt(); +} + +quint32 QNetworkManagerInterfaceAccessPoint::rsnFlags() const +{ + return d->connectionInterface->property("RsnFlags").toUInt(); +} + +QString QNetworkManagerInterfaceAccessPoint::ssid() const +{ + return d->connectionInterface->property("Ssid").toString(); +} + +quint32 QNetworkManagerInterfaceAccessPoint::frequency() const +{ + return d->connectionInterface->property("Frequency").toUInt(); +} + +QString QNetworkManagerInterfaceAccessPoint::hwAddress() const +{ + return d->connectionInterface->property("HwAddress").toString(); +} + +quint32 QNetworkManagerInterfaceAccessPoint::mode() const +{ + return d->connectionInterface->property("Mode").toUInt(); +} + +quint32 QNetworkManagerInterfaceAccessPoint::maxBitrate() const +{ + return d->connectionInterface->property("MaxBitrate").toUInt(); +} + +quint32 QNetworkManagerInterfaceAccessPoint::strength() const +{ + return d->connectionInterface->property("Strength").toUInt(); +} + +///////////// +class QNetworkManagerInterfaceDevicePrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + bool valid; +}; + +QNetworkManagerInterfaceDevice::QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent) + : QObject(parent), nmDBusHelper(0) +{ + d = new QNetworkManagerInterfaceDevicePrivate(); + d->path = deviceObjectPath; + d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_DEVICE, + dbusConnection); + if (!d->connectionInterface->isValid()) { + d->valid = false; + qWarning() << "Could not find NetworkManager"; + return; + } + d->valid = true; +} + +QNetworkManagerInterfaceDevice::~QNetworkManagerInterfaceDevice() +{ + if (nmDBusHelper) + delete nmDBusHelper; + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerInterfaceDevice::isValid() +{ + return d->valid; +} + +bool QNetworkManagerInterfaceDevice::setConnections() +{ + if(!isValid() ) + return false; + + bool allOk = false; + if (nmDBusHelper) + delete nmDBusHelper; + nmDBusHelper = 0; + nmDBusHelper = new QNmDBusHelper; + connect(nmDBusHelper,SIGNAL(pathForStateChanged(const QString &, quint32)), + this, SIGNAL(stateChanged(const QString&, quint32))); + if(dbusConnection.connect(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_DEVICE, + "StateChanged", + nmDBusHelper,SLOT(deviceStateChanged(quint32)))) { + allOk = true; + } + return allOk; +} + +QDBusInterface *QNetworkManagerInterfaceDevice::connectionInterface() const +{ + return d->connectionInterface; +} + +QString QNetworkManagerInterfaceDevice::udi() const +{ + return d->connectionInterface->property("Udi").toString(); +} + +QNetworkInterface QNetworkManagerInterfaceDevice::interface() const +{ + return QNetworkInterface::interfaceFromName(d->connectionInterface->property("Interface").toString()); +} + +quint32 QNetworkManagerInterfaceDevice::ip4Address() const +{ + return d->connectionInterface->property("Ip4Address").toUInt(); +} + +quint32 QNetworkManagerInterfaceDevice::state() const +{ + return d->connectionInterface->property("State").toUInt(); +} + +quint32 QNetworkManagerInterfaceDevice::deviceType() const +{ + return d->connectionInterface->property("DeviceType").toUInt(); +} + +QDBusObjectPath QNetworkManagerInterfaceDevice::ip4config() const +{ + QVariant prop = d->connectionInterface->property("Ip4Config"); + return prop.value<QDBusObjectPath>(); +} + +///////////// +class QNetworkManagerInterfaceDeviceWiredPrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + bool valid; +}; + +QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, QObject *parent) + : QObject(parent), nmDBusHelper(0) +{ + d = new QNetworkManagerInterfaceDeviceWiredPrivate(); + d->path = ifaceDevicePath; + d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_DEVICE_WIRED, + dbusConnection, parent); + if (!d->connectionInterface->isValid()) { + d->valid = false; + qWarning() << "Could not find InterfaceDeviceWired"; + return; + } + d->valid = true; +} + +QNetworkManagerInterfaceDeviceWired::~QNetworkManagerInterfaceDeviceWired() +{ + if (nmDBusHelper) + delete nmDBusHelper; + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerInterfaceDeviceWired::isValid() +{ + + return d->valid; +} + +bool QNetworkManagerInterfaceDeviceWired::setConnections() +{ + if(!isValid() ) + return false; + + bool allOk = false; + + if (nmDBusHelper) + delete nmDBusHelper; + nmDBusHelper = 0; + nmDBusHelper = new QNmDBusHelper; + connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)), + this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>))); + if(dbusConnection.connect(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_DEVICE_WIRED, + "PropertiesChanged", + nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>))) ) { + allOk = true; + } + return allOk; +} + +QDBusInterface *QNetworkManagerInterfaceDeviceWired::connectionInterface() const +{ + return d->connectionInterface; +} + +QString QNetworkManagerInterfaceDeviceWired::hwAddress() const +{ + return d->connectionInterface->property("HwAddress").toString(); +} + +quint32 QNetworkManagerInterfaceDeviceWired::speed() const +{ + return d->connectionInterface->property("Speed").toUInt(); +} + +bool QNetworkManagerInterfaceDeviceWired::carrier() const +{ + return d->connectionInterface->property("Carrier").toBool(); +} + +///////////// +class QNetworkManagerInterfaceDeviceWirelessPrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + bool valid; +}; + +QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, QObject *parent) + : QObject(parent), nmDBusHelper(0) +{ + d = new QNetworkManagerInterfaceDeviceWirelessPrivate(); + d->path = ifaceDevicePath; + d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + dbusConnection, parent); + if (!d->connectionInterface->isValid()) { + d->valid = false; + qWarning() << "Could not find InterfaceDeviceWireless"; + return; + } + d->valid = true; +} + +QNetworkManagerInterfaceDeviceWireless::~QNetworkManagerInterfaceDeviceWireless() +{ + if (nmDBusHelper) + delete nmDBusHelper; + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerInterfaceDeviceWireless::isValid() +{ + return d->valid; +} + +bool QNetworkManagerInterfaceDeviceWireless::setConnections() +{ + if(!isValid() ) + return false; + + bool allOk = false; + if (nmDBusHelper) + delete nmDBusHelper; + nmDBusHelper = 0; + nmDBusHelper = new QNmDBusHelper; + connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)), + this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>))); + + connect(nmDBusHelper, SIGNAL(pathForAccessPointAdded(const QString &,QDBusObjectPath)), + this,SIGNAL(accessPointAdded(const QString &,QDBusObjectPath))); + + connect(nmDBusHelper, SIGNAL(pathForAccessPointRemoved(const QString &,QDBusObjectPath)), + this,SIGNAL(accessPointRemoved(const QString &,QDBusObjectPath))); + + if(!dbusConnection.connect(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + "AccessPointAdded", + nmDBusHelper, SLOT(slotAccessPointAdded( QDBusObjectPath )))) { + allOk = true; + } + + + if(!dbusConnection.connect(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + "AccessPointRemoved", + nmDBusHelper, SLOT(slotAccessPointRemoved( QDBusObjectPath )))) { + allOk = true; + } + + + if(!dbusConnection.connect(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + "PropertiesChanged", + nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>)))) { + allOk = true; + } + + return allOk; +} + +QDBusInterface *QNetworkManagerInterfaceDeviceWireless::connectionInterface() const +{ + return d->connectionInterface; +} + +QList <QDBusObjectPath> QNetworkManagerInterfaceDeviceWireless::getAccessPoints() +{ + QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call("GetAccessPoints"); + return reply.value(); +} + +QString QNetworkManagerInterfaceDeviceWireless::hwAddress() const +{ + return d->connectionInterface->property("HwAddress").toString(); +} + +quint32 QNetworkManagerInterfaceDeviceWireless::mode() const +{ + return d->connectionInterface->property("Mode").toUInt(); +} + +quint32 QNetworkManagerInterfaceDeviceWireless::bitrate() const +{ + return d->connectionInterface->property("Bitrate").toUInt(); +} + +QDBusObjectPath QNetworkManagerInterfaceDeviceWireless::activeAccessPoint() const +{ + return d->connectionInterface->property("ActiveAccessPoint").value<QDBusObjectPath>(); +} + +quint32 QNetworkManagerInterfaceDeviceWireless::wirelessCapabilities() const +{ + return d->connectionInterface->property("WirelelessCapabilities").toUInt(); +} + +///////////// +class QNetworkManagerSettingsPrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + bool valid; +}; + +QNetworkManagerSettings::QNetworkManagerSettings(const QString &settingsService, QObject *parent) + : QObject(parent) +{ + d = new QNetworkManagerSettingsPrivate(); + d->path = settingsService; + d->connectionInterface = new QDBusInterface(settingsService, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_IFACE_SETTINGS, + dbusConnection); + if (!d->connectionInterface->isValid()) { + d->valid = false; + qWarning() << "Could not find NetworkManagerSettings"; + return; + } + d->valid = true; +} + +QNetworkManagerSettings::~QNetworkManagerSettings() +{ + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerSettings::isValid() +{ + return d->valid; +} + +bool QNetworkManagerSettings::setConnections() +{ + bool allOk = false; + + if (!dbusConnection.connect(d->path, NM_DBUS_PATH_SETTINGS, + NM_DBUS_IFACE_SETTINGS, "NewConnection", + this, SIGNAL(newConnection(QDBusObjectPath)))) { + allOk = true; + } + + return allOk; +} + +QList <QDBusObjectPath> QNetworkManagerSettings::listConnections() +{ + QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call("ListConnections"); + return reply.value(); +} + +QDBusInterface *QNetworkManagerSettings::connectionInterface() const +{ + return d->connectionInterface; +} + + +///////////// +class QNetworkManagerSettingsConnectionPrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + QString service; + QNmSettingsMap settingsMap; + bool valid; +}; + +QNetworkManagerSettingsConnection::QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent) + : QObject(parent), nmDBusHelper(0) +{ + qDBusRegisterMetaType<QNmSettingsMap>(); + d = new QNetworkManagerSettingsConnectionPrivate(); + d->path = connectionObjectPath; + d->service = settingsService; + d->connectionInterface = new QDBusInterface(settingsService, + d->path, + NM_DBUS_IFACE_SETTINGS_CONNECTION, + dbusConnection, parent); + if (!d->connectionInterface->isValid()) { + qWarning() << "Could not find NetworkManagerSettingsConnection"; + d->valid = false; + return; + } + d->valid = true; + QDBusReply< QNmSettingsMap > rep = d->connectionInterface->call("GetSettings"); + d->settingsMap = rep.value(); +} + +QNetworkManagerSettingsConnection::~QNetworkManagerSettingsConnection() +{ + if (nmDBusHelper) + delete nmDBusHelper; + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerSettingsConnection::isValid() +{ + return d->valid; +} + +bool QNetworkManagerSettingsConnection::setConnections() +{ + if(!isValid() ) + return false; + + bool allOk = false; + if(!dbusConnection.connect(d->service, d->path, + NM_DBUS_IFACE_SETTINGS_CONNECTION, "Updated", + this, SIGNAL(updated(QNmSettingsMap)))) { + allOk = true; + } else { + QDBusError error = dbusConnection.lastError(); + } + + if (nmDBusHelper) + delete nmDBusHelper; + nmDBusHelper = 0; + nmDBusHelper = new QNmDBusHelper; + connect(nmDBusHelper, SIGNAL(pathForSettingsRemoved(const QString &)), + this,SIGNAL(removed( const QString &))); + + if (!dbusConnection.connect(d->service, d->path, + NM_DBUS_IFACE_SETTINGS_CONNECTION, "Removed", + nmDBusHelper, SIGNAL(slotSettingsRemoved()))) { + allOk = true; + } + + return allOk; +} +//QNetworkManagerSettingsConnection::update(QNmSettingsMap map) +//{ +// d->connectionInterface->call("Update", QVariant::fromValue(map)); +//} + +QDBusInterface *QNetworkManagerSettingsConnection::connectionInterface() const +{ + return d->connectionInterface; +} + +QNmSettingsMap QNetworkManagerSettingsConnection::getSettings() +{ + QDBusReply< QNmSettingsMap > rep = d->connectionInterface->call("GetSettings"); + d->settingsMap = rep.value(); + return d->settingsMap; +} + +NMDeviceType QNetworkManagerSettingsConnection::getType() +{ + QNmSettingsMap::const_iterator i = d->settingsMap.find("connection"); + while (i != d->settingsMap.end() && i.key() == "connection") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("type"); + while (ii != innerMap.end() && ii.key() == "type") { + QString devType = ii.value().toString(); + if (devType == "802-3-ethernet") { + return DEVICE_TYPE_802_3_ETHERNET; + } + if (devType == "802-11-wireless") { + return DEVICE_TYPE_802_11_WIRELESS; + } + ii++; + } + i++; + } + return DEVICE_TYPE_UNKNOWN; +} + +bool QNetworkManagerSettingsConnection::isAutoConnect() +{ + QNmSettingsMap::const_iterator i = d->settingsMap.find("connection"); + while (i != d->settingsMap.end() && i.key() == "connection") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("autoconnect"); + while (ii != innerMap.end() && ii.key() == "autoconnect") { + return ii.value().toBool(); + ii++; + } + i++; + } + return true; //default networkmanager is autoconnect +} + +quint64 QNetworkManagerSettingsConnection::getTimestamp() +{ + QNmSettingsMap::const_iterator i = d->settingsMap.find("connection"); + while (i != d->settingsMap.end() && i.key() == "connection") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("timestamp"); + while (ii != innerMap.end() && ii.key() == "timestamp") { + return ii.value().toUInt(); + ii++; + } + i++; + } + return 0; +} + +QString QNetworkManagerSettingsConnection::getId() +{ + QNmSettingsMap::const_iterator i = d->settingsMap.find("connection"); + while (i != d->settingsMap.end() && i.key() == "connection") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("id"); + while (ii != innerMap.end() && ii.key() == "id") { + return ii.value().toString(); + ii++; + } + i++; + } + return QString(); +} + +QString QNetworkManagerSettingsConnection::getUuid() +{ + QNmSettingsMap::const_iterator i = d->settingsMap.find("connection"); + while (i != d->settingsMap.end() && i.key() == "connection") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("uuid"); + while (ii != innerMap.end() && ii.key() == "uuid") { + return ii.value().toString(); + ii++; + } + i++; + } + // is no uuid, return the connection path + return d->connectionInterface->path(); +} + +QString QNetworkManagerSettingsConnection::getSsid() +{ + QNmSettingsMap::const_iterator i = d->settingsMap.find("802-11-wireless"); + while (i != d->settingsMap.end() && i.key() == "802-11-wireless") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("ssid"); + while (ii != innerMap.end() && ii.key() == "ssid") { + return ii.value().toString(); + ii++; + } + i++; + } + return QString(); +} + +QString QNetworkManagerSettingsConnection::getMacAddress() +{ + if(getType() == DEVICE_TYPE_802_3_ETHERNET) { + QNmSettingsMap::const_iterator i = d->settingsMap.find("802-3-ethernet"); + while (i != d->settingsMap.end() && i.key() == "802-3-ethernet") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("mac-address"); + while (ii != innerMap.end() && ii.key() == "mac-address") { + return ii.value().toString(); + ii++; + } + i++; + } + } + + else if(getType() == DEVICE_TYPE_802_11_WIRELESS) { + QNmSettingsMap::const_iterator i = d->settingsMap.find("802-11-wireless"); + while (i != d->settingsMap.end() && i.key() == "802-11-wireless") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("mac-address"); + while (ii != innerMap.end() && ii.key() == "mac-address") { + return ii.value().toString(); + ii++; + } + i++; + } + } + return QString(); +} + +QStringList QNetworkManagerSettingsConnection::getSeenBssids() +{ + if(getType() == DEVICE_TYPE_802_11_WIRELESS) { + QNmSettingsMap::const_iterator i = d->settingsMap.find("802-11-wireless"); + while (i != d->settingsMap.end() && i.key() == "802-11-wireless") { + QMap<QString,QVariant> innerMap = i.value(); + QMap<QString,QVariant>::const_iterator ii = innerMap.find("seen-bssids"); + while (ii != innerMap.end() && ii.key() == "seen-bssids") { + return ii.value().toStringList(); + ii++; + } + i++; + } + } + return QStringList(); +} + +///////////// +class QNetworkManagerConnectionActivePrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + bool valid; +}; + +QNetworkManagerConnectionActive::QNetworkManagerConnectionActive( const QString &activeConnectionObjectPath, QObject *parent) + : QObject(parent), nmDBusHelper(0) +{ + d = new QNetworkManagerConnectionActivePrivate(); + d->path = activeConnectionObjectPath; + d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + dbusConnection, parent); + if (!d->connectionInterface->isValid()) { + d->valid = false; + qWarning() << "Could not find NetworkManagerSettingsConnection"; + return; + } + d->valid = true; +} + +QNetworkManagerConnectionActive::~QNetworkManagerConnectionActive() +{ + if (nmDBusHelper) + delete nmDBusHelper; + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerConnectionActive::isValid() +{ + return d->valid; +} + +bool QNetworkManagerConnectionActive::setConnections() +{ + if(!isValid() ) + return false; + + bool allOk = false; + if (nmDBusHelper) + delete nmDBusHelper; + nmDBusHelper = 0; + nmDBusHelper = new QNmDBusHelper; + connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(const QString &,QMap<QString,QVariant>)), + this,SIGNAL(propertiesChanged( const QString &, QMap<QString,QVariant>))); + if(dbusConnection.connect(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + "PropertiesChanged", + nmDBusHelper,SLOT(slotPropertiesChanged( QMap<QString,QVariant>))) ) { + allOk = true; + } + + return allOk; +} + +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"); + return prop.value<QDBusObjectPath>(); +} + +QDBusObjectPath QNetworkManagerConnectionActive::specificObject() const +{ + QVariant prop = d->connectionInterface->property("SpecificObject"); + return prop.value<QDBusObjectPath>(); +} + +QList<QDBusObjectPath> QNetworkManagerConnectionActive::devices() const +{ + QVariant prop = d->connectionInterface->property("Devices"); + return prop.value<QList<QDBusObjectPath> >(); +} + +quint32 QNetworkManagerConnectionActive::state() const +{ + return d->connectionInterface->property("State").toUInt(); +} + +bool QNetworkManagerConnectionActive::defaultRoute() const +{ + return d->connectionInterface->property("Default").toBool(); +} + + +//// +class QNetworkManagerIp4ConfigPrivate +{ +public: + QDBusInterface *connectionInterface; + QString path; + bool valid; +}; + +QNetworkManagerIp4Config::QNetworkManagerIp4Config( const QString &deviceObjectPath, QObject *parent) + : QObject(parent) +{ + d = new QNetworkManagerIp4ConfigPrivate(); + d->path = deviceObjectPath; + d->connectionInterface = new QDBusInterface(NM_DBUS_SERVICE, + d->path, + NM_DBUS_INTERFACE_IP4_CONFIG, + dbusConnection, parent); + if (!d->connectionInterface->isValid()) { + d->valid = false; + qWarning() << "Could not find NetworkManagerIp4Config"; + return; + } + d->valid = true; +} + +QNetworkManagerIp4Config::~QNetworkManagerIp4Config() +{ + delete d->connectionInterface; + delete d; +} + +bool QNetworkManagerIp4Config::isValid() +{ + return d->valid; +} + +QStringList QNetworkManagerIp4Config::domains() const +{ + return d->connectionInterface->property("Domains").toStringList(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h new file mode 100644 index 0000000..81903ec --- /dev/null +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -0,0 +1,397 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKMANAGERSERVICE_H +#define QNETWORKMANAGERSERVICE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <NetworkManager/NetworkManager.h> +#include <QtDBus> +#include <QDBusConnection> +#include <QDBusError> +#include <QDBusInterface> +#include <QDBusMessage> +#include <QDBusReply> +#include <QNetworkInterface> + + +#include <QDBusPendingCallWatcher> +#include "qnmdbushelper.h" + +QT_BEGIN_NAMESPACE + +typedef QMap< QString, QMap<QString,QVariant> > QNmSettingsMap; +typedef QList<quint32> ServerThing; + +Q_DECLARE_METATYPE(QNmSettingsMap) +Q_DECLARE_METATYPE(ServerThing) + +class QNetworkManagerInterfacePrivate; +class QNetworkManagerInterface : public QObject +{ + Q_OBJECT + +public: + + QNetworkManagerInterface(QObject *parent = 0); + ~QNetworkManagerInterface(); + + QList <QDBusObjectPath> getDevices() const; + void activateConnection(const QString &serviceName, QDBusObjectPath connection, QDBusObjectPath device, QDBusObjectPath specificObject); + void deactivateConnection(QDBusObjectPath connectionPath) const; + + QDBusObjectPath path() const; + QDBusInterface *connectionInterface() const; + + bool wirelessEnabled() const; + bool wirelessHardwareEnabled() const; + QList <QDBusObjectPath> activeConnections() const; + quint32 state(); + bool setConnections(); + bool isValid(); + +Q_SIGNALS: + void deviceAdded(QDBusObjectPath); + void deviceRemoved(QDBusObjectPath); + void propertiesChanged( const QString &, QMap<QString,QVariant>); + void stateChanged(const QString&, quint32); + void activationFinished(QDBusPendingCallWatcher*); + +private Q_SLOTS: +private: +// Q_DISABLE_COPY(QNetworkManagerInterface); ?? + QNetworkManagerInterfacePrivate *d; + QNmDBusHelper *nmDBusHelper; +}; //end QNetworkManagerInterface + +//////// +class QNetworkManagerInterfaceAccessPointPrivate; +class QNetworkManagerInterfaceAccessPoint : public QObject +{ + Q_OBJECT + +public: + + // NM_DEVICE_STATE + enum DeviceState { + Unknown = 0, + Unmanaged, + Unavailable, + Disconnected, + Prepare, + Config, + NeedAuthentication, + IpConfig, + Activated, + Failed + }; + + enum ApFlag { + ApNone = 0x0, + Privacy = 0x1 + }; + + Q_DECLARE_FLAGS(ApFlags, ApFlag); + + enum ApSecurityFlag { + ApSecurityNone = 0x0, + PairWep40 = 0x1, + PairWep104 = 0x2, + PairTkip = 0x4, + PairCcmp = 0x8, + GroupWep40 = 0x10, + GroupWep104 = 0x20, + GroupTkip = 0x40, + GroupCcmp = 0x80, + KeyPsk = 0x100, + Key8021x = 0x200 + }; + + Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag); + + QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = 0); + ~QNetworkManagerInterfaceAccessPoint(); + + QDBusInterface *connectionInterface() const; + + quint32 flags() const; + quint32 wpaFlags() const; + quint32 rsnFlags() const; + QString ssid() const; + quint32 frequency() const; + QString hwAddress() const; + quint32 mode() const; + quint32 maxBitrate() const; + quint32 strength() const; + bool setConnections(); + bool isValid(); + +Q_SIGNALS: + void propertiesChanged(QMap <QString,QVariant>); + void propertiesChanged( const QString &, QMap<QString,QVariant>); +private: + QNetworkManagerInterfaceAccessPointPrivate *d; + QNmDBusHelper *nmDBusHelper; + +}; //end QNetworkManagerInterfaceAccessPoint + +//////// +class QNetworkManagerInterfaceDevicePrivate; +class QNetworkManagerInterfaceDevice : public QObject +{ + Q_OBJECT + +public: + + QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent = 0); + ~QNetworkManagerInterfaceDevice(); + + QString udi() const; + QNetworkInterface interface() const; + QDBusInterface *connectionInterface() const; + quint32 ip4Address() const; + quint32 state() const; + quint32 deviceType() const; + + QDBusObjectPath ip4config() const; + bool setConnections(); + bool isValid(); + +Q_SIGNALS: + void stateChanged(const QString &, quint32); + +private: + QNetworkManagerInterfaceDevicePrivate *d; + QNmDBusHelper *nmDBusHelper; +}; //end QNetworkManagerInterfaceDevice + +//////// +class QNetworkManagerInterfaceDeviceWiredPrivate; +class QNetworkManagerInterfaceDeviceWired : public QObject +{ + Q_OBJECT + +public: + + QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, QObject *parent = 0); + ~QNetworkManagerInterfaceDeviceWired(); + + QDBusInterface *connectionInterface() const; + QString hwAddress() const; + quint32 speed() const; + bool carrier() const; + bool setConnections(); + bool isValid(); + +Q_SIGNALS: + void propertiesChanged( const QString &, QMap<QString,QVariant>); +private: + QNetworkManagerInterfaceDeviceWiredPrivate *d; + QNmDBusHelper *nmDBusHelper; +}; // end QNetworkManagerInterfaceDeviceWired + +//// +class QNetworkManagerInterfaceDeviceWirelessPrivate; +class QNetworkManagerInterfaceDeviceWireless : public QObject +{ + Q_OBJECT + +public: + + enum DeviceCapability { + None = 0x0, + Wep40 = 0x1, + Wep104 = 0x2, + Tkip = 0x4, + Ccmp = 0x8, + Wpa = 0x10, + Rsn = 0x20 + }; + + QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, QObject *parent = 0); + ~QNetworkManagerInterfaceDeviceWireless(); + + QDBusObjectPath path() const; + QList <QDBusObjectPath> getAccessPoints(); + QDBusInterface *connectionInterface() const; + + QString hwAddress() const; + quint32 mode() const; + quint32 bitrate() const; + QDBusObjectPath activeAccessPoint() const; + quint32 wirelessCapabilities() const; + bool setConnections(); + bool isValid(); + +Q_SIGNALS: + void propertiesChanged( const QString &, QMap<QString,QVariant>); + void accessPointAdded(const QString &,QDBusObjectPath); + void accessPointRemoved(const QString &,QDBusObjectPath); +private: + QNetworkManagerInterfaceDeviceWirelessPrivate *d; + QNmDBusHelper *nmDBusHelper; +}; // end QNetworkManagerInterfaceDeviceWireless + +//// +class QNetworkManagerSettingsPrivate; +class QNetworkManagerSettings : public QObject +{ + Q_OBJECT + +public: + + QNetworkManagerSettings(const QString &settingsService, QObject *parent = 0); + ~QNetworkManagerSettings(); + + QDBusInterface *connectionInterface() const; + QList <QDBusObjectPath> listConnections(); + bool setConnections(); + bool isValid(); + +Q_SIGNALS: + void newConnection(QDBusObjectPath); +private: + QNetworkManagerSettingsPrivate *d; +}; //end QNetworkManagerSettings + +//// +class QNetworkManagerSettingsConnectionPrivate; +class QNetworkManagerSettingsConnection : public QObject +{ + Q_OBJECT + +public: + + QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent = 0); + ~QNetworkManagerSettingsConnection(); + + QDBusInterface *connectionInterface() const; + QNmSettingsMap getSettings(); + // void update(QNmSettingsMap map); + bool setConnections(); + NMDeviceType getType(); + bool isAutoConnect(); + quint64 getTimestamp(); + QString getId(); + QString getUuid(); + QString getSsid(); + QString getMacAddress(); + QStringList getSeenBssids(); + bool isValid(); + +Q_SIGNALS: + + void updated(const QNmSettingsMap &settings); + void removed(const QString &path); + +private: + QNmDBusHelper *nmDBusHelper; + QNetworkManagerSettingsConnectionPrivate *d; +}; //end QNetworkManagerSettingsConnection + +//// +class QNetworkManagerConnectionActivePrivate; +class QNetworkManagerConnectionActive : public QObject +{ + Q_OBJECT + +public: + + enum ActiveConnectionState { + Unknown = 0, + Activating = 1, + Activated = 2 + }; + + QNetworkManagerConnectionActive(const QString &dbusPathName, QObject *parent = 0); + ~ QNetworkManagerConnectionActive(); + + QDBusInterface *connectionInterface() const; + QString serviceName() const; + QDBusObjectPath connection() const; + QDBusObjectPath specificObject() const; + QList<QDBusObjectPath> devices() const; + quint32 state() const; + bool defaultRoute() const; + bool setConnections(); + bool isValid(); + + +Q_SIGNALS: + void propertiesChanged(QList<QDBusObjectPath>); + void propertiesChanged( const QString &, QMap<QString,QVariant>); +private: + QNetworkManagerConnectionActivePrivate *d; + QNmDBusHelper *nmDBusHelper; +}; //QNetworkManagerConnectionActive + +//// +class QNetworkManagerIp4ConfigPrivate; +class QNetworkManagerIp4Config : public QObject +{ + Q_OBJECT + +public: + QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = 0); + ~QNetworkManagerIp4Config(); + + // QList<quint32> nameservers(); + QStringList domains() const; + bool isValid(); + + private: + QNetworkManagerIp4ConfigPrivate *d; +}; +//// + +QT_END_NAMESPACE + +#endif //QNETWORKMANAGERSERVICE_H diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.cpp b/src/plugins/bearer/networkmanager/qnmdbushelper.cpp new file mode 100644 index 0000000..d5e20f3 --- /dev/null +++ b/src/plugins/bearer/networkmanager/qnmdbushelper.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// this class is for helping qdbus get stuff + +#include "qnmdbushelper.h" + +#include <NetworkManager/NetworkManager.h> + +#include <QDBusError> +#include <QDBusInterface> +#include <QDBusMessage> +#include <QDBusReply> + +#include <QDebug> + +QT_BEGIN_NAMESPACE + +void QNmDBusHelper::deviceStateChanged(quint32 state) + { + QDBusMessage msg = this->message(); + if(state == NM_DEVICE_STATE_ACTIVATED + || state == NM_DEVICE_STATE_DISCONNECTED + || state == NM_DEVICE_STATE_UNAVAILABLE + || state == NM_DEVICE_STATE_FAILED) { + emit pathForStateChanged(msg.path(), state); + } + } + +void QNmDBusHelper::slotAccessPointAdded(QDBusObjectPath path) +{ + if(path.path().length() > 2) { + QDBusMessage msg = this->message(); + emit pathForAccessPointAdded(msg.path(), path); + } +} + +void QNmDBusHelper::slotAccessPointRemoved(QDBusObjectPath path) +{ + if(path.path().length() > 2) { + QDBusMessage msg = this->message(); + emit pathForAccessPointRemoved(msg.path(), path); + } +} + +void QNmDBusHelper::slotPropertiesChanged(QMap<QString,QVariant> map) +{ + QDBusMessage msg = this->message(); + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + if( i.key() == "State") { //state only applies to device interfaces + quint32 state = i.value().toUInt(); + 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); + } + } else if( i.key() == "ActiveAccessPoint") { + emit pathForPropertiesChanged(msg.path(), map); + // qWarning() << __PRETTY_FUNCTION__ << i.key() << ": " << i.value().value<QDBusObjectPath>().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") { + emit pathForPropertiesChanged(msg.path(), map); + } + } +} + +void QNmDBusHelper::slotSettingsRemoved() +{ + QDBusMessage msg = this->message(); + emit pathForSettingsRemoved(msg.path()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.h b/src/plugins/bearer/networkmanager/qnmdbushelper.h new file mode 100644 index 0000000..862290c --- /dev/null +++ b/src/plugins/bearer/networkmanager/qnmdbushelper.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNMDBUSHELPERPRIVATE_H +#define QNMDBUSHELPERPRIVATE_H + +#include <QDBusObjectPath> +#include <QDBusContext> +#include <QMap> + +QT_BEGIN_NAMESPACE + +class QNmDBusHelper: public QObject, protected QDBusContext + { + Q_OBJECT + public: + + public slots: + void deviceStateChanged(quint32); + void slotAccessPointAdded( QDBusObjectPath ); + void slotAccessPointRemoved( QDBusObjectPath ); + void slotPropertiesChanged( QMap<QString,QVariant>); + void slotSettingsRemoved(); + +Q_SIGNALS: + void pathForStateChanged(const QString &, quint32); + void pathForAccessPointAdded(const QString &, QDBusObjectPath ); + void pathForAccessPointRemoved(const QString &, QDBusObjectPath ); + void pathForPropertiesChanged(const QString &, QMap<QString,QVariant>); + void pathForSettingsRemoved(const QString &); +}; + +QT_END_NAMESPACE + +#endif// QNMDBUSHELPERPRIVATE_H diff --git a/src/plugins/bearer/nla/main.cpp b/src/plugins/bearer/nla/main.cpp new file mode 100644 index 0000000..479a933 --- /dev/null +++ b/src/plugins/bearer/nla/main.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnlaengine.h" + +#include <QtNetwork/private/qbearerplugin_p.h> + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QNlaEnginePlugin : public QBearerEnginePlugin +{ +public: + QNlaEnginePlugin(); + ~QNlaEnginePlugin(); + + QStringList keys() const; + QBearerEngine *create(const QString &key) const; +}; + +QNlaEnginePlugin::QNlaEnginePlugin() +{ +} + +QNlaEnginePlugin::~QNlaEnginePlugin() +{ +} + +QStringList QNlaEnginePlugin::keys() const +{ + return QStringList() << QLatin1String("nla"); +} + +QBearerEngine *QNlaEnginePlugin::create(const QString &key) const +{ + if (key == QLatin1String("nla")) + return new QNlaEngine; + else + return 0; +} + +Q_EXPORT_STATIC_PLUGIN(QNlaEnginePlugin) +Q_EXPORT_PLUGIN2(qnlabearer, QNlaEnginePlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/nla/nla.pro b/src/plugins/bearer/nla/nla.pro new file mode 100644 index 0000000..5ba171e --- /dev/null +++ b/src/plugins/bearer/nla/nla.pro @@ -0,0 +1,23 @@ +TARGET = qnlabearer +include(../../qpluginbase.pri) + +QT += network + +!wince* { + LIBS += -lWs2_32 +} else { + LIBS += -lWs2 +} + +HEADERS += qnlaengine.h \ + ../platformdefs_win.h \ + ../qnetworksession_impl.h \ + ../qbeaerengine_impl.h + +SOURCES += main.cpp \ + qnlaengine.cpp \ + ../qnetworksession_impl.cpp + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer +target.path += $$[QT_INSTALL_PLUGINS]/bearer +INSTALLS += target diff --git a/src/plugins/bearer/nla/qnlaengine.cpp b/src/plugins/bearer/nla/qnlaengine.cpp new file mode 100644 index 0000000..2001c0b --- /dev/null +++ b/src/plugins/bearer/nla/qnlaengine.cpp @@ -0,0 +1,651 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnlaengine.h" +#include "../qnetworksession_impl.h" + +#include <QtNetwork/private/qnetworkconfiguration_p.h> + +#include <QtCore/qthread.h> +#include <QtCore/qmutex.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qstringlist.h> + +#include <QtCore/qdebug.h> + +#include "../platformdefs_win.h" + +QT_BEGIN_NAMESPACE + +QWindowsSockInit2::QWindowsSockInit2() +: version(0) +{ + //### should we try for 2.2 on all platforms ?? + WSAData wsadata; + + // IPv6 requires Winsock v2.0 or better. + if (WSAStartup(MAKEWORD(2,0), &wsadata) != 0) { + qWarning("QBearerManagementAPI: WinSock v2.0 initialization failed."); + } else { + version = 0x20; + } +} + +QWindowsSockInit2::~QWindowsSockInit2() +{ + WSACleanup(); +} + +#ifdef BEARER_MANAGEMENT_DEBUG +static void printBlob(NLA_BLOB *blob) +{ + qDebug() << "==== BEGIN NLA_BLOB ===="; + + qDebug() << "type:" << blob->header.type; + qDebug() << "size:" << blob->header.dwSize; + qDebug() << "next offset:" << blob->header.nextOffset; + + switch (blob->header.type) { + case NLA_RAW_DATA: + qDebug() << "Raw Data"; + qDebug() << '\t' << blob->data.rawData; + break; + case NLA_INTERFACE: + qDebug() << "Interface"; + qDebug() << "\ttype:" << blob->data.interfaceData.dwType; + qDebug() << "\tspeed:" << blob->data.interfaceData.dwSpeed; + qDebug() << "\tadapter:" << blob->data.interfaceData.adapterName; + break; + case NLA_802_1X_LOCATION: + qDebug() << "802.1x Location"; + qDebug() << '\t' << blob->data.locationData.information; + break; + case NLA_CONNECTIVITY: + qDebug() << "Connectivity"; + qDebug() << "\ttype:" << blob->data.connectivity.type; + qDebug() << "\tinternet:" << blob->data.connectivity.internet; + break; + case NLA_ICS: + qDebug() << "ICS"; + qDebug() << "\tspeed:" << blob->data.ICS.remote.speed; + qDebug() << "\ttype:" << blob->data.ICS.remote.type; + qDebug() << "\tstate:" << blob->data.ICS.remote.state; + qDebug() << "\tmachine name:" << blob->data.ICS.remote.machineName; + qDebug() << "\tshared adapter name:" << blob->data.ICS.remote.sharedAdapterName; + break; + default: + qDebug() << "UNKNOWN BLOB TYPE"; + } + + qDebug() << "===== END NLA_BLOB ====="; +} +#endif + +static QString qGetInterfaceType(const QString &interface) +{ +#ifdef Q_OS_WINCE + Q_UNUSED(interface) +#else + unsigned long oid; + DWORD bytesWritten; + + NDIS_MEDIUM medium; + NDIS_PHYSICAL_MEDIUM physicalMedium; + + HANDLE handle = CreateFile((TCHAR *)QString(QLatin1String("\\\\.\\%1")).arg(interface).utf16(), + 0, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if (handle == INVALID_HANDLE_VALUE) + return QLatin1String("Unknown"); + + oid = OID_GEN_MEDIA_SUPPORTED; + bytesWritten = 0; + bool result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid), + &medium, sizeof(medium), &bytesWritten, 0); + if (!result) { + CloseHandle(handle); + return QLatin1String("Unknown"); + } + + oid = OID_GEN_PHYSICAL_MEDIUM; + bytesWritten = 0; + result = DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof(oid), + &physicalMedium, sizeof(physicalMedium), &bytesWritten, 0); + if (!result) { + CloseHandle(handle); + + if (medium == NdisMedium802_3) + return QLatin1String("Ethernet"); + else + return QLatin1String("Unknown"); + } + + CloseHandle(handle); + + if (medium == NdisMedium802_3) { + switch (physicalMedium) { + case NdisPhysicalMediumWirelessLan: + return QLatin1String("WLAN"); + case NdisPhysicalMediumBluetooth: + return QLatin1String("Bluetooth"); + case NdisPhysicalMediumWiMax: + return QLatin1String("WiMAX"); + default: +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "Physical Medium" << physicalMedium; +#endif + return QLatin1String("Ethernet"); + } + } + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << medium << physicalMedium; +#endif + +#endif + + return QLatin1String("Unknown"); +} + +class QNlaThread : public QThread +{ + Q_OBJECT + +public: + QNlaThread(QNlaEngine *parent = 0); + ~QNlaThread(); + + QList<QNetworkConfigurationPrivate *> getConfigurations(); + + void forceUpdate(); + +protected: + virtual void run(); + +private: + void updateConfigurations(QList<QNetworkConfigurationPrivate *> &configs); + DWORD parseBlob(NLA_BLOB *blob, QNetworkConfigurationPrivate *cpPriv) const; + QNetworkConfigurationPrivate *parseQuerySet(const WSAQUERYSET *querySet) const; + void fetchConfigurations(); + +signals: + void networksChanged(); + +private: + QMutex mutex; + HANDLE handle; + bool done; + QList<QNetworkConfigurationPrivate *> fetchedConfigurations; +}; + +QNlaThread::QNlaThread(QNlaEngine *parent) +: QThread(parent), handle(0), done(false) +{ +} + +QNlaThread::~QNlaThread() +{ + mutex.lock(); + + done = true; + + if (handle) { + /* cancel completion event */ + if (WSALookupServiceEnd(handle) == SOCKET_ERROR) + qWarning("WSALookupServiceEnd error %d", WSAGetLastError()); + } + mutex.unlock(); + + wait(); +} + +QList<QNetworkConfigurationPrivate *> QNlaThread::getConfigurations() +{ + QMutexLocker locker(&mutex); + + QList<QNetworkConfigurationPrivate *> foundConfigurations = fetchedConfigurations; + fetchedConfigurations.clear(); + + return foundConfigurations; +} + +void QNlaThread::forceUpdate() +{ + mutex.lock(); + + if (handle) { + /* cancel completion event */ + if (WSALookupServiceEnd(handle) == SOCKET_ERROR) + qWarning("WSALookupServiceEnd error %d", WSAGetLastError()); + handle = 0; + } + mutex.unlock(); +} + +void QNlaThread::run() +{ + WSAEVENT changeEvent = WSACreateEvent(); + if (changeEvent == WSA_INVALID_EVENT) { + qWarning("WSACreateEvent error %d", WSAGetLastError()); + return; + } + + while (true) { + fetchConfigurations(); + + WSAQUERYSET qsRestrictions; + + memset(&qsRestrictions, 0, sizeof(qsRestrictions)); + qsRestrictions.dwSize = sizeof(qsRestrictions); + qsRestrictions.dwNameSpace = NS_NLA; + + mutex.lock(); + if (done) { + mutex.unlock(); + break; + } + int result = WSALookupServiceBegin(&qsRestrictions, LUP_RETURN_ALL, &handle); + mutex.unlock(); + + if (result == SOCKET_ERROR) { + qWarning("%s: WSALookupServiceBegin error %d", __FUNCTION__, WSAGetLastError()); + break; + } + + WSACOMPLETION completion; + WSAOVERLAPPED overlapped; + + memset(&overlapped, 0, sizeof(overlapped)); + overlapped.hEvent = changeEvent; + + memset(&completion, 0, sizeof(completion)); + completion.Type = NSP_NOTIFY_EVENT; + completion.Parameters.Event.lpOverlapped = &overlapped; + + DWORD bytesReturned = 0; + result = WSANSPIoctl(handle, SIO_NSP_NOTIFY_CHANGE, 0, 0, 0, 0, + &bytesReturned, &completion); + if (result == SOCKET_ERROR) { + int error = WSAGetLastError(); + if (error != WSA_IO_PENDING) { + qWarning("WSANSPIoctl error %d", error); + break; + } + } + +#ifndef Q_OS_WINCE + // Not interested in unrelated IO completion events + // although we also don't want to block them + while (WaitForSingleObjectEx(changeEvent, WSA_INFINITE, true) != WAIT_IO_COMPLETION && + handle) + { + } +#else + WaitForSingleObject(changeEvent, WSA_INFINITE); +#endif + + mutex.lock(); + if (handle) { + result = WSALookupServiceEnd(handle); + if (result == SOCKET_ERROR) { + qWarning("WSALookupServiceEnd error %d", WSAGetLastError()); + mutex.unlock(); + break; + } + handle = 0; + } + mutex.unlock(); + } + + WSACloseEvent(changeEvent); +} + +void QNlaThread::updateConfigurations(QList<QNetworkConfigurationPrivate *> &configs) +{ + mutex.lock(); + + while (!fetchedConfigurations.isEmpty()) + delete fetchedConfigurations.takeFirst(); + + fetchedConfigurations = configs; + + mutex.unlock(); + + emit networksChanged(); +} + +DWORD QNlaThread::parseBlob(NLA_BLOB *blob, QNetworkConfigurationPrivate *cpPriv) const +{ +#ifdef BEARER_MANAGEMENT_DEBUG + printBlob(blob); +#endif + + switch (blob->header.type) { + case NLA_RAW_DATA: +#ifdef BEARER_MANAGEMENT_DEBUG + qWarning("%s: unhandled header type NLA_RAW_DATA", __FUNCTION__); +#endif + break; + case NLA_INTERFACE: + cpPriv->state = QNetworkConfiguration::Active; + if (QNlaEngine *engine = qobject_cast<QNlaEngine *>(parent())) { + engine->configurationInterface[cpPriv->id.toUInt()] = + QString::fromLatin1(blob->data.interfaceData.adapterName); + } + break; + case NLA_802_1X_LOCATION: +#ifdef BEARER_MANAGEMENT_DEBUG + qWarning("%s: unhandled header type NLA_802_1X_LOCATION", __FUNCTION__); +#endif + break; + case NLA_CONNECTIVITY: + if (blob->data.connectivity.internet == NLA_INTERNET_YES) + cpPriv->internet = true; + else + cpPriv->internet = false; +#ifdef BEARER_MANAGEMENT_DEBUG + qWarning("%s: unhandled header type NLA_CONNECTIVITY", __FUNCTION__); +#endif + break; + case NLA_ICS: +#ifdef BEARER_MANAGEMENT_DEBUG + qWarning("%s: unhandled header type NLA_ICS", __FUNCTION__); +#endif + break; + default: +#ifdef BEARER_MANAGEMENT_DEBUG + qWarning("%s: unhandled header type %d", __FUNCTION__, blob->header.type); +#endif + ; + } + + return blob->header.nextOffset; +} + +QNetworkConfigurationPrivate *QNlaThread::parseQuerySet(const WSAQUERYSET *querySet) const +{ + QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate; + + cpPriv->name = QString::fromWCharArray(querySet->lpszServiceInstanceName); + cpPriv->isValid = true; + cpPriv->id = QString::number(qHash(QLatin1String("NLA:") + cpPriv->name)); + cpPriv->state = QNetworkConfiguration::Defined; + cpPriv->type = QNetworkConfiguration::InternetAccessPoint; + +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "size:" << querySet->dwSize; + qDebug() << "service instance name:" << QString::fromUtf16(querySet->lpszServiceInstanceName); + qDebug() << "service class id:" << querySet->lpServiceClassId; + qDebug() << "version:" << querySet->lpVersion; + qDebug() << "comment:" << QString::fromUtf16(querySet->lpszComment); + qDebug() << "namespace:" << querySet->dwNameSpace; + qDebug() << "namespace provider id:" << querySet->lpNSProviderId; + qDebug() << "context:" << QString::fromUtf16(querySet->lpszContext); + qDebug() << "number of protocols:" << querySet->dwNumberOfProtocols; + qDebug() << "protocols:" << querySet->lpafpProtocols; + qDebug() << "query string:" << QString::fromUtf16(querySet->lpszQueryString); + qDebug() << "number of cs addresses:" << querySet->dwNumberOfCsAddrs; + qDebug() << "cs addresses:" << querySet->lpcsaBuffer; + qDebug() << "output flags:" << querySet->dwOutputFlags; +#endif + + if (querySet->lpBlob) { +#ifdef BEARER_MANAGEMENT_DEBUG + qDebug() << "blob size:" << querySet->lpBlob->cbSize; + qDebug() << "blob data:" << querySet->lpBlob->pBlobData; +#endif + + DWORD offset = 0; + do { + NLA_BLOB *blob = reinterpret_cast<NLA_BLOB *>(querySet->lpBlob->pBlobData + offset); + DWORD nextOffset = parseBlob(blob, cpPriv); + if (nextOffset == offset) + break; + else + offset = nextOffset; + } while (offset != 0 && offset < querySet->lpBlob->cbSize); + } + + if (QNlaEngine *engine = qobject_cast<QNlaEngine *>(parent())) + cpPriv->bearer = engine->bearerName(cpPriv->id); + + return cpPriv; +} + +void QNlaThread::fetchConfigurations() +{ + QList<QNetworkConfigurationPrivate *> foundConfigurations; + + WSAQUERYSET qsRestrictions; + HANDLE hLookup = 0; + + memset(&qsRestrictions, 0, sizeof(qsRestrictions)); + qsRestrictions.dwSize = sizeof(qsRestrictions); + qsRestrictions.dwNameSpace = NS_NLA; + + int result = WSALookupServiceBegin(&qsRestrictions, LUP_RETURN_ALL | LUP_DEEP, &hLookup); + if (result == SOCKET_ERROR) { + qWarning("%s: WSALookupServiceBegin error %d", __FUNCTION__, WSAGetLastError()); + mutex.lock(); + fetchedConfigurations.clear(); + mutex.unlock(); + } + + char buffer[0x10000]; + while (result == 0) { + DWORD bufferLength = sizeof(buffer); + result = WSALookupServiceNext(hLookup, LUP_RETURN_ALL, + &bufferLength, reinterpret_cast<WSAQUERYSET *>(buffer)); + + if (result == SOCKET_ERROR) { + int error = WSAGetLastError(); + + if (error == WSA_E_NO_MORE) + break; + + if (error == WSAEFAULT) + break; + + qWarning("WSALookupServiceNext error %d", WSAGetLastError()); + break; + } + + QNetworkConfigurationPrivate *cpPriv = + parseQuerySet(reinterpret_cast<WSAQUERYSET *>(buffer)); + + foundConfigurations.append(cpPriv); + } + + if (hLookup) { + result = WSALookupServiceEnd(hLookup); + if (result == SOCKET_ERROR) { + qWarning("WSALookupServiceEnd error %d", WSAGetLastError()); + } + } + + updateConfigurations(foundConfigurations); +} + +QNlaEngine::QNlaEngine(QObject *parent) +: QBearerEngineImpl(parent), nlaThread(0) +{ + nlaThread = new QNlaThread(this); + connect(nlaThread, SIGNAL(networksChanged()), + this, SLOT(networksChanged())); + nlaThread->start(); + + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); +} + +QNlaEngine::~QNlaEngine() +{ + delete nlaThread; +} + +void QNlaEngine::networksChanged() +{ + QStringList previous = accessPointConfigurations.keys(); + + QList<QNetworkConfigurationPrivate *> foundConfigurations = nlaThread->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; + + if (ptr->isValid != cpPriv->isValid) { + ptr->isValid = cpPriv->isValid; + changed = true; + } + + if (ptr->name != cpPriv->name) { + ptr->name = cpPriv->name; + changed = true; + } + + if (ptr->state != cpPriv->state) { + ptr->state = cpPriv->state; + changed = true; + } + + if (changed) + emit configurationChanged(ptr); + + delete cpPriv; + } else { + QNetworkConfigurationPrivatePointer ptr(cpPriv); + + accessPointConfigurations.insert(ptr->id, ptr); + + emit configurationAdded(ptr); + } + } + + while (!previous.isEmpty()) { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.take(previous.takeFirst()); + + emit configurationRemoved(ptr); + } + + emit updateCompleted(); +} + +QString QNlaEngine::getInterfaceFromId(const QString &id) +{ + return configurationInterface.value(id.toUInt()); +} + +bool QNlaEngine::hasIdentifier(const QString &id) +{ + return configurationInterface.contains(id.toUInt()); +} + +QString QNlaEngine::bearerName(const QString &id) +{ + QString interface = getInterfaceFromId(id); + + if (interface.isEmpty()) + return QString(); + + return qGetInterfaceType(interface); +} + +void QNlaEngine::connectToId(const QString &id) +{ + emit connectionError(id, OperationNotSupported); +} + +void QNlaEngine::disconnectFromId(const QString &id) +{ + emit connectionError(id, OperationNotSupported); +} + +void QNlaEngine::requestUpdate() +{ + nlaThread->forceUpdate(); +} + +QNetworkSession::State QNlaEngine::sessionStateForId(const QString &id) +{ + 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 QNlaEngine::capabilities() const +{ + return QNetworkConfigurationManager::ForcedRoaming; +} + +QNetworkSessionPrivate *QNlaEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl; +} + +QNetworkConfigurationPrivatePointer QNlaEngine::defaultConfiguration() +{ + return QNetworkConfigurationPrivatePointer(); +} + +#include "qnlaengine.moc" +QT_END_NAMESPACE + diff --git a/src/plugins/bearer/nla/qnlaengine.h b/src/plugins/bearer/nla/qnlaengine.h new file mode 100644 index 0000000..14c5201 --- /dev/null +++ b/src/plugins/bearer/nla/qnlaengine.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNLAENGINE_P_H +#define QNLAENGINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "../qbearerengine_impl.h" + +#include <QtNetwork/private/qnativesocketengine_p.h> + +#include <QMap> + +QT_BEGIN_NAMESPACE + +class QNetworkConfigurationPrivate; +class QNlaThread; + +class QWindowsSockInit2 +{ +public: + QWindowsSockInit2(); + ~QWindowsSockInit2(); + int version; +}; + +class QNlaEngine : public QBearerEngineImpl +{ + Q_OBJECT + + friend class QNlaThread; + +public: + QNlaEngine(QObject *parent = 0); + ~QNlaEngine(); + + QString getInterfaceFromId(const QString &id); + bool hasIdentifier(const QString &id); + + QString bearerName(const QString &id); + + void connectToId(const QString &id); + void disconnectFromId(const QString &id); + + void requestUpdate(); + + QNetworkSession::State sessionStateForId(const QString &id); + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkSessionPrivate *createSessionBackend(); + + QNetworkConfigurationPrivatePointer defaultConfiguration(); + +private Q_SLOTS: + void networksChanged(); + +private: + QWindowsSockInit2 winSock; + QNlaThread *nlaThread; + QMap<uint, QString> configurationInterface; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/bearer/platformdefs_win.h b/src/plugins/bearer/platformdefs_win.h new file mode 100644 index 0000000..37d099c --- /dev/null +++ b/src/plugins/bearer/platformdefs_win.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMDEFS_WIN_H +#define QPLATFORMDEFS_WIN_H + +#include <winsock2.h> +#include <mswsock.h> +#undef interface +#include <winioctl.h> + +#ifndef NS_NLA + +#define NS_NLA 15 + +enum NLA_BLOB_DATA_TYPE { + NLA_RAW_DATA = 0, + NLA_INTERFACE = 1, + NLA_802_1X_LOCATION = 2, + NLA_CONNECTIVITY = 3, + NLA_ICS = 4 +}; + +enum NLA_CONNECTIVITY_TYPE { + NLA_NETWORK_AD_HOC = 0, + NLA_NETWORK_MANAGED = 1, + NLA_NETWORK_UNMANAGED = 2, + NLA_NETWORK_UNKNOWN = 3 +}; + +enum NLA_INTERNET { + NLA_INTERNET_UNKNOWN = 0, + NLA_INTERNET_NO = 1, + NLA_INTERNET_YES = 2 +}; + +struct NLA_BLOB { + struct { + NLA_BLOB_DATA_TYPE type; + DWORD dwSize; + DWORD nextOffset; + } header; + + union { + // NLA_RAW_DATA + CHAR rawData[1]; + + // NLA_INTERFACE + struct { + DWORD dwType; + DWORD dwSpeed; + CHAR adapterName[1]; + } interfaceData; + + // NLA_802_1X_LOCATION + struct { + CHAR information[1]; + } locationData; + + // NLA_CONNECTIVITY + struct { + NLA_CONNECTIVITY_TYPE type; + NLA_INTERNET internet; + } connectivity; + + // NLA_ICS + struct { + struct { + DWORD speed; + DWORD type; + DWORD state; + WCHAR machineName[256]; + WCHAR sharedAdapterName[256]; + } remote; + } ICS; + } data; +}; +#endif + +enum NDIS_MEDIUM { + NdisMedium802_3 = 0, +}; + +enum NDIS_PHYSICAL_MEDIUM { + NdisPhysicalMediumWirelessLan = 1, + NdisPhysicalMediumBluetooth = 10, + NdisPhysicalMediumWiMax = 12, +}; + +#define OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 + +#define IOCTL_NDIS_QUERY_GLOBAL_STATS \ + CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, 0, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + +#endif diff --git a/src/plugins/bearer/qbearerengine_impl.h b/src/plugins/bearer/qbearerengine_impl.h new file mode 100644 index 0000000..740def3 --- /dev/null +++ b/src/plugins/bearer/qbearerengine_impl.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBEARERENGINE_IMPL_H +#define QBEARERENGINE_IMPL_H + +#include <QtNetwork/private/qbearerengine_p.h> + +QT_BEGIN_NAMESPACE + +class QBearerEngineImpl : public QBearerEngine +{ + Q_OBJECT + +public: + enum ConnectionError { + InterfaceLookupError = 0, + ConnectError, + OperationNotSupported, + DisconnectionError, + }; + + QBearerEngineImpl(QObject *parent = 0) : QBearerEngine(parent) { } + ~QBearerEngineImpl() { } + + virtual void connectToId(const QString &id) = 0; + virtual void disconnectFromId(const QString &id) = 0; + + virtual QString getInterfaceFromId(const QString &id) = 0; + + virtual QNetworkSession::State sessionStateForId(const QString &id) = 0; + + virtual quint64 bytesWritten(const QString &) { return Q_UINT64_C(0); } + virtual quint64 bytesReceived(const QString &) { return Q_UINT64_C(0); } + virtual quint64 startTime(const QString &) { return Q_UINT64_C(0); } + +Q_SIGNALS: + void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp new file mode 100644 index 0000000..3fe844a --- /dev/null +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -0,0 +1,408 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworksession_impl.h" +#include "qbearerengine_impl.h" + +#include <QtNetwork/qnetworksession.h> +#include <QtNetwork/private/qnetworkconfigmanager_p.h> + +#include <QtCore/qstringlist.h> +#include <QtCore/qdebug.h> +#include <QtCore/qmutex.h> + +#include <QtNetwork/qnetworkinterface.h> + +QT_BEGIN_NAMESPACE + +static QBearerEngineImpl *getEngineFromId(const QString &id) +{ + QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); + + foreach (QBearerEngine *engine, priv->sessionEngines) { + QBearerEngineImpl *engineImpl = qobject_cast<QBearerEngineImpl *>(engine); + if (engineImpl && engineImpl->hasIdentifier(id)) + return engineImpl; + } + + return 0; +} + +class QNetworkSessionManagerPrivate : public QObject +{ + Q_OBJECT + +public: + QNetworkSessionManagerPrivate(QObject *parent = 0); + ~QNetworkSessionManagerPrivate(); + + void forceSessionClose(const QNetworkConfiguration &config); + +Q_SIGNALS: + void forcedSessionClose(const QNetworkConfiguration &config); +}; + +#include "qnetworksession_impl.moc" + +Q_GLOBAL_STATIC(QNetworkSessionManagerPrivate, sessionManager); + +QNetworkSessionManagerPrivate::QNetworkSessionManagerPrivate(QObject *parent) +: QObject(parent) +{ +} + +QNetworkSessionManagerPrivate::~QNetworkSessionManagerPrivate() +{ +} + +void QNetworkSessionManagerPrivate::forceSessionClose(const QNetworkConfiguration &config) +{ + emit forcedSessionClose(config); +} + +void QNetworkSessionPrivateImpl::syncStateWithInterface() +{ + connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged())); + connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)), + this, SLOT(configurationChanged(QNetworkConfiguration))); + connect(sessionManager(), SIGNAL(forcedSessionClose(QNetworkConfiguration)), + this, SLOT(forcedSessionClose(QNetworkConfiguration))); + + opened = false; + isOpen = false; + state = QNetworkSession::Invalid; + lastError = QNetworkSession::UnknownSessionError; + + qRegisterMetaType<QBearerEngineImpl::ConnectionError> + ("QBearerEngineImpl::ConnectionError"); + + switch (publicConfig.type()) { + case QNetworkConfiguration::InternetAccessPoint: + activeConfig = publicConfig; + engine = getEngineFromId(activeConfig.identifier()); + if (engine) { + connect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), + this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)), + Qt::QueuedConnection); + } + break; + case QNetworkConfiguration::ServiceNetwork: + serviceConfig = publicConfig; + // Defer setting engine and signals until open(). + // fall through + case QNetworkConfiguration::UserChoice: + // Defer setting serviceConfig and activeConfig until open(). + // fall through + default: + engine = 0; + } + + networkConfigurationsChanged(); +} + +void QNetworkSessionPrivateImpl::open() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else if (!isOpen) { + if ((activeConfig.state() & QNetworkConfiguration::Discovered) != + QNetworkConfiguration::Discovered) { + lastError =QNetworkSession::InvalidConfigurationError; + emit QNetworkSessionPrivate::error(lastError); + return; + } + opened = true; + + if ((activeConfig.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active && + (activeConfig.state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) { + state = QNetworkSession::Connecting; + emit stateChanged(state); + + engine->connectToId(activeConfig.identifier()); + } + + isOpen = (activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active; + if (isOpen) + emit quitPendingWaitsForOpened(); + } +} + +void QNetworkSessionPrivateImpl::close() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else if (isOpen) { + opened = false; + isOpen = false; + emit closed(); + } +} + +void QNetworkSessionPrivateImpl::stop() +{ + if (serviceConfig.isValid()) { + lastError = QNetworkSession::OperationNotSupportedError; + emit QNetworkSessionPrivate::error(lastError); + } else { + if ((activeConfig.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + state = QNetworkSession::Closing; + emit stateChanged(state); + + engine->disconnectFromId(activeConfig.identifier()); + + sessionManager()->forceSessionClose(activeConfig); + } + + opened = false; + isOpen = false; + emit closed(); + } +} + +void QNetworkSessionPrivateImpl::migrate() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + +void QNetworkSessionPrivateImpl::accept() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + +void QNetworkSessionPrivateImpl::ignore() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + +void QNetworkSessionPrivateImpl::reject() +{ + qWarning("This platform does not support roaming (%s).", __FUNCTION__); +} + +QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const +{ + if (!publicConfig.isValid() || !engine || state != QNetworkSession::Connected) + return QNetworkInterface(); + + QString interface = engine->getInterfaceFromId(activeConfig.identifier()); + + if (interface.isEmpty()) + return QNetworkInterface(); + return QNetworkInterface::interfaceFromName(interface); +} + +QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& /*key*/) const +{ + return QVariant(); +} + +void QNetworkSessionPrivateImpl::setSessionProperty(const QString& /*key*/, const QVariant& /*value*/) +{ +} + +QString QNetworkSessionPrivateImpl::errorString() const +{ + switch (lastError) { + case QNetworkSession::UnknownSessionError: + return tr("Unknown session error."); + case QNetworkSession::SessionAbortedError: + return tr("The session was aborted by the user or system."); + case QNetworkSession::OperationNotSupportedError: + return tr("The requested operation is not supported by the system."); + case QNetworkSession::InvalidConfigurationError: + return tr("The specified configuration cannot be used."); + case QNetworkSession::RoamingError: + return tr("Roaming was aborted or is not possible."); + + } + + return QString(); +} + +QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const +{ + return lastError; +} + +quint64 QNetworkSessionPrivateImpl::bytesWritten() const +{ + if (engine && state == QNetworkSession::Connected) + return engine->bytesWritten(activeConfig.identifier()); + else + return Q_UINT64_C(0); +} + +quint64 QNetworkSessionPrivateImpl::bytesReceived() const +{ + if (engine && state == QNetworkSession::Connected) + return engine->bytesReceived(activeConfig.identifier()); + else + return Q_UINT64_C(0); +} + +quint64 QNetworkSessionPrivateImpl::activeTime() const +{ + if (state == QNetworkSession::Connected && startTime != Q_UINT64_C(0)) + return QDateTime::currentDateTime().toTime_t() - startTime; + else + return Q_UINT64_C(0); +} + +void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork() +{ + QNetworkSession::State oldState = state; + + foreach (const QNetworkConfiguration &config, serviceConfig.children()) { + if ((config.state() & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) + continue; + + if (activeConfig != config) { + if (engine) { + disconnect(engine, + SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), + this, + SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError))); + } + + activeConfig = config; + engine = getEngineFromId(activeConfig.identifier()); + if (engine) { + connect(engine, + SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), + this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)), + Qt::QueuedConnection); + } + emit newConfigurationActivated(); + } + + state = QNetworkSession::Connected; + if (state != oldState) + emit stateChanged(state); + + return; + } + + if (serviceConfig.children().isEmpty()) + state = QNetworkSession::NotAvailable; + else + state = QNetworkSession::Disconnected; + + if (state != oldState) + emit stateChanged(state); +} + +void QNetworkSessionPrivateImpl::updateStateFromActiveConfig() +{ + if (!engine) + return; + + QNetworkSession::State oldState = state; + + state = engine->sessionStateForId(activeConfig.identifier()); + + bool oldActive = isOpen; + isOpen = (state == QNetworkSession::Connected) ? opened : false; + + if (!oldActive && isOpen) + emit quitPendingWaitsForOpened(); + if (oldActive && !isOpen) + emit closed(); + + if (oldState != state) + emit stateChanged(state); +} + +void QNetworkSessionPrivateImpl::networkConfigurationsChanged() +{ + if (serviceConfig.isValid()) + updateStateFromServiceNetwork(); + else + updateStateFromActiveConfig(); + + startTime = engine->startTime(activeConfig.identifier()); +} + +void QNetworkSessionPrivateImpl::configurationChanged(const QNetworkConfiguration &config) +{ + if (serviceConfig.isValid() && (config == serviceConfig || config == activeConfig)) + updateStateFromServiceNetwork(); + else if (config == activeConfig) + updateStateFromActiveConfig(); +} + +void QNetworkSessionPrivateImpl::forcedSessionClose(const QNetworkConfiguration &config) +{ + if (activeConfig == config) { + opened = false; + isOpen = false; + + emit closed(); + + lastError = QNetworkSession::SessionAbortedError; + emit QNetworkSessionPrivate::error(lastError); + } +} + +void QNetworkSessionPrivateImpl::connectionError(const QString &id, + QBearerEngineImpl::ConnectionError error) +{ + if (activeConfig.identifier() == id) { + networkConfigurationsChanged(); + switch (error) { + case QBearerEngineImpl::OperationNotSupported: + lastError = QNetworkSession::OperationNotSupportedError; + opened = false; + break; + case QBearerEngineImpl::InterfaceLookupError: + case QBearerEngineImpl::ConnectError: + case QBearerEngineImpl::DisconnectionError: + default: + lastError = QNetworkSession::UnknownSessionError; + } + + emit quitPendingWaitsForOpened(); + emit QNetworkSessionPrivate::error(lastError); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h new file mode 100644 index 0000000..7349e77 --- /dev/null +++ b/src/plugins/bearer/qnetworksession_impl.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKSESSION_IMPL_H +#define QNETWORKSESSION_IMPL_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qbearerengine_impl.h" + +#include <QtNetwork/private/qnetworkconfigmanager_p.h> +#include <QtNetwork/private/qnetworksession_p.h> + +#include <QtCore/qdatetime.h> + +QT_BEGIN_NAMESPACE + +class QBearerEngineImpl; + +class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate +{ + Q_OBJECT +public: + QNetworkSessionPrivateImpl() + : startTime(0) + { + } + + ~QNetworkSessionPrivateImpl() + { + } + + //called by QNetworkSession constructor and ensures + //that the state is immediately updated (w/o actually opening + //a session). Also this function should take care of + //notification hooks to discover future state changes. + void syncStateWithInterface(); + + QNetworkInterface currentInterface() const; + QVariant sessionProperty(const QString& key) const; + void setSessionProperty(const QString& key, const QVariant& value); + + void open(); + void close(); + void stop(); + void migrate(); + void accept(); + void ignore(); + void reject(); + + QString errorString() const; //must return translated string + QNetworkSession::SessionError error() const; + + quint64 bytesWritten() const; + quint64 bytesReceived() const; + quint64 activeTime() const; + +private: + void updateStateFromServiceNetwork(); + void updateStateFromActiveConfig(); + +private Q_SLOTS: + void networkConfigurationsChanged(); + void configurationChanged(const QNetworkConfiguration &config); + void forcedSessionClose(const QNetworkConfiguration &config); + void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error); + +private: + QNetworkConfigurationManager manager; + + bool opened; + + QBearerEngineImpl *engine; + + QNetworkSession::SessionError lastError; + + quint64 startTime; +}; + +QT_END_NAMESPACE + +#endif //QNETWORKSESSION_IMPL_H + diff --git a/src/plugins/bearer/symbian/main.cpp b/src/plugins/bearer/symbian/main.cpp new file mode 100644 index 0000000..0321451 --- /dev/null +++ b/src/plugins/bearer/symbian/main.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbianengine.h" + +#include <QtNetwork/private/qbearerplugin_p.h> + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QSymbianEnginePlugin : public QBearerEnginePlugin +{ +public: + QSymbianEnginePlugin(); + ~QSymbianEnginePlugin(); + + QStringList keys() const; + QBearerEngine *create(const QString &key) const; +}; + +QSymbianEnginePlugin::QSymbianEnginePlugin() +{ +} + +QSymbianEnginePlugin::~QSymbianEnginePlugin() +{ +} + +QStringList QSymbianEnginePlugin::keys() const +{ + return QStringList() << QLatin1String("symbian"); +} + +QBearerEngine *QSymbianEnginePlugin::create(const QString &key) const +{ + if (key == QLatin1String("symbian")) + return new SymbianEngine; + else + return 0; +} + +Q_EXPORT_STATIC_PLUGIN(QSymbianEnginePlugin) +Q_EXPORT_PLUGIN2(qsymbianbearer, QSymbianEnginePlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp new file mode 100644 index 0000000..7762fb5 --- /dev/null +++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp @@ -0,0 +1,1135 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnetworksession_impl.h" +#include "symbianengine.h" + +#include <es_enum.h> +#include <es_sock.h> +#include <in_sock.h> +#include <stdapis/sys/socket.h> +#include <stdapis/net/if.h> + +QT_BEGIN_NAMESPACE + +QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine) + : CActive(CActive::EPriorityStandard), engine(engine), ipConnectionNotifier(0), + iError(QNetworkSession::UnknownSessionError), + iALREnabled(0) +{ + CActiveScheduler::Add(this); + + // Try to load "Open C" dll dynamically and + // try to attach to setdefaultif function dynamically. + if (iOpenCLibrary.Load(_L("libc")) == KErrNone) { + iDynamicSetdefaultif = (TOpenCSetdefaultifFunction)iOpenCLibrary.Lookup(564); + } + + TRAP_IGNORE(iConnectionMonitor.ConnectL()); +} + +QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl() +{ + isOpen = false; + + // Cancel Connection Progress Notifications first. + // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start() + // => deleting ipConnectionNotifier results RConnection::CancelProgressNotification() + delete ipConnectionNotifier; + ipConnectionNotifier = NULL; + + // Cancel possible RConnection::Start() + Cancel(); + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + if (iMobility) { + delete iMobility; + iMobility = NULL; + } +#endif + + iConnection.Close(); + iSocketServ.Close(); + if (iDynamicSetdefaultif) { + iDynamicSetdefaultif(0); + } + + iConnectionMonitor.CancelNotifications(); + iConnectionMonitor.Close(); + + iOpenCLibrary.Close(); +} + +void QNetworkSessionPrivateImpl::syncStateWithInterface() +{ + if (!privateConfiguration(publicConfig)) + return; + + // Start monitoring changes in IAP states + TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this)); + + // Check open connections to see if there is already + // an open connection to selected IAP or SNAP + TUint count; + TRequestStatus status; + iConnectionMonitor.GetConnectionCount(count, status); + User::WaitForRequest(status); + if (status.Int() != KErrNone) { + return; + } + + TUint numSubConnections; + TUint connectionId; + for (TUint i = 1; i <= count; i++) { + TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections); + if (ret == KErrNone) { + TUint apId; + iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status); + User::WaitForRequest(status); + if (status.Int() == KErrNone) { + TInt connectionStatus; + iConnectionMonitor.GetIntAttribute(connectionId, 0, KConnectionStatus, connectionStatus, status); + User::WaitForRequest(status); + if (connectionStatus == KLinkLayerOpen) { + if (state != QNetworkSession::Closing) { + if (newState(QNetworkSession::Connected, apId)) { + return; + } + } + } + } + } + } + + if (state != QNetworkSession::Connected) { + // There were no open connections to used IAP or SNAP + if ((privateConfiguration(publicConfig)->state & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + newState(QNetworkSession::Disconnected); + } else { + newState(QNetworkSession::NotAvailable); + } + } +} + +QNetworkInterface QNetworkSessionPrivateImpl::interface(TUint iapId) const +{ + QString interfaceName; + + TSoInetInterfaceInfo ifinfo; + TPckg<TSoInetInterfaceInfo> ifinfopkg(ifinfo); + TSoInetIfQuery ifquery; + TPckg<TSoInetIfQuery> ifquerypkg(ifquery); + + // Open dummy socket for interface queries + RSocket socket; + TInt retVal = socket.Open(iSocketServ, _L("udp")); + if (retVal != KErrNone) { + return QNetworkInterface(); + } + + // Start enumerating interfaces + socket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); + while(socket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, ifinfopkg) == KErrNone) { + ifquery.iName = ifinfo.iName; + TInt err = socket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, ifquerypkg); + if(err == KErrNone && ifquery.iZone[1] == iapId) { // IAP ID is index 1 of iZone + if(ifinfo.iAddress.Address() > 0) { + interfaceName = QString::fromUtf16(ifinfo.iName.Ptr(),ifinfo.iName.Length()); + break; + } + } + } + + socket.Close(); + + if (interfaceName.isEmpty()) { + return QNetworkInterface(); + } + + return QNetworkInterface::interfaceFromName(interfaceName); +} + +QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const +{ + if (!publicConfig.isValid() || state != QNetworkSession::Connected) { + return QNetworkInterface(); + } + + return activeInterface; +} + +QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& /*key*/) const +{ + return QVariant(); +} + +void QNetworkSessionPrivateImpl::setSessionProperty(const QString& /*key*/, const QVariant& /*value*/) +{ +} + +QString QNetworkSessionPrivateImpl::errorString() const +{ + switch (iError) { + case QNetworkSession::UnknownSessionError: + return tr("Unknown session error."); + case QNetworkSession::SessionAbortedError: + return tr("The session was aborted by the user or system."); + case QNetworkSession::OperationNotSupportedError: + return tr("The requested operation is not supported by the system."); + case QNetworkSession::InvalidConfigurationError: + return tr("The specified configuration cannot be used."); + case QNetworkSession::RoamingError: + return tr("Roaming was aborted or is not possible."); + } + + return QString(); +} + +QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const +{ + return iError; +} + +void QNetworkSessionPrivateImpl::open() +{ + if (isOpen || !privateConfiguration(publicConfig) || (state == QNetworkSession::Connecting)) { + return; + } + + // Cancel notifications from RConnectionMonitor + // => RConnection::ProgressNotification will be used for IAP/SNAP monitoring + iConnectionMonitor.CancelNotifications(); + + TInt error = iSocketServ.Connect(); + if (error != KErrNone) { + // Could not open RSocketServ + newState(QNetworkSession::Invalid); + iError = QNetworkSession::UnknownSessionError; + emit QNetworkSessionPrivate::error(iError); + syncStateWithInterface(); + return; + } + + error = iConnection.Open(iSocketServ); + if (error != KErrNone) { + // Could not open RConnection + iSocketServ.Close(); + newState(QNetworkSession::Invalid); + iError = QNetworkSession::UnknownSessionError; + emit QNetworkSessionPrivate::error(iError); + syncStateWithInterface(); + return; + } + + // Use RConnection::ProgressNotification for IAP/SNAP monitoring + // (<=> ConnectionProgressNotifier uses RConnection::ProgressNotification) + if (!ipConnectionNotifier) { + ipConnectionNotifier = new ConnectionProgressNotifier(*this,iConnection); + } + if (ipConnectionNotifier) { + ipConnectionNotifier->StartNotifications(); + } + + if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { + // Search through existing connections. + // If there is already connection which matches to given IAP + // try to attach to existing connection. + TBool connected(EFalse); + TConnectionInfoBuf connInfo; + TUint count; + if (iConnection.EnumerateConnections(count) == KErrNone) { + for (TUint i=1; i<=count; i++) { + // Note: GetConnectionInfo expects 1-based index. + if (iConnection.GetConnectionInfo(i, connInfo) == KErrNone) { + if (connInfo().iIapId == toSymbianConfig(privateConfiguration(publicConfig))->numericId) { + if (iConnection.Attach(connInfo, RConnection::EAttachTypeNormal) == KErrNone) { + activeConfig = publicConfig; + activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId); + connected = ETrue; + startTime = QDateTime::currentDateTime(); + if (iDynamicSetdefaultif) { + // Use name of the IAP to set default IAP + QByteArray nameAsByteArray = publicConfig.name().toUtf8(); + ifreq ifr; + strcpy(ifr.ifr_name, nameAsByteArray.constData()); + + error = iDynamicSetdefaultif(&ifr); + } + isOpen = true; + // Make sure that state will be Connected + newState(QNetworkSession::Connected); + emit quitPendingWaitsForOpened(); + break; + } + } + } + } + } + if (!connected) { + TCommDbConnPref pref; + pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); + pref.SetIapId(toSymbianConfig(privateConfiguration(publicConfig))->numericId); + iConnection.Start(pref, iStatus); + if (!IsActive()) { + SetActive(); + } + newState(QNetworkSession::Connecting); + } + } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { + TConnSnapPref snapPref(toSymbianConfig(privateConfiguration(publicConfig))->numericId); + iConnection.Start(snapPref, iStatus); + if (!IsActive()) { + SetActive(); + } + newState(QNetworkSession::Connecting); + } else if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + iKnownConfigsBeforeConnectionStart = engine->accessPointConfigurations.keys(); + iConnection.Start(iStatus); + if (!IsActive()) { + SetActive(); + } + newState(QNetworkSession::Connecting); + } + + if (error != KErrNone) { + isOpen = false; + iError = QNetworkSession::UnknownSessionError; + emit QNetworkSessionPrivate::error(iError); + if (ipConnectionNotifier) { + ipConnectionNotifier->StopNotifications(); + } + syncStateWithInterface(); + } +} + +TUint QNetworkSessionPrivateImpl::iapClientCount(TUint aIAPId) const +{ + TRequestStatus status; + TUint connectionCount; + iConnectionMonitor.GetConnectionCount(connectionCount, status); + User::WaitForRequest(status); + if (status.Int() == KErrNone) { + for (TUint i = 1; i <= connectionCount; i++) { + TUint connectionId; + TUint subConnectionCount; + iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount); + TUint apId; + iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); + User::WaitForRequest(status); + if (apId == aIAPId) { + TConnMonClientEnumBuf buf; + iConnectionMonitor.GetPckgAttribute(connectionId, 0, KClientInfo, buf, status); + User::WaitForRequest(status); + if (status.Int() == KErrNone) { + return buf().iCount; + } + } + } + } + return 0; +} + +void QNetworkSessionPrivateImpl::close(bool allowSignals) +{ + if (!isOpen) { + return; + } + + TUint activeIap = toSymbianConfig(privateConfiguration(activeConfig))->numericId; + isOpen = false; + activeConfig = QNetworkConfiguration(); + serviceConfig = QNetworkConfiguration(); + + Cancel(); +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + if (iMobility) { + delete iMobility; + iMobility = NULL; + } +#endif + + if (ipConnectionNotifier) { + ipConnectionNotifier->StopNotifications(); + } + + iConnection.Close(); + iSocketServ.Close(); + if (iDynamicSetdefaultif) { + iDynamicSetdefaultif(0); + } + +#ifdef Q_CC_NOKIAX86 + if ((allowSignals && iapClientCount(activeIap) <= 0) || +#else + if ((allowSignals && iapClientCount(activeIap) <= 1) || +#endif + (publicConfig.type() == QNetworkConfiguration::UserChoice)) { + newState(QNetworkSession::Closing); + } + + syncStateWithInterface(); + if (allowSignals) { + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + newState(QNetworkSession::Disconnected); + } + emit closed(); + } +} + +void QNetworkSessionPrivateImpl::stop() +{ + if (!isOpen) { + return; + } + isOpen = false; + newState(QNetworkSession::Closing); + iConnection.Stop(RConnection::EStopAuthoritative); + isOpen = true; + close(false); + emit closed(); +} + +void QNetworkSessionPrivateImpl::migrate() +{ +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + iMobility->MigrateToPreferredCarrier(); +#endif +} + +void QNetworkSessionPrivateImpl::ignore() +{ +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + iMobility->IgnorePreferredCarrier(); + if (!iALRUpgradingConnection) { + newState(QNetworkSession::Disconnected); + } else { + newState(QNetworkSession::Connected,iOldRoamingIap); + } +#endif +} + +void QNetworkSessionPrivateImpl::accept() +{ +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + iMobility->NewCarrierAccepted(); + if (iDynamicSetdefaultif) { + // Use name of the IAP to set default IAP + QByteArray nameAsByteArray = activeConfig.name().toUtf8(); + ifreq ifr; + strcpy(ifr.ifr_name, nameAsByteArray.constData()); + + iDynamicSetdefaultif(&ifr); + } + newState(QNetworkSession::Connected, iNewRoamingIap); +#endif +} + +void QNetworkSessionPrivateImpl::reject() +{ +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + iMobility->NewCarrierRejected(); + if (!iALRUpgradingConnection) { + newState(QNetworkSession::Disconnected); + } else { + newState(QNetworkSession::Connected, iOldRoamingIap); + } +#endif +} + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE +void QNetworkSessionPrivateImpl::PreferredCarrierAvailable(TAccessPointInfo aOldAPInfo, + TAccessPointInfo aNewAPInfo, + TBool aIsUpgrade, + TBool aIsSeamless) +{ + iOldRoamingIap = aOldAPInfo.AccessPoint(); + iNewRoamingIap = aNewAPInfo.AccessPoint(); + newState(QNetworkSession::Roaming); + if (iALREnabled > 0) { + iALRUpgradingConnection = aIsUpgrade; + QList<QNetworkConfiguration> configs = publicConfig.children(); + for (int i=0; i < configs.count(); i++) { + if (toSymbianConfig(privateConfiguration(configs[i]))->numericId == aNewAPInfo.AccessPoint()) { + emit preferredConfigurationChanged(configs[i], aIsSeamless); + } + } + } else { + migrate(); + } +} + +void QNetworkSessionPrivateImpl::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsSeamless*/) +{ + if (iALREnabled > 0) { + emit newConfigurationActivated(); + } else { + accept(); + } +} + +void QNetworkSessionPrivateImpl::Error(TInt /*aError*/) +{ + if (isOpen) { + isOpen = false; + activeConfig = QNetworkConfiguration(); + serviceConfig = QNetworkConfiguration(); + iError = QNetworkSession::RoamingError; + emit QNetworkSessionPrivate::error(iError); + Cancel(); + if (ipConnectionNotifier) { + ipConnectionNotifier->StopNotifications(); + } + syncStateWithInterface(); + // In some cases IAP is still in Connected state when + // syncStateWithInterface(); is called + // => Following call makes sure that Session state + // changes immediately to Disconnected. + newState(QNetworkSession::Disconnected); + emit closed(); + } +} +#endif + +void QNetworkSessionPrivateImpl::setALREnabled(bool enabled) +{ + if (enabled) { + iALREnabled++; + } else { + iALREnabled--; + } +} + +QNetworkConfiguration QNetworkSessionPrivateImpl::bestConfigFromSNAP(const QNetworkConfiguration& snapConfig) const +{ + QNetworkConfiguration config; + QList<QNetworkConfiguration> subConfigurations = snapConfig.children(); + for (int i = 0; i < subConfigurations.count(); i++ ) { + if (subConfigurations[i].state() == QNetworkConfiguration::Active) { + config = subConfigurations[i]; + break; + } else if (!config.isValid() && subConfigurations[i].state() == QNetworkConfiguration::Discovered) { + config = subConfigurations[i]; + } + } + if (!config.isValid() && subConfigurations.count() > 0) { + config = subConfigurations[0]; + } + return config; +} + +quint64 QNetworkSessionPrivateImpl::bytesWritten() const +{ + return transferredData(KUplinkData); +} + +quint64 QNetworkSessionPrivateImpl::bytesReceived() const +{ + return transferredData(KDownlinkData); +} + +quint64 QNetworkSessionPrivateImpl::transferredData(TUint dataType) const +{ + if (!publicConfig.isValid()) { + return 0; + } + + QNetworkConfiguration config; + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + if (serviceConfig.isValid()) { + config = serviceConfig; + } else { + if (activeConfig.isValid()) { + config = activeConfig; + } + } + } else { + config = publicConfig; + } + + if (!config.isValid()) { + return 0; + } + + TUint count; + TRequestStatus status; + iConnectionMonitor.GetConnectionCount(count, status); + User::WaitForRequest(status); + if (status.Int() != KErrNone) { + return 0; + } + + TUint transferredData = 0; + TUint numSubConnections; + TUint connectionId; + bool configFound; + for (TUint i = 1; i <= count; i++) { + TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections); + if (ret == KErrNone) { + TUint apId; + iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status); + User::WaitForRequest(status); + if (status.Int() == KErrNone) { + configFound = false; + if (config.type() == QNetworkConfiguration::ServiceNetwork) { + QList<QNetworkConfiguration> configs = config.children(); + for (int i=0; i < configs.count(); i++) { + if (toSymbianConfig(privateConfiguration(configs[i]))->numericId == apId) { + configFound = true; + break; + } + } + } else if (toSymbianConfig(privateConfiguration(config))->numericId == apId) { + configFound = true; + } + if (configFound) { + TUint tData; + iConnectionMonitor.GetUintAttribute(connectionId, 0, dataType, tData, status ); + User::WaitForRequest(status); + if (status.Int() == KErrNone) { + transferredData += tData; + } + } + } + } + } + + return transferredData; +} + +quint64 QNetworkSessionPrivateImpl::activeTime() const +{ + if (!isOpen || startTime.isNull()) { + return 0; + } + return startTime.secsTo(QDateTime::currentDateTime()); +} + +QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 iapId) const +{ + if (iapId == 0) { + _LIT(KSetting, "IAP\\Id"); + iConnection.GetIntSetting(KSetting, iapId); + } + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { + // Try to search IAP from the used SNAP using IAP Id + QList<QNetworkConfiguration> children = publicConfig.children(); + for (int i=0; i < children.count(); i++) { + if (toSymbianConfig(privateConfiguration(children[i]))->numericId == iapId) { + return children[i]; + } + } + + // Given IAP Id was not found from the used SNAP + // => Try to search matching IAP using mappingName + // mappingName contains: + // 1. "Access point name" for "Packet data" Bearer + // 2. "WLAN network name" (= SSID) for "Wireless LAN" Bearer + // 3. "Dial-up number" for "Data call Bearer" or "High Speed (GSM)" Bearer + // <=> Note: It's possible that in this case reported IAP is + // clone of the one of the IAPs of the used SNAP + // => If mappingName matches, clone has been found + QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier(QString::number(qHash(iapId))); + if (privateConfiguration(pt)) { + for (int i=0; i < children.count(); i++) { + if (toSymbianConfig(privateConfiguration(children[i]))->mappingName == toSymbianConfig(privateConfiguration(pt))->mappingName) { + return children[i]; + } + } + } else { + // Given IAP Id was not found from known IAPs array + return QNetworkConfiguration(); + } + + // Matching IAP was not found from used SNAP + // => IAP from another SNAP is returned + // (Note: Returned IAP matches to given IAP Id) + return pt; + } +#endif + + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + if (engine) { + QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier(QString::number(qHash(iapId))); + // Try to found User Selected IAP from known IAPs (accessPointConfigurations) + if (pt.isValid()) { + return pt; + } else { + // Check if new (WLAN) IAP was created in IAP/SNAP dialog + // 1. Sync internal configurations array to commsdb first + engine->updateConfigurations(); + // 2. Check if new configuration was created during connection creation + QList<QString> knownConfigs = engine->accessPointConfigurations.keys(); + if (knownConfigs.count() > iKnownConfigsBeforeConnectionStart.count()) { + // Configuration count increased => new configuration was created + // => Search new, created configuration + QString newIapId; + for (int i=0; i < iKnownConfigsBeforeConnectionStart.count(); i++) { + if (knownConfigs[i] != iKnownConfigsBeforeConnectionStart[i]) { + newIapId = knownConfigs[i]; + break; + } + } + if (newIapId.isEmpty()) { + newIapId = knownConfigs[knownConfigs.count()-1]; + } + pt = QNetworkConfigurationManager().configurationFromIdentifier(newIapId); + if (pt.isValid()) + return pt; + } + } + } + return QNetworkConfiguration(); + } + + return publicConfig; +} + +void QNetworkSessionPrivateImpl::RunL() +{ + TInt statusCode = iStatus.Int(); + + switch (statusCode) { + case KErrNone: // Connection created succesfully + { + TInt error = KErrNone; + QNetworkConfiguration newActiveConfig = activeConfiguration(); + if (!newActiveConfig.isValid()) { + error = KErrGeneral; + } else if (iDynamicSetdefaultif) { + // Use name of the IAP to set default IAP + QByteArray nameAsByteArray = newActiveConfig.name().toUtf8(); + ifreq ifr; + strcpy(ifr.ifr_name, nameAsByteArray.constData()); + + error = iDynamicSetdefaultif(&ifr); + } + + if (error != KErrNone) { + isOpen = false; + iError = QNetworkSession::UnknownSessionError; + emit QNetworkSessionPrivate::error(iError); + Cancel(); + if (ipConnectionNotifier) { + ipConnectionNotifier->StopNotifications(); + } + syncStateWithInterface(); + return; + } + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { + // Activate ALR monitoring + iMobility = CActiveCommsMobilityApiExt::NewL(iConnection, *this); + } +#endif + isOpen = true; + activeConfig = newActiveConfig; + activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId); + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + serviceConfig = QNetworkConfigurationManager().configurationFromIdentifier(toSymbianConfig(privateConfiguration(activeConfig))->serviceNetworkPtr->id); + } + + startTime = QDateTime::currentDateTime(); + + newState(QNetworkSession::Connected); + emit quitPendingWaitsForOpened(); + } + break; + case KErrNotFound: // Connection failed + isOpen = false; + activeConfig = QNetworkConfiguration(); + serviceConfig = QNetworkConfiguration(); + iError = QNetworkSession::InvalidConfigurationError; + emit QNetworkSessionPrivate::error(iError); + Cancel(); + if (ipConnectionNotifier) { + ipConnectionNotifier->StopNotifications(); + } + syncStateWithInterface(); + break; + case KErrCancel: // Connection attempt cancelled + case KErrAlreadyExists: // Connection already exists + default: + isOpen = false; + activeConfig = QNetworkConfiguration(); + serviceConfig = QNetworkConfiguration(); + iError = QNetworkSession::UnknownSessionError; + emit QNetworkSessionPrivate::error(iError); + Cancel(); + if (ipConnectionNotifier) { + ipConnectionNotifier->StopNotifications(); + } + syncStateWithInterface(); + break; + } +} + +void QNetworkSessionPrivateImpl::DoCancel() +{ + iConnection.Close(); +} + +bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint accessPointId) +{ + // Make sure that activeConfig is always updated when SNAP is signaled to be + // connected. + if (isOpen && publicConfig.type() == QNetworkConfiguration::ServiceNetwork && + newState == QNetworkSession::Connected) { + activeConfig = activeConfiguration(accessPointId); + activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId); +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + if (iDynamicSetdefaultif) { + // Use name of the IAP to set default IAP + QByteArray nameAsByteArray = activeConfig.name().toUtf8(); + ifreq ifr; + strcpy(ifr.ifr_name, nameAsByteArray.constData()); + + iDynamicSetdefaultif(&ifr); + } +#endif + } + + // Make sure that same state is not signaled twice in a row. + if (state == newState) { + return true; + } + + // Make sure that Connecting state does not overwrite Roaming state + if (state == QNetworkSession::Roaming && newState == QNetworkSession::Connecting) { + return false; + } + + bool emitSessionClosed = false; + if (isOpen && state == QNetworkSession::Connected && newState == QNetworkSession::Disconnected) { + // Active & Connected state should change directly to Disconnected state + // only when something forces connection to close (eg. when another + // application or session stops connection or when network drops + // unexpectedly). + isOpen = false; + activeConfig = QNetworkConfiguration(); + serviceConfig = QNetworkConfiguration(); + iError = QNetworkSession::SessionAbortedError; + emit QNetworkSessionPrivate::error(iError); + Cancel(); + if (ipConnectionNotifier) { + ipConnectionNotifier->StopNotifications(); + } + // Start monitoring changes in IAP states + TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this)); + emitSessionClosed = true; // Emit SessionClosed after state change has been reported + } + + bool retVal = false; + if (accessPointId == 0) { + state = newState; + emit stateChanged(state); + retVal = true; + } else { + if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { + if (toSymbianConfig(privateConfiguration(publicConfig))->numericId == accessPointId) { + state = newState; + emit stateChanged(state); + retVal = true; + } + } else if (publicConfig.type() == QNetworkConfiguration::UserChoice && isOpen) { + if (toSymbianConfig(privateConfiguration(activeConfig))->numericId == accessPointId) { + state = newState; + emit stateChanged(state); + retVal = true; + } + } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { + QList<QNetworkConfiguration> subConfigurations = publicConfig.children(); + for (int i = 0; i < subConfigurations.count(); i++) { + if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId == accessPointId) { + if (newState == QNetworkSession::Connected) { + // Make sure that when AccessPoint is reported to be Connected + // also state of the related configuration changes to Active. + privateConfiguration(subConfigurations[i])->state = QNetworkConfiguration::Active; + + state = newState; + emit stateChanged(state); + retVal = true; + } else { + if (newState == QNetworkSession::Disconnected) { + // Make sure that when AccessPoint is reported to be disconnected + // also state of the related configuration changes from Active to Defined. + privateConfiguration(subConfigurations[i])->state = QNetworkConfiguration::Defined; + } + QNetworkConfiguration config = bestConfigFromSNAP(publicConfig); + if ((config.state() == QNetworkConfiguration::Defined) || + (config.state() == QNetworkConfiguration::Discovered)) { + state = newState; + emit stateChanged(state); + retVal = true; + } + } + } + } + } + } + + if (emitSessionClosed) { + emit closed(); + } + + return retVal; +} + +void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConnectionStatus, + TInt aError, + TUint accessPointId) +{ + switch (aConnectionStatus) + { + // Connection unitialised + case KConnectionUninitialised: + break; + + // Starting connetion selection + case KStartingSelection: + break; + + // Selection finished + case KFinishedSelection: + if (aError == KErrNone) + { + // The user successfully selected an IAP to be used + break; + } + else + { + // The user pressed e.g. "Cancel" and did not select an IAP + newState(QNetworkSession::Disconnected,accessPointId); + } + break; + + // Connection failure + case KConnectionFailure: + newState(QNetworkSession::NotAvailable); + break; + + // Prepearing connection (e.g. dialing) + case KPsdStartingConfiguration: + case KPsdFinishedConfiguration: + case KCsdFinishedDialling: + case KCsdScanningScript: + case KCsdGettingLoginInfo: + case KCsdGotLoginInfo: + break; + + // Creating connection (e.g. GPRS activation) + case KCsdStartingConnect: + case KCsdFinishedConnect: + newState(QNetworkSession::Connecting,accessPointId); + break; + + // Starting log in + case KCsdStartingLogIn: + break; + + // Finished login + case KCsdFinishedLogIn: + break; + + // Connection open + case KConnectionOpen: + break; + + case KLinkLayerOpen: + newState(QNetworkSession::Connected,accessPointId); + break; + + // Connection blocked or suspended + case KDataTransferTemporarilyBlocked: + break; + + // Hangup or GRPS deactivation + case KConnectionStartingClose: + newState(QNetworkSession::Closing,accessPointId); + break; + + // Connection closed + case KConnectionClosed: + break; + + case KLinkLayerClosed: + newState(QNetworkSession::Disconnected,accessPointId); + break; + + // Unhandled state + default: + break; + } +} + +void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent) +{ + switch (aEvent.EventType()) + { + case EConnMonConnectionStatusChange: + { + CConnMonConnectionStatusChange* realEvent; + realEvent = (CConnMonConnectionStatusChange*) &aEvent; + + TUint connectionId = realEvent->ConnectionId(); + TInt connectionStatus = realEvent->ConnectionStatus(); + + // Try to Find IAP Id using connection Id + TUint apId = 0; + if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { + QList<QNetworkConfiguration> subConfigurations = publicConfig.children(); + for (int i = 0; i < subConfigurations.count(); i++ ) { + if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId == connectionId) { + apId = toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId; + break; + } + } + } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { + if (toSymbianConfig(privateConfiguration(publicConfig))->connectionId == connectionId) { + apId = toSymbianConfig(privateConfiguration(publicConfig))->numericId; + } + } + + if (apId > 0) { + handleSymbianConnectionStatusChange(connectionStatus, KErrNone, apId); + } + } + break; + + case EConnMonCreateConnection: + { + CConnMonCreateConnection* realEvent; + realEvent = (CConnMonCreateConnection*) &aEvent; + TUint apId; + TUint connectionId = realEvent->ConnectionId(); + TRequestStatus status; + iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status); + User::WaitForRequest(status); + if (status.Int() == KErrNone) { + // Store connection id to related AccessPoint Configuration + if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { + QList<QNetworkConfiguration> subConfigurations = publicConfig.children(); + for (int i = 0; i < subConfigurations.count(); i++ ) { + if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId == apId) { + toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId = connectionId; + break; + } + } + } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { + if (toSymbianConfig(privateConfiguration(publicConfig))->numericId == apId) { + toSymbianConfig(privateConfiguration(publicConfig))->connectionId = connectionId; + } + } + } + } + break; + + case EConnMonDeleteConnection: + { + CConnMonDeleteConnection* realEvent; + realEvent = (CConnMonDeleteConnection*) &aEvent; + TUint connectionId = realEvent->ConnectionId(); + // Remove connection id from related AccessPoint Configuration + if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { + QList<QNetworkConfiguration> subConfigurations = publicConfig.children(); + for (int i = 0; i < subConfigurations.count(); i++ ) { + if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId == connectionId) { + toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId = 0; + break; + } + } + } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { + if (toSymbianConfig(privateConfiguration(publicConfig))->connectionId == connectionId) { + toSymbianConfig(privateConfiguration(publicConfig))->connectionId = 0; + } + } + } + break; + + default: + // For unrecognized events + break; + } +} + +ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivateImpl &owner, RConnection &connection) + : CActive(CActive::EPriorityStandard), iOwner(owner), iConnection(connection) +{ + CActiveScheduler::Add(this); +} + +ConnectionProgressNotifier::~ConnectionProgressNotifier() +{ + Cancel(); +} + +void ConnectionProgressNotifier::StartNotifications() +{ + if (!IsActive()) { + SetActive(); + } + iConnection.ProgressNotification(iProgress, iStatus); +} + +void ConnectionProgressNotifier::StopNotifications() +{ + Cancel(); +} + +void ConnectionProgressNotifier::DoCancel() +{ + iConnection.CancelProgressNotification(); +} + +void ConnectionProgressNotifier::RunL() +{ + if (iStatus == KErrNone) { + iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError); + + SetActive(); + iConnection.ProgressNotification(iProgress, iStatus); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h new file mode 100644 index 0000000..30f51e1 --- /dev/null +++ b/src/plugins/bearer/symbian/qnetworksession_impl.h @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNETWORKSESSION_IMPL_H +#define QNETWORKSESSION_IMPL_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtNetwork/private/qnetworksession_p.h> + +#include <QDateTime> + +#include <e32base.h> +#include <CommDbConnPref.h> +#include <es_sock.h> +#include <rconnmon.h> +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + #include <comms-infras/cs_mobility_apiext.h> +#endif + +typedef int(*TOpenCSetdefaultifFunction)(const struct ifreq*); + +QT_BEGIN_NAMESPACE + +class ConnectionProgressNotifier; +class SymbianEngine; + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE +class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive, public MMobilityProtocolResp, + public MConnectionMonitorObserver +#else +class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive, public MConnectionMonitorObserver +#endif +{ + Q_OBJECT +public: + QNetworkSessionPrivateImpl(SymbianEngine *engine); + ~QNetworkSessionPrivateImpl(); + + //called by QNetworkSession constructor and ensures + //that the state is immediately updated (w/o actually opening + //a session). Also this function should take care of + //notification hooks to discover future state changes. + void syncStateWithInterface(); + + QNetworkInterface currentInterface() const; + QVariant sessionProperty(const QString& key) const; + void setSessionProperty(const QString& key, const QVariant& value); + + void setALREnabled(bool enabled); + + void open(); + inline void close() { close(true); } + void close(bool allowSignals); + void stop(); + void migrate(); + void accept(); + void ignore(); + void reject(); + + QString errorString() const; //must return translated string + QNetworkSession::SessionError error() const; + + quint64 bytesWritten() const; + quint64 bytesReceived() const; + quint64 activeTime() const; + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE +public: // From MMobilityProtocolResp + void PreferredCarrierAvailable(TAccessPointInfo aOldAPInfo, + TAccessPointInfo aNewAPInfo, + TBool aIsUpgrade, + TBool aIsSeamless); + + void NewCarrierActive(TAccessPointInfo aNewAPInfo, TBool aIsSeamless); + + void Error(TInt aError); +#endif + +protected: // From CActive + void RunL(); + void DoCancel(); + +private: // MConnectionMonitorObserver + void EventL(const CConnMonEventBase& aEvent); + +private: + TUint iapClientCount(TUint aIAPId) const; + quint64 transferredData(TUint dataType) const; + bool newState(QNetworkSession::State newState, TUint accessPointId = 0); + void handleSymbianConnectionStatusChange(TInt aConnectionStatus, TInt aError, TUint accessPointId = 0); + QNetworkConfiguration bestConfigFromSNAP(const QNetworkConfiguration& snapConfig) const; + QNetworkConfiguration activeConfiguration(TUint32 iapId = 0) const; + QNetworkInterface interface(TUint iapId) const; + +private: // data + SymbianEngine *engine; + + mutable QNetworkInterface activeInterface; + + QDateTime startTime; + + RLibrary iOpenCLibrary; + TOpenCSetdefaultifFunction iDynamicSetdefaultif; + + mutable RSocketServ iSocketServ; + mutable RConnection iConnection; + mutable RConnectionMonitor iConnectionMonitor; + ConnectionProgressNotifier* ipConnectionNotifier; +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + CActiveCommsMobilityApiExt* iMobility; +#endif + + QNetworkSession::SessionError iError; + TInt iALREnabled; + TBool iALRUpgradingConnection; + + QList<QString> iKnownConfigsBeforeConnectionStart; + + TUint32 iOldRoamingIap; + TUint32 iNewRoamingIap; + + friend class ConnectionProgressNotifier; +}; + +class ConnectionProgressNotifier : public CActive +{ +public: + ConnectionProgressNotifier(QNetworkSessionPrivateImpl &owner, RConnection &connection); + ~ConnectionProgressNotifier(); + + void StartNotifications(); + void StopNotifications(); + +protected: // From CActive + void RunL(); + void DoCancel(); + +private: // Data + QNetworkSessionPrivateImpl &iOwner; + RConnection& iConnection; + TNifProgressBuf iProgress; + +}; + +QT_END_NAMESPACE + +#endif //QNETWORKSESSION_IMPL_H + diff --git a/src/plugins/bearer/symbian/symbian.pro b/src/plugins/bearer/symbian/symbian.pro new file mode 100644 index 0000000..9fd1a74 --- /dev/null +++ b/src/plugins/bearer/symbian/symbian.pro @@ -0,0 +1,37 @@ +TARGET = qsymbianbearer +include(../../qpluginbase.pri) + +QT += network + +HEADERS += symbianengine.h \ + qnetworksession_impl.h + +SOURCES += symbianengine.cpp \ + qnetworksession_impl.cpp \ + main.cpp + +exists($${EPOCROOT}epoc32/release/winscw/udeb/cmmanager.lib)| \ +exists($${EPOCROOT}epoc32/release/armv5/lib/cmmanager.lib) { + message("Building with SNAP support") + DEFINES += SNAP_FUNCTIONALITY_AVAILABLE + LIBS += -lcmmanager +} else { + message("Building without SNAP support") + LIBS += -lapengine +} + +INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE + +LIBS += -lcommdb \ + -lapsettingshandlerui \ + -lconnmon \ + -lcentralrepository \ + -lesock \ + -linsock \ + -lecom \ + -lefsrv \ + -lnetmeta + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/bearer +target.path += $$[QT_INSTALL_PLUGINS]/bearer +INSTALLS += target diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp new file mode 100644 index 0000000..e25eda4 --- /dev/null +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -0,0 +1,955 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbianengine.h" +#include "qnetworksession_impl.h" + +#include <commdb.h> +#include <cdbcols.h> +#include <d32dbms.h> + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + #include <cmdestination.h> + #include <cmconnectionmethod.h> + #include <cmconnectionmethoddef.h> + #include <cmpluginwlandef.h> + #include <cmpluginpacketdatadef.h> + #include <cmplugindialcommondefs.h> +#else + #include <apaccesspointitem.h> + #include <apdatahandler.h> + #include <aputils.h> +#endif + +QT_BEGIN_NAMESPACE + +static const int KValueThatWillBeAddedToSNAPId = 1000; +static const int KUserChoiceIAPId = 0; + +SymbianNetworkConfigurationPrivate::SymbianNetworkConfigurationPrivate() +: bearer(BearerUnknown), numericId(0), connectionId(0) +{ +} + +SymbianNetworkConfigurationPrivate::~SymbianNetworkConfigurationPrivate() +{ +} + +QString SymbianNetworkConfigurationPrivate::bearerName() const +{ + switch (bearer) { + case BearerEthernet: + return QLatin1String("Ethernet"); + case BearerWLAN: + return QLatin1String("WLAN"); + case Bearer2G: + return QLatin1String("2G"); + case BearerCDMA2000: + return QLatin1String("CDMA2000"); + case BearerWCDMA: + return QLatin1String("WCDMA"); + case BearerHSPA: + return QLatin1String("HSPA"); + case BearerBluetooth: + return QLatin1String("Bluetooth"); + case BearerWiMAX: + return QLatin1String("WiMAX"); + default: + return QString(); + } +} + +SymbianEngine::SymbianEngine(QObject *parent) +: QBearerEngine(parent), CActive(CActive::EPriorityIdle), iInitOk(true) +{ + CActiveScheduler::Add(this); + + TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP)); + if (error != KErrNone) { + iInitOk = false; + return; + } + + TRAP_IGNORE(iConnectionMonitor.ConnectL()); + TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this)); + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + TRAP(error, iCmManager.OpenL()); + if (error != KErrNone) { + iInitOk = false; + return; + } +#endif + + SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate; + cpPriv->name = "UserChoice"; + cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown; + cpPriv->state = QNetworkConfiguration::Discovered; + cpPriv->isValid = true; + cpPriv->id = QString::number(qHash(KUserChoiceIAPId)); + cpPriv->numericId = KUserChoiceIAPId; + cpPriv->connectionId = 0; + cpPriv->type = QNetworkConfiguration::UserChoice; + cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; + cpPriv->roamingSupported = false; + + QNetworkConfigurationPrivatePointer ptr(cpPriv); + userChoiceConfigurations.insert(ptr->id, ptr); + + updateConfigurations(); + updateStatesToSnaps(); + + // Start monitoring IAP and/or SNAP changes in Symbian CommsDB + startCommsDatabaseNotifications(); +} + +SymbianEngine::~SymbianEngine() +{ + Cancel(); + + iConnectionMonitor.CancelNotifications(); + iConnectionMonitor.Close(); + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + iCmManager.Close(); +#endif + + delete ipAccessPointsAvailabilityScanner; + delete ipCommsDB; +} + +bool SymbianEngine::hasIdentifier(const QString &id) +{ + return accessPointConfigurations.contains(id) || + snapConfigurations.contains(id) || + userChoiceConfigurations.contains(id); +} + +QNetworkConfigurationManager::Capabilities SymbianEngine::capabilities() const +{ + QNetworkConfigurationManager::Capabilities capFlags; + + capFlags = QNetworkConfigurationManager::CanStartAndStopInterfaces | + QNetworkConfigurationManager::DirectConnectionRouting | + QNetworkConfigurationManager::SystemSessionSupport | + QNetworkConfigurationManager::DataStatistics; + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + capFlags |= QNetworkConfigurationManager::ApplicationLevelRoaming | + QNetworkConfigurationManager::ForcedRoaming; +#endif + + return capFlags; +} + +QNetworkSessionPrivate *SymbianEngine::createSessionBackend() +{ + return new QNetworkSessionPrivateImpl(this); +} + +void SymbianEngine::requestUpdate() +{ + if (!iInitOk || iUpdateGoingOn) { + return; + } + iUpdateGoingOn = true; + + stopCommsDatabaseNotifications(); + updateConfigurations(); // Synchronous call + updateAvailableAccessPoints(); // Asynchronous call +} + +void SymbianEngine::updateConfigurations() +{ + if (!iInitOk) { + return; + } + + TRAP_IGNORE(updateConfigurationsL()); +} + +void SymbianEngine::updateConfigurationsL() +{ + QList<QString> knownConfigs = accessPointConfigurations.keys(); + QList<QString> knownSnapConfigs = snapConfigurations.keys(); + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + // S60 version is >= Series60 3rd Edition Feature Pack 2 + TInt error = KErrNone; + + // Loop through all IAPs + RArray<TUint32> connectionMethods; // IAPs + CleanupClosePushL(connectionMethods); + iCmManager.ConnectionMethodL(connectionMethods); + for(int i = 0; i < connectionMethods.Count(); i++) { + RCmConnectionMethod connectionMethod = iCmManager.ConnectionMethodL(connectionMethods[i]); + CleanupClosePushL(connectionMethod); + TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); + QString ident = QString::number(qHash(iapId)); + if (accessPointConfigurations.contains(ident)) { + knownConfigs.removeOne(ident); + } else { + SymbianNetworkConfigurationPrivate* cpPriv = NULL; + TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod)); + if (error == KErrNone) { + QNetworkConfigurationPrivatePointer ptr(cpPriv); + accessPointConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); + } + } + CleanupStack::PopAndDestroy(&connectionMethod); + } + CleanupStack::PopAndDestroy(&connectionMethods); + + // Loop through all SNAPs + RArray<TUint32> destinations; + CleanupClosePushL(destinations); + iCmManager.AllDestinationsL(destinations); + for(int i = 0; i < destinations.Count(); i++) { + RCmDestination destination; + destination = iCmManager.DestinationL(destinations[i]); + CleanupClosePushL(destination); + QString ident = QString::number(qHash(destination.Id()+KValueThatWillBeAddedToSNAPId)); //TODO: Check if it's ok to add 1000 SNAP Id to prevent SNAP ids overlapping IAP ids + if (snapConfigurations.contains(ident)) { + knownSnapConfigs.removeOne(ident); + } else { + SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate; + CleanupStack::PushL(cpPriv); + + HBufC *pName = destination.NameLC(); + cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()); + CleanupStack::PopAndDestroy(pName); + pName = NULL; + + cpPriv->isValid = true; + cpPriv->id = ident; + cpPriv->numericId = destination.Id(); + cpPriv->connectionId = 0; + cpPriv->state = QNetworkConfiguration::Defined; + cpPriv->type = QNetworkConfiguration::ServiceNetwork; + cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; + cpPriv->roamingSupported = false; + + QNetworkConfigurationPrivatePointer ptr(cpPriv); + snapConfigurations.insert(ident, ptr); + emit configurationAdded(ptr); + + CleanupStack::Pop(cpPriv); + } + QNetworkConfigurationPrivatePointer privSNAP = snapConfigurations.value(ident); + + for (int j=0; j < destination.ConnectionMethodCount(); j++) { + RCmConnectionMethod connectionMethod = destination.ConnectionMethodL(j); + CleanupClosePushL(connectionMethod); + + TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); + QString iface = QString::number(qHash(iapId)); + // Check that IAP can be found from accessPointConfigurations list + QNetworkConfigurationPrivatePointer priv = accessPointConfigurations.value(iface); + if (!priv) { + SymbianNetworkConfigurationPrivate *cpPriv = NULL; + TRAP(error, cpPriv = configFromConnectionMethodL(connectionMethod)); + if (error == KErrNone) { + QNetworkConfigurationPrivatePointer ptr(cpPriv); + toSymbianConfig(ptr)->serviceNetworkPtr = privSNAP; + accessPointConfigurations.insert(ptr->id, ptr); + emit configurationAdded(ptr); + privSNAP->serviceNetworkMembers.append(ptr); + } + } else { + knownConfigs.removeOne(iface); + // Check that IAP can be found from related SNAP's configuration list + bool iapFound = false; + for (int i = 0; i < privSNAP->serviceNetworkMembers.count(); i++) { + if (toSymbianConfig(privSNAP->serviceNetworkMembers[i])->numericId == iapId) { + iapFound = true; + break; + } + } + if (!iapFound) { + toSymbianConfig(priv)->serviceNetworkPtr = privSNAP; + privSNAP->serviceNetworkMembers.append(priv); + } + } + + CleanupStack::PopAndDestroy(&connectionMethod); + } + + if (privSNAP->serviceNetworkMembers.count() > 1) { + // Roaming is supported only if SNAP contains more than one IAP + privSNAP->roamingSupported = true; + } + + CleanupStack::PopAndDestroy(&destination); + } + CleanupStack::PopAndDestroy(&destinations); + +#else + // S60 version is < Series60 3rd Edition Feature Pack 2 + CCommsDbTableView* pDbTView = ipCommsDB->OpenTableLC(TPtrC(IAP)); + + // Loop through all IAPs + TUint32 apId = 0; + TInt retVal = pDbTView->GotoFirstRecord(); + while (retVal == KErrNone) { + pDbTView->ReadUintL(TPtrC(COMMDB_ID), apId); + QString ident = QString::number(qHash(apId)); + if (accessPointConfigurations.contains(ident)) { + knownConfigs.removeOne(ident); + } else { + SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate; + if (readNetworkConfigurationValuesFromCommsDb(apId, cpPriv)) { + QNetworkConfigurationPrivatePointer ptr(cpPriv); + accessPointConfigurations.insert(ident, ptr); + + emit configurationAdded(ptr); + } else { + delete cpPriv; + } + } + retVal = pDbTView->GotoNextRecord(); + } + CleanupStack::PopAndDestroy(pDbTView); +#endif + updateActiveAccessPoints(); + + foreach (const QString &oldIface, knownConfigs) { + //remove non existing IAP + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface); + emit configurationRemoved(ptr); + + // Remove non existing IAP from SNAPs + foreach (const QString &iface, snapConfigurations.keys()) { + QNetworkConfigurationPrivatePointer ptr2 = snapConfigurations.value(iface); + // => Check if one of the IAPs of the SNAP is active + for (int i = 0; i < ptr2->serviceNetworkMembers.count(); ++i) { + if (toSymbianConfig(ptr2->serviceNetworkMembers[i])->numericId == + toSymbianConfig(ptr)->numericId) { + ptr2->serviceNetworkMembers.removeAt(i); + break; + } + } + } + } + + foreach (const QString &oldIface, knownSnapConfigs) { + //remove non existing SNAPs + QNetworkConfigurationPrivatePointer ptr = snapConfigurations.take(oldIface); + emit configurationRemoved(ptr); + } +} + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE +SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( + RCmConnectionMethod& connectionMethod) +{ + SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate; + CleanupStack::PushL(cpPriv); + + TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); + QString ident = QString::number(qHash(iapId)); + + HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName); + CleanupStack::PushL(pName); + cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length()); + CleanupStack::PopAndDestroy(pName); + pName = NULL; + + TUint32 bearerId = connectionMethod.GetIntAttributeL(CMManager::ECmCommsDBBearerType); + switch (bearerId) { + case KCommDbBearerCSD: + cpPriv->bearer = SymbianNetworkConfigurationPrivate::Bearer2G; + break; + case KCommDbBearerWcdma: + cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerWCDMA; + break; + case KCommDbBearerLAN: + cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet; + break; + case KCommDbBearerVirtual: + cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown; + break; + case KCommDbBearerPAN: + cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown; + break; + case KCommDbBearerWLAN: + cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerWLAN; + break; + default: + cpPriv->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown; + break; + } + + TInt error = KErrNone; + TUint32 bearerType = connectionMethod.GetIntAttributeL(CMManager::ECmBearerType); + switch (bearerType) { + case KUidPacketDataBearerType: + // "Packet data" Bearer => Mapping is done using "Access point name" + TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EPacketDataAPName)); + break; + case KUidWlanBearerType: + // "Wireless LAN" Bearer => Mapping is done using "WLAN network name" = SSID + TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EWlanSSID)); + break; + } + if (!pName) { + // "Data call" Bearer or "High Speed (GSM)" Bearer => Mapping is done using "Dial-up number" + TRAP(error, pName = connectionMethod.GetStringAttributeL(CMManager::EDialDefaultTelNum)); + } + + if (error == KErrNone && pName) { + CleanupStack::PushL(pName); + cpPriv->mappingName = QString::fromUtf16(pName->Ptr(),pName->Length()); + CleanupStack::PopAndDestroy(pName); + pName = NULL; + } + + cpPriv->state = QNetworkConfiguration::Defined; + TBool isConnected = connectionMethod.GetBoolAttributeL(CMManager::ECmConnected); + if (isConnected) { + cpPriv->state = QNetworkConfiguration::Active; + } + + cpPriv->isValid = true; + cpPriv->id = ident; + cpPriv->numericId = iapId; + cpPriv->connectionId = 0; + cpPriv->type = QNetworkConfiguration::InternetAccessPoint; + cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; + cpPriv->roamingSupported = false; + + CleanupStack::Pop(cpPriv); + return cpPriv; +} +#else +bool SymbianEngine::readNetworkConfigurationValuesFromCommsDb( + TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration) +{ + TRAPD(error, readNetworkConfigurationValuesFromCommsDbL(aApId,apNetworkConfiguration)); + if (error != KErrNone) { + return false; + } + return true; +} + +void SymbianEngine::readNetworkConfigurationValuesFromCommsDbL( + TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration) +{ + CApDataHandler* pDataHandler = CApDataHandler::NewLC(*ipCommsDB); + CApAccessPointItem* pAPItem = CApAccessPointItem::NewLC(); + TBuf<KCommsDbSvrMaxColumnNameLength> name; + + CApUtils* pApUtils = CApUtils::NewLC(*ipCommsDB); + TUint32 apId = pApUtils->WapIdFromIapIdL(aApId); + + pDataHandler->AccessPointDataL(apId,*pAPItem); + pAPItem->ReadTextL(EApIapName, name); + if (name.Compare(_L("Easy WLAN")) == 0) { + // "Easy WLAN" won't be accepted to the Configurations list + User::Leave(KErrNotFound); + } + + QString ident = QString::number(qHash(aApId)); + + apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length()); + apNetworkConfiguration->isValid = true; + apNetworkConfiguration->id = ident; + apNetworkConfiguration->numericId = aApId; + apNetworkConfiguration->connectionId = 0; + apNetworkConfiguration->state = (QNetworkConfiguration::Defined); + apNetworkConfiguration->type = QNetworkConfiguration::InternetAccessPoint; + apNetworkConfiguration->purpose = QNetworkConfiguration::UnknownPurpose; + apNetworkConfiguration->roamingSupported = false; + switch (pAPItem->BearerTypeL()) { + case EApBearerTypeCSD: + apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::Bearer2G; + break; + case EApBearerTypeGPRS: + apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::Bearer2G; + break; + case EApBearerTypeHSCSD: + apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerHSPA; + break; + case EApBearerTypeCDMA: + apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerCDMA2000; + break; + case EApBearerTypeWLAN: + apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerWLAN; + break; + case EApBearerTypeLAN: + apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet; + break; + case EApBearerTypeLANModem: + apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerEthernet; + break; + default: + apNetworkConfiguration->bearer = SymbianNetworkConfigurationPrivate::BearerUnknown; + break; + } + + CleanupStack::PopAndDestroy(pApUtils); + CleanupStack::PopAndDestroy(pAPItem); + CleanupStack::PopAndDestroy(pDataHandler); +} +#endif + +QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfiguration() +{ + QNetworkConfigurationPrivatePointer ptr; + + if (iInitOk) { + stopCommsDatabaseNotifications(); + TRAP_IGNORE(ptr = defaultConfigurationL()); + startCommsDatabaseNotifications(); + } + + return ptr; +} + +QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfigurationL() +{ + QNetworkConfigurationPrivatePointer ptr; + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + // Check Default Connection (SNAP or IAP) + TCmDefConnValue defaultConnectionValue; + iCmManager.ReadDefConnL(defaultConnectionValue); + if (defaultConnectionValue.iType == ECmDefConnDestination) { + QString iface = QString::number(qHash(defaultConnectionValue.iId+KValueThatWillBeAddedToSNAPId)); + ptr = snapConfigurations.value(iface); + } else if (defaultConnectionValue.iType == ECmDefConnConnectionMethod) { + QString iface = QString::number(qHash(defaultConnectionValue.iId)); + ptr = accessPointConfigurations.value(iface); + } +#endif + + if (!ptr->isValid) { + QString iface = QString::number(qHash(KUserChoiceIAPId)); + ptr = userChoiceConfigurations.value(iface); + } + + return ptr; +} + +void SymbianEngine::updateActiveAccessPoints() +{ + bool online = false; + QList<QString> inactiveConfigs = accessPointConfigurations.keys(); + + TRequestStatus status; + TUint connectionCount; + iConnectionMonitor.GetConnectionCount(connectionCount, status); + User::WaitForRequest(status); + + // Go through all connections and set state of related IAPs to Active + TUint connectionId; + TUint subConnectionCount; + TUint apId; + if (status.Int() == KErrNone) { + for (TUint i = 1; i <= connectionCount; i++) { + iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount); + iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); + User::WaitForRequest(status); + QString ident = QString::number(qHash(apId)); + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); + if (ptr) { + online = true; + inactiveConfigs.removeOne(ident); + + toSymbianConfig(ptr)->connectionId = connectionId; + + // Configuration is Active + changeConfigurationStateTo(ptr, QNetworkConfiguration::Active); + } + } + } + + // Make sure that state of rest of the IAPs won't be Active + foreach (const QString &iface, inactiveConfigs) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface); + if (ptr) { + // Configuration is either Defined or Discovered + changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered); + } + } + + if (iOnline != online) { + iOnline = online; + emit this->onlineStateChanged(iOnline); + } +} + +void SymbianEngine::updateAvailableAccessPoints() +{ + if (!ipAccessPointsAvailabilityScanner) { + ipAccessPointsAvailabilityScanner = new AccessPointsAvailabilityScanner(*this, iConnectionMonitor); + } + if (ipAccessPointsAvailabilityScanner) { + // Scanning may take a while because WLAN scanning will be done (if device supports WLAN). + ipAccessPointsAvailabilityScanner->StartScanning(); + } +} + +void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo) +{ + iUpdateGoingOn = false; + if (scanSuccessful) { + QList<QString> unavailableConfigs = accessPointConfigurations.keys(); + + // Set state of returned IAPs to Discovered + // if state is not already Active + for(TUint i=0; i<iapInfo.iCount; i++) { + QString ident = QString::number(qHash(iapInfo.iIap[i].iIapId)); + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); + if (ptr) { + unavailableConfigs.removeOne(ident); + if (ptr->state < QNetworkConfiguration::Active) { + // Configuration is either Discovered or Active + changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered); + } + } + } + + // Make sure that state of rest of the IAPs won't be Discovered or Active + foreach (const QString &iface, unavailableConfigs) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface); + if (ptr) { + // Configuration is Defined + changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined); + } + } + } + + updateStatesToSnaps(); + + startCommsDatabaseNotifications(); + + emit updateCompleted(); +} + +void SymbianEngine::updateStatesToSnaps() +{ + // Go through SNAPs and set correct state to SNAPs + QList<QString> snapConfigIdents = snapConfigurations.keys(); + foreach (QString iface, snapConfigIdents) { + bool discovered = false; + bool active = false; + QNetworkConfigurationPrivatePointer ptr = snapConfigurations.value(iface); + // => Check if one of the IAPs of the SNAP is discovered or active + // => If one of IAPs is active, also SNAP is active + // => If one of IAPs is discovered but none of the IAPs is active, SNAP is discovered + for (int i=0; i<ptr->serviceNetworkMembers.count(); i++) { + if ((ptr->serviceNetworkMembers[i]->state & QNetworkConfiguration::Active) + == QNetworkConfiguration::Active) { + active = true; + break; + } else if ((ptr->serviceNetworkMembers[i]->state & QNetworkConfiguration::Discovered) + == QNetworkConfiguration::Discovered) { + discovered = true; + } + } + if (active) { + changeConfigurationStateTo(ptr, QNetworkConfiguration::Active); + } else if (discovered) { + changeConfigurationStateTo(ptr, QNetworkConfiguration::Discovered); + } else { + changeConfigurationStateTo(ptr, QNetworkConfiguration::Defined); + } + } +} + +bool SymbianEngine::changeConfigurationStateTo(QNetworkConfigurationPrivatePointer ptr, + QNetworkConfiguration::StateFlags newState) +{ + if (newState != ptr->state) { + ptr->state = newState; + emit configurationChanged(ptr); + return true; + } + return false; +} + +/* changeConfigurationStateAtMinTo function does not overwrite possible better + * state (e.g. Discovered state does not overwrite Active state) but + * makes sure that state is at minimum given state. +*/ +bool SymbianEngine::changeConfigurationStateAtMinTo(QNetworkConfigurationPrivatePointer ptr, + QNetworkConfiguration::StateFlags newState) +{ + if ((newState | ptr->state) != ptr->state) { + ptr->state = (ptr->state | newState); + emit configurationChanged(ptr); + return true; + } + return false; +} + +/* changeConfigurationStateAtMaxTo function overwrites possible better + * state (e.g. Discovered state overwrites Active state) and + * makes sure that state is at maximum given state (e.g. Discovered state + * does not overwrite Defined state). +*/ +bool SymbianEngine::changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivatePointer ptr, + QNetworkConfiguration::StateFlags newState) +{ + if ((newState & ptr->state) != ptr->state) { + ptr->state = (newState & ptr->state); + emit configurationChanged(ptr); + return true; + } + return false; +} + +void SymbianEngine::startCommsDatabaseNotifications() +{ + if (!iWaitingCommsDatabaseNotifications) { + iWaitingCommsDatabaseNotifications = ETrue; + if (!IsActive()) { + SetActive(); + // Start waiting for new notification + ipCommsDB->RequestNotification(iStatus); + } + } +} + +void SymbianEngine::stopCommsDatabaseNotifications() +{ + if (iWaitingCommsDatabaseNotifications) { + iWaitingCommsDatabaseNotifications = EFalse; + if (!IsActive()) { + SetActive(); + // Make sure that notifier recorded events will not be returned + // as soon as the client issues the next RequestNotification() request. + ipCommsDB->RequestNotification(iStatus); + ipCommsDB->CancelRequestNotification(); + } else { + ipCommsDB->CancelRequestNotification(); + } + } +} + +void SymbianEngine::RunL() +{ + if (iStatus != KErrCancel) { + RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); + switch (event) { + case RDbNotifier::EUnlock: /** All read locks have been removed. */ + case RDbNotifier::ECommit: /** A transaction has been committed. */ + case RDbNotifier::ERollback: /** A transaction has been rolled back */ + case RDbNotifier::ERecover: /** The database has been recovered */ + // Note that if further database events occur while a client is handling + // a request completion, the notifier records the most significant database + // event and this is signalled as soon as the client issues the next + // RequestNotification() request. + // => Stop recording notifications + stopCommsDatabaseNotifications(); + TRAPD(error, updateConfigurationsL()); + if (error == KErrNone) { + updateStatesToSnaps(); + } + iWaitingCommsDatabaseNotifications = true; + break; + default: + // Do nothing + break; + } + } + + if (iWaitingCommsDatabaseNotifications) { + if (!IsActive()) { + SetActive(); + // Start waiting for new notification + ipCommsDB->RequestNotification(iStatus); + } + } +} + +void SymbianEngine::DoCancel() +{ + ipCommsDB->CancelRequestNotification(); +} + + +void SymbianEngine::EventL(const CConnMonEventBase& aEvent) +{ + switch (aEvent.EventType()) { + case EConnMonCreateConnection: + { + CConnMonCreateConnection* realEvent; + realEvent = (CConnMonCreateConnection*) &aEvent; + TUint subConnectionCount = 0; + TUint apId; + TUint connectionId = realEvent->ConnectionId(); + TRequestStatus status; + iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); + User::WaitForRequest(status); + QString ident = QString::number(qHash(apId)); + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); + if (ptr) { + toSymbianConfig(ptr)->connectionId = connectionId; + // Configuration is Active + if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active)) + updateStatesToSnaps(); + + if (!iOnline) { + iOnline = true; + emit this->onlineStateChanged(iOnline); + } + } + } + break; + + case EConnMonDeleteConnection: + { + CConnMonDeleteConnection* realEvent; + realEvent = (CConnMonDeleteConnection*) &aEvent; + TUint connectionId = realEvent->ConnectionId(); + + QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId); + if (ptr) { + toSymbianConfig(ptr)->connectionId = 0; + // Configuration is either Defined or Discovered + if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) + updateStatesToSnaps(); + } + + bool online = false; + foreach (const QString &iface, accessPointConfigurations.keys()) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface); + if (ptr->state == QNetworkConfiguration::Active) { + online = true; + break; + } + } + if (iOnline != online) { + iOnline = online; + emit this->onlineStateChanged(iOnline); + } + } + break; + + case EConnMonIapAvailabilityChange: + { + CConnMonIapAvailabilityChange* realEvent; + realEvent = (CConnMonIapAvailabilityChange*) &aEvent; + TConnMonIapInfo iaps = realEvent->IapAvailability(); + QList<QString> unDiscoveredConfigs = accessPointConfigurations.keys(); + for ( TUint i = 0; i < iaps.Count(); i++ ) { + QString ident = QString::number(qHash(iaps.iIap[i].iIapId)); + + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); + if (ptr) { + // Configuration is either Discovered or Active + changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered); + unDiscoveredConfigs.removeOne(ident); + } + } + foreach (const QString &iface, unDiscoveredConfigs) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface); + if (ptr) { + // Configuration is Defined + changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined); + } + } + } + break; + + default: + // For unrecognized events + break; + } +} + +QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aConnectionId) +{ + QNetworkConfiguration item; + + QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i = + accessPointConfigurations.constBegin(); + while (i != accessPointConfigurations.constEnd()) { + QNetworkConfigurationPrivatePointer ptr = i.value(); + if (toSymbianConfig(ptr)->connectionId == aConnectionId) + return ptr; + + ++i; + } + + return QNetworkConfigurationPrivatePointer(); +} + +AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(SymbianEngine& owner, + RConnectionMonitor& connectionMonitor) + : CActive(CActive::EPriorityStandard), iOwner(owner), iConnectionMonitor(connectionMonitor) +{ + CActiveScheduler::Add(this); +} + +AccessPointsAvailabilityScanner::~AccessPointsAvailabilityScanner() +{ + Cancel(); +} + +void AccessPointsAvailabilityScanner::DoCancel() +{ + iConnectionMonitor.CancelAsyncRequest(EConnMonGetPckgAttribute); +} + +void AccessPointsAvailabilityScanner::StartScanning() +{ + iConnectionMonitor.GetPckgAttribute(EBearerIdAll, 0, KIapAvailability, iIapBuf, iStatus); + if (!IsActive()) { + SetActive(); + } +} + +void AccessPointsAvailabilityScanner::RunL() +{ + if (iStatus.Int() != KErrNone) { + iIapBuf().iCount = 0; + iOwner.accessPointScanningReady(false,iIapBuf()); + } else { + iOwner.accessPointScanningReady(true,iIapBuf()); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h new file mode 100644 index 0000000..587585b --- /dev/null +++ b/src/plugins/bearer/symbian/symbianengine.h @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANENGINE_H +#define SYMBIANENGINE_H + +#include <QtNetwork/private/qbearerengine_p.h> +#include <QtNetwork/qnetworkconfigmanager.h> + +#include <QHash> +#include <rconnmon.h> +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + #include <cmmanager.h> +#endif + +class CCommsDatabase; + +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +QT_BEGIN_NAMESPACE + +class QNetworkSessionPrivate; +class AccessPointsAvailabilityScanner; + +class SymbianNetworkConfigurationPrivate : public QNetworkConfigurationPrivate +{ +public: + enum Bearer { + BearerEthernet, + BearerWLAN, + Bearer2G, + BearerCDMA2000, + BearerWCDMA, + BearerHSPA, + BearerBluetooth, + BearerWiMAX, + BearerUnknown = -1 + }; + + SymbianNetworkConfigurationPrivate(); + ~SymbianNetworkConfigurationPrivate(); + + QString bearerName() const; + + Bearer bearer; + + TUint32 numericId; + TUint connectionId; + + QNetworkConfigurationPrivatePointer serviceNetworkPtr; + + QString mappingName; +}; + +inline SymbianNetworkConfigurationPrivate *toSymbianConfig(QNetworkConfigurationPrivatePointer ptr) +{ + return static_cast<SymbianNetworkConfigurationPrivate *>(ptr.data()); +} + +class SymbianEngine : public QBearerEngine, public CActive, + public MConnectionMonitorObserver +{ + Q_OBJECT + +public: + SymbianEngine(QObject *parent = 0); + virtual ~SymbianEngine(); + + bool hasIdentifier(const QString &id); + + void requestUpdate(); + + QNetworkConfigurationManager::Capabilities capabilities() const; + + QNetworkSessionPrivate *createSessionBackend(); + + QNetworkConfigurationPrivatePointer defaultConfiguration(); + +Q_SIGNALS: + void onlineStateChanged(bool isOnline); + +public Q_SLOTS: + void updateConfigurations(); + +private: + void updateStatesToSnaps(); + bool changeConfigurationStateTo(QNetworkConfigurationPrivatePointer ptr, + QNetworkConfiguration::StateFlags newState); + bool changeConfigurationStateAtMinTo(QNetworkConfigurationPrivatePointer ptr, + QNetworkConfiguration::StateFlags newState); + bool changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivatePointer ptr, + QNetworkConfiguration::StateFlags newState); +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + SymbianNetworkConfigurationPrivate *configFromConnectionMethodL(RCmConnectionMethod& connectionMethod); +#else + bool readNetworkConfigurationValuesFromCommsDb( + TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration); + void readNetworkConfigurationValuesFromCommsDbL( + TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration); +#endif + + void updateConfigurationsL(); + void updateActiveAccessPoints(); + void updateAvailableAccessPoints(); + void accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo); + void startCommsDatabaseNotifications(); + void stopCommsDatabaseNotifications(); + + QNetworkConfigurationPrivatePointer defaultConfigurationL(); + TBool GetS60PlatformVersion(TUint& aMajor, TUint& aMinor) const; + void startMonitoringIAPData(TUint32 aIapId); + QNetworkConfigurationPrivatePointer dataByConnectionId(TUint aConnectionId); + +protected: // From CActive + void RunL(); + void DoCancel(); + +private: // MConnectionMonitorObserver + void EventL(const CConnMonEventBase& aEvent); + +private: // Data + CCommsDatabase* ipCommsDB; + RConnectionMonitor iConnectionMonitor; + + TBool iWaitingCommsDatabaseNotifications; + TBool iOnline; + TBool iInitOk; + TBool iUpdateGoingOn; + + + AccessPointsAvailabilityScanner* ipAccessPointsAvailabilityScanner; + + friend class QNetworkSessionPrivate; + friend class AccessPointsAvailabilityScanner; + +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + RCmManager iCmManager; +#endif +}; + +class AccessPointsAvailabilityScanner : public CActive +{ +public: + AccessPointsAvailabilityScanner(SymbianEngine& owner, + RConnectionMonitor& connectionMonitor); + ~AccessPointsAvailabilityScanner(); + + void StartScanning(); + +protected: // From CActive + void RunL(); + void DoCancel(); + +private: // Data + SymbianEngine& iOwner; + RConnectionMonitor& iConnectionMonitor; + TConnMonIapInfoBuf iIapBuf; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index f27440e..ba50329 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -593,6 +593,17 @@ void QDirectFBPixmapData::invalidate() imageFormat = QImage::Format_Invalid; } +#ifndef QT_DIRECTFB_PLUGIN +Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_pixmap(const QPixmap &pixmap) +{ + const QPixmapData *data = pixmap.pixmapData(); + if (!data || data->classId() != QPixmapData::DirectFBClass) + return 0; + const QDirectFBPixmapData *dfbData = static_cast<const QDirectFBPixmapData*>(data); + return dfbData->directFBSurface(); +} +#endif + QT_END_NAMESPACE #endif // QT_NO_QWS_DIRECTFB diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 004b816..d6a426f 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -SUBDIRS *= accessible imageformats sqldrivers iconengines script +SUBDIRS *= accessible imageformats sqldrivers iconengines script bearer unix:!symbian { contains(QT_CONFIG,iconv)|contains(QT_CONFIG,gnu-libiconv):SUBDIRS *= codecs } else { diff --git a/src/qt3support/dialogs/q3filedialog.cpp b/src/qt3support/dialogs/q3filedialog.cpp index 9b8e4d3..35f7890 100644 --- a/src/qt3support/dialogs/q3filedialog.cpp +++ b/src/qt3support/dialogs/q3filedialog.cpp @@ -475,9 +475,17 @@ static int sortFilesBy = (int)QDir::Name; static bool sortAscending = true; static bool detailViewMode = false; -static Q3CleanupHandler<QPixmap> qfd_cleanup_pixmap; static Q3CleanupHandler<QString> qfd_cleanup_string; +static void qt_cleanup_fd_pixmaps(); +typedef QList<QPixmap *> FDPixmaps; +Q_GLOBAL_STATIC_WITH_INITIALIZER(FDPixmaps, qfd_pixmaps, qAddPostRoutine(qt_cleanup_fd_pixmaps)) + +static void qt_cleanup_fd_pixmaps() +{ + qDeleteAll(*qfd_pixmaps()); +} + static QString toRootIfNotExists( const QString &path ) { if ( !path.isEmpty() ) @@ -533,37 +541,37 @@ static void makeVariables() { qfd_cleanup_string.add(&workingDirectory); openFolderIcon = new QPixmap((const char **)open_xpm); - qfd_cleanup_pixmap.add(&openFolderIcon); + qfd_pixmaps()->append(openFolderIcon); symLinkDirIcon = new QPixmap((const char **)link_dir_xpm); - qfd_cleanup_pixmap.add(&symLinkDirIcon); + qfd_pixmaps()->append(symLinkDirIcon); symLinkFileIcon = new QPixmap((const char **)link_file_xpm); - qfd_cleanup_pixmap.add(&symLinkFileIcon); + qfd_pixmaps()->append(symLinkFileIcon); fileIcon = new QPixmap((const char **)file_xpm); - qfd_cleanup_pixmap.add(&fileIcon); + qfd_pixmaps()->append(fileIcon); closedFolderIcon = new QPixmap((const char **)closed_xpm); - qfd_cleanup_pixmap.add(&closedFolderIcon); + qfd_pixmaps()->append(closedFolderIcon); detailViewIcon = new QPixmap((const char **)detailedview_xpm); - qfd_cleanup_pixmap.add(&detailViewIcon); + qfd_pixmaps()->append(detailViewIcon); multiColumnListViewIcon = new QPixmap((const char **)mclistview_xpm); - qfd_cleanup_pixmap.add(&multiColumnListViewIcon); + qfd_pixmaps()->append(multiColumnListViewIcon); cdToParentIcon = new QPixmap((const char **)cdtoparent_xpm); - qfd_cleanup_pixmap.add(&cdToParentIcon); + qfd_pixmaps()->append(cdToParentIcon); newFolderIcon = new QPixmap((const char **)newfolder_xpm); - qfd_cleanup_pixmap.add(&newFolderIcon); + qfd_pixmaps()->append(newFolderIcon); previewInfoViewIcon = new QPixmap((const char **)previewinfoview_xpm); - qfd_cleanup_pixmap.add(&previewInfoViewIcon); + qfd_pixmaps()->append(previewInfoViewIcon); previewContentsViewIcon = new QPixmap((const char **)previewcontentsview_xpm); - qfd_cleanup_pixmap.add(&previewContentsViewIcon); + qfd_pixmaps()->append(previewContentsViewIcon); startCopyIcon = new QPixmap((const char **)start_xpm); - qfd_cleanup_pixmap.add(&startCopyIcon); + qfd_pixmaps()->append(startCopyIcon); endCopyIcon = new QPixmap((const char **)end_xpm); - qfd_cleanup_pixmap.add(&endCopyIcon); + qfd_pixmaps()->append(endCopyIcon); goBackIcon = new QPixmap((const char **)back_xpm); - qfd_cleanup_pixmap.add(&goBackIcon); + qfd_pixmaps()->append(goBackIcon); fifteenTransparentPixels = new QPixmap(closedFolderIcon->width(), 1); - qfd_cleanup_pixmap.add(&fifteenTransparentPixels); + qfd_pixmaps()->append(fifteenTransparentPixels); QBitmap m(fifteenTransparentPixels->width(), 1); m.fill(Qt::color0); fifteenTransparentPixels->setMask(m); diff --git a/src/qt3support/itemviews/q3iconview.cpp b/src/qt3support/itemviews/q3iconview.cpp index 67c956e..683e3d6 100644 --- a/src/qt3support/itemviews/q3iconview.cpp +++ b/src/qt3support/itemviews/q3iconview.cpp @@ -132,14 +132,21 @@ static QPixmap *qiv_selection = 0; #endif static bool optimize_layout = false; -static Q3CleanupHandler<QPixmap> qiv_cleanup_pixmap; +static void qt_cleanup_iv_pixmaps(); +typedef QList<QPixmap *> IVPixmaps; +Q_GLOBAL_STATIC_WITH_INITIALIZER(IVPixmaps, qiv_pixmaps, qAddPostRoutine(qt_cleanup_iv_pixmaps)) + +static void qt_cleanup_iv_pixmaps() +{ + qDeleteAll(*qiv_pixmaps()); +} static QPixmap *get_qiv_buffer_pixmap(const QSize &s) { if (!qiv_buffer_pixmap) { qiv_buffer_pixmap = new QPixmap(s); - qiv_cleanup_pixmap.add(&qiv_buffer_pixmap); + qiv_pixmaps()->append(qiv_buffer_pixmap); return qiv_buffer_pixmap; } @@ -2580,7 +2587,7 @@ Q3IconView::Q3IconView(QWidget *parent, const char *name, Qt::WindowFlags f) { if (!unknown_icon) { unknown_icon = new QPixmap((const char **)unknown_xpm); - qiv_cleanup_pixmap.add(&unknown_icon); + qiv_pixmaps()->append(unknown_icon); } d = new Q3IconViewPrivate; diff --git a/src/qt3support/itemviews/q3listview.cpp b/src/qt3support/itemviews/q3listview.cpp index 2c15ad0..12dad84 100644 --- a/src/qt3support/itemviews/q3listview.cpp +++ b/src/qt3support/itemviews/q3listview.cpp @@ -70,9 +70,6 @@ QT_BEGIN_NAMESPACE const int Unsorted = 16383; -static Q3CleanupHandler<QBitmap> qlv_cleanup_bitmap; - - struct Q3ListViewPrivate { // classes that are here to avoid polluting the global name space diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 5318693..6d07f7c 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -82,7 +82,16 @@ symbian: { qtbackup.sources = backup_registration.xml qtbackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) - DEPLOYMENT += qtresources qtlibraries qtbackup imageformats_plugins codecs_plugins graphicssystems_plugins + bearer_plugins.path = c:$$QT_PLUGINS_BASE_DIR/bearer + bearer_plugins.sources += qsymbianbearer.dll + + DEPLOYMENT += qtresources \ + qtlibraries \ + qtbackup \ + imageformats_plugins \ + codecs_plugins \ + graphicssystems_plugins \ + bearer_plugins contains(QT_CONFIG, svg): { qtlibraries.sources += QtSvg.dll diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 9fff552..d3be304 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -500,32 +500,6 @@ bool QSQLiteDriver::hasFeature(DriverFeature f) const return false; } -static int qGetSqliteTimeout(QString opts) -{ - enum { DefaultTimeout = 5000 }; - - opts.remove(QLatin1Char(' ')); - foreach(QString option, opts.split(QLatin1Char(';'))) { - if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) { - bool ok; - int nt = option.mid(21).toInt(&ok); - if (ok) - return nt; - } - } - return DefaultTimeout; -} - -static int qGetSqliteOpenMode(QString opts) -{ - opts.remove(QLatin1Char(' ')); - foreach(QString option, opts.split(QLatin1Char(';'))) { - if (option == QLatin1String("QSQLITE_OPEN_READONLY")) - return SQLITE_OPEN_READONLY; - } - return SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; -} - /* SQLite dbs have no user name, passwords, hosts or ports. just file names. @@ -537,9 +511,26 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c if (db.isEmpty()) return false; + bool sharedCache = false; + int openMode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, timeOut=5000; + QStringList opts=QString(conOpts).remove(QLatin1Char(' ')).split(QLatin1Char(';')); + foreach(const QString &option, opts) { + if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) { + bool ok; + int nt = option.mid(21).toInt(&ok); + if (ok) + timeOut = nt; + } + if (option == QLatin1String("QSQLITE_OPEN_READONLY")) + openMode = SQLITE_OPEN_READONLY; + if (option == QLatin1String("QSQLITE_ENABLE_SHARED_CACHE")) + sharedCache = true; + } + + sqlite3_enable_shared_cache(sharedCache); - if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, qGetSqliteOpenMode(conOpts), NULL) == SQLITE_OK) { - sqlite3_busy_timeout(d->access, qGetSqliteTimeout(conOpts)); + if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) { + sqlite3_busy_timeout(d->access, timeOut); setOpen(true); setOpenError(false); return true; diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index 031261d..1416ee3 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -1267,6 +1267,7 @@ QSqlRecord QSqlDatabase::record(const QString& tablename) const \list \i QSQLITE_BUSY_TIMEOUT \i QSQLITE_OPEN_READONLY + \i QSQLITE_ENABLE_SHARED_CACHE \endlist \i diff --git a/src/xmlpatterns/data/qatomicvalue.cpp b/src/xmlpatterns/data/qatomicvalue.cpp index 6858e27..c4f3578 100644 --- a/src/xmlpatterns/data/qatomicvalue.cpp +++ b/src/xmlpatterns/data/qatomicvalue.cpp @@ -226,6 +226,8 @@ ItemType::Ptr AtomicValue::qtToXDMType(const QXmlItem &item) /* Fallthrough. */ case QVariant::Time: return BuiltinTypes::xsDateTime; + case QMetaType::Float: + return BuiltinTypes::xsFloat; case QVariant::Double: return BuiltinTypes::xsDouble; default: diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 9c4b4f0..bdbf5ce 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -439,7 +439,10 @@ SUBDIRS += \ qmargins \ qnetworkaddressentry \ qnetworkcachemetadata \ + qnetworkconfigmanager \ + qnetworkconfiguration \ qnetworkdiskcache \ + qnetworksession \ qobjectperformance \ qpainterpathstroker \ qplugin \ diff --git a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp index 504ceac..ea86c16 100644 --- a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp @@ -1213,14 +1213,14 @@ void tst_QAbstractItemView::task250754_fontChange() tree.setModel(m); w.show(); - w.resize(150,150); + w.resize(150,240); QTest::qWait(30); QFont font = tree.font(); - font.setPointSize(5); + font.setPixelSize(10); tree.setFont(font); QTRY_VERIFY(!tree.verticalScrollBar()->isVisible()); - font.setPointSize(45); + font.setPixelSize(60); tree.setFont(font); //now with the huge items, the scrollbar must be visible QTRY_VERIFY(tree.verticalScrollBar()->isVisible()); @@ -1444,7 +1444,10 @@ void tst_QAbstractItemView::QTBUG6407_extendedSelection() for(int i = 0; i < 50; ++i) view.addItem(QString::number(i)); - view.resize(200,200); + QFont font = view.font(); + font.setPixelSize(10); + view.setFont(font); + view.resize(200,240); view.show(); QApplication::setActiveWindow(&view); diff --git a/tests/auto/qbearertestcommon.h b/tests/auto/qbearertestcommon.h new file mode 100644 index 0000000..0bfe622 --- /dev/null +++ b/tests/auto/qbearertestcommon.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBEARERTESTCOMMON_H +#define QBEARERTESTCOMMON_H + +// Will try to wait for the condition while allowing event processing +#define QTRY_VERIFY(__expr) \ + do { \ + const int __step = 50; \ + const int __timeout = 90000; \ + if (!(__expr)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QVERIFY(__expr); \ + } while(0) + +// Will try to wait for the condition while allowing event processing +#define QTRY_COMPARE(__expr, __expected) \ + do { \ + const int __step = 50; \ + const int __timeout = 90000; \ + if ((__expr) != (__expected)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QCOMPARE(__expr, __expected); \ + } while(0) + +#endif + diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 7b54a3b..7c1b97e 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -90,6 +90,8 @@ Q_DECLARE_METATYPE(QRectF) #define COMPARE_REGIONS QTRY_COMPARE #endif +static QGraphicsRectItem staticItem; //QTBUG-7629, we should not crash at exit. + static void sendMousePress(QGraphicsScene *scene, const QPointF &point, Qt::MouseButton button = Qt::LeftButton) { QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index 121a8fa..99244c2 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -1633,6 +1633,35 @@ void tst_QImageReader::autoDetectImageFormat() QVERIFY(reader.canRead()); QVERIFY(!reader.read().isNull()); } + +#ifdef QTEST_HAVE_JPEG + { + QImageReader io(prefix + "YCbCr_rgb.jpg"); + io.setAutoDetectImageFormat(false); + // This should fail since no format string is given + QImage image; + QVERIFY(!io.read(&image)); + } + { + QImageReader io(prefix + "YCbCr_rgb.jpg", "jpg"); + io.setAutoDetectImageFormat(false); + QImage image; + QVERIFY(io.read(&image)); + } +#endif + { + QImageReader io(prefix + "tst7.png"); + io.setAutoDetectImageFormat(false); + // This should fail since no format string is given + QImage image; + QVERIFY(!io.read(&image)); + } + { + QImageReader io(prefix + "tst7.png", "png"); + io.setAutoDetectImageFormat(false); + QImage image; + QVERIFY(io.read(&image)); + } } void tst_QImageReader::fileNameProbing() diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index fcca58a..2be68e6 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -271,6 +271,7 @@ private slots: void taskQTBUG_4401_enterKeyClearsPassword(); void taskQTBUG_4679_moveToStartEndOfBlock(); void taskQTBUG_4679_selectToStartEndOfBlock(); + void taskQTBUG_7395_readOnlyShortcut(); #ifndef QT_NO_CONTEXTMENU void taskQTBUG_7902_contextMenuCrash(); #endif @@ -3457,10 +3458,8 @@ void tst_QLineEdit::task210502_caseInsensitiveInlineCompletion() completer.setCompletionMode(QCompleter::InlineCompletion); lineEdit.setCompleter(&completer); lineEdit.show(); -#ifdef Q_WS_X11 - // to be safe and avoid failing setFocus with window managers - qt_x11_wait_for_window_manager(&lineEdit); -#endif + QTest::qWaitForWindowShown(&lineEdit); + QApplication::setActiveWindow(&lineEdit); lineEdit.setFocus(); QTRY_VERIFY(lineEdit.hasFocus()); QTest::keyPress(&lineEdit, 'a'); @@ -3641,6 +3640,27 @@ void tst_QLineEdit::taskQTBUG_4679_selectToStartEndOfBlock() #endif // Q_OS_MAC } +void tst_QLineEdit::taskQTBUG_7395_readOnlyShortcut() +{ + //ReadOnly QLineEdit should not intercept shortcut. + QLineEdit le; + le.setReadOnly(true); + + QAction action(QString::fromLatin1("hello"), &le); + action.setShortcut(QString::fromLatin1("p")); + QSignalSpy spy(&action, SIGNAL(triggered())); + le.addAction(&action); + + le.show(); + QTest::qWaitForWindowShown(&le); + QApplication::setActiveWindow(&le); + le.setFocus(); + QTRY_VERIFY(le.hasFocus()); + + QTest::keyClick(0, Qt::Key_P); + QCOMPARE(spy.count(), 1); +} + #ifndef QT_NO_CONTEXTMENU void tst_QLineEdit::taskQTBUG_7902_contextMenuCrash() { diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 7109213..d2181f8 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -606,9 +606,8 @@ void tst_QListView::indexAt() view2.setWrapping(true); // We really want to make sure it is shown, because the layout won't be known until it is shown view2.show(); - for (int i = 0; i < 5 && !view2.m_shown; ++i) { - QTest::qWait(500); - } + QTest::qWaitForWindowShown(&view2); + QTRY_VERIFY(view2.m_shown); QVERIFY(view2.m_index.isValid()); QVERIFY(view2.m_index.row() != 0); @@ -760,7 +759,8 @@ void tst_QListView::hideFirstRow() view.setUniformItemSizes(true); view.setRowHidden(0,true); view.show(); - QTest::qWait(100); + QTest::qWaitForWindowShown(&view); + QTest::qWait(10); } void tst_QListView::batchedMode() @@ -778,10 +778,10 @@ void tst_QListView::batchedMode() view.setBatchSize(2); view.resize(200,400); view.show(); - -#if !defined(Q_OS_WINCE) + QTest::qWaitForWindowShown(&view); QTest::qWait(100); -#else + +#if defined(Q_OS_WINCE) QTest::qWait(2000); #endif QBitArray ba; @@ -1203,9 +1203,9 @@ void tst_QListView::scrollTo() //we click the item QPoint p = lv.visualRect(index).center(); QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p); - //let's wait 1 second because the scrolling is delayed - QTest::qWait(1000); - QCOMPARE(lv.visualRect(index).y(),0); + //let's wait because the scrolling is delayed + QTest::qWait(QApplication::doubleClickInterval() + 150); + QTRY_COMPARE(lv.visualRect(index).y(),0); //we scroll down. As the item is to tall for the view, it will disappear QTest::keyClick(lv.viewport(), Qt::Key_Down, Qt::NoModifier); @@ -1222,9 +1222,9 @@ void tst_QListView::scrollTo() //we click the item p = lv.visualRect(index).center(); QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p); - //let's wait 1 second because the scrolling is delayed - QTest::qWait(1000); - QCOMPARE(lv.visualRect(index).x(),0); + //let's wait because the scrolling is delayed + QTest::qWait(QApplication::doubleClickInterval() + 150); + QTRY_COMPARE(lv.visualRect(index).x(),0); //we scroll right. As the item is too wide for the view, it will disappear QTest::keyClick(lv.viewport(), Qt::Key_Right, Qt::NoModifier); @@ -1243,9 +1243,9 @@ void tst_QListView::scrollTo() //we click the item p = lv.visualRect(index).center(); QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p); - //let's wait 1 second because the scrolling is delayed - QTest::qWait(1000); - QCOMPARE(lv.visualRect(index).y(),0); + //let's wait because the scrolling is delayed + QTest::qWait(QApplication::doubleClickInterval() + 150); + QTRY_COMPARE(lv.visualRect(index).y(),0); //we scroll down. As the item is too tall for the view, it will partially disappear QTest::keyClick(lv.viewport(), Qt::Key_Down, Qt::NoModifier); @@ -1277,7 +1277,7 @@ void tst_QListView::scrollBarRanges() for (int h = 30; h <= 210; ++h) { lv.resize(250, h); - QTest::qWait(100); // wait for the layout to be done + QApplication::processEvents(); // wait for the layout to be done int visibleRowCount = lv.viewport()->size().height() / rowHeight; int invisibleRowCount = rowCount - visibleRowCount; QCOMPARE(lv.verticalScrollBar()->maximum(), invisibleRowCount); @@ -1366,7 +1366,7 @@ void tst_QListView::scrollBarAsNeeded() model.setStringList(list); QApplication::processEvents(); - QTest::qWait(100); + QTest::qWait(50); QStringList replacement; for (i = 0; i < itemCount; ++i) { @@ -1375,10 +1375,9 @@ void tst_QListView::scrollBarAsNeeded() model.setStringList(replacement); QApplication::processEvents(); - QTest::qWait(100); - QCOMPARE(lv.horizontalScrollBar()->isVisible(), horizontalScrollBarVisible); - QCOMPARE(lv.verticalScrollBar()->isVisible(), verticalScrollBarVisible); + QTRY_COMPARE(lv.horizontalScrollBar()->isVisible(), horizontalScrollBarVisible); + QTRY_COMPARE(lv.verticalScrollBar()->isVisible(), verticalScrollBarVisible); } } @@ -1433,10 +1432,9 @@ void tst_QListView::wordWrap() lv.setFixedSize(150, 150); lv.show(); QApplication::processEvents(); - QTest::qWait(100); - QCOMPARE(lv.horizontalScrollBar()->isVisible(), false); - QCOMPARE(lv.verticalScrollBar()->isVisible(), true); + QTRY_COMPARE(lv.horizontalScrollBar()->isVisible(), false); + QTRY_COMPARE(lv.verticalScrollBar()->isVisible(), true); } #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) @@ -1557,7 +1555,8 @@ void tst_QListView::task248430_crashWith0SizedItem() QStringListModel model(QStringList() << QLatin1String("item1") << QString()); view.setModel(&model); view.show(); - QTest::qWait(100); + QTest::qWaitForWindowShown(&view); + QTest::qWait(20); } void tst_QListView::task250446_scrollChanged() @@ -1569,21 +1568,21 @@ void tst_QListView::task250446_scrollChanged() QVERIFY(index.isValid()); view.setCurrentIndex(index); view.show(); - QTest::qWait(100); + QTest::qWaitForWindowShown(&view); const int scrollValue = view.verticalScrollBar()->maximum(); view.verticalScrollBar()->setValue(scrollValue); QCOMPARE(view.verticalScrollBar()->value(), scrollValue); QCOMPARE(view.currentIndex(), index); view.showMinimized(); - QTest::qWait(100); - QCOMPARE(view.verticalScrollBar()->value(), scrollValue); - QCOMPARE(view.currentIndex(), index); + QTest::qWait(50); + QTRY_COMPARE(view.verticalScrollBar()->value(), scrollValue); + QTRY_COMPARE(view.currentIndex(), index); view.showNormal(); - QTest::qWait(100); - QCOMPARE(view.verticalScrollBar()->value(), scrollValue); - QCOMPARE(view.currentIndex(), index); + QTest::qWait(50); + QTRY_COMPARE(view.verticalScrollBar()->value(), scrollValue); + QTRY_COMPARE(view.currentIndex(), index); } void tst_QListView::task196118_visualRegionForSelection() @@ -1699,7 +1698,7 @@ void tst_QListView::shiftSelectionWithNonUniformItemSizes() view.setViewMode(QListView::IconMode); view.setModel(&model); view.show(); - QTest::qWait(30); + QTest::qWaitForWindowShown(&view); // Verfify that item sizes are non-uniform QVERIFY(view.sizeHintForIndex(model.index(0, 0)).height() > view.sizeHintForIndex(model.index(1, 0)).height()); @@ -1729,7 +1728,7 @@ void tst_QListView::shiftSelectionWithNonUniformItemSizes() view.setViewMode(QListView::IconMode); view.setModel(&model); view.show(); - QTest::qWait(30); + QTest::qWaitForWindowShown(&view); // Verfify that item sizes are non-uniform QVERIFY(view.sizeHintForIndex(model.index(0, 0)).width() > view.sizeHintForIndex(model.index(1, 0)).width()); @@ -1789,7 +1788,6 @@ void tst_QListView::task262152_setModelColumnNavigate() view.show(); QApplication::setActiveWindow(&view); QTest::qWaitForWindowShown(&view); - QTest::qWait(30); QTRY_COMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow()); QTest::keyClick(&view, Qt::Key_Down); QTest::qWait(30); @@ -1834,6 +1832,24 @@ void tst_QListView::taskQTBUG_2233_scrollHiddenItems() QVERIFY(index.isValid()); QCOMPARE(index.row(), 2 * i + 1); } + + //QTBUG-7929 should not crash + view.show(); + QTest::qWaitForWindowShown(&view); + QScrollBar *bar = view.flow() == QListView::TopToBottom + ? view.verticalScrollBar() : view.horizontalScrollBar(); + + int nbVisibleItem = rowCount / 2 - bar->maximum(); + + bar->setValue(bar->maximum()); + QApplication::processEvents(); + for (int i = rowCount; i > rowCount / 2; i--) { + view.setRowHidden(i, true); + } + QApplication::processEvents(); + QTest::qWait(50); + QCOMPARE(bar->value(), bar->maximum()); + QCOMPARE(bar->maximum(), rowCount/4 - nbVisibleItem); } void tst_QListView::taskQTBUG_633_changeModelData() diff --git a/tests/auto/qnetworkconfigmanager/qnetworkconfigmanager.pro b/tests/auto/qnetworkconfigmanager/qnetworkconfigmanager.pro new file mode 100644 index 0000000..30eb5f0 --- /dev/null +++ b/tests/auto/qnetworkconfigmanager/qnetworkconfigmanager.pro @@ -0,0 +1,15 @@ +load(qttest_p4) +SOURCES += tst_qnetworkconfigmanager.cpp +HEADERS += ../qbearertestcommon.h + +QT = core network + +symbian { + TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData +} + +maemo6 { + CONFIG += link_pkgconfig + + PKGCONFIG += conninet +} diff --git a/tests/auto/qnetworkconfigmanager/tst_qnetworkconfigmanager.cpp b/tests/auto/qnetworkconfigmanager/tst_qnetworkconfigmanager.cpp new file mode 100644 index 0000000..3052330 --- /dev/null +++ b/tests/auto/qnetworkconfigmanager/tst_qnetworkconfigmanager.cpp @@ -0,0 +1,335 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include "../qbearertestcommon.h" +#include "qnetworkconfiguration.h" +#include "qnetworkconfigmanager.h" + +#ifdef Q_WS_MAEMO_6 +#include <stdio.h> +#include <iapconf.h> +#endif + +QT_USE_NAMESPACE +class tst_QNetworkConfigurationManager : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void allConfigurations(); + void defaultConfiguration(); + void configurationFromIdentifier(); + +private: +#ifdef Q_WS_MAEMO_6 + Maemo::IAPConf *iapconf; + Maemo::IAPConf *iapconf2; + Maemo::IAPConf *gprsiap; +#define MAX_IAPS 50 + Maemo::IAPConf *iaps[MAX_IAPS]; + QProcess *icd_stub; +#endif +}; + +void tst_QNetworkConfigurationManager::initTestCase() +{ +#ifdef Q_WS_MAEMO_6 + iapconf = new Maemo::IAPConf("007"); + iapconf->setValue("ipv4_type", "AUTO"); + iapconf->setValue("wlan_wepkey1", "connt"); + iapconf->setValue("wlan_wepdefkey", 1); + iapconf->setValue("wlan_ssid", QByteArray("JamesBond")); + iapconf->setValue("name", "James Bond"); + iapconf->setValue("type", "WLAN_INFRA"); + + gprsiap = new Maemo::IAPConf("This-is-GPRS-IAP"); + gprsiap->setValue("ask_password", false); + gprsiap->setValue("gprs_accesspointname", "internet"); + gprsiap->setValue("gprs_password", ""); + gprsiap->setValue("gprs_username", ""); + gprsiap->setValue("ipv4_autodns", true); + gprsiap->setValue("ipv4_type", "AUTO"); + gprsiap->setValue("sim_imsi", "244070123456789"); + gprsiap->setValue("name", "MI6"); + gprsiap->setValue("type", "GPRS"); + + iapconf2 = new Maemo::IAPConf("osso.net"); + iapconf2->setValue("ipv4_type", "AUTO"); + iapconf2->setValue("wlan_wepkey1", "osso.net"); + iapconf2->setValue("wlan_wepdefkey", 1); + iapconf2->setValue("wlan_ssid", QByteArray("osso.net")); + iapconf2->setValue("name", "osso.net"); + iapconf2->setValue("type", "WLAN_INFRA"); + iapconf2->setValue("wlan_security", "WEP"); + + /* Create large number of IAPs in the gconf and see what happens */ + fflush(stdout); + printf("Creating %d IAPS: ", MAX_IAPS); + for (int i=0; i<MAX_IAPS; i++) { + QString num = QString().sprintf("%d", i); + QString iap = "iap-" + num; + iaps[i] = new Maemo::IAPConf(iap); + iaps[i]->setValue("name", QString("test-iap-")+num); + iaps[i]->setValue("type", "WLAN_INFRA"); + iaps[i]->setValue("wlan_ssid", QString(QString("test-ssid-")+num).toAscii()); + iaps[i]->setValue("wlan_security", "WPA_PSK"); + iaps[i]->setValue("EAP_wpa_preshared_passphrase", QString("test-passphrase-")+num); + printf("."); + fflush(stdout); + } + printf("\n"); + fflush(stdout); + + icd_stub = new QProcess(this); + icd_stub->start("/usr/bin/icd2_stub.py"); + QTest::qWait(1000); + + // Add a known network to scan list that icd2 stub returns + QProcess dbus_send; + // 007 network + dbus_send.start("dbus-send --type=method_call --system " + "--dest=com.nokia.icd2 /com/nokia/icd2 " + "com.nokia.icd2.testing.add_available_network " + "string:'' uint32:0 string:'' " + "string:WLAN_INFRA uint32:5000011 array:byte:48,48,55"); + dbus_send.waitForFinished(); + + // osso.net network + dbus_send.start("dbus-send --type=method_call --system " + "--dest=com.nokia.icd2 /com/nokia/icd2 " + "com.nokia.icd2.testing.add_available_network " + "string:'' uint32:0 string:'' " + "string:WLAN_INFRA uint32:83886097 array:byte:111,115,115,111,46,110,101,116"); + dbus_send.waitForFinished(); +#endif +} + + +void tst_QNetworkConfigurationManager::cleanupTestCase() +{ +#ifdef Q_WS_MAEMO_6 + iapconf->clear(); + delete iapconf; + iapconf2->clear(); + delete iapconf2; + gprsiap->clear(); + delete gprsiap; + + printf("Deleting %d IAPS : ", MAX_IAPS); + for (int i=0; i<MAX_IAPS; i++) { + iaps[i]->clear(); + delete iaps[i]; + printf("."); + fflush(stdout); + } + printf("\n"); + qDebug() << "Deleted" << MAX_IAPS << "IAPs"; + + icd_stub->terminate(); + icd_stub->waitForFinished(); +#endif +} + +void tst_QNetworkConfigurationManager::init() +{ +} + +void tst_QNetworkConfigurationManager::cleanup() +{ +} + +void printConfigurationDetails(const QNetworkConfiguration& p) +{ + qDebug() << p.name() <<": isvalid->" <<p.isValid() << " type->"<< p.type() << + " roaming->" << p.isRoamingAvailable() << "identifier->" << p.identifier() << + " purpose->" << p.purpose() << " state->" << p.state(); +} + +void tst_QNetworkConfigurationManager::allConfigurations() +{ + QNetworkConfigurationManager manager; + QList<QNetworkConfiguration> preScanConfigs = manager.allConfigurations(); + + foreach(QNetworkConfiguration c, preScanConfigs) + { + QVERIFY2(c.type()!=QNetworkConfiguration::UserChoice, "allConfiguration must not return UserChoice configs"); + } + + QSignalSpy spy(&manager, SIGNAL(updateCompleted())); + manager.updateConfigurations(); //initiate scans + QTRY_VERIFY(spy.count() == 1); //wait for scan to complete + + QList<QNetworkConfiguration> configs = manager.allConfigurations(); + + int all = configs.count(); + qDebug() << "All configurations:" << all; + QVERIFY(all); + foreach(QNetworkConfiguration p, configs) { + QVERIFY(p.isValid()); + printConfigurationDetails(p); + QVERIFY(p.type() != QNetworkConfiguration::Invalid); + QVERIFY(p.type() != QNetworkConfiguration::UserChoice); + } + + configs = manager.allConfigurations(QNetworkConfiguration::Undefined); + int undefined = configs.count(); + QVERIFY(undefined <= all); + qDebug() << "Undefined configurations:" << undefined; + foreach( const QNetworkConfiguration p, configs) { + printConfigurationDetails(p); + QVERIFY(p.state() & QNetworkConfiguration::Undefined); + QVERIFY(!(p.state() & QNetworkConfiguration::Defined)); + } + + //get defined configs only (same as all) + configs = manager.allConfigurations(QNetworkConfiguration::Defined); + int defined = configs.count(); + qDebug() << "Defined configurations:" << defined; + QVERIFY(defined <= all); + foreach( const QNetworkConfiguration p, configs) { + printConfigurationDetails(p); + QVERIFY(p.state() & QNetworkConfiguration::Defined); + QVERIFY(!(p.state() & QNetworkConfiguration::Undefined)); + } + + //get discovered configurations only + configs = manager.allConfigurations(QNetworkConfiguration::Discovered); + int discovered = configs.count(); + //QVERIFY(discovered); + qDebug() << "Discovered configurations:" << discovered; + foreach(const QNetworkConfiguration p, configs) { + printConfigurationDetails(p); + QVERIFY(p.isValid()); + QVERIFY(!(p.state() & QNetworkConfiguration::Undefined)); + QVERIFY(p.state() & QNetworkConfiguration::Defined); + QVERIFY(p.state() & QNetworkConfiguration::Discovered); + } + + //getactive configurations only + configs = manager.allConfigurations(QNetworkConfiguration::Active); + int active = configs.count(); + if (active) + QVERIFY(manager.isOnline()); + else + QVERIFY(!manager.isOnline()); + + //QVERIFY(active); + qDebug() << "Active configurations:" << active; + foreach(const QNetworkConfiguration p, configs) { + printConfigurationDetails(p); + QVERIFY(p.isValid()); + QVERIFY(!(p.state() & QNetworkConfiguration::Undefined)); + QVERIFY(p.state() & QNetworkConfiguration::Active); + QVERIFY(p.state() & QNetworkConfiguration::Discovered); + QVERIFY(p.state() & QNetworkConfiguration::Defined); + } + + QVERIFY(all >= discovered); + QVERIFY(discovered >= active); +} + + +void tst_QNetworkConfigurationManager::defaultConfiguration() +{ + QNetworkConfigurationManager manager; + QSignalSpy spy(&manager, SIGNAL(updateCompleted())); + manager.updateConfigurations(); //initiate scans + QTRY_VERIFY(spy.count() == 1); //wait for scan to complete + + QList<QNetworkConfiguration> configs = manager.allConfigurations(); + QNetworkConfiguration defaultConfig = manager.defaultConfiguration(); + + bool confirm = configs.contains(defaultConfig); + bool isUserChoice = (defaultConfig.type() == QNetworkConfiguration::UserChoice); + + //user choice config is not part of allConfigurations() + QVERIFY(isUserChoice != confirm); + if (!isUserChoice) { + QVERIFY(confirm || !defaultConfig.isValid()); + QVERIFY(!(confirm && !defaultConfig.isValid())); + } else { + QVERIFY(defaultConfig.isValid()); + QCOMPARE(defaultConfig.name(), QString("UserChoice")); + QCOMPARE(defaultConfig.children().count(), 0); + QVERIFY(!defaultConfig.isRoamingAvailable()); + QCOMPARE(defaultConfig.state(), QNetworkConfiguration::Discovered); + QNetworkConfiguration copy = manager.configurationFromIdentifier(defaultConfig.identifier()); + QVERIFY(copy == defaultConfig); + } +} + +void tst_QNetworkConfigurationManager::configurationFromIdentifier() +{ + QNetworkConfigurationManager manager; + QSet<QString> allIdentifier; + + //force an update to get maximum number of configs + QSignalSpy spy(&manager, SIGNAL(updateCompleted())); + manager.updateConfigurations(); //initiate scans + QTRY_VERIFY(spy.count() == 1); //wait for scan to complete + + QList<QNetworkConfiguration> configs = manager.allConfigurations(); + + foreach(QNetworkConfiguration c, configs) { + QVERIFY(!allIdentifier.contains(c.identifier())); + allIdentifier.insert(c.identifier()); + + QNetworkConfiguration direct = manager.configurationFromIdentifier(c.identifier()); + QVERIFY(direct.isValid()); + QVERIFY(direct == c); + } + + //assume that there is no item with identifier 'FooBar' + QVERIFY(!allIdentifier.contains("FooBar")); + QNetworkConfiguration invalid = manager.configurationFromIdentifier("FooBar"); + QVERIFY(!invalid.isValid()); +} + + +QTEST_MAIN(tst_QNetworkConfigurationManager) +#include "tst_qnetworkconfigmanager.moc" diff --git a/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro b/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro new file mode 100644 index 0000000..df2d2d9 --- /dev/null +++ b/tests/auto/qnetworkconfiguration/qnetworkconfiguration.pro @@ -0,0 +1,15 @@ +load(qttest_p4) +SOURCES += tst_qnetworkconfiguration.cpp +HEADERS += ../qbearertestcommon.h + +QT = core network + +symbian { + TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData +} + +maemo6 { + CONFIG += link_pkgconfig + + PKGCONFIG += conninet +} diff --git a/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp b/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp new file mode 100644 index 0000000..70f4447 --- /dev/null +++ b/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp @@ -0,0 +1,303 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include "../qbearertestcommon.h" +#include "qnetworkconfiguration.h" +#include "qnetworkconfigmanager.h" + +#ifdef Q_WS_MAEMO_6 +#include <stdio.h> +#include <iapconf.h> +#endif + +QT_USE_NAMESPACE +class tst_QNetworkConfiguration : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + +private slots: + void invalidPoint(); + void comparison(); + void children(); + void isRoamingAvailable(); + +private: +#ifdef Q_WS_MAEMO_6 + Maemo::IAPConf *iapconf; + Maemo::IAPConf *iapconf2; + Maemo::IAPConf *gprsiap; +#define MAX_IAPS 50 + Maemo::IAPConf *iaps[MAX_IAPS]; + QProcess *icd_stub; +#endif +}; + +void tst_QNetworkConfiguration::initTestCase() +{ +#ifdef Q_WS_MAEMO_6 + iapconf = new Maemo::IAPConf("007"); + iapconf->setValue("ipv4_type", "AUTO"); + iapconf->setValue("wlan_wepkey1", "connt"); + iapconf->setValue("wlan_wepdefkey", 1); + iapconf->setValue("wlan_ssid", QByteArray("JamesBond")); + iapconf->setValue("name", "James Bond"); + iapconf->setValue("type", "WLAN_INFRA"); + + iapconf2 = new Maemo::IAPConf("osso.net"); + iapconf2->setValue("ipv4_type", "AUTO"); + iapconf2->setValue("wlan_wepkey1", "osso.net"); + iapconf2->setValue("wlan_wepdefkey", 1); + iapconf2->setValue("wlan_ssid", QByteArray("osso.net")); + iapconf2->setValue("name", "osso.net"); + iapconf2->setValue("type", "WLAN_INFRA"); + iapconf2->setValue("wlan_security", "WEP"); + + gprsiap = new Maemo::IAPConf("This-is-GPRS-IAP"); + gprsiap->setValue("ask_password", false); + gprsiap->setValue("gprs_accesspointname", "internet"); + gprsiap->setValue("gprs_password", ""); + gprsiap->setValue("gprs_username", ""); + gprsiap->setValue("ipv4_autodns", true); + gprsiap->setValue("ipv4_type", "AUTO"); + gprsiap->setValue("sim_imsi", "244070123456789"); + gprsiap->setValue("name", "MI6"); + gprsiap->setValue("type", "GPRS"); + + /* Create large number of IAPs in the gconf and see what happens */ + fflush(stdout); + printf("Creating %d IAPS: ", MAX_IAPS); + for (int i=0; i<MAX_IAPS; i++) { + QString num = QString().sprintf("%d", i); + QString iap = "iap-" + num; + iaps[i] = new Maemo::IAPConf(iap); + iaps[i]->setValue("name", QString("test-iap-")+num); + iaps[i]->setValue("type", "WLAN_INFRA"); + iaps[i]->setValue("wlan_ssid", QString(QString("test-ssid-")+num).toAscii()); + iaps[i]->setValue("wlan_security", "WPA_PSK"); + iaps[i]->setValue("EAP_wpa_preshared_passphrase", QString("test-passphrase-")+num); + printf("."); + fflush(stdout); + } + printf("\n"); + fflush(stdout); + + icd_stub = new QProcess(this); + icd_stub->start("/usr/bin/icd2_stub.py"); + QTest::qWait(1000); + + // Add a known network to scan list that icd2 stub returns + QProcess dbus_send; + // 007 network + dbus_send.start("dbus-send --type=method_call --system " + "--dest=com.nokia.icd2 /com/nokia/icd2 " + "com.nokia.icd2.testing.add_available_network " + "string:'' uint32:0 string:'' " + "string:WLAN_INFRA uint32:5000011 array:byte:48,48,55"); + dbus_send.waitForFinished(); + + // osso.net network + dbus_send.start("dbus-send --type=method_call --system " + "--dest=com.nokia.icd2 /com/nokia/icd2 " + "com.nokia.icd2.testing.add_available_network " + "string:'' uint32:0 string:'' " + "string:WLAN_INFRA uint32:83886097 array:byte:111,115,115,111,46,110,101,116"); + dbus_send.waitForFinished(); +#endif +} + +void tst_QNetworkConfiguration::cleanupTestCase() +{ +#ifdef Q_WS_MAEMO_6 + iapconf->clear(); + delete iapconf; + iapconf2->clear(); + delete iapconf2; + gprsiap->clear(); + delete gprsiap; + + printf("Deleting %d IAPS : ", MAX_IAPS); + for (int i=0; i<MAX_IAPS; i++) { + iaps[i]->clear(); + delete iaps[i]; + printf("."); + fflush(stdout); + } + printf("\n"); + qDebug() << "Deleted" << MAX_IAPS << "IAPs"; + + // Terminate icd2 stub + icd_stub->terminate(); + icd_stub->waitForFinished(); +#endif +} + +void tst_QNetworkConfiguration::invalidPoint() +{ + QNetworkConfiguration pt; + + QVERIFY(pt.name().isEmpty()); + QVERIFY(!pt.isValid()); + QVERIFY(pt.type() == QNetworkConfiguration::Invalid); + QVERIFY(!(pt.state() & QNetworkConfiguration::Defined)); + QVERIFY(!(pt.state() & QNetworkConfiguration::Discovered)); + QVERIFY(!(pt.state() & QNetworkConfiguration::Active)); + QVERIFY(!pt.isRoamingAvailable()); + + QNetworkConfiguration pt2(pt); + QVERIFY(pt2.name().isEmpty()); + QVERIFY(!pt2.isValid()); + QVERIFY(pt2.type() == QNetworkConfiguration::Invalid); + QVERIFY(!(pt2.state() & QNetworkConfiguration::Defined)); + QVERIFY(!(pt2.state() & QNetworkConfiguration::Discovered)); + QVERIFY(!(pt2.state() & QNetworkConfiguration::Active)); + QVERIFY(!pt2.isRoamingAvailable()); + +} + +void tst_QNetworkConfiguration::comparison() +{ + //test copy constructor and assignment operator + //compare invalid connection points + QNetworkConfiguration pt1; + QVERIFY(!pt1.isValid()); + QVERIFY(pt1.type() == QNetworkConfiguration::Invalid); + + QNetworkConfiguration pt2(pt1); + QVERIFY(pt1==pt2); + QVERIFY(!(pt1!=pt2)); + QVERIFY(pt1.name() == pt2.name()); + QVERIFY(pt1.isValid() == pt2.isValid()); + QVERIFY(pt1.type() == pt2.type()); + QVERIFY(pt1.state() == pt2.state()); + QVERIFY(pt1.purpose() == pt2.purpose()); + + + QNetworkConfiguration pt3; + pt3 = pt1; + QVERIFY(pt1==pt3); + QVERIFY(!(pt1!=pt3)); + QVERIFY(pt1.name() == pt3.name()); + QVERIFY(pt1.isValid() == pt3.isValid()); + QVERIFY(pt1.type() == pt3.type()); + QVERIFY(pt1.state() == pt3.state()); + QVERIFY(pt1.purpose() == pt3.purpose()); + + //test case must run on machine that has valid connection points + QNetworkConfigurationManager manager; + QList<QNetworkConfiguration> preScanConfigs = manager.allConfigurations(); + + QSignalSpy spy(&manager, SIGNAL(updateCompleted())); + manager.updateConfigurations(); //initiate scans + QTRY_VERIFY(spy.count() == 1); //wait for scan to complete + + QList<QNetworkConfiguration> configs = manager.allConfigurations(QNetworkConfiguration::Discovered); + QVERIFY(configs.count()); + QNetworkConfiguration defaultConfig = manager.defaultConfiguration(); + QVERIFY(defaultConfig.isValid()); + QVERIFY(defaultConfig.type() != QNetworkConfiguration::Invalid); + QVERIFY(!defaultConfig.name().isEmpty()); + + pt3 = defaultConfig; + QVERIFY(defaultConfig==pt3); + QVERIFY(!(defaultConfig!=pt3)); + QVERIFY(defaultConfig.name() == pt3.name()); + QVERIFY(defaultConfig.isValid() == pt3.isValid()); + QVERIFY(defaultConfig.type() == pt3.type()); + QVERIFY(defaultConfig.state() == pt3.state()); + QVERIFY(defaultConfig.purpose() == pt3.purpose()); +} + +void tst_QNetworkConfiguration::children() +{ + QNetworkConfigurationManager manager; + QList<QNetworkConfiguration> configs = manager.allConfigurations(); + + foreach(QNetworkConfiguration c, configs) + { + if ( c.type() == QNetworkConfiguration::ServiceNetwork ) { + qDebug() << "found service network" << c.name() << c.children().count(); + QVERIFY(c.isValid()); + QList<QNetworkConfiguration> members = c.children(); + foreach(QNetworkConfiguration child, members) { + QVERIFY(child.isValid()); + QVERIFY(configs.contains(child)); + qDebug() << "\t" << child.name(); + } + } + } +} + +void tst_QNetworkConfiguration::isRoamingAvailable() +{ + QNetworkConfigurationManager manager; + QList<QNetworkConfiguration> configs = manager.allConfigurations(); + + //force update to get maximum list + QSignalSpy spy(&manager, SIGNAL(updateCompleted())); + manager.updateConfigurations(); //initiate scans + QTRY_VERIFY(spy.count() == 1); //wait for scan to complete + + foreach(QNetworkConfiguration c, configs) + { + QVERIFY(QNetworkConfiguration::UserChoice != c.type()); + QVERIFY(QNetworkConfiguration::Invalid != c.type()); + if ( c.type() == QNetworkConfiguration::ServiceNetwork ) { + //cannot test flag as some SNAPs may not support roaming anyway + //QVERIFY(c.roamingavailable()) + if ( c.children().count() <= 1 ) + QVERIFY(!c.isRoamingAvailable()); + foreach(QNetworkConfiguration child, c.children()) { + QVERIFY(QNetworkConfiguration::InternetAccessPoint == child.type()); + QCOMPARE(child.children().count(), 0); + } + } else { + QVERIFY(!c.isRoamingAvailable()); + } + } +} + +QTEST_MAIN(tst_QNetworkConfiguration) +#include "tst_qnetworkconfiguration.moc" diff --git a/tests/auto/qnetworksession/lackey/lackey.pro b/tests/auto/qnetworksession/lackey/lackey.pro new file mode 100644 index 0000000..3ed9850 --- /dev/null +++ b/tests/auto/qnetworksession/lackey/lackey.pro @@ -0,0 +1,10 @@ +SOURCES += main.cpp +TARGET = qnetworksessionlackey + +QT = core network + +symbian { + # Needed for interprocess communication and opening QNetworkSession + TARGET.CAPABILITY = NetworkControl NetworkServices +} + diff --git a/tests/auto/qnetworksession/lackey/main.cpp b/tests/auto/qnetworksession/lackey/main.cpp new file mode 100644 index 0000000..1e40485 --- /dev/null +++ b/tests/auto/qnetworksession/lackey/main.cpp @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QStringList> +#include <QLocalSocket> +#include <qnetworkconfigmanager.h> +#include <qnetworkconfiguration.h> +#include <qnetworksession.h> + +#include <QDebug> + +QT_USE_NAMESPACE + + +#define NO_DISCOVERED_CONFIGURATIONS_ERROR 1 +#define SESSION_OPEN_ERROR 2 + + +int main(int argc, char** argv) +{ + QCoreApplication app(argc, argv); + + QNetworkConfigurationManager manager; + QList<QNetworkConfiguration> discovered = +#if defined (Q_OS_SYMBIAN) + // On Symbian, on the first query (before updateConfigurations() call + // the discovered-states are not correct, so defined-state will do. + manager.allConfigurations(QNetworkConfiguration::Defined); +#else + manager.allConfigurations(QNetworkConfiguration::Discovered); +#endif + if (discovered.isEmpty()) { + return NO_DISCOVERED_CONFIGURATIONS_ERROR; + } + + // Cannot read/write to processes on WinCE or Symbian. + // Easiest alternative is to use sockets for IPC. + + QLocalSocket oopSocket; + + oopSocket.connectToServer("tst_qnetworksession"); + oopSocket.waitForConnected(-1); + + qDebug() << "Lackey started"; + + QNetworkSession *session = 0; + do { + if (session) { + delete session; + session = 0; + } + + qDebug() << "Discovered configurations:" << discovered.count(); + + if (discovered.isEmpty()) { + qDebug() << "No more discovered configurations"; + break; + } + + qDebug() << "Taking first configuration"; + + QNetworkConfiguration config = discovered.takeFirst(); + + if ((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + qDebug() << config.name() << "is active, therefore skipping it (looking for configs in 'discovered' state)."; + continue; + } + + qDebug() << "Creating session for" << config.name() << config.identifier(); + + session = new QNetworkSession(config); + + QString output = QString("Starting session for %1\n").arg(config.identifier()); + oopSocket.write(output.toAscii()); + oopSocket.waitForBytesWritten(); + session->open(); + session->waitForOpened(); + } while (!(session && session->isOpen())); + + qDebug() << "lackey: loop done"; + + if (!session) { + qDebug() << "Could not start session"; + + oopSocket.disconnectFromServer(); + oopSocket.waitForDisconnected(-1); + + return SESSION_OPEN_ERROR; + } + + QString output = QString("Started session for %1\n").arg(session->configuration().identifier()); + oopSocket.write(output.toAscii()); + oopSocket.waitForBytesWritten(); + + oopSocket.waitForReadyRead(); + oopSocket.readLine(); + + session->stop(); + + delete session; + + oopSocket.disconnectFromServer(); + oopSocket.waitForDisconnected(-1); + + return 0; +} diff --git a/tests/auto/qnetworksession/qnetworksession.pro b/tests/auto/qnetworksession/qnetworksession.pro new file mode 100644 index 0000000..14dbb3e --- /dev/null +++ b/tests/auto/qnetworksession/qnetworksession.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = lackey tst_qnetworksession diff --git a/tests/auto/qnetworksession/tst_qnetworksession/tst_qnetworksession.cpp b/tests/auto/qnetworksession/tst_qnetworksession/tst_qnetworksession.cpp new file mode 100644 index 0000000..48db6cb --- /dev/null +++ b/tests/auto/qnetworksession/tst_qnetworksession/tst_qnetworksession.cpp @@ -0,0 +1,919 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QLocalServer> +#include <QLocalSocket> +#include "../../qbearertestcommon.h" +#include <qnetworkconfigmanager.h> +#include <qnetworksession.h> + +#ifdef Q_WS_MAEMO_6 +#include <stdio.h> +#include <iapconf.h> +#endif + +QT_USE_NAMESPACE + +Q_DECLARE_METATYPE(QNetworkConfiguration) +Q_DECLARE_METATYPE(QNetworkSession::State); +Q_DECLARE_METATYPE(QNetworkSession::SessionError); + +class tst_QNetworkSession : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + +private slots: + + void outOfProcessSession(); + void invalidSession(); + + void sessionProperties_data(); + void sessionProperties(); + + void userChoiceSession_data(); + void userChoiceSession(); + + void sessionOpenCloseStop_data(); + void sessionOpenCloseStop(); + +private: + QNetworkConfigurationManager manager; + + int inProcessSessionManagementCount; + +#ifdef Q_WS_MAEMO_6 + Maemo::IAPConf *iapconf; + Maemo::IAPConf *iapconf2; + Maemo::IAPConf *gprsiap; +#define MAX_IAPS 10 + Maemo::IAPConf *iaps[MAX_IAPS]; + QProcess *icd_stub; +#endif +}; + +void tst_QNetworkSession::initTestCase() +{ + qRegisterMetaType<QNetworkSession::State>("QNetworkSession::State"); + qRegisterMetaType<QNetworkSession::SessionError>("QNetworkSession::SessionError"); + qRegisterMetaType<QNetworkConfiguration>("QNetworkConfiguration"); + +#ifdef Q_WS_MAEMO_6 + iapconf = new Maemo::IAPConf("007"); + iapconf->setValue("ipv4_type", "AUTO"); + iapconf->setValue("wlan_wepkey1", "connt"); + iapconf->setValue("wlan_wepdefkey", 1); + iapconf->setValue("wlan_ssid", QByteArray("JamesBond")); + iapconf->setValue("name", "James Bond"); + iapconf->setValue("type", "WLAN_INFRA"); + + gprsiap = new Maemo::IAPConf("This-is-GPRS-IAP"); + gprsiap->setValue("ask_password", false); + gprsiap->setValue("gprs_accesspointname", "internet"); + gprsiap->setValue("gprs_password", ""); + gprsiap->setValue("gprs_username", ""); + gprsiap->setValue("ipv4_autodns", true); + gprsiap->setValue("ipv4_type", "AUTO"); + gprsiap->setValue("sim_imsi", "244070123456789"); + gprsiap->setValue("name", "MI6"); + gprsiap->setValue("type", "GPRS"); + + iapconf2 = new Maemo::IAPConf("osso.net"); + iapconf2->setValue("ipv4_type", "AUTO"); + iapconf2->setValue("wlan_wepkey1", "osso.net"); + iapconf2->setValue("wlan_wepdefkey", 1); + iapconf2->setValue("wlan_ssid", QByteArray("osso.net")); + iapconf2->setValue("name", "osso.net"); + iapconf2->setValue("type", "WLAN_INFRA"); + iapconf2->setValue("wlan_security", "WEP"); + + /* Create large number of IAPs in the gconf and see what happens */ + fflush(stdout); + printf("Creating %d IAPS: ", MAX_IAPS); + for (int i=0; i<MAX_IAPS; i++) { + QString num = QString().sprintf("%d", i); + QString iap = "iap-" + num; + iaps[i] = new Maemo::IAPConf(iap); + iaps[i]->setValue("name", QString("test-iap-")+num); + iaps[i]->setValue("type", "WLAN_INFRA"); + iaps[i]->setValue("wlan_ssid", QString(QString("test-ssid-")+num).toAscii()); + iaps[i]->setValue("wlan_security", "WPA_PSK"); + iaps[i]->setValue("EAP_wpa_preshared_passphrase", QString("test-passphrase-")+num); + printf("."); + fflush(stdout); + } + printf("\n"); + fflush(stdout); + + icd_stub = new QProcess(this); + icd_stub->start("/usr/bin/icd2_stub.py"); + QTest::qWait(1000); + + // Add a known network to scan list that icd2 stub returns + QProcess dbus_send; + // 007 network + dbus_send.start("dbus-send --type=method_call --system " + "--dest=com.nokia.icd2 /com/nokia/icd2 " + "com.nokia.icd2.testing.add_available_network " + "string:'' uint32:0 string:'' " + "string:WLAN_INFRA uint32:5000011 array:byte:48,48,55"); + dbus_send.waitForFinished(); + + // osso.net network + dbus_send.start("dbus-send --type=method_call --system " + "--dest=com.nokia.icd2 /com/nokia/icd2 " + "com.nokia.icd2.testing.add_available_network " + "string:'' uint32:0 string:'' " + "string:WLAN_INFRA uint32:83886097 array:byte:111,115,115,111,46,110,101,116"); + dbus_send.waitForFinished(); +#endif + + inProcessSessionManagementCount = -1; + + QSignalSpy spy(&manager, SIGNAL(updateCompleted())); + manager.updateConfigurations(); + QTRY_VERIFY(spy.count() == 1); +} + +void tst_QNetworkSession::cleanupTestCase() +{ + if (!(manager.capabilities() & QNetworkConfigurationManager::SystemSessionSupport) && + (manager.capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces) && + inProcessSessionManagementCount == 0) { + QFAIL("No usable configurations found to complete all possible " + "tests in inProcessSessionManagement()"); + } + +#ifdef Q_WS_MAEMO_6 + iapconf->clear(); + delete iapconf; + iapconf2->clear(); + delete iapconf2; + gprsiap->clear(); + delete gprsiap; + + printf("Deleting %d IAPS : ", MAX_IAPS); + for (int i=0; i<MAX_IAPS; i++) { + iaps[i]->clear(); + delete iaps[i]; + printf("."); + fflush(stdout); + } + printf("\n"); + qDebug() << "Deleted" << MAX_IAPS << "IAPs"; + + icd_stub->terminate(); + icd_stub->waitForFinished(); +#endif +} + +void tst_QNetworkSession::invalidSession() +{ + QNetworkSession session(QNetworkConfiguration(), 0); + QVERIFY(!session.isOpen()); + QVERIFY(session.state() == QNetworkSession::Invalid); +} + +void tst_QNetworkSession::sessionProperties_data() +{ + QTest::addColumn<QNetworkConfiguration>("configuration"); + + QTest::newRow("invalid configuration") << QNetworkConfiguration(); + + foreach (const QNetworkConfiguration &config, manager.allConfigurations()) { + const QString name = config.name().isEmpty() ? QString("<Hidden>") : config.name(); + QTest::newRow(name.toLocal8Bit().constData()) << config; + } +} + +void tst_QNetworkSession::sessionProperties() +{ + QFETCH(QNetworkConfiguration, configuration); + + QNetworkSession session(configuration); + + QVERIFY(session.configuration() == configuration); + + QStringList validBearerNames = QStringList() << QLatin1String("Unknown") + << QLatin1String("Ethernet") + << QLatin1String("WLAN") + << QLatin1String("2G") + << QLatin1String("CDMA2000") + << QLatin1String("WCDMA") + << QLatin1String("HSPA") + << QLatin1String("Bluetooth") + << QLatin1String("WiMAX"); + + if (!configuration.isValid()) { + QVERIFY(configuration.bearerName().isEmpty()); + } else { + qDebug() << "Type:" << configuration.type() + << "Bearer:" << configuration.bearerName(); + + switch (configuration.type()) + { + case QNetworkConfiguration::ServiceNetwork: + case QNetworkConfiguration::UserChoice: + default: + QVERIFY(configuration.bearerName().isEmpty()); + break; + case QNetworkConfiguration::InternetAccessPoint: + QVERIFY(validBearerNames.contains(configuration.bearerName())); + break; + } + } + + // QNetworkSession::interface() should return an invalid interface unless + // session is in the connected state. + qDebug() << "Session state:" << session.state(); + qDebug() << "Session iface:" << session.interface().isValid() << session.interface().name(); +#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__)) + // On Symbian emulator, the support for data bearers is limited + QCOMPARE(session.state() == QNetworkSession::Connected, session.interface().isValid()); +#endif + + if (!configuration.isValid()) { + QVERIFY(configuration.state() == QNetworkConfiguration::Undefined && + session.state() == QNetworkSession::Invalid); + } else { + switch (configuration.state()) { + case QNetworkConfiguration::Undefined: + QVERIFY(session.state() == QNetworkSession::NotAvailable); + break; + case QNetworkConfiguration::Defined: + QVERIFY(session.state() == QNetworkSession::NotAvailable); + break; + case QNetworkConfiguration::Discovered: + QVERIFY(session.state() == QNetworkSession::Connecting || + session.state() == QNetworkSession::Disconnected); + break; + case QNetworkConfiguration::Active: + QVERIFY(session.state() == QNetworkSession::Connected || + session.state() == QNetworkSession::Closing || + session.state() == QNetworkSession::Roaming); + break; + default: + QFAIL("Invalid configuration state"); + }; + } +} + +void tst_QNetworkSession::userChoiceSession_data() +{ + QTest::addColumn<QNetworkConfiguration>("configuration"); + + QNetworkConfiguration config = manager.defaultConfiguration(); + if (config.type() == QNetworkConfiguration::UserChoice) + QTest::newRow("UserChoice") << config; + else + QSKIP("Default configuration is not a UserChoice configuration.", SkipAll); +} + +void tst_QNetworkSession::userChoiceSession() +{ + QFETCH(QNetworkConfiguration, configuration); + + QVERIFY(configuration.type() == QNetworkConfiguration::UserChoice); + + QNetworkSession session(configuration); + + // Check that configuration was really set + QVERIFY(session.configuration() == configuration); + + QVERIFY(!session.isOpen()); + + // Check that session is not active + QVERIFY(session.sessionProperty("ActiveConfiguration").toString().isEmpty()); + + // The remaining tests require the session to be not NotAvailable. + if (session.state() == QNetworkSession::NotAvailable) + QSKIP("Network is not available.", SkipSingle); + + QSignalSpy sessionOpenedSpy(&session, SIGNAL(opened())); + QSignalSpy sessionClosedSpy(&session, SIGNAL(closed())); + QSignalSpy stateChangedSpy(&session, SIGNAL(stateChanged(QNetworkSession::State))); + QSignalSpy errorSpy(&session, SIGNAL(error(QNetworkSession::SessionError))); + + // Test opening the session. + { + bool expectStateChange = session.state() != QNetworkSession::Connected; + + session.open(); + + session.waitForOpened(); + + if (session.isOpen()) + QVERIFY(!sessionOpenedSpy.isEmpty() || !errorSpy.isEmpty()); + if (!errorSpy.isEmpty()) { + QNetworkSession::SessionError error = + qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0)); + if (error == QNetworkSession::OperationNotSupportedError) { + // The session needed to bring up the interface, + // but the operation is not supported. + QSKIP("Configuration does not support open().", SkipSingle); + } else if (error == QNetworkSession::InvalidConfigurationError) { + // The session needed to bring up the interface, but it is not possible for the + // specified configuration. + if ((session.configuration().state() & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + QFAIL("Failed to open session for Discovered configuration."); + } else { + QSKIP("Cannot test session for non-Discovered configuration.", SkipSingle); + } + } else if (error == QNetworkSession::UnknownSessionError) { + QSKIP("Unknown session error.", SkipSingle); + } else { + QFAIL("Error opening session."); + } + } else if (!sessionOpenedSpy.isEmpty()) { + QCOMPARE(sessionOpenedSpy.count(), 1); + QVERIFY(sessionClosedSpy.isEmpty()); + QVERIFY(errorSpy.isEmpty()); + + if (expectStateChange) + QTRY_VERIFY(!stateChangedSpy.isEmpty()); + + QVERIFY(session.state() == QNetworkSession::Connected); +#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__)) + // On Symbian emulator, the support for data bearers is limited + QVERIFY(session.interface().isValid()); +#endif + + const QString userChoiceIdentifier = + session.sessionProperty("UserChoiceConfiguration").toString(); + + QVERIFY(!userChoiceIdentifier.isEmpty()); + QVERIFY(userChoiceIdentifier != configuration.identifier()); + + QNetworkConfiguration userChoiceConfiguration = + manager.configurationFromIdentifier(userChoiceIdentifier); + + QVERIFY(userChoiceConfiguration.isValid()); + QVERIFY(userChoiceConfiguration.type() != QNetworkConfiguration::UserChoice); + + const QString testIdentifier("abc"); + //resetting UserChoiceConfiguration is ignored (read only property) + session.setSessionProperty("UserChoiceConfiguration", testIdentifier); + QVERIFY(session.sessionProperty("UserChoiceConfiguration").toString() != testIdentifier); + + const QString activeIdentifier = + session.sessionProperty("ActiveConfiguration").toString(); + + QVERIFY(!activeIdentifier.isEmpty()); + QVERIFY(activeIdentifier != configuration.identifier()); + + QNetworkConfiguration activeConfiguration = + manager.configurationFromIdentifier(activeIdentifier); + + QVERIFY(activeConfiguration.isValid()); + QVERIFY(activeConfiguration.type() == QNetworkConfiguration::InternetAccessPoint); + + //resetting ActiveConfiguration is ignored (read only property) + session.setSessionProperty("ActiveConfiguration", testIdentifier); + QVERIFY(session.sessionProperty("ActiveConfiguration").toString() != testIdentifier); + + if (userChoiceConfiguration.type() == QNetworkConfiguration::InternetAccessPoint) { + QVERIFY(userChoiceConfiguration == activeConfiguration); + } else { + QVERIFY(userChoiceConfiguration.type() == QNetworkConfiguration::ServiceNetwork); + QVERIFY(userChoiceConfiguration.children().contains(activeConfiguration)); + } + } else { + QFAIL("Timeout waiting for session to open."); + } + } +} + +void tst_QNetworkSession::sessionOpenCloseStop_data() +{ + QTest::addColumn<QNetworkConfiguration>("configuration"); + QTest::addColumn<bool>("forceSessionStop"); + + foreach (const QNetworkConfiguration &config, manager.allConfigurations()) { + const QString name = config.name().isEmpty() ? QString("<Hidden>") : config.name(); + QTest::newRow((name + QLatin1String(" close")).toLocal8Bit().constData()) + << config << false; + QTest::newRow((name + QLatin1String(" stop")).toLocal8Bit().constData()) + << config << true; + } + + inProcessSessionManagementCount = 0; +} + +void tst_QNetworkSession::sessionOpenCloseStop() +{ + QFETCH(QNetworkConfiguration, configuration); + QFETCH(bool, forceSessionStop); + + QNetworkSession session(configuration); + + // Test initial state of the session. + { + QVERIFY(session.configuration() == configuration); + QVERIFY(!session.isOpen()); + // session may be invalid if configuration is removed between when + // sessionOpenCloseStop_data() is called and here. + QVERIFY((configuration.isValid() && (session.state() != QNetworkSession::Invalid)) || + (!configuration.isValid() && (session.state() == QNetworkSession::Invalid))); + QVERIFY(session.error() == QNetworkSession::UnknownSessionError); + } + + // The remaining tests require the session to be not NotAvailable. + if (session.state() == QNetworkSession::NotAvailable) + QSKIP("Network is not available.", SkipSingle); + + QSignalSpy sessionOpenedSpy(&session, SIGNAL(opened())); + QSignalSpy sessionClosedSpy(&session, SIGNAL(closed())); + QSignalSpy stateChangedSpy(&session, SIGNAL(stateChanged(QNetworkSession::State))); + QSignalSpy errorSpy(&session, SIGNAL(error(QNetworkSession::SessionError))); + + // Test opening the session. + { + QNetworkSession::State previousState = session.state(); + bool expectStateChange = previousState != QNetworkSession::Connected; + + session.open(); + + session.waitForOpened(); + + if (session.isOpen()) + QVERIFY(!sessionOpenedSpy.isEmpty() || !errorSpy.isEmpty()); + if (!errorSpy.isEmpty()) { + QNetworkSession::SessionError error = + qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0)); + + QVERIFY(session.state() == previousState); + + if (error == QNetworkSession::OperationNotSupportedError) { + // The session needed to bring up the interface, + // but the operation is not supported. + QSKIP("Configuration does not support open().", SkipSingle); + } else if (error == QNetworkSession::InvalidConfigurationError) { + // The session needed to bring up the interface, but it is not possible for the + // specified configuration. + if ((session.configuration().state() & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + QFAIL("Failed to open session for Discovered configuration."); + } else { + QSKIP("Cannot test session for non-Discovered configuration.", SkipSingle); + } + } else if (error == QNetworkSession::UnknownSessionError) { + QSKIP("Unknown Session error.", SkipSingle); + } else { + QFAIL("Error opening session."); + } + } else if (!sessionOpenedSpy.isEmpty()) { + QCOMPARE(sessionOpenedSpy.count(), 1); + QVERIFY(sessionClosedSpy.isEmpty()); + QVERIFY(errorSpy.isEmpty()); + + if (expectStateChange) { + QTRY_VERIFY(stateChangedSpy.count() >= 2); + + QNetworkSession::State state = + qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(0).at(0)); + QVERIFY(state == QNetworkSession::Connecting); + + state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(1).at(0)); + QVERIFY(state == QNetworkSession::Connected); + } + + QVERIFY(session.state() == QNetworkSession::Connected); +#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__)) + // On Symbian emulator, the support for data bearers is limited + QVERIFY(session.interface().isValid()); +#endif + } else { + QFAIL("Timeout waiting for session to open."); + } + } + + sessionOpenedSpy.clear(); + sessionClosedSpy.clear(); + stateChangedSpy.clear(); + errorSpy.clear(); + + QNetworkSession session2(configuration); + + QSignalSpy sessionOpenedSpy2(&session2, SIGNAL(opened())); + QSignalSpy sessionClosedSpy2(&session2, SIGNAL(closed())); + QSignalSpy stateChangedSpy2(&session2, SIGNAL(stateChanged(QNetworkSession::State))); + QSignalSpy errorSpy2(&session2, SIGNAL(error(QNetworkSession::SessionError))); + + // Test opening a second session. + { + QVERIFY(session2.configuration() == configuration); + QVERIFY(!session2.isOpen()); + QVERIFY(session2.state() == QNetworkSession::Connected); + QVERIFY(session.error() == QNetworkSession::UnknownSessionError); + + session2.open(); + + QTRY_VERIFY(!sessionOpenedSpy2.isEmpty() || !errorSpy2.isEmpty()); + + QVERIFY(session.isOpen()); + QVERIFY(session2.isOpen()); + QVERIFY(session.state() == QNetworkSession::Connected); + QVERIFY(session2.state() == QNetworkSession::Connected); +#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__)) + // On Symbian emulator, the support for data bearers is limited + QVERIFY(session.interface().isValid()); +#endif + QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress()); + QCOMPARE(session.interface().index(), session2.interface().index()); + } + + sessionOpenedSpy2.clear(); + + if (forceSessionStop) { + // Test forcing the second session to stop the interface. + QNetworkSession::State previousState = session.state(); +#ifdef Q_CC_NOKIAX86 + // For S60 emulator builds: RConnection::Stop does not work on all Emulators + bool expectStateChange = false; +#else + bool expectStateChange = previousState != QNetworkSession::Disconnected; +#endif + + session2.stop(); + + QTRY_VERIFY(!sessionClosedSpy2.isEmpty() || !errorSpy2.isEmpty()); + + QVERIFY(!session2.isOpen()); + + if (!errorSpy2.isEmpty()) { + QVERIFY(!errorSpy.isEmpty()); + + // check for SessionAbortedError + QNetworkSession::SessionError error = + qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0)); + QNetworkSession::SessionError error2 = + qvariant_cast<QNetworkSession::SessionError>(errorSpy2.first().at(0)); + + QVERIFY(error == QNetworkSession::SessionAbortedError); + QVERIFY(error2 == QNetworkSession::SessionAbortedError); + + QCOMPARE(errorSpy.count(), 1); + QCOMPARE(errorSpy2.count(), 1); + + errorSpy.clear(); + errorSpy2.clear(); + } + + QVERIFY(errorSpy.isEmpty()); + QVERIFY(errorSpy2.isEmpty()); + + if (expectStateChange) + QTRY_VERIFY(stateChangedSpy2.count() >= 2 || !errorSpy2.isEmpty()); + + if (!errorSpy2.isEmpty()) { + QVERIFY(session2.state() == previousState); + QVERIFY(session.state() == previousState); + + QNetworkSession::SessionError error = + qvariant_cast<QNetworkSession::SessionError>(errorSpy2.first().at(0)); + if (error == QNetworkSession::OperationNotSupportedError) { + // The session needed to bring down the interface, + // but the operation is not supported. + QSKIP("Configuration does not support stop().", SkipSingle); + } else if (error == QNetworkSession::InvalidConfigurationError) { + // The session needed to bring down the interface, but it is not possible for the + // specified configuration. + if ((session.configuration().state() & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + QFAIL("Failed to stop session for Discovered configuration."); + } else { + QSKIP("Cannot test session for non-Discovered configuration.", SkipSingle); + } + } else { + QFAIL("Error stopping session."); + } + } else if (!sessionClosedSpy2.isEmpty()) { + if (expectStateChange) { + if (configuration.type() == QNetworkConfiguration::ServiceNetwork) { + bool roamedSuccessfully = false; + + QCOMPARE(stateChangedSpy2.count(), 4); + + QNetworkSession::State state = + qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0)); + QVERIFY(state == QNetworkSession::Connecting); + + state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0)); + QVERIFY(state == QNetworkSession::Connected); + + state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(2).at(0)); + QVERIFY(state == QNetworkSession::Closing); + + state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(3).at(0)); + QVERIFY(state == QNetworkSession::Disconnected); + + QTRY_VERIFY(stateChangedSpy.count() > 0); + state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(0).at(0)); + if (state == QNetworkSession::Roaming) { + QTRY_VERIFY(!errorSpy.isEmpty() || stateChangedSpy.count() > 1); + if (stateChangedSpy.count() > 1) { + state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(1).at(0)); + if (state == QNetworkSession::Connected) { + roamedSuccessfully = true; + QTRY_VERIFY(session2.state() == QNetworkSession::Disconnected); + } + } + } + if (roamedSuccessfully) { + QString configId = session.sessionProperty("ActiveConfiguration").toString(); + QNetworkConfiguration config = manager.configurationFromIdentifier(configId); + QNetworkSession session3(config); + QSignalSpy errorSpy3(&session3, SIGNAL(error(QNetworkSession::SessionError))); + QSignalSpy sessionOpenedSpy3(&session3, SIGNAL(opened())); + + session3.open(); + session3.waitForOpened(); + + if (session.isOpen()) + QVERIFY(!sessionOpenedSpy3.isEmpty() || !errorSpy3.isEmpty()); + + session.stop(); + + QTRY_VERIFY(session.state() == QNetworkSession::Disconnected); + QTRY_VERIFY(session3.state() == QNetworkSession::Disconnected); + } +#ifndef Q_CC_NOKIAX86 + if (!roamedSuccessfully) + QVERIFY(!errorSpy.isEmpty()); +#endif + } else { + QCOMPARE(stateChangedSpy2.count(), 2); + + QNetworkSession::State state = + qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0)); + QVERIFY(state == QNetworkSession::Closing); + + state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0)); + QVERIFY(state == QNetworkSession::Disconnected); + } + + QTRY_VERIFY(!sessionClosedSpy.isEmpty()); + QVERIFY(session.state() == QNetworkSession::Disconnected); + QVERIFY(session2.state() == QNetworkSession::Disconnected); + } + + QVERIFY(errorSpy2.isEmpty()); + + ++inProcessSessionManagementCount; + } else { + QFAIL("Timeout waiting for session to stop."); + } + +#ifndef Q_CC_NOKIAX86 + QVERIFY(!sessionClosedSpy.isEmpty()); +#endif + QVERIFY(!sessionClosedSpy2.isEmpty()); + +#ifndef Q_CC_NOKIAX86 + QVERIFY(!session.isOpen()); +#endif + QVERIFY(!session2.isOpen()); + } else { + // Test closing the second session. + { + int stateChangedCountBeforeClose = stateChangedSpy2.count(); + session2.close(); + + QTRY_VERIFY(!sessionClosedSpy2.isEmpty()); +#ifndef Q_CC_NOKIAX86 + QVERIFY(stateChangedSpy2.count() == stateChangedCountBeforeClose); +#endif + + QVERIFY(sessionClosedSpy.isEmpty()); + + QVERIFY(session.isOpen()); + QVERIFY(!session2.isOpen()); + QVERIFY(session.state() == QNetworkSession::Connected); + QVERIFY(session2.state() == QNetworkSession::Connected); +#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__)) + // On Symbian emulator, the support for data bearers is limited + QVERIFY(session.interface().isValid()); +#endif + QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress()); + QCOMPARE(session.interface().index(), session2.interface().index()); + } + + sessionClosedSpy2.clear(); + + // Test closing the first session. + { +#ifdef Q_CC_NOKIAX86 + // For S60 emulator builds: RConnection::Close does not actually + // close network connection on all Emulators + bool expectStateChange = false; +#else + bool expectStateChange = session.state() != QNetworkSession::Disconnected && + manager.capabilities() & QNetworkConfigurationManager::SystemSessionSupport; +#endif + + session.close(); + + QTRY_VERIFY(!sessionClosedSpy.isEmpty() || !errorSpy.isEmpty()); + + QVERIFY(!session.isOpen()); + + if (expectStateChange) + QTRY_VERIFY(!stateChangedSpy.isEmpty() || !errorSpy.isEmpty()); + + if (!errorSpy.isEmpty()) { + QNetworkSession::SessionError error = + qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0)); + if (error == QNetworkSession::OperationNotSupportedError) { + // The session needed to bring down the interface, + // but the operation is not supported. + QSKIP("Configuration does not support close().", SkipSingle); + } else if (error == QNetworkSession::InvalidConfigurationError) { + // The session needed to bring down the interface, but it is not possible for the + // specified configuration. + if ((session.configuration().state() & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + QFAIL("Failed to close session for Discovered configuration."); + } else { + QSKIP("Cannot test session for non-Discovered configuration.", SkipSingle); + } + } else { + QFAIL("Error closing session."); + } + } else if (!sessionClosedSpy.isEmpty()) { + QVERIFY(sessionOpenedSpy.isEmpty()); + QCOMPARE(sessionClosedSpy.count(), 1); + if (expectStateChange) + QVERIFY(!stateChangedSpy.isEmpty()); + QVERIFY(errorSpy.isEmpty()); + + if (expectStateChange) + QTRY_VERIFY(session.state() == QNetworkSession::Disconnected); + + ++inProcessSessionManagementCount; + } else { + QFAIL("Timeout waiting for session to close."); + } + } + } +} + +QDebug operator<<(QDebug debug, const QList<QNetworkConfiguration> &list) +{ + debug.nospace() << "( "; + foreach (const QNetworkConfiguration &config, list) + debug.nospace() << config.identifier() << ", "; + debug.nospace() << ")\n"; + return debug; +} + +// Note: outOfProcessSession requires that at least one configuration is +// at Discovered -state (Defined is ok for symbian as well, as long as it is possible to open). +void tst_QNetworkSession::outOfProcessSession() +{ + qDebug() << "START"; + +#if defined(Q_OS_SYMBIAN) && defined(__WINS__) + QSKIP("Symbian emulator does not support two [QR]PRocesses linking a dll (QtBearer.dll) with global writeable static data.", SkipAll); +#endif + QNetworkConfigurationManager manager; + // Create a QNetworkConfigurationManager to detect configuration changes made in Lackey. This + // is actually the essence of this testcase - to check that platform mediates/reflects changes + // regardless of process boundaries. The interprocess communication is more like a way to get + // this test-case act correctly and timely. + QList<QNetworkConfiguration> before = manager.allConfigurations(QNetworkConfiguration::Active); + QSignalSpy spy(&manager, SIGNAL(configurationChanged(QNetworkConfiguration))); + + // Cannot read/write to processes on WinCE or Symbian. + // Easiest alternative is to use sockets for IPC. + QLocalServer oopServer; + // First remove possible earlier listening address which would cause listen to fail + // (e.g. previously abruptly ended unit test might cause this) + QLocalServer::removeServer("tst_qnetworksession"); + oopServer.listen("tst_qnetworksession"); + + qDebug() << "starting lackey"; + QProcess lackey; + lackey.start("qnetworksessionlackey"); + qDebug() << lackey.error() << lackey.errorString(); + QVERIFY(lackey.waitForStarted()); + + qDebug() << "waiting for connection"; + QVERIFY(oopServer.waitForNewConnection(-1)); + QLocalSocket *oopSocket = oopServer.nextPendingConnection(); + qDebug() << "got connection"; + do { + QByteArray output; + + if (oopSocket->waitForReadyRead()) + output = oopSocket->readLine().trimmed(); + + if (output.startsWith("Started session ")) { + QString identifier = QString::fromLocal8Bit(output.mid(20).constData()); + QNetworkConfiguration changed; + + do { + QTRY_VERIFY(!spy.isEmpty()); + changed = qvariant_cast<QNetworkConfiguration>(spy.takeFirst().at(0)); + } while (changed.identifier() != identifier); + + QVERIFY((changed.state() & QNetworkConfiguration::Active) == + QNetworkConfiguration::Active); + + QVERIFY(!before.contains(changed)); + + QList<QNetworkConfiguration> after = + manager.allConfigurations(QNetworkConfiguration::Active); + + QVERIFY(after.contains(changed)); + + spy.clear(); + + oopSocket->write("stop\n"); + oopSocket->waitForBytesWritten(); + + do { + QTRY_VERIFY(!spy.isEmpty()); + + changed = qvariant_cast<QNetworkConfiguration>(spy.takeFirst().at(0)); + } while (changed.identifier() != identifier); + + QVERIFY((changed.state() & QNetworkConfiguration::Active) != + QNetworkConfiguration::Active); + + QList<QNetworkConfiguration> afterStop = + manager.allConfigurations(QNetworkConfiguration::Active); + + QVERIFY(!afterStop.contains(changed)); + + oopSocket->disconnectFromServer(); + oopSocket->waitForDisconnected(-1); + + lackey.waitForFinished(); + } + // This is effected by QTBUG-4903, process will always report as running + //} while (lackey.state() == QProcess::Running); + + // Workaround: the socket in the lackey will disconnect on exit + } while (oopSocket->state() == QLocalSocket::ConnectedState); + + switch (lackey.exitCode()) { + case 0: + qDebug("Lackey returned exit success (0)"); + break; + case 1: + QSKIP("No discovered configurations found.", SkipAll); + case 2: + QSKIP("Lackey could not start session.", SkipAll); + default: + QSKIP("Lackey failed", SkipAll); + } + qDebug("STOP"); +} + +QTEST_MAIN(tst_QNetworkSession) + +#include "tst_qnetworksession.moc" + diff --git a/tests/auto/qnetworksession/tst_qnetworksession/tst_qnetworksession.pro b/tests/auto/qnetworksession/tst_qnetworksession/tst_qnetworksession.pro new file mode 100644 index 0000000..cad388c --- /dev/null +++ b/tests/auto/qnetworksession/tst_qnetworksession/tst_qnetworksession.pro @@ -0,0 +1,15 @@ +load(qttest_p4) +SOURCES += tst_qnetworksession.cpp +HEADERS += ../../qbearertestcommon.h + +QT = core network + +symbian { + TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData PowerMgmt +} + +maemo6 { + CONFIG += link_pkgconfig + + PKGCONFIG += conninet +} diff --git a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp index 8e26696..ac9ca46 100644 --- a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp +++ b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp @@ -832,6 +832,7 @@ void tst_QScriptEngineAgent::functionEntryAndExit_builtin_data() /** check behaiviour of built-in function */ void tst_QScriptEngineAgent::functionEntryAndExit_builtin() { + QSKIP("The test fails on platforms others than Linux. The issue will be fixed with next JSC update", SkipAll); QFETCH(QString, script); QFETCH(QString, result); QScriptEngine eng; diff --git a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp index b2a85d7..41df98c 100644 --- a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp +++ b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp @@ -683,8 +683,72 @@ tst_Suite::tst_Suite() addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 7", willFixInNextReleaseMessage); addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 26", willFixInNextReleaseMessage); +#ifndef Q_CC_MINGW addExpectedFailure("ecma/Expressions/11.4.7-02.js", "-(-2147483648) == 2147483648", willFixInNextReleaseMessage); addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "- -\"0x80000000\"", willFixInNextReleaseMessage); +#endif + +#ifdef Q_OS_WIN + addExpectedFailure("ecma_3/Expressions/11.7.3-01.js", "11.7.3 - >>> should evaluate operands in order: order", "QTBUG-8056"); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.7.3 >>>", "QTBUG-8056"); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 >>>=", "QTBUG-8056"); +#endif + +#ifdef Q_CC_MINGW + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(Infinity, Infinity)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(Infinity, -Infinity)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-Infinity, Infinity)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-Infinity, -Infinity)", willFixInNextReleaseMessage); +#endif + +#ifdef Q_OS_SOLARIS + addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = 1; VAR2= -0; VAR1 /= VAR2", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -1; VAR2= -0; VAR1 /= VAR2", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.5.2.js", "Number.POSITIVE_INFINITY / -0", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.5.2.js", "Number.NEGATIVE_INFINITY / -0", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.5.2.js", "1 / -0", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.5.2.js", "-1 / -0", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.10.js", "Math.log(-0.0000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.10.js", "Math.log(-1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.11.js", "Infinity/Math.max(-0,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.12.js", "Infinity/Math.min(0,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.12.js", "Infinity/Math.min(-0,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-Infinity, -1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -0.5)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -1000)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-0, 1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-0, 3)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-0, -2)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0.49)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0.5)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.17.js", "Infinity/Math.sqrt(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.18.js", "Infinity/Math.tan(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.2.js", "Math.acos(1.00000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.2.js", "Math.acos(11.00000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.3.js", "Math.asin(1.000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.3.js", "Math.asin(-1.000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.3.js", "Infinity/Math.asin(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.4.js", "Infinity/Math.atan(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(0, -0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Infinity/Math.atan2(-0, 1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-0,\t-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-0,\t-1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil('-0')", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-Number.MIN_VALUE)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-0.9)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.9.js", "Infinity/Math.floor(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "var z = 0; print(1/-z)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "1/-1e-2000", willFixInNextReleaseMessage); +#endif static const char klass[] = "tst_QScriptJsTestSuite"; diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp index 147896e..a3dfd6c 100644 --- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp +++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp @@ -236,6 +236,16 @@ tst_Suite::tst_Suite() addExpectedFailure("global-const-var-conflicts", "false", "true", willFixInNextReleaseMessage); addExpectedFailure("string-lastindexof", "0", "-1", "test is wrong?"); +#ifndef Q_OS_LINUX + addExpectedFailure("to-precision", "1.235e+27", "1.234e+27", "QTBUG-8053: toPrecision(4) gives wrong result on Mac"); +#endif + +#ifdef Q_OS_SOLARIS + addExpectedFailure("math-min-max", "Infinity", "-Infinity", willFixInNextReleaseMessage); + addExpectedFailure("negate-zero", "false", "true", willFixInNextReleaseMessage); + addExpectedFailure("str-to-num", "Infinity", "-Infinity", willFixInNextReleaseMessage); +#endif + addTestExclusion("debug-*", "not applicable"); addTestExclusion("mirror-*", "not applicable"); @@ -245,6 +255,10 @@ tst_Suite::tst_Suite() addTestExclusion("string-case", "V8-specific behavior? (Doesn't pass on SpiderMonkey either)"); +#ifdef Q_CC_MINGW + addTestExclusion("date$", "QTBUG-7698: Date.prototype.setMonth() crashes on win32-g++"); +#endif + #ifdef Q_OS_WINCE addTestExclusion("deep-recursion", "Demands too much memory on WinCE"); addTestExclusion("nested-repetition-count-overflow", "Demands too much memory on WinCE"); diff --git a/tests/auto/qscriptvalue/testgen/data.txt b/tests/auto/qscriptvalue/testgen/data.txt index 8e7026e..a041c9b 100644 --- a/tests/auto/qscriptvalue/testgen/data.txt +++ b/tests/auto/qscriptvalue/testgen/data.txt @@ -114,3 +114,7 @@ engine->evaluate("/foo/") engine->evaluate("new Object()") engine->evaluate("new Array()") engine->evaluate("new Error()") + +#other +engine->nullValue() +engine->undefinedValue()
\ No newline at end of file diff --git a/tests/auto/qscriptvalue/testgen/gen.py b/tests/auto/qscriptvalue/testgen/gen.py index 7161e6b..b3c81b9 100755 --- a/tests/auto/qscriptvalue/testgen/gen.py +++ b/tests/auto/qscriptvalue/testgen/gen.py @@ -231,7 +231,7 @@ if __name__ == '__main__': row_esc = escape(row) out.append(qsvTempl.substitute(expr = row, expr_esc = row_esc)) - result = mainTempl.substitute(dump= "".join(out) \ + result = mainTempl.safe_substitute(dump= "".join(out) \ , values = (11 * ' ' + '<< ').join(qsv) \ , count = len(qsv) \ , dataTags = (11 * ' ' + '<< ').join(map(lambda w: '"' + escape(w.replace('\n','')) + '"\n', qsv))) diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue_generated.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue_generated.cpp index 1d105b4..4e621b3 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue_generated.cpp +++ b/tests/auto/qscriptvalue/tst_qscriptvalue_generated.cpp @@ -152,6 +152,8 @@ void tst_QScriptValue::initScriptValues() DEFINE_TEST_VALUE(engine->evaluate("new Object()")); DEFINE_TEST_VALUE(engine->evaluate("new Array()")); DEFINE_TEST_VALUE(engine->evaluate("new Error()")); + DEFINE_TEST_VALUE(engine->nullValue()); + DEFINE_TEST_VALUE(engine->undefinedValue()); } @@ -267,6 +269,8 @@ void tst_QScriptValue::isValid_makeData(const char* expr) << "engine->evaluate(\"new Object()\")" << "engine->evaluate(\"new Array()\")" << "engine->evaluate(\"new Error()\")" + << "engine->nullValue()" + << "engine->undefinedValue()" ; } newRow(expr) << isValid.contains(expr); @@ -453,6 +457,7 @@ void tst_QScriptValue::isNull_makeData(const char* expr) isNull << "QScriptValue(QScriptValue::NullValue)" << "QScriptValue(0, QScriptValue::NullValue)" << "QScriptValue(engine, QScriptValue::NullValue)" + << "engine->nullValue()" ; } newRow(expr) << isNull.contains(expr); @@ -535,6 +540,7 @@ void tst_QScriptValue::isUndefined_makeData(const char* expr) << "QScriptValue(0, QScriptValue::UndefinedValue)" << "QScriptValue(engine, QScriptValue::UndefinedValue)" << "engine->evaluate(\"{}\")" + << "engine->undefinedValue()" ; } newRow(expr) << isUndefined.contains(expr); @@ -810,6 +816,8 @@ void tst_QScriptValue::toString_makeData(const char* expr) toString.insert("engine->evaluate(\"new Object()\")", "[object Object]"); toString.insert("engine->evaluate(\"new Array()\")", ""); toString.insert("engine->evaluate(\"new Error()\")", "Error: Unknown error"); + toString.insert("engine->nullValue()", "null"); + toString.insert("engine->undefinedValue()", "undefined"); } newRow(expr) << toString.value(expr); } @@ -936,6 +944,8 @@ void tst_QScriptValue::toNumber_makeData(const char* expr) toNumber.insert("engine->evaluate(\"new Object()\")", qQNaN()); toNumber.insert("engine->evaluate(\"new Array()\")", 0); toNumber.insert("engine->evaluate(\"new Error()\")", qQNaN()); + toNumber.insert("engine->nullValue()", 0); + toNumber.insert("engine->undefinedValue()", qQNaN()); } newRow(expr) << toNumber.value(expr); } @@ -1070,6 +1080,8 @@ void tst_QScriptValue::toBool_makeData(const char* expr) toBool.insert("engine->evaluate(\"new Object()\")", true); toBool.insert("engine->evaluate(\"new Array()\")", true); toBool.insert("engine->evaluate(\"new Error()\")", true); + toBool.insert("engine->nullValue()", false); + toBool.insert("engine->undefinedValue()", false); } newRow(expr) << toBool.value(expr); } @@ -1196,6 +1208,8 @@ void tst_QScriptValue::toBoolean_makeData(const char* expr) toBoolean.insert("engine->evaluate(\"new Object()\")", true); toBoolean.insert("engine->evaluate(\"new Array()\")", true); toBoolean.insert("engine->evaluate(\"new Error()\")", true); + toBoolean.insert("engine->nullValue()", false); + toBoolean.insert("engine->undefinedValue()", false); } newRow(expr) << toBoolean.value(expr); } @@ -1322,6 +1336,8 @@ void tst_QScriptValue::toInteger_makeData(const char* expr) toInteger.insert("engine->evaluate(\"new Object()\")", 0); toInteger.insert("engine->evaluate(\"new Array()\")", 0); toInteger.insert("engine->evaluate(\"new Error()\")", 0); + toInteger.insert("engine->nullValue()", 0); + toInteger.insert("engine->undefinedValue()", 0); } newRow(expr) << toInteger.value(expr); } @@ -1452,6 +1468,8 @@ void tst_QScriptValue::toInt32_makeData(const char* expr) toInt32.insert("engine->evaluate(\"new Object()\")", 0); toInt32.insert("engine->evaluate(\"new Array()\")", 0); toInt32.insert("engine->evaluate(\"new Error()\")", 0); + toInt32.insert("engine->nullValue()", 0); + toInt32.insert("engine->undefinedValue()", 0); } newRow(expr) << toInt32.value(expr); } @@ -1578,6 +1596,8 @@ void tst_QScriptValue::toUInt32_makeData(const char* expr) toUInt32.insert("engine->evaluate(\"new Object()\")", 0); toUInt32.insert("engine->evaluate(\"new Array()\")", 0); toUInt32.insert("engine->evaluate(\"new Error()\")", 0); + toUInt32.insert("engine->nullValue()", 0); + toUInt32.insert("engine->undefinedValue()", 0); } newRow(expr) << toUInt32.value(expr); } @@ -1704,6 +1724,8 @@ void tst_QScriptValue::toUInt16_makeData(const char* expr) toUInt16.insert("engine->evaluate(\"new Object()\")", 0); toUInt16.insert("engine->evaluate(\"new Array()\")", 0); toUInt16.insert("engine->evaluate(\"new Error()\")", 0); + toUInt16.insert("engine->nullValue()", 0); + toUInt16.insert("engine->undefinedValue()", 0); } newRow(expr) << toUInt16.value(expr); } @@ -1736,6 +1758,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); @@ -1743,6 +1767,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(QScriptValue::NullValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(QScriptValue::NullValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(true) <=> QScriptValue(true)"); equals.insert("QScriptValue(true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(true) <=> QScriptValue(engine, true)"); @@ -1937,6 +1963,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); @@ -1944,6 +1972,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(0, true) <=> QScriptValue(true)"); equals.insert("QScriptValue(0, true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(0, true) <=> QScriptValue(engine, true)"); @@ -2138,6 +2168,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); @@ -2145,6 +2177,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(true)"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(engine, true)"); @@ -2355,6 +2389,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("engine->evaluate(\"{}\") <=> engine->evaluate(\"{}\")"); + equals.insert("engine->evaluate(\"{}\") <=> engine->nullValue()"); + equals.insert("engine->evaluate(\"{}\") <=> engine->undefinedValue()"); equals.insert("engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"Object.prototype\")"); equals.insert("engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Date.prototype\")"); equals.insert("engine->evaluate(\"Array.prototype\") <=> QScriptValue(false)"); @@ -2401,6 +2437,24 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("engine->evaluate(\"new Array()\") <=> QScriptValue(engine, QString())"); equals.insert("engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Array()\")"); equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("engine->nullValue() <=> QScriptValue(QScriptValue::UndefinedValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> engine->evaluate(\"{}\")"); + equals.insert("engine->nullValue() <=> engine->nullValue()"); + equals.insert("engine->nullValue() <=> engine->undefinedValue()"); + equals.insert("engine->undefinedValue() <=> QScriptValue(QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(QScriptValue::NullValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(0, QScriptValue::NullValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("engine->undefinedValue() <=> engine->evaluate(\"{}\")"); + equals.insert("engine->undefinedValue() <=> engine->nullValue()"); + equals.insert("engine->undefinedValue() <=> engine->undefinedValue()"); } QHash<QString, QScriptValue>::const_iterator it; for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { @@ -2435,9 +2489,11 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("QScriptValue(QScriptValue::NullValue) <=> engine->nullValue()"); equals.insert("QScriptValue(true) <=> QScriptValue(true)"); equals.insert("QScriptValue(true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(true) <=> QScriptValue(engine, true)"); @@ -2530,9 +2586,11 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> engine->nullValue()"); equals.insert("QScriptValue(0, true) <=> QScriptValue(true)"); equals.insert("QScriptValue(0, true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(0, true) <=> QScriptValue(engine, true)"); @@ -2625,9 +2683,11 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> engine->nullValue()"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(true)"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(engine, true)"); @@ -2721,6 +2781,7 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("engine->evaluate(\"{}\") <=> QScriptValue(0, QScriptValue::UndefinedValue)"); equals.insert("engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("engine->evaluate(\"{}\") <=> engine->evaluate(\"{}\")"); + equals.insert("engine->evaluate(\"{}\") <=> engine->undefinedValue()"); equals.insert("engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"Object.prototype\")"); equals.insert("engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Date.prototype\")"); equals.insert("engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"Array.prototype\")"); @@ -2737,6 +2798,15 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("engine->evaluate(\"new Object()\") <=> engine->evaluate(\"new Object()\")"); equals.insert("engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Array()\")"); equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("engine->nullValue() <=> QScriptValue(QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> engine->nullValue()"); + equals.insert("engine->undefinedValue() <=> QScriptValue(QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> engine->evaluate(\"{}\")"); + equals.insert("engine->undefinedValue() <=> engine->undefinedValue()"); } QHash<QString, QScriptValue>::const_iterator it; for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { @@ -3090,6 +3160,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(-6.37e-8) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(-6.37e-8) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(-6.37e-8) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(-6.37e-8) <=> engine->nullValue()"); equals.insert("QScriptValue(0x43211234) <=> QScriptValue(qInf())"); equals.insert("QScriptValue(0x43211234) <=> QScriptValue(\"Infinity\")"); equals.insert("QScriptValue(0x43211234) <=> QScriptValue(0, qInf())"); @@ -3180,6 +3251,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(-qInf()) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(-qInf()) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(-qInf()) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(-qInf()) <=> engine->nullValue()"); equals.insert("QScriptValue(\"NaN\") <=> QScriptValue(\"ciao\")"); equals.insert("QScriptValue(\"NaN\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))"); equals.insert("QScriptValue(\"NaN\") <=> QScriptValue(0, \"ciao\")"); @@ -3291,6 +3363,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(\"-Infinity\") <=> engine->evaluate(\"/foo/\")"); equals.insert("QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Object()\")"); equals.insert("QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("QScriptValue(\"-Infinity\") <=> engine->nullValue()"); equals.insert("QScriptValue(\"ciao\") <=> engine->evaluate(\"Function.prototype\")"); equals.insert("QScriptValue(\"ciao\") <=> engine->evaluate(\"Object\")"); equals.insert("QScriptValue(\"ciao\") <=> engine->evaluate(\"Array\")"); @@ -3903,6 +3976,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(0, -6.37e-8) <=> engine->nullValue()"); equals.insert("QScriptValue(0, 0x43211234) <=> QScriptValue(qInf())"); equals.insert("QScriptValue(0, 0x43211234) <=> QScriptValue(\"Infinity\")"); equals.insert("QScriptValue(0, 0x43211234) <=> QScriptValue(0, qInf())"); @@ -3993,6 +4067,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(0, -qInf()) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(0, -qInf()) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(0, -qInf()) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(0, -qInf()) <=> engine->nullValue()"); equals.insert("QScriptValue(0, \"NaN\") <=> QScriptValue(\"ciao\")"); equals.insert("QScriptValue(0, \"NaN\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))"); equals.insert("QScriptValue(0, \"NaN\") <=> QScriptValue(0, \"ciao\")"); @@ -4104,6 +4179,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"/foo/\")"); equals.insert("QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Object()\")"); equals.insert("QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("QScriptValue(0, \"-Infinity\") <=> engine->nullValue()"); equals.insert("QScriptValue(0, \"ciao\") <=> engine->evaluate(\"Function.prototype\")"); equals.insert("QScriptValue(0, \"ciao\") <=> engine->evaluate(\"Object\")"); equals.insert("QScriptValue(0, \"ciao\") <=> engine->evaluate(\"Array\")"); @@ -4717,6 +4793,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(engine, -6.37e-8) <=> engine->nullValue()"); equals.insert("QScriptValue(engine, 0x43211234) <=> QScriptValue(qInf())"); equals.insert("QScriptValue(engine, 0x43211234) <=> QScriptValue(\"Infinity\")"); equals.insert("QScriptValue(engine, 0x43211234) <=> QScriptValue(0, qInf())"); @@ -4807,6 +4884,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(engine, -qInf()) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(engine, -qInf()) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(engine, -qInf()) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(engine, -qInf()) <=> engine->nullValue()"); equals.insert("QScriptValue(engine, \"NaN\") <=> QScriptValue(\"ciao\")"); equals.insert("QScriptValue(engine, \"NaN\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))"); equals.insert("QScriptValue(engine, \"NaN\") <=> QScriptValue(0, \"ciao\")"); @@ -4918,6 +4996,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"/foo/\")"); equals.insert("QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Object()\")"); equals.insert("QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("QScriptValue(engine, \"-Infinity\") <=> engine->nullValue()"); equals.insert("QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"Function.prototype\")"); equals.insert("QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"Object\")"); equals.insert("QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"Array\")"); @@ -5533,6 +5612,42 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")"); equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")"); equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Object()\")"); + equals.insert("engine->nullValue() <=> QScriptValue(true)"); + equals.insert("engine->nullValue() <=> QScriptValue(int(122))"); + equals.insert("engine->nullValue() <=> QScriptValue(uint(124))"); + equals.insert("engine->nullValue() <=> QScriptValue(123.0)"); + equals.insert("engine->nullValue() <=> QScriptValue(6.37e-8)"); + equals.insert("engine->nullValue() <=> QScriptValue(0x43211234)"); + equals.insert("engine->nullValue() <=> QScriptValue(0x10000)"); + equals.insert("engine->nullValue() <=> QScriptValue(0x10001)"); + equals.insert("engine->nullValue() <=> QScriptValue(qInf())"); + equals.insert("engine->nullValue() <=> QScriptValue(\"Infinity\")"); + equals.insert("engine->nullValue() <=> QScriptValue(QString(\"123\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(QString(\"12.4\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(0, true)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, int(122))"); + equals.insert("engine->nullValue() <=> QScriptValue(0, uint(124))"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 123.0)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 6.37e-8)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 0x43211234)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 0x10000)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 0x10001)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, qInf())"); + equals.insert("engine->nullValue() <=> QScriptValue(0, \"Infinity\")"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QString(\"123\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QString(\"12.3\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, true)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, int(122))"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, uint(124))"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 123.0)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 6.37e-8)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 0x43211234)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 0x10000)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 0x10001)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, qInf())"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, \"Infinity\")"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QString(\"123\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QString(\"1.23\"))"); } QHash<QString, QScriptValue>::const_iterator it; for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { @@ -5718,6 +5833,8 @@ void tst_QScriptValue::qscriptvalue_castQString_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", "[object Object]"); value.insert("engine->evaluate(\"new Array()\")", ""); value.insert("engine->evaluate(\"new Error()\")", "Error: Unknown error"); + value.insert("engine->nullValue()", ""); + value.insert("engine->undefinedValue()", ""); } newRow(expr) << value.value(expr); } @@ -5844,6 +5961,8 @@ void tst_QScriptValue::qscriptvalue_castqsreal_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", qQNaN()); value.insert("engine->evaluate(\"new Array()\")", 0); value.insert("engine->evaluate(\"new Error()\")", qQNaN()); + value.insert("engine->nullValue()", 0); + value.insert("engine->undefinedValue()", qQNaN()); } newRow(expr) << value.value(expr); } @@ -5978,6 +6097,8 @@ void tst_QScriptValue::qscriptvalue_castbool_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", true); value.insert("engine->evaluate(\"new Array()\")", true); value.insert("engine->evaluate(\"new Error()\")", true); + value.insert("engine->nullValue()", false); + value.insert("engine->undefinedValue()", false); } newRow(expr) << value.value(expr); } @@ -6104,6 +6225,8 @@ void tst_QScriptValue::qscriptvalue_castqint32_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", 0); value.insert("engine->evaluate(\"new Array()\")", 0); value.insert("engine->evaluate(\"new Error()\")", 0); + value.insert("engine->nullValue()", 0); + value.insert("engine->undefinedValue()", 0); } newRow(expr) << value.value(expr); } @@ -6230,6 +6353,8 @@ void tst_QScriptValue::qscriptvalue_castquint32_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", 0); value.insert("engine->evaluate(\"new Array()\")", 0); value.insert("engine->evaluate(\"new Error()\")", 0); + value.insert("engine->nullValue()", 0); + value.insert("engine->undefinedValue()", 0); } newRow(expr) << value.value(expr); } @@ -6356,6 +6481,8 @@ void tst_QScriptValue::qscriptvalue_castquint16_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", 0); value.insert("engine->evaluate(\"new Array()\")", 0); value.insert("engine->evaluate(\"new Error()\")", 0); + value.insert("engine->nullValue()", 0); + value.insert("engine->undefinedValue()", 0); } newRow(expr) << value.value(expr); } diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 5b61da2..fe084fa 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -202,6 +202,8 @@ private slots: void sqlStatementUseIsNull_189093_data() { generic_data(); } void sqlStatementUseIsNull_189093(); + void sqlite_enable_cache_mode_data() { generic_data("QSQLITE"); } + void sqlite_enable_cache_mode(); private: void createTestTables(QSqlDatabase db); @@ -2485,5 +2487,23 @@ void tst_QSqlDatabase::oci_tables() QVERIFY(db.tables(QSql::SystemTables).contains(systemTableName.toUpper())); } +void tst_QSqlDatabase::sqlite_enable_cache_mode() +{ + QFETCH(QString, dbName); + if(dbName.endsWith(":memory:")) + QSKIP( "cache mode is meaningless for :memory: databases", SkipSingle ); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + db.close(); + db.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE"); + QVERIFY_SQL(db, open()); + QSqlDatabase db2 = QSqlDatabase::cloneDatabase(db, dbName+":cachemodeconn2"); + db2.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE"); + QVERIFY_SQL(db2, open()); + QSqlQuery q(db), q2(db2); + QVERIFY_SQL(q, exec("select * from "+qTableName("qtest"))); + QVERIFY_SQL(q2, exec("select * from "+qTableName("qtest"))); +} + QTEST_MAIN(tst_QSqlDatabase) #include "tst_qsqldatabase.moc" diff --git a/tests/auto/qtextcodec/tst_qtextcodec.cpp b/tests/auto/qtextcodec/tst_qtextcodec.cpp index eb348fb..65b0448 100644 --- a/tests/auto/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/qtextcodec/tst_qtextcodec.cpp @@ -47,6 +47,8 @@ #include <qtextdocument.h> #include <time.h> #include <qprocess.h> +#include <QtConcurrentMap> +#include <QThreadPool> #ifdef Q_OS_SYMBIAN #define SRCDIR "" @@ -58,6 +60,9 @@ class tst_QTextCodec : public QObject Q_OBJECT private slots: + + void threadSafety(); + void toUnicode_data(); void toUnicode(); void codecForName_data(); @@ -1904,5 +1909,46 @@ void tst_QTextCodec::toLocal8Bit() } #endif +static QByteArray loadAndConvert(const QByteArray &codecName) +{ + QTextCodec *c = QTextCodec::codecForName(codecName); + if (!c) { + qDebug() << "WARNING " << codecName << " not found? "; + return QByteArray(); + } + QString str = QString::fromLatin1(codecName); + QByteArray b = c->fromUnicode(str); + c->toUnicode(b); + return codecName; +} + +static int loadAndConvertMIB(int mib) +{ + QTextCodec *c = QTextCodec::codecForMib(mib); + if (!c) { + qDebug() << "WARNING " << mib << " not found? "; + return 0; + } + QString str = QString::number(mib); + QByteArray b = c->fromUnicode(str); + c->toUnicode(b); + return mib; +} + + +void tst_QTextCodec::threadSafety() +{ + QThreadPool::globalInstance()->setMaxThreadCount(12); + + QList<QByteArray> codecList = QTextCodec::availableCodecs(); + QFuture<QByteArray> res = QtConcurrent::mapped(codecList, loadAndConvert); + + QList<int> mibList = QTextCodec::availableMibs(); + QFuture<int> res2 = QtConcurrent::mapped(mibList, loadAndConvertMIB); + + QCOMPARE(res.results(), codecList); + QCOMPARE(res2.results(), mibList); +} + QTEST_MAIN(tst_QTextCodec) #include "tst_qtextcodec.moc" diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 03eddee..b59017b 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -250,6 +250,7 @@ private slots: #else void persistentWinId(); #endif + void showNativeChild(); void qobject_castInDestroyedSlot(); void showHideEvent_data(); @@ -4586,6 +4587,16 @@ void tst_QWidget::persistentWinId() } #endif // Q_OS_SYMBIAN +void tst_QWidget::showNativeChild() +{ + QWidget topLevel; + topLevel.setGeometry(0, 0, 100, 100); + QWidget child(&topLevel); + child.winId(); + topLevel.show(); + QTest::qWaitForWindowShown(&topLevel); +} + class ShowHideEventWidget : public QWidget { public: diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 7a27cc9..c406d54 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -1,48 +1,8 @@ TEMPLATE = subdirs -SUBDIRS = containers-associative \ - containers-sequential \ - qanimation \ - qbytearray \ - qfileinfo \ - qfile_vs_qnetworkaccessmanager \ - qfontmetrics \ - qhostinfo \ - qpainter \ - qtestlib-simple events \ - qtext \ - qiodevice \ - qpixmap \ - blendbench \ - qstring \ - qstringlist \ - qmatrix4x4 \ - qnetworkreply \ - qobject \ - qrect \ - qregexp \ - qregion \ - qvariant \ - qwidget \ - qtwidgets \ - qapplication \ - qdir \ - qdiriterator \ - qgraphicsanchorlayout \ - qgraphicsitem \ - qgraphicswidget \ - qmetaobject \ - qpixmapcache \ - qquaternion \ - qscriptclass \ - qscriptengine \ - qscriptvalue \ - qstringbuilder \ - qstylesheetstyle \ - qsvgrenderer \ - qtcpserver \ - qtableview \ - qthreadstorage - - - +SUBDIRS = \ + corelib \ + gui \ + network \ + script \ + svg contains(QT_CONFIG, opengl): SUBDIRS += opengl diff --git a/tests/benchmarks/corelib/corelib.pro b/tests/benchmarks/corelib/corelib.pro new file mode 100644 index 0000000..72fca33 --- /dev/null +++ b/tests/benchmarks/corelib/corelib.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = \ + io \ + kernel \ + thread \ + tools diff --git a/tests/benchmarks/corelib/io/io.pro b/tests/benchmarks/corelib/io/io.pro new file mode 100644 index 0000000..97445d7 --- /dev/null +++ b/tests/benchmarks/corelib/io/io.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qdir \ + qdiriterator \ + qfile \ + qfileinfo \ + qiodevice \ + qtemporaryfile + diff --git a/tests/benchmarks/qdir/qdir.pro b/tests/benchmarks/corelib/io/qdir/qdir.pro index 2cdebfd..2cdebfd 100644 --- a/tests/benchmarks/qdir/qdir.pro +++ b/tests/benchmarks/corelib/io/qdir/qdir.pro diff --git a/tests/benchmarks/qdir/tst_qdir.cpp b/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp index aea9fd0..aea9fd0 100644 --- a/tests/benchmarks/qdir/tst_qdir.cpp +++ b/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp diff --git a/tests/benchmarks/qdiriterator/main.cpp b/tests/benchmarks/corelib/io/qdiriterator/main.cpp index afa6b7b..afa6b7b 100644 --- a/tests/benchmarks/qdiriterator/main.cpp +++ b/tests/benchmarks/corelib/io/qdiriterator/main.cpp diff --git a/tests/benchmarks/qdiriterator/qdiriterator.pro b/tests/benchmarks/corelib/io/qdiriterator/qdiriterator.pro index e06d746..e06d746 100755 --- a/tests/benchmarks/qdiriterator/qdiriterator.pro +++ b/tests/benchmarks/corelib/io/qdiriterator/qdiriterator.pro diff --git a/tests/benchmarks/qdiriterator/qfilesystemiterator.cpp b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp index 267d53f..267d53f 100644 --- a/tests/benchmarks/qdiriterator/qfilesystemiterator.cpp +++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp diff --git a/tests/benchmarks/qdiriterator/qfilesystemiterator.h b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h index 4aad3a1..4aad3a1 100644 --- a/tests/benchmarks/qdiriterator/qfilesystemiterator.h +++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h diff --git a/tests/benchmarks/qfile/main.cpp b/tests/benchmarks/corelib/io/qfile/main.cpp index 103b77c..103b77c 100644 --- a/tests/benchmarks/qfile/main.cpp +++ b/tests/benchmarks/corelib/io/qfile/main.cpp diff --git a/tests/benchmarks/qfile/qfile.pro b/tests/benchmarks/corelib/io/qfile/qfile.pro index 99505c3..99505c3 100644 --- a/tests/benchmarks/qfile/qfile.pro +++ b/tests/benchmarks/corelib/io/qfile/qfile.pro diff --git a/tests/benchmarks/qfileinfo/main.cpp b/tests/benchmarks/corelib/io/qfileinfo/main.cpp index 025787f..025787f 100644 --- a/tests/benchmarks/qfileinfo/main.cpp +++ b/tests/benchmarks/corelib/io/qfileinfo/main.cpp diff --git a/tests/benchmarks/qfileinfo/qfileinfo.pro b/tests/benchmarks/corelib/io/qfileinfo/qfileinfo.pro index 295cb50..295cb50 100644 --- a/tests/benchmarks/qfileinfo/qfileinfo.pro +++ b/tests/benchmarks/corelib/io/qfileinfo/qfileinfo.pro diff --git a/tests/benchmarks/qiodevice/main.cpp b/tests/benchmarks/corelib/io/qiodevice/main.cpp index 4af697c..4af697c 100644 --- a/tests/benchmarks/qiodevice/main.cpp +++ b/tests/benchmarks/corelib/io/qiodevice/main.cpp diff --git a/tests/benchmarks/qiodevice/qiodevice.pro b/tests/benchmarks/corelib/io/qiodevice/qiodevice.pro index 749a4d6..749a4d6 100755 --- a/tests/benchmarks/qiodevice/qiodevice.pro +++ b/tests/benchmarks/corelib/io/qiodevice/qiodevice.pro diff --git a/tests/benchmarks/qtemporaryfile/main.cpp b/tests/benchmarks/corelib/io/qtemporaryfile/main.cpp index 8b71189..8b71189 100644 --- a/tests/benchmarks/qtemporaryfile/main.cpp +++ b/tests/benchmarks/corelib/io/qtemporaryfile/main.cpp diff --git a/tests/benchmarks/qtemporaryfile/qtemporaryfile.pro b/tests/benchmarks/corelib/io/qtemporaryfile/qtemporaryfile.pro index c1b04f4..c1b04f4 100644 --- a/tests/benchmarks/qtemporaryfile/qtemporaryfile.pro +++ b/tests/benchmarks/corelib/io/qtemporaryfile/qtemporaryfile.pro diff --git a/tests/benchmarks/events/events.pro b/tests/benchmarks/corelib/kernel/events/events.pro index adf2317..adf2317 100644 --- a/tests/benchmarks/events/events.pro +++ b/tests/benchmarks/corelib/kernel/events/events.pro diff --git a/tests/benchmarks/events/main.cpp b/tests/benchmarks/corelib/kernel/events/main.cpp index 0dd2c18..0dd2c18 100644 --- a/tests/benchmarks/events/main.cpp +++ b/tests/benchmarks/corelib/kernel/events/main.cpp diff --git a/tests/benchmarks/corelib/kernel/kernel.pro b/tests/benchmarks/corelib/kernel/kernel.pro new file mode 100644 index 0000000..91cf3c5 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/kernel.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = \ + events \ + qmetaobject \ + qobject \ + qvariant diff --git a/tests/benchmarks/qmetaobject/main.cpp b/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp index eef6020..eef6020 100644 --- a/tests/benchmarks/qmetaobject/main.cpp +++ b/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp diff --git a/tests/benchmarks/qmetaobject/qmetaobject.pro b/tests/benchmarks/corelib/kernel/qmetaobject/qmetaobject.pro index 78300f6..78300f6 100644 --- a/tests/benchmarks/qmetaobject/qmetaobject.pro +++ b/tests/benchmarks/corelib/kernel/qmetaobject/qmetaobject.pro diff --git a/tests/benchmarks/qobject/main.cpp b/tests/benchmarks/corelib/kernel/qobject/main.cpp index 7f24ebd..7f24ebd 100644 --- a/tests/benchmarks/qobject/main.cpp +++ b/tests/benchmarks/corelib/kernel/qobject/main.cpp diff --git a/tests/benchmarks/qobject/object.cpp b/tests/benchmarks/corelib/kernel/qobject/object.cpp index d775a32..d775a32 100644 --- a/tests/benchmarks/qobject/object.cpp +++ b/tests/benchmarks/corelib/kernel/qobject/object.cpp diff --git a/tests/benchmarks/qobject/object.h b/tests/benchmarks/corelib/kernel/qobject/object.h index 7e4933f..7e4933f 100644 --- a/tests/benchmarks/qobject/object.h +++ b/tests/benchmarks/corelib/kernel/qobject/object.h diff --git a/tests/benchmarks/qobject/qobject.pro b/tests/benchmarks/corelib/kernel/qobject/qobject.pro index 2855de4..2855de4 100644 --- a/tests/benchmarks/qobject/qobject.pro +++ b/tests/benchmarks/corelib/kernel/qobject/qobject.pro diff --git a/tests/benchmarks/qvariant/qvariant.pro b/tests/benchmarks/corelib/kernel/qvariant/qvariant.pro index 63b5442..63b5442 100644 --- a/tests/benchmarks/qvariant/qvariant.pro +++ b/tests/benchmarks/corelib/kernel/qvariant/qvariant.pro diff --git a/tests/benchmarks/qvariant/tst_qvariant.cpp b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp index 82dc7dd..82dc7dd 100644 --- a/tests/benchmarks/qvariant/tst_qvariant.cpp +++ b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp diff --git a/tests/benchmarks/qthreadstorage/qthreadstorage.pro b/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro index f9c1978..f9c1978 100644 --- a/tests/benchmarks/qthreadstorage/qthreadstorage.pro +++ b/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro diff --git a/tests/benchmarks/qthreadstorage/tst_qthreadstorage.cpp b/tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp index faae4d7..faae4d7 100644 --- a/tests/benchmarks/qthreadstorage/tst_qthreadstorage.cpp +++ b/tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp diff --git a/tests/benchmarks/corelib/thread/thread.pro b/tests/benchmarks/corelib/thread/thread.pro new file mode 100644 index 0000000..26570ba --- /dev/null +++ b/tests/benchmarks/corelib/thread/thread.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qthreadstorage diff --git a/tests/benchmarks/containers-associative/containers-associative.pro b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro index c6f3fa6..c6f3fa6 100644 --- a/tests/benchmarks/containers-associative/containers-associative.pro +++ b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro diff --git a/tests/benchmarks/containers-associative/main.cpp b/tests/benchmarks/corelib/tools/containers-associative/main.cpp index 4c6dae4..4c6dae4 100644 --- a/tests/benchmarks/containers-associative/main.cpp +++ b/tests/benchmarks/corelib/tools/containers-associative/main.cpp diff --git a/tests/benchmarks/containers-sequential/containers-sequential.pro b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro index bf6db44..bf6db44 100644 --- a/tests/benchmarks/containers-sequential/containers-sequential.pro +++ b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro diff --git a/tests/benchmarks/containers-sequential/main.cpp b/tests/benchmarks/corelib/tools/containers-sequential/main.cpp index a6e405c..a6e405c 100644 --- a/tests/benchmarks/containers-sequential/main.cpp +++ b/tests/benchmarks/corelib/tools/containers-sequential/main.cpp diff --git a/tests/benchmarks/qbytearray/main.cpp b/tests/benchmarks/corelib/tools/qbytearray/main.cpp index 22d4815..22d4815 100644 --- a/tests/benchmarks/qbytearray/main.cpp +++ b/tests/benchmarks/corelib/tools/qbytearray/main.cpp diff --git a/tests/benchmarks/qbytearray/qbytearray.pro b/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro index a0bf021..a0bf021 100755 --- a/tests/benchmarks/qbytearray/qbytearray.pro +++ b/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro diff --git a/tests/benchmarks/qrect/main.cpp b/tests/benchmarks/corelib/tools/qrect/main.cpp index e293bfa..e293bfa 100644 --- a/tests/benchmarks/qrect/main.cpp +++ b/tests/benchmarks/corelib/tools/qrect/main.cpp diff --git a/tests/benchmarks/qrect/qrect.pro b/tests/benchmarks/corelib/tools/qrect/qrect.pro index 6e35119..6e35119 100644 --- a/tests/benchmarks/qrect/qrect.pro +++ b/tests/benchmarks/corelib/tools/qrect/qrect.pro diff --git a/tests/benchmarks/qregexp/main.cpp b/tests/benchmarks/corelib/tools/qregexp/main.cpp index ab9ed71..ab9ed71 100644 --- a/tests/benchmarks/qregexp/main.cpp +++ b/tests/benchmarks/corelib/tools/qregexp/main.cpp diff --git a/tests/benchmarks/qregexp/qregexp.pro b/tests/benchmarks/corelib/tools/qregexp/qregexp.pro index 83d723c..83d723c 100644 --- a/tests/benchmarks/qregexp/qregexp.pro +++ b/tests/benchmarks/corelib/tools/qregexp/qregexp.pro diff --git a/tests/benchmarks/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp index 12826eb..12826eb 100644 --- a/tests/benchmarks/qstring/main.cpp +++ b/tests/benchmarks/corelib/tools/qstring/main.cpp diff --git a/tests/benchmarks/qstring/qstring.pro b/tests/benchmarks/corelib/tools/qstring/qstring.pro index 2e7c86a..2e7c86a 100644 --- a/tests/benchmarks/qstring/qstring.pro +++ b/tests/benchmarks/corelib/tools/qstring/qstring.pro diff --git a/tests/benchmarks/qstring/utf-8.txt b/tests/benchmarks/corelib/tools/qstring/utf-8.txt index a8a58de..a8a58de 100644 --- a/tests/benchmarks/qstring/utf-8.txt +++ b/tests/benchmarks/corelib/tools/qstring/utf-8.txt diff --git a/tests/benchmarks/qstringbuilder/main.cpp b/tests/benchmarks/corelib/tools/qstringbuilder/main.cpp index 9bd146f..9bd146f 100644 --- a/tests/benchmarks/qstringbuilder/main.cpp +++ b/tests/benchmarks/corelib/tools/qstringbuilder/main.cpp diff --git a/tests/benchmarks/qstringbuilder/qstringbuilder.pro b/tests/benchmarks/corelib/tools/qstringbuilder/qstringbuilder.pro index 79171b4..79171b4 100644 --- a/tests/benchmarks/qstringbuilder/qstringbuilder.pro +++ b/tests/benchmarks/corelib/tools/qstringbuilder/qstringbuilder.pro diff --git a/tests/benchmarks/qstringlist/.gitignore b/tests/benchmarks/corelib/tools/qstringlist/.gitignore index 3e0cdc9..3e0cdc9 100644 --- a/tests/benchmarks/qstringlist/.gitignore +++ b/tests/benchmarks/corelib/tools/qstringlist/.gitignore diff --git a/tests/benchmarks/qstringlist/main.cpp b/tests/benchmarks/corelib/tools/qstringlist/main.cpp index 1717b88..1717b88 100644 --- a/tests/benchmarks/qstringlist/main.cpp +++ b/tests/benchmarks/corelib/tools/qstringlist/main.cpp diff --git a/tests/benchmarks/qstringlist/qstringlist.pro b/tests/benchmarks/corelib/tools/qstringlist/qstringlist.pro index 5c64b34..5c64b34 100644 --- a/tests/benchmarks/qstringlist/qstringlist.pro +++ b/tests/benchmarks/corelib/tools/qstringlist/qstringlist.pro diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro new file mode 100644 index 0000000..12c23fc --- /dev/null +++ b/tests/benchmarks/corelib/tools/tools.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs +SUBDIRS = \ + containers-associative \ + containers-sequential \ + qbytearray \ + qrect \ + qregexp \ + qstring \ + qstringbuilder \ + qstringlist diff --git a/tests/benchmarks/gui/animation/animation.pro b/tests/benchmarks/gui/animation/animation.pro new file mode 100644 index 0000000..a4ba273 --- /dev/null +++ b/tests/benchmarks/gui/animation/animation.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = qanimation diff --git a/tests/benchmarks/qanimation/dummyanimation.cpp b/tests/benchmarks/gui/animation/qanimation/dummyanimation.cpp index f79cc5b..f79cc5b 100644 --- a/tests/benchmarks/qanimation/dummyanimation.cpp +++ b/tests/benchmarks/gui/animation/qanimation/dummyanimation.cpp diff --git a/tests/benchmarks/qanimation/dummyanimation.h b/tests/benchmarks/gui/animation/qanimation/dummyanimation.h index 1df76be..1df76be 100644 --- a/tests/benchmarks/qanimation/dummyanimation.h +++ b/tests/benchmarks/gui/animation/qanimation/dummyanimation.h diff --git a/tests/benchmarks/qanimation/dummyobject.cpp b/tests/benchmarks/gui/animation/qanimation/dummyobject.cpp index 2b66cda..2b66cda 100644 --- a/tests/benchmarks/qanimation/dummyobject.cpp +++ b/tests/benchmarks/gui/animation/qanimation/dummyobject.cpp diff --git a/tests/benchmarks/qanimation/dummyobject.h b/tests/benchmarks/gui/animation/qanimation/dummyobject.h index 31614fd..31614fd 100644 --- a/tests/benchmarks/qanimation/dummyobject.h +++ b/tests/benchmarks/gui/animation/qanimation/dummyobject.h diff --git a/tests/benchmarks/qanimation/main.cpp b/tests/benchmarks/gui/animation/qanimation/main.cpp index 8b9884e..8b9884e 100644 --- a/tests/benchmarks/qanimation/main.cpp +++ b/tests/benchmarks/gui/animation/qanimation/main.cpp diff --git a/tests/benchmarks/qanimation/qanimation.pro b/tests/benchmarks/gui/animation/qanimation/qanimation.pro index 55cd75e..55cd75e 100644 --- a/tests/benchmarks/qanimation/qanimation.pro +++ b/tests/benchmarks/gui/animation/qanimation/qanimation.pro diff --git a/tests/benchmarks/qanimation/rectanimation.cpp b/tests/benchmarks/gui/animation/qanimation/rectanimation.cpp index e6d7a7e..e6d7a7e 100644 --- a/tests/benchmarks/qanimation/rectanimation.cpp +++ b/tests/benchmarks/gui/animation/qanimation/rectanimation.cpp diff --git a/tests/benchmarks/qanimation/rectanimation.h b/tests/benchmarks/gui/animation/qanimation/rectanimation.h index 42b9376..42b9376 100644 --- a/tests/benchmarks/qanimation/rectanimation.h +++ b/tests/benchmarks/gui/animation/qanimation/rectanimation.h diff --git a/tests/benchmarks/gui/graphicsview/graphicsview.pro b/tests/benchmarks/gui/graphicsview/graphicsview.pro new file mode 100644 index 0000000..93c00d2 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/graphicsview.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qgraphicsanchorlayout \ + qgraphicsitem \ + qgraphicsscene \ + qgraphicsview \ + qgraphicswidget diff --git a/tests/benchmarks/qgraphicsanchorlayout/qgraphicsanchorlayout.pro b/tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro index 0d563b9..0d563b9 100644 --- a/tests/benchmarks/qgraphicsanchorlayout/qgraphicsanchorlayout.pro +++ b/tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro diff --git a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 01285d1..01285d1 100644 --- a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp diff --git a/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro b/tests/benchmarks/gui/graphicsview/qgraphicsitem/qgraphicsitem.pro index 726bb96..726bb96 100644 --- a/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro +++ b/tests/benchmarks/gui/graphicsview/qgraphicsitem/qgraphicsitem.pro diff --git a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index ac51072..ac51072 100644 --- a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp diff --git a/tests/benchmarks/qgraphicsscene/qgraphicsscene.pro b/tests/benchmarks/gui/graphicsview/qgraphicsscene/qgraphicsscene.pro index b460e2a..b460e2a 100644 --- a/tests/benchmarks/qgraphicsscene/qgraphicsscene.pro +++ b/tests/benchmarks/gui/graphicsview/qgraphicsscene/qgraphicsscene.pro diff --git a/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index 5bd07f9..5bd07f9 100644 --- a/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/chip.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp index 77b86c1..77b86c1 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/chip.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/chip.debug b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.debug Binary files differindex 8fe1e5b..8fe1e5b 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/chip.debug +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.debug diff --git a/tests/benchmarks/qgraphicsview/chiptester/chip.h b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.h index 9db23f9..9db23f9 100644 --- a/tests/benchmarks/qgraphicsview/chiptester/chip.h +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.h diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/chip.pro b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.pro index 53fa23b..53fa23b 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/chip.pro +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.pro diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/fileprint.png b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/fileprint.png Binary files differindex ba7c02d..ba7c02d 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/fileprint.png +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/fileprint.png diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/images.qrc b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/images.qrc index c7cdf0c..c7cdf0c 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/images.qrc +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/images.qrc diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/main.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/main.cpp index ea2f94a..ea2f94a 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/main.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/main.cpp diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/mainwindow.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.cpp index 452b42c..452b42c 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/mainwindow.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.cpp diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/mainwindow.h b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.h index 558bbef..558bbef 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/mainwindow.h +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.h diff --git a/tests/benchmarks/qgraphicsview/chiptester/qt4logo.png b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/qt4logo.png Binary files differindex 157e86e..157e86e 100644 --- a/tests/benchmarks/qgraphicsview/chiptester/qt4logo.png +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/qt4logo.png diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/rotateleft.png b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateleft.png Binary files differindex 8cfa931..8cfa931 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/rotateleft.png +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateleft.png diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/rotateright.png b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateright.png Binary files differindex ec5e866..ec5e866 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/rotateright.png +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateright.png diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/view.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp index 1028f42..1028f42 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/view.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/view.h b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.h index fc5c226..fc5c226 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/view.h +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.h diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/zoomin.png b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomin.png Binary files differindex 8b0daee..8b0daee 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/zoomin.png +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomin.png diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/zoomout.png b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomout.png Binary files differindex 1575dd2..1575dd2 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/zoomout.png +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomout.png diff --git a/tests/benchmarks/qgraphicsview/benchapps/moveItems/main.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp index 527713f..527713f 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/moveItems/main.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp diff --git a/tests/benchmarks/qgraphicsview/benchapps/moveItems/moveItems.pro b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/moveItems.pro index 28dcadc..28dcadc 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/moveItems/moveItems.pro +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/moveItems.pro diff --git a/tests/benchmarks/qgraphicsview/benchapps/scrolltest/main.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp index 7419206..7419206 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/scrolltest/main.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp diff --git a/tests/benchmarks/qgraphicsview/benchapps/scrolltest/scrolltest.pro b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/scrolltest.pro index 28dcadc..28dcadc 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/scrolltest/scrolltest.pro +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/scrolltest.pro diff --git a/tests/benchmarks/qgraphicsview/chiptester/chip.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.cpp index 4c1020a..4c1020a 100644 --- a/tests/benchmarks/qgraphicsview/chiptester/chip.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.cpp diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/chip.h b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.h index 9db23f9..9db23f9 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/chip.h +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.h diff --git a/tests/benchmarks/qgraphicsview/chiptester/chiptester.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp index 8cada67..8cada67 100644 --- a/tests/benchmarks/qgraphicsview/chiptester/chiptester.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp diff --git a/tests/benchmarks/qgraphicsview/chiptester/chiptester.h b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h index 1a73bb7..1a73bb7 100644 --- a/tests/benchmarks/qgraphicsview/chiptester/chiptester.h +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h diff --git a/tests/benchmarks/qgraphicsview/chiptester/chiptester.pri b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.pri index a9e0bf8..a9e0bf8 100644 --- a/tests/benchmarks/qgraphicsview/chiptester/chiptester.pri +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.pri diff --git a/tests/benchmarks/qgraphicsview/chiptester/images.qrc b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/images.qrc index 73e8620..73e8620 100644 --- a/tests/benchmarks/qgraphicsview/chiptester/images.qrc +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/images.qrc diff --git a/tests/benchmarks/qgraphicsview/benchapps/chipTest/qt4logo.png b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/qt4logo.png Binary files differindex 157e86e..157e86e 100644 --- a/tests/benchmarks/qgraphicsview/benchapps/chipTest/qt4logo.png +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/qt4logo.png diff --git a/tests/benchmarks/qgraphicsview/images/designer.png b/tests/benchmarks/gui/graphicsview/qgraphicsview/images/designer.png Binary files differindex 0988fce..0988fce 100644 --- a/tests/benchmarks/qgraphicsview/images/designer.png +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/images/designer.png diff --git a/tests/benchmarks/qgraphicsview/images/wine-big.jpeg b/tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine-big.jpeg Binary files differindex 9900a50..9900a50 100644 --- a/tests/benchmarks/qgraphicsview/images/wine-big.jpeg +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine-big.jpeg diff --git a/tests/benchmarks/qgraphicsview/images/wine.jpeg b/tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine.jpeg Binary files differindex 8fe1d3a..8fe1d3a 100644 --- a/tests/benchmarks/qgraphicsview/images/wine.jpeg +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine.jpeg diff --git a/tests/benchmarks/qgraphicsview/qgraphicsview.pro b/tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.pro index 927d731..927d731 100644 --- a/tests/benchmarks/qgraphicsview/qgraphicsview.pro +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.pro diff --git a/tests/benchmarks/qgraphicsview/qgraphicsview.qrc b/tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.qrc index 3681648..3681648 100644 --- a/tests/benchmarks/qgraphicsview/qgraphicsview.qrc +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.qrc diff --git a/tests/benchmarks/qgraphicsview/random.data b/tests/benchmarks/gui/graphicsview/qgraphicsview/random.data Binary files differindex 190a36c..190a36c 100644 --- a/tests/benchmarks/qgraphicsview/random.data +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/random.data diff --git a/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 4cb07db..10e00a6 100644 --- a/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -555,7 +555,11 @@ void tst_QGraphicsView::imageRiver() QFile file(":/random.data"); QVERIFY(file.open(QIODevice::ReadOnly)); QDataStream str(&file); +#if defined(Q_OS_SYMBIAN) + for (int i = 0; i < 50; ++i) { +#else for (int i = 0; i < 100; ++i) { +#endif AnimatedPixmapItem *item; if (direction == 0) item = new AnimatedPixmapItem((i % 4) + 1, 0, rotation, scale); if (direction == 1) item = new AnimatedPixmapItem(0, (i % 4) + 1, rotation, scale); @@ -574,7 +578,11 @@ void tst_QGraphicsView::imageRiver() #ifdef CALLGRIND_DEBUG CALLGRIND_START_INSTRUMENTATION #endif +#if defined(Q_OS_SYMBIAN) + for (int i = 0; i < 50; ++i) { +#else for (int i = 0; i < 100; ++i) { +#endif scene.advance(); while (view.count < (i+1)) qApp->processEvents(); @@ -669,7 +677,11 @@ void tst_QGraphicsView::textRiver() QFile file(":/random.data"); QVERIFY(file.open(QIODevice::ReadOnly)); QDataStream str(&file); +#if defined(Q_OS_SYMBIAN) + for (int i = 0; i < 50; ++i) { +#else for (int i = 0; i < 100; ++i) { +#endif AnimatedTextItem *item; if (direction == 0) item = new AnimatedTextItem((i % 4) + 1, 0, rotation, scale); if (direction == 1) item = new AnimatedTextItem(0, (i % 4) + 1, rotation, scale); @@ -687,7 +699,11 @@ void tst_QGraphicsView::textRiver() #ifdef CALLGRIND_DEBUG CALLGRIND_START_INSTRUMENTATION #endif +#if defined(Q_OS_SYMBIAN) + for (int i = 0; i < 50; ++i) { +#else for (int i = 0; i < 100; ++i) { +#endif scene.advance(); while (view.count < (i+1)) qApp->processEvents(); @@ -771,7 +787,11 @@ void tst_QGraphicsView::moveItemCache() QFile file(":/random.data"); QVERIFY(file.open(QIODevice::ReadOnly)); QDataStream str(&file); +#if defined(Q_OS_SYMBIAN) + for (int i = 0; i < 5; ++i) { +#else for (int i = 0; i < 50; ++i) { +#endif AnimatedPixmapCacheItem *item; if (direction == 0) item = new AnimatedPixmapCacheItem((i % 4) + 1, 0); if (direction == 1) item = new AnimatedPixmapCacheItem(0, (i % 4) + 1); @@ -793,7 +813,11 @@ void tst_QGraphicsView::moveItemCache() #ifdef CALLGRIND_DEBUG CALLGRIND_START_INSTRUMENTATION #endif +#if defined(Q_OS_SYMBIAN) + for (int i = 0; i < 50; ++i) { +#else for (int i = 0; i < 100; ++i) { +#endif scene.advance(); while (view.count < (i+1)) qApp->processEvents(); @@ -893,7 +917,11 @@ void tst_QGraphicsView::paintItemCache() #ifdef CALLGRIND_DEBUG CALLGRIND_START_INSTRUMENTATION #endif +#if defined(Q_OS_SYMBIAN) + for (int i = 0; i < 5; ++i) { +#else for (int i = 0; i < 50; ++i) { +#endif scene.advance(); while (view.count < (i+1)) qApp->processEvents(); diff --git a/tests/benchmarks/qgraphicswidget/qgraphicswidget.pro b/tests/benchmarks/gui/graphicsview/qgraphicswidget/qgraphicswidget.pro index f1ec54e..f1ec54e 100644 --- a/tests/benchmarks/qgraphicswidget/qgraphicswidget.pro +++ b/tests/benchmarks/gui/graphicsview/qgraphicswidget/qgraphicswidget.pro diff --git a/tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp index 7db98ce..7db98ce 100644 --- a/tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp diff --git a/tests/benchmarks/gui/gui.pro b/tests/benchmarks/gui/gui.pro new file mode 100644 index 0000000..946f184 --- /dev/null +++ b/tests/benchmarks/gui/gui.pro @@ -0,0 +1,11 @@ +TEMPLATE = subdirs +SUBDIRS = \ + animation \ + graphicsview \ + image \ + itemviews \ + kernel \ + math3d \ + painting \ + styles \ + text diff --git a/tests/benchmarks/blendbench/blendbench.pro b/tests/benchmarks/gui/image/blendbench/blendbench.pro index a3228c5..a3228c5 100644 --- a/tests/benchmarks/blendbench/blendbench.pro +++ b/tests/benchmarks/gui/image/blendbench/blendbench.pro diff --git a/tests/benchmarks/blendbench/main.cpp b/tests/benchmarks/gui/image/blendbench/main.cpp index 92d1633..92d1633 100644 --- a/tests/benchmarks/blendbench/main.cpp +++ b/tests/benchmarks/gui/image/blendbench/main.cpp diff --git a/tests/benchmarks/gui/image/image.pro b/tests/benchmarks/gui/image/image.pro new file mode 100644 index 0000000..3094e72 --- /dev/null +++ b/tests/benchmarks/gui/image/image.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = \ + blendbench \ + qimagereader \ + qpixmap \ + qpixmapcache diff --git a/tests/benchmarks/qimagereader/images/16bpp.bmp b/tests/benchmarks/gui/image/qimagereader/images/16bpp.bmp Binary files differindex 74ce63e..74ce63e 100644 --- a/tests/benchmarks/qimagereader/images/16bpp.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/16bpp.bmp diff --git a/tests/benchmarks/qimagereader/images/4bpp-rle.bmp b/tests/benchmarks/gui/image/qimagereader/images/4bpp-rle.bmp Binary files differindex ae71e67..ae71e67 100644 --- a/tests/benchmarks/qimagereader/images/4bpp-rle.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/4bpp-rle.bmp diff --git a/tests/benchmarks/qimagereader/images/YCbCr_cmyk.jpg b/tests/benchmarks/gui/image/qimagereader/images/YCbCr_cmyk.jpg Binary files differindex b8aa9ea..b8aa9ea 100644 --- a/tests/benchmarks/qimagereader/images/YCbCr_cmyk.jpg +++ b/tests/benchmarks/gui/image/qimagereader/images/YCbCr_cmyk.jpg diff --git a/tests/benchmarks/qimagereader/images/YCbCr_cmyk.png b/tests/benchmarks/gui/image/qimagereader/images/YCbCr_cmyk.png Binary files differindex a24db1b..a24db1b 100644 --- a/tests/benchmarks/qimagereader/images/YCbCr_cmyk.png +++ b/tests/benchmarks/gui/image/qimagereader/images/YCbCr_cmyk.png diff --git a/tests/benchmarks/qimagereader/images/YCbCr_rgb.jpg b/tests/benchmarks/gui/image/qimagereader/images/YCbCr_rgb.jpg Binary files differindex 8771224..8771224 100644 --- a/tests/benchmarks/qimagereader/images/YCbCr_rgb.jpg +++ b/tests/benchmarks/gui/image/qimagereader/images/YCbCr_rgb.jpg diff --git a/tests/benchmarks/qimagereader/images/away.png b/tests/benchmarks/gui/image/qimagereader/images/away.png Binary files differindex 0e21a37..0e21a37 100644 --- a/tests/benchmarks/qimagereader/images/away.png +++ b/tests/benchmarks/gui/image/qimagereader/images/away.png diff --git a/tests/benchmarks/qimagereader/images/ball.mng b/tests/benchmarks/gui/image/qimagereader/images/ball.mng Binary files differindex 8154478..8154478 100644 --- a/tests/benchmarks/qimagereader/images/ball.mng +++ b/tests/benchmarks/gui/image/qimagereader/images/ball.mng diff --git a/tests/benchmarks/qimagereader/images/bat1.gif b/tests/benchmarks/gui/image/qimagereader/images/bat1.gif Binary files differindex cb6f4f7..cb6f4f7 100644 --- a/tests/benchmarks/qimagereader/images/bat1.gif +++ b/tests/benchmarks/gui/image/qimagereader/images/bat1.gif diff --git a/tests/benchmarks/qimagereader/images/bat2.gif b/tests/benchmarks/gui/image/qimagereader/images/bat2.gif Binary files differindex fbbda4e..fbbda4e 100644 --- a/tests/benchmarks/qimagereader/images/bat2.gif +++ b/tests/benchmarks/gui/image/qimagereader/images/bat2.gif diff --git a/tests/benchmarks/qimagereader/images/beavis.jpg b/tests/benchmarks/gui/image/qimagereader/images/beavis.jpg Binary files differindex d555047..d555047 100644 --- a/tests/benchmarks/qimagereader/images/beavis.jpg +++ b/tests/benchmarks/gui/image/qimagereader/images/beavis.jpg diff --git a/tests/benchmarks/qimagereader/images/black.png b/tests/benchmarks/gui/image/qimagereader/images/black.png Binary files differindex 6c94085..6c94085 100644 --- a/tests/benchmarks/qimagereader/images/black.png +++ b/tests/benchmarks/gui/image/qimagereader/images/black.png diff --git a/tests/benchmarks/qimagereader/images/black.xpm b/tests/benchmarks/gui/image/qimagereader/images/black.xpm index d7925bf..d7925bf 100644 --- a/tests/benchmarks/qimagereader/images/black.xpm +++ b/tests/benchmarks/gui/image/qimagereader/images/black.xpm diff --git a/tests/benchmarks/qimagereader/images/colorful.bmp b/tests/benchmarks/gui/image/qimagereader/images/colorful.bmp Binary files differindex 8ea6f4a..8ea6f4a 100644 --- a/tests/benchmarks/qimagereader/images/colorful.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/colorful.bmp diff --git a/tests/benchmarks/qimagereader/images/corrupt-colors.xpm b/tests/benchmarks/gui/image/qimagereader/images/corrupt-colors.xpm index f8d80ed..f8d80ed 100644 --- a/tests/benchmarks/qimagereader/images/corrupt-colors.xpm +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt-colors.xpm diff --git a/tests/benchmarks/qimagereader/images/corrupt-data.tif b/tests/benchmarks/gui/image/qimagereader/images/corrupt-data.tif Binary files differindex d63c688..d63c688 100644 --- a/tests/benchmarks/qimagereader/images/corrupt-data.tif +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt-data.tif diff --git a/tests/benchmarks/qimagereader/images/corrupt-pixels.xpm b/tests/benchmarks/gui/image/qimagereader/images/corrupt-pixels.xpm index 21031ee..21031ee 100644 --- a/tests/benchmarks/qimagereader/images/corrupt-pixels.xpm +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt-pixels.xpm diff --git a/tests/benchmarks/qimagereader/images/corrupt.bmp b/tests/benchmarks/gui/image/qimagereader/images/corrupt.bmp Binary files differindex 824190b..824190b 100644 --- a/tests/benchmarks/qimagereader/images/corrupt.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt.bmp diff --git a/tests/benchmarks/qimagereader/images/corrupt.gif b/tests/benchmarks/gui/image/qimagereader/images/corrupt.gif Binary files differindex 0725945..0725945 100644 --- a/tests/benchmarks/qimagereader/images/corrupt.gif +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt.gif diff --git a/tests/benchmarks/qimagereader/images/corrupt.jpg b/tests/benchmarks/gui/image/qimagereader/images/corrupt.jpg Binary files differindex 1959662..1959662 100644 --- a/tests/benchmarks/qimagereader/images/corrupt.jpg +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt.jpg diff --git a/tests/benchmarks/qimagereader/images/corrupt.mng b/tests/benchmarks/gui/image/qimagereader/images/corrupt.mng Binary files differindex 17fd43a..17fd43a 100644 --- a/tests/benchmarks/qimagereader/images/corrupt.mng +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt.mng diff --git a/tests/benchmarks/qimagereader/images/corrupt.png b/tests/benchmarks/gui/image/qimagereader/images/corrupt.png Binary files differindex 9d8911c..9d8911c 100644 --- a/tests/benchmarks/qimagereader/images/corrupt.png +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt.png diff --git a/tests/benchmarks/qimagereader/images/corrupt.xbm b/tests/benchmarks/gui/image/qimagereader/images/corrupt.xbm index 8510634..8510634 100644 --- a/tests/benchmarks/qimagereader/images/corrupt.xbm +++ b/tests/benchmarks/gui/image/qimagereader/images/corrupt.xbm diff --git a/tests/benchmarks/qimagereader/images/crash-signed-char.bmp b/tests/benchmarks/gui/image/qimagereader/images/crash-signed-char.bmp Binary files differindex b35cda6..b35cda6 100644 --- a/tests/benchmarks/qimagereader/images/crash-signed-char.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/crash-signed-char.bmp diff --git a/tests/benchmarks/qimagereader/images/earth.gif b/tests/benchmarks/gui/image/qimagereader/images/earth.gif Binary files differindex 2c229eb..2c229eb 100644 --- a/tests/benchmarks/qimagereader/images/earth.gif +++ b/tests/benchmarks/gui/image/qimagereader/images/earth.gif diff --git a/tests/benchmarks/qimagereader/images/fire.mng b/tests/benchmarks/gui/image/qimagereader/images/fire.mng Binary files differindex c6695c8..c6695c8 100644 --- a/tests/benchmarks/qimagereader/images/fire.mng +++ b/tests/benchmarks/gui/image/qimagereader/images/fire.mng diff --git a/tests/benchmarks/qimagereader/images/font.bmp b/tests/benchmarks/gui/image/qimagereader/images/font.bmp Binary files differindex 28b8c66..28b8c66 100644 --- a/tests/benchmarks/qimagereader/images/font.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/font.bmp diff --git a/tests/benchmarks/qimagereader/images/gnus.xbm b/tests/benchmarks/gui/image/qimagereader/images/gnus.xbm index 58d1ac8..58d1ac8 100644 --- a/tests/benchmarks/qimagereader/images/gnus.xbm +++ b/tests/benchmarks/gui/image/qimagereader/images/gnus.xbm diff --git a/tests/benchmarks/qimagereader/images/image.pbm b/tests/benchmarks/gui/image/qimagereader/images/image.pbm index 67e5efa..67e5efa 100644 --- a/tests/benchmarks/qimagereader/images/image.pbm +++ b/tests/benchmarks/gui/image/qimagereader/images/image.pbm diff --git a/tests/benchmarks/qimagereader/images/image.pgm b/tests/benchmarks/gui/image/qimagereader/images/image.pgm index 443bf40..443bf40 100644 --- a/tests/benchmarks/qimagereader/images/image.pgm +++ b/tests/benchmarks/gui/image/qimagereader/images/image.pgm diff --git a/tests/benchmarks/qimagereader/images/image.png b/tests/benchmarks/gui/image/qimagereader/images/image.png Binary files differindex 7d4890a..7d4890a 100644 --- a/tests/benchmarks/qimagereader/images/image.png +++ b/tests/benchmarks/gui/image/qimagereader/images/image.png diff --git a/tests/benchmarks/qimagereader/images/image.ppm b/tests/benchmarks/gui/image/qimagereader/images/image.ppm index 2a5640e..2a5640e 100644 --- a/tests/benchmarks/qimagereader/images/image.ppm +++ b/tests/benchmarks/gui/image/qimagereader/images/image.ppm diff --git a/tests/benchmarks/qimagereader/images/kollada-noext b/tests/benchmarks/gui/image/qimagereader/images/kollada-noext Binary files differindex 2abd4bb..2abd4bb 100644 --- a/tests/benchmarks/qimagereader/images/kollada-noext +++ b/tests/benchmarks/gui/image/qimagereader/images/kollada-noext diff --git a/tests/benchmarks/qimagereader/images/kollada.png b/tests/benchmarks/gui/image/qimagereader/images/kollada.png Binary files differindex 2abd4bb..2abd4bb 100644 --- a/tests/benchmarks/qimagereader/images/kollada.png +++ b/tests/benchmarks/gui/image/qimagereader/images/kollada.png diff --git a/tests/benchmarks/qimagereader/images/marble.xpm b/tests/benchmarks/gui/image/qimagereader/images/marble.xpm index 1c08049..1c08049 100644 --- a/tests/benchmarks/qimagereader/images/marble.xpm +++ b/tests/benchmarks/gui/image/qimagereader/images/marble.xpm diff --git a/tests/benchmarks/qimagereader/images/namedcolors.xpm b/tests/benchmarks/gui/image/qimagereader/images/namedcolors.xpm index f6485d5..f6485d5 100644 --- a/tests/benchmarks/qimagereader/images/namedcolors.xpm +++ b/tests/benchmarks/gui/image/qimagereader/images/namedcolors.xpm diff --git a/tests/benchmarks/qimagereader/images/negativeheight.bmp b/tests/benchmarks/gui/image/qimagereader/images/negativeheight.bmp Binary files differindex 875887a..875887a 100644 --- a/tests/benchmarks/qimagereader/images/negativeheight.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/negativeheight.bmp diff --git a/tests/benchmarks/qimagereader/images/noclearcode.bmp b/tests/benchmarks/gui/image/qimagereader/images/noclearcode.bmp Binary files differindex 1a5ca9c..1a5ca9c 100644 --- a/tests/benchmarks/qimagereader/images/noclearcode.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/noclearcode.bmp diff --git a/tests/benchmarks/qimagereader/images/noclearcode.gif b/tests/benchmarks/gui/image/qimagereader/images/noclearcode.gif Binary files differindex 27784d6..27784d6 100644 --- a/tests/benchmarks/qimagereader/images/noclearcode.gif +++ b/tests/benchmarks/gui/image/qimagereader/images/noclearcode.gif diff --git a/tests/benchmarks/qimagereader/images/nontransparent.xpm b/tests/benchmarks/gui/image/qimagereader/images/nontransparent.xpm index 00c21ef..00c21ef 100644 --- a/tests/benchmarks/qimagereader/images/nontransparent.xpm +++ b/tests/benchmarks/gui/image/qimagereader/images/nontransparent.xpm diff --git a/tests/benchmarks/qimagereader/images/pngwithcompressedtext.png b/tests/benchmarks/gui/image/qimagereader/images/pngwithcompressedtext.png Binary files differindex 01b2270..01b2270 100644 --- a/tests/benchmarks/qimagereader/images/pngwithcompressedtext.png +++ b/tests/benchmarks/gui/image/qimagereader/images/pngwithcompressedtext.png diff --git a/tests/benchmarks/qimagereader/images/pngwithtext.png b/tests/benchmarks/gui/image/qimagereader/images/pngwithtext.png Binary files differindex 5d93799..5d93799 100644 --- a/tests/benchmarks/qimagereader/images/pngwithtext.png +++ b/tests/benchmarks/gui/image/qimagereader/images/pngwithtext.png diff --git a/tests/benchmarks/qimagereader/images/rgba_adobedeflate_littleendian.tif b/tests/benchmarks/gui/image/qimagereader/images/rgba_adobedeflate_littleendian.tif Binary files differindex 78868b0..78868b0 100644 --- a/tests/benchmarks/qimagereader/images/rgba_adobedeflate_littleendian.tif +++ b/tests/benchmarks/gui/image/qimagereader/images/rgba_adobedeflate_littleendian.tif diff --git a/tests/benchmarks/qimagereader/images/rgba_lzw_littleendian.tif b/tests/benchmarks/gui/image/qimagereader/images/rgba_lzw_littleendian.tif Binary files differindex 107eab7..107eab7 100644 --- a/tests/benchmarks/qimagereader/images/rgba_lzw_littleendian.tif +++ b/tests/benchmarks/gui/image/qimagereader/images/rgba_lzw_littleendian.tif diff --git a/tests/benchmarks/qimagereader/images/rgba_nocompression_bigendian.tif b/tests/benchmarks/gui/image/qimagereader/images/rgba_nocompression_bigendian.tif Binary files differindex c314bae..c314bae 100644 --- a/tests/benchmarks/qimagereader/images/rgba_nocompression_bigendian.tif +++ b/tests/benchmarks/gui/image/qimagereader/images/rgba_nocompression_bigendian.tif diff --git a/tests/benchmarks/qimagereader/images/rgba_nocompression_littleendian.tif b/tests/benchmarks/gui/image/qimagereader/images/rgba_nocompression_littleendian.tif Binary files differindex 4f820f6..4f820f6 100644 --- a/tests/benchmarks/qimagereader/images/rgba_nocompression_littleendian.tif +++ b/tests/benchmarks/gui/image/qimagereader/images/rgba_nocompression_littleendian.tif diff --git a/tests/benchmarks/qimagereader/images/rgba_packbits_littleendian.tif b/tests/benchmarks/gui/image/qimagereader/images/rgba_packbits_littleendian.tif Binary files differindex ddeec38..ddeec38 100644 --- a/tests/benchmarks/qimagereader/images/rgba_packbits_littleendian.tif +++ b/tests/benchmarks/gui/image/qimagereader/images/rgba_packbits_littleendian.tif diff --git a/tests/benchmarks/qimagereader/images/rgba_zipdeflate_littleendian.tif b/tests/benchmarks/gui/image/qimagereader/images/rgba_zipdeflate_littleendian.tif Binary files differindex 50a3024..50a3024 100644 --- a/tests/benchmarks/qimagereader/images/rgba_zipdeflate_littleendian.tif +++ b/tests/benchmarks/gui/image/qimagereader/images/rgba_zipdeflate_littleendian.tif diff --git a/tests/benchmarks/qimagereader/images/runners.ppm b/tests/benchmarks/gui/image/qimagereader/images/runners.ppm Binary files differindex fda1c97..fda1c97 100644 --- a/tests/benchmarks/qimagereader/images/runners.ppm +++ b/tests/benchmarks/gui/image/qimagereader/images/runners.ppm diff --git a/tests/benchmarks/qimagereader/images/task210380.jpg b/tests/benchmarks/gui/image/qimagereader/images/task210380.jpg Binary files differindex fd045ea..fd045ea 100644 --- a/tests/benchmarks/qimagereader/images/task210380.jpg +++ b/tests/benchmarks/gui/image/qimagereader/images/task210380.jpg diff --git a/tests/benchmarks/qimagereader/images/teapot.ppm b/tests/benchmarks/gui/image/qimagereader/images/teapot.ppm index b8ab85f..b8ab85f 100644 --- a/tests/benchmarks/qimagereader/images/teapot.ppm +++ b/tests/benchmarks/gui/image/qimagereader/images/teapot.ppm diff --git a/tests/benchmarks/qimagereader/images/test.ppm b/tests/benchmarks/gui/image/qimagereader/images/test.ppm index 05d627c..05d627c 100644 --- a/tests/benchmarks/qimagereader/images/test.ppm +++ b/tests/benchmarks/gui/image/qimagereader/images/test.ppm diff --git a/tests/benchmarks/qimagereader/images/test.xpm b/tests/benchmarks/gui/image/qimagereader/images/test.xpm index 5fcf075..5fcf075 100644 --- a/tests/benchmarks/qimagereader/images/test.xpm +++ b/tests/benchmarks/gui/image/qimagereader/images/test.xpm diff --git a/tests/benchmarks/qimagereader/images/transparent.xpm b/tests/benchmarks/gui/image/qimagereader/images/transparent.xpm index 5ddcf0b..5ddcf0b 100644 --- a/tests/benchmarks/qimagereader/images/transparent.xpm +++ b/tests/benchmarks/gui/image/qimagereader/images/transparent.xpm diff --git a/tests/benchmarks/qimagereader/images/trolltech.gif b/tests/benchmarks/gui/image/qimagereader/images/trolltech.gif Binary files differindex f674369..f674369 100644 --- a/tests/benchmarks/qimagereader/images/trolltech.gif +++ b/tests/benchmarks/gui/image/qimagereader/images/trolltech.gif diff --git a/tests/benchmarks/qimagereader/images/tst7.bmp b/tests/benchmarks/gui/image/qimagereader/images/tst7.bmp Binary files differindex 6d3ac92..6d3ac92 100644 --- a/tests/benchmarks/qimagereader/images/tst7.bmp +++ b/tests/benchmarks/gui/image/qimagereader/images/tst7.bmp diff --git a/tests/benchmarks/qimagereader/images/tst7.png b/tests/benchmarks/gui/image/qimagereader/images/tst7.png Binary files differindex 96efae4..96efae4 100644 --- a/tests/benchmarks/qimagereader/images/tst7.png +++ b/tests/benchmarks/gui/image/qimagereader/images/tst7.png diff --git a/tests/benchmarks/qimagereader/qimagereader.pro b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro index 276ac33..276ac33 100644 --- a/tests/benchmarks/qimagereader/qimagereader.pro +++ b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro diff --git a/tests/benchmarks/qimagereader/tst_qimagereader.cpp b/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp index 3f38d19..3f38d19 100644 --- a/tests/benchmarks/qimagereader/tst_qimagereader.cpp +++ b/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp diff --git a/tests/benchmarks/qpixmap/qpixmap.pro b/tests/benchmarks/gui/image/qpixmap/qpixmap.pro index e8330bd..e8330bd 100644 --- a/tests/benchmarks/qpixmap/qpixmap.pro +++ b/tests/benchmarks/gui/image/qpixmap/qpixmap.pro diff --git a/tests/benchmarks/qpixmap/tst_qpixmap.cpp b/tests/benchmarks/gui/image/qpixmap/tst_qpixmap.cpp index 9ffbefb..9ffbefb 100644 --- a/tests/benchmarks/qpixmap/tst_qpixmap.cpp +++ b/tests/benchmarks/gui/image/qpixmap/tst_qpixmap.cpp diff --git a/tests/benchmarks/qpixmapcache/qpixmapcache.pro b/tests/benchmarks/gui/image/qpixmapcache/qpixmapcache.pro index e0d7543..e0d7543 100644 --- a/tests/benchmarks/qpixmapcache/qpixmapcache.pro +++ b/tests/benchmarks/gui/image/qpixmapcache/qpixmapcache.pro diff --git a/tests/benchmarks/qpixmapcache/tst_qpixmapcache.cpp b/tests/benchmarks/gui/image/qpixmapcache/tst_qpixmapcache.cpp index 1031ba7..1031ba7 100644 --- a/tests/benchmarks/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/benchmarks/gui/image/qpixmapcache/tst_qpixmapcache.cpp diff --git a/tests/benchmarks/gui/itemviews/itemviews.pro b/tests/benchmarks/gui/itemviews/itemviews.pro new file mode 100644 index 0000000..be0ee55 --- /dev/null +++ b/tests/benchmarks/gui/itemviews/itemviews.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qtableview diff --git a/tests/benchmarks/qtableview/qtableview.pro b/tests/benchmarks/gui/itemviews/qtableview/qtableview.pro index 02bc530..02bc530 100644 --- a/tests/benchmarks/qtableview/qtableview.pro +++ b/tests/benchmarks/gui/itemviews/qtableview/qtableview.pro diff --git a/tests/benchmarks/qtableview/tst_qtableview.cpp b/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp index a84d8b5..a84d8b5 100644 --- a/tests/benchmarks/qtableview/tst_qtableview.cpp +++ b/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp diff --git a/tests/benchmarks/gui/kernel/kernel.pro b/tests/benchmarks/gui/kernel/kernel.pro new file mode 100644 index 0000000..a50aad2 --- /dev/null +++ b/tests/benchmarks/gui/kernel/kernel.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qapplication \ + qwidget diff --git a/tests/benchmarks/qapplication/main.cpp b/tests/benchmarks/gui/kernel/qapplication/main.cpp index c912497..c912497 100644 --- a/tests/benchmarks/qapplication/main.cpp +++ b/tests/benchmarks/gui/kernel/qapplication/main.cpp diff --git a/tests/benchmarks/qapplication/qapplication.pro b/tests/benchmarks/gui/kernel/qapplication/qapplication.pro index f8601e4..f8601e4 100644 --- a/tests/benchmarks/qapplication/qapplication.pro +++ b/tests/benchmarks/gui/kernel/qapplication/qapplication.pro diff --git a/tests/benchmarks/qwidget/qwidget.pro b/tests/benchmarks/gui/kernel/qwidget/qwidget.pro index ff47445..ff47445 100644 --- a/tests/benchmarks/qwidget/qwidget.pro +++ b/tests/benchmarks/gui/kernel/qwidget/qwidget.pro diff --git a/tests/benchmarks/qwidget/tst_qwidget.cpp b/tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp index f21bd44..f21bd44 100644 --- a/tests/benchmarks/qwidget/tst_qwidget.cpp +++ b/tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp diff --git a/tests/benchmarks/gui/math3d/math3d.pro b/tests/benchmarks/gui/math3d/math3d.pro new file mode 100644 index 0000000..c511d9a --- /dev/null +++ b/tests/benchmarks/gui/math3d/math3d.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qmatrix4x4 \ + qquaternion diff --git a/tests/benchmarks/qmatrix4x4/qmatrix4x4.pro b/tests/benchmarks/gui/math3d/qmatrix4x4/qmatrix4x4.pro index e82d9de..e82d9de 100644 --- a/tests/benchmarks/qmatrix4x4/qmatrix4x4.pro +++ b/tests/benchmarks/gui/math3d/qmatrix4x4/qmatrix4x4.pro diff --git a/tests/benchmarks/qmatrix4x4/tst_qmatrix4x4.cpp b/tests/benchmarks/gui/math3d/qmatrix4x4/tst_qmatrix4x4.cpp index e962198..e962198 100644 --- a/tests/benchmarks/qmatrix4x4/tst_qmatrix4x4.cpp +++ b/tests/benchmarks/gui/math3d/qmatrix4x4/tst_qmatrix4x4.cpp diff --git a/tests/benchmarks/qquaternion/qquaternion.pro b/tests/benchmarks/gui/math3d/qquaternion/qquaternion.pro index cd68423..cd68423 100644 --- a/tests/benchmarks/qquaternion/qquaternion.pro +++ b/tests/benchmarks/gui/math3d/qquaternion/qquaternion.pro diff --git a/tests/benchmarks/qquaternion/tst_qquaternion.cpp b/tests/benchmarks/gui/math3d/qquaternion/tst_qquaternion.cpp index 7930092..7930092 100644 --- a/tests/benchmarks/qquaternion/tst_qquaternion.cpp +++ b/tests/benchmarks/gui/math3d/qquaternion/tst_qquaternion.cpp diff --git a/tests/benchmarks/gui/painting/painting.pro b/tests/benchmarks/gui/painting/painting.pro new file mode 100644 index 0000000..878567d --- /dev/null +++ b/tests/benchmarks/gui/painting/painting.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qpainter \ + qregion \ + qtransform diff --git a/tests/benchmarks/qpainter/qpainter.pro b/tests/benchmarks/gui/painting/qpainter/qpainter.pro index 5ac8c64..5ac8c64 100644 --- a/tests/benchmarks/qpainter/qpainter.pro +++ b/tests/benchmarks/gui/painting/qpainter/qpainter.pro diff --git a/tests/benchmarks/qpainter/tst_qpainter.cpp b/tests/benchmarks/gui/painting/qpainter/tst_qpainter.cpp index 39b2244..39b2244 100644 --- a/tests/benchmarks/qpainter/tst_qpainter.cpp +++ b/tests/benchmarks/gui/painting/qpainter/tst_qpainter.cpp diff --git a/tests/benchmarks/qregion/main.cpp b/tests/benchmarks/gui/painting/qregion/main.cpp index 3d16e41..3d16e41 100644 --- a/tests/benchmarks/qregion/main.cpp +++ b/tests/benchmarks/gui/painting/qregion/main.cpp diff --git a/tests/benchmarks/qregion/qregion.pro b/tests/benchmarks/gui/painting/qregion/qregion.pro index fc67177..fc67177 100644 --- a/tests/benchmarks/qregion/qregion.pro +++ b/tests/benchmarks/gui/painting/qregion/qregion.pro diff --git a/tests/benchmarks/qtransform/qtransform.pro b/tests/benchmarks/gui/painting/qtransform/qtransform.pro index 8d87656..8d87656 100644 --- a/tests/benchmarks/qtransform/qtransform.pro +++ b/tests/benchmarks/gui/painting/qtransform/qtransform.pro diff --git a/tests/benchmarks/qtransform/tst_qtransform.cpp b/tests/benchmarks/gui/painting/qtransform/tst_qtransform.cpp index b33cf58..b33cf58 100644 --- a/tests/benchmarks/qtransform/tst_qtransform.cpp +++ b/tests/benchmarks/gui/painting/qtransform/tst_qtransform.cpp diff --git a/tests/benchmarks/qstylesheetstyle/main.cpp b/tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp index 226b661..226b661 100644 --- a/tests/benchmarks/qstylesheetstyle/main.cpp +++ b/tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp diff --git a/tests/benchmarks/qstylesheetstyle/qstylesheetstyle.pro b/tests/benchmarks/gui/styles/qstylesheetstyle/qstylesheetstyle.pro index c097307..c097307 100644 --- a/tests/benchmarks/qstylesheetstyle/qstylesheetstyle.pro +++ b/tests/benchmarks/gui/styles/qstylesheetstyle/qstylesheetstyle.pro diff --git a/tests/benchmarks/gui/styles/styles.pro b/tests/benchmarks/gui/styles/styles.pro new file mode 100644 index 0000000..7c1d069 --- /dev/null +++ b/tests/benchmarks/gui/styles/styles.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qstylesheetstyle diff --git a/tests/benchmarks/qfontmetrics/main.cpp b/tests/benchmarks/gui/text/qfontmetrics/main.cpp index d3f85ef..d3f85ef 100644 --- a/tests/benchmarks/qfontmetrics/main.cpp +++ b/tests/benchmarks/gui/text/qfontmetrics/main.cpp diff --git a/tests/benchmarks/qfontmetrics/qfontmetrics.pro b/tests/benchmarks/gui/text/qfontmetrics/qfontmetrics.pro index b6c7b92..b6c7b92 100644 --- a/tests/benchmarks/qfontmetrics/qfontmetrics.pro +++ b/tests/benchmarks/gui/text/qfontmetrics/qfontmetrics.pro diff --git a/tests/benchmarks/qtext/bidi.txt b/tests/benchmarks/gui/text/qtext/bidi.txt index 7c74cb4..7c74cb4 100644 --- a/tests/benchmarks/qtext/bidi.txt +++ b/tests/benchmarks/gui/text/qtext/bidi.txt diff --git a/tests/benchmarks/qtext/main.cpp b/tests/benchmarks/gui/text/qtext/main.cpp index d4f3165..d4f3165 100644 --- a/tests/benchmarks/qtext/main.cpp +++ b/tests/benchmarks/gui/text/qtext/main.cpp diff --git a/tests/benchmarks/qtext/qtext.pro b/tests/benchmarks/gui/text/qtext/qtext.pro index 9e8860f..9e8860f 100644 --- a/tests/benchmarks/qtext/qtext.pro +++ b/tests/benchmarks/gui/text/qtext/qtext.pro diff --git a/tests/benchmarks/gui/text/text.pro b/tests/benchmarks/gui/text/text.pro new file mode 100644 index 0000000..34e548b --- /dev/null +++ b/tests/benchmarks/gui/text/text.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qfontmetrics \ + qtext diff --git a/tests/benchmarks/network/access/access.pro b/tests/benchmarks/network/access/access.pro new file mode 100644 index 0000000..43357e2 --- /dev/null +++ b/tests/benchmarks/network/access/access.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qfile_vs_qnetworkaccessmanager \ + qnetworkreply diff --git a/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp b/tests/benchmarks/network/access/qfile_vs_qnetworkaccessmanager/main.cpp index 23e07db..26308e9 100644 --- a/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp +++ b/tests/benchmarks/network/access/qfile_vs_qnetworkaccessmanager/main.cpp @@ -46,7 +46,7 @@ #include <QtNetwork/qnetworkaccessmanager.h> #include <QtCore/QTemporaryFile> #include <QtCore/QFile> -#include "../../auto/network-settings.h" +#include "../../../../auto/network-settings.h" class qfile_vs_qnetworkaccessmanager : public QObject { diff --git a/tests/benchmarks/qfile_vs_qnetworkaccessmanager/qfile_vs_qnetworkaccessmanager.pro b/tests/benchmarks/network/access/qfile_vs_qnetworkaccessmanager/qfile_vs_qnetworkaccessmanager.pro index 99d1935..99d1935 100644 --- a/tests/benchmarks/qfile_vs_qnetworkaccessmanager/qfile_vs_qnetworkaccessmanager.pro +++ b/tests/benchmarks/network/access/qfile_vs_qnetworkaccessmanager/qfile_vs_qnetworkaccessmanager.pro diff --git a/tests/benchmarks/qnetworkreply/qnetworkreply.pro b/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro index 1e67d81..1e67d81 100644 --- a/tests/benchmarks/qnetworkreply/qnetworkreply.pro +++ b/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro diff --git a/tests/benchmarks/qnetworkreply/tst_qnetworkreply.cpp b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp index a92359f..f173ed1 100644 --- a/tests/benchmarks/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -48,7 +48,7 @@ #include <QtNetwork/qnetworkaccessmanager.h> #include <QtNetwork/qtcpsocket.h> #include <QtNetwork/qtcpserver.h> -#include "../../auto/network-settings.h" +#include "../../../../auto/network-settings.h" class TimedSender: public QThread diff --git a/tests/benchmarks/network/kernel/kernel.pro b/tests/benchmarks/network/kernel/kernel.pro new file mode 100644 index 0000000..1ec3071 --- /dev/null +++ b/tests/benchmarks/network/kernel/kernel.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qhostinfo diff --git a/tests/benchmarks/qhostinfo/main.cpp b/tests/benchmarks/network/kernel/qhostinfo/main.cpp index 0ae1b7f..0ae1b7f 100644 --- a/tests/benchmarks/qhostinfo/main.cpp +++ b/tests/benchmarks/network/kernel/qhostinfo/main.cpp diff --git a/tests/benchmarks/qhostinfo/qhostinfo.pro b/tests/benchmarks/network/kernel/qhostinfo/qhostinfo.pro index f18d6d7..f18d6d7 100755 --- a/tests/benchmarks/qhostinfo/qhostinfo.pro +++ b/tests/benchmarks/network/kernel/qhostinfo/qhostinfo.pro diff --git a/tests/benchmarks/network/network.pro b/tests/benchmarks/network/network.pro new file mode 100644 index 0000000..4e83db2 --- /dev/null +++ b/tests/benchmarks/network/network.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs +SUBDIRS = \ + access \ + kernel \ + socket diff --git a/tests/benchmarks/qtcpserver/qtcpserver.pro b/tests/benchmarks/network/socket/qtcpserver/qtcpserver.pro index e7bf13a..e7bf13a 100644 --- a/tests/benchmarks/qtcpserver/qtcpserver.pro +++ b/tests/benchmarks/network/socket/qtcpserver/qtcpserver.pro diff --git a/tests/benchmarks/qtcpserver/tst_qtcpserver.cpp b/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp index b6b55c3..022bf3d 100644 --- a/tests/benchmarks/qtcpserver/tst_qtcpserver.cpp +++ b/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp @@ -58,7 +58,7 @@ Q_DECLARE_METATYPE(QNetworkProxy) Q_DECLARE_METATYPE(QList<QNetworkProxy>) -#include "../../auto/network-settings.h" +#include "../../../../auto/network-settings.h" //TESTED_CLASS= //TESTED_FILES= diff --git a/tests/benchmarks/network/socket/socket.pro b/tests/benchmarks/network/socket/socket.pro new file mode 100644 index 0000000..2d676a2 --- /dev/null +++ b/tests/benchmarks/network/socket/socket.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qtcpserver diff --git a/tests/benchmarks/qscriptclass/tst_qscriptclass.cpp b/tests/benchmarks/qscriptclass/tst_qscriptclass.cpp deleted file mode 100644 index 7985028..0000000 --- a/tests/benchmarks/qscriptclass/tst_qscriptclass.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qtest.h> -#include <QtScript> - -Q_DECLARE_METATYPE(QScriptContext*) -Q_DECLARE_METATYPE(QScriptValue) -Q_DECLARE_METATYPE(QScriptValueList) - -//TESTED_FILES= - -class TestClass : public QScriptClass -{ -public: - struct CustomProperty { - QueryFlags qflags; - uint id; - QScriptValue::PropertyFlags pflags; - QScriptValue value; - - CustomProperty(QueryFlags qf, uint i, QScriptValue::PropertyFlags pf, - const QScriptValue &val) - : qflags(qf), id(i), pflags(pf), value(val) { } - }; - - enum CallableMode { - NotCallable, - CallableReturnsSum, - CallableReturnsArgument, - CallableReturnsInvalidVariant - }; - - TestClass(QScriptEngine *engine); - ~TestClass(); - - void addCustomProperty(const QScriptString &name, QueryFlags qflags, - uint id, QScriptValue::PropertyFlags pflags, - const QScriptValue &value); - void removeCustomProperty(const QScriptString &name); - - QueryFlags queryProperty(const QScriptValue &object, - const QScriptString &name, - QueryFlags flags, uint *id); - - QScriptValue property(const QScriptValue &object, - const QScriptString &name, uint id); - - void setProperty(QScriptValue &object, const QScriptString &name, - uint id, const QScriptValue &value); - - QScriptValue::PropertyFlags propertyFlags( - const QScriptValue &object, const QScriptString &name, uint id); - - QScriptClassPropertyIterator *newIterator(const QScriptValue &object); - - QScriptValue prototype() const; - - QString name() const; - - bool supportsExtension(Extension extension) const; - QVariant extension(Extension extension, - const QVariant &argument = QVariant()); - - void setIterationEnabled(bool enable); - bool isIterationEnabled() const; - - void setCallableMode(CallableMode mode); - CallableMode callableMode() const; - - void setHasInstance(bool hasInstance); - bool hasInstance() const; - -private: - inline CustomProperty *findCustomProperty(const QScriptString &name); - - QHash<QScriptString, CustomProperty*> customProperties; - - QScriptValue m_prototype; - bool m_iterationEnabled; - CallableMode m_callableMode; - bool m_hasInstance; -}; - -class TestClassPropertyIterator : public QScriptClassPropertyIterator -{ -public: - TestClassPropertyIterator(const QHash<QScriptString, TestClass::CustomProperty*> &props, - const QScriptValue &object); - ~TestClassPropertyIterator(); - - bool hasNext() const; - void next(); - - bool hasPrevious() const; - void previous(); - - void toFront(); - void toBack(); - - QScriptString name() const; - uint id() const; - QScriptValue::PropertyFlags flags() const; - -private: - int m_index; - int m_last; - QHash<QScriptString, TestClass::CustomProperty*> m_props; -}; - -TestClass::TestClass(QScriptEngine *engine) - : QScriptClass(engine), m_iterationEnabled(true), - m_callableMode(NotCallable), m_hasInstance(false) -{ - m_prototype = engine->newObject(); -} - -TestClass::~TestClass() -{ - qDeleteAll(customProperties); -} - -TestClass::CustomProperty* TestClass::findCustomProperty(const QScriptString &name) -{ - QHash<QScriptString, CustomProperty*>::const_iterator it; - it = customProperties.constFind(name); - if (it == customProperties.constEnd()) - return 0; - return it.value(); - -} - -void TestClass::addCustomProperty(const QScriptString &name, QueryFlags qflags, - uint id, QScriptValue::PropertyFlags pflags, - const QScriptValue &value) -{ - customProperties.insert(name, new CustomProperty(qflags, id, pflags, value)); -} - -void TestClass::removeCustomProperty(const QScriptString &name) -{ - CustomProperty *prop = customProperties.take(name); - if (prop) - delete prop; -} - -QScriptClass::QueryFlags TestClass::queryProperty(const QScriptValue &/*object*/, - const QScriptString &name, - QueryFlags flags, uint *id) -{ - CustomProperty *prop = findCustomProperty(name); - if (!prop) - return 0; - *id = prop->id; - return prop->qflags & flags; -} - -QScriptValue TestClass::property(const QScriptValue &/*object*/, - const QScriptString &name, uint /*id*/) -{ - CustomProperty *prop = findCustomProperty(name); - if (!prop) - return QScriptValue(); - return prop->value; -} - -void TestClass::setProperty(QScriptValue &/*object*/, const QScriptString &name, - uint /*id*/, const QScriptValue &value) -{ - CustomProperty *prop = findCustomProperty(name); - if (!prop) - return; - prop->value = value; -} - -QScriptValue::PropertyFlags TestClass::propertyFlags( - const QScriptValue &/*object*/, const QScriptString &name, uint /*id*/) -{ - CustomProperty *prop = findCustomProperty(name); - if (!prop) - return 0; - return prop->pflags; -} - -QScriptClassPropertyIterator *TestClass::newIterator(const QScriptValue &object) -{ - if (!m_iterationEnabled) - return 0; - return new TestClassPropertyIterator(customProperties, object); -} - -QScriptValue TestClass::prototype() const -{ - return m_prototype; -} - -QString TestClass::name() const -{ - return QLatin1String("TestClass"); -} - -bool TestClass::supportsExtension(Extension extension) const -{ - if (extension == Callable) - return (m_callableMode != NotCallable); - if (extension == HasInstance) - return m_hasInstance; - return false; -} - -QVariant TestClass::extension(Extension extension, - const QVariant &argument) -{ - if (extension == Callable) { - Q_ASSERT(m_callableMode != NotCallable); - QScriptContext *ctx = qvariant_cast<QScriptContext*>(argument); - if (m_callableMode == CallableReturnsSum) { - qsreal sum = 0; - for (int i = 0; i < ctx->argumentCount(); ++i) - sum += ctx->argument(i).toNumber(); - QScriptValueIterator it(ctx->thisObject()); - while (it.hasNext()) { - it.next(); - sum += it.value().toNumber(); - } - return sum; - } else if (m_callableMode == CallableReturnsArgument) { - return qVariantFromValue(ctx->argument(0)); - } else if (m_callableMode == CallableReturnsInvalidVariant) { - return QVariant(); - } - } else if (extension == HasInstance) { - Q_ASSERT(m_hasInstance); - QScriptValueList args = qvariant_cast<QScriptValueList>(argument); - QScriptValue obj = args.at(0); - QScriptValue value = args.at(1); - return value.property("foo").equals(obj.property("foo")); - } - return QVariant(); -} - -void TestClass::setIterationEnabled(bool enable) -{ - m_iterationEnabled = enable; -} - -bool TestClass::isIterationEnabled() const -{ - return m_iterationEnabled; -} - -void TestClass::setCallableMode(CallableMode mode) -{ - m_callableMode = mode; -} - -TestClass::CallableMode TestClass::callableMode() const -{ - return m_callableMode; -} - -void TestClass::setHasInstance(bool hasInstance) -{ - m_hasInstance = hasInstance; -} - -bool TestClass::hasInstance() const -{ - return m_hasInstance; -} - -TestClassPropertyIterator::TestClassPropertyIterator(const QHash<QScriptString, TestClass::CustomProperty*> &props, - const QScriptValue &object) - : QScriptClassPropertyIterator(object) -{ - m_props = props; - toFront(); -} - -TestClassPropertyIterator::~TestClassPropertyIterator() -{ -} - -bool TestClassPropertyIterator::hasNext() const -{ - return m_index < m_props.size(); -} - -void TestClassPropertyIterator::next() -{ - m_last = m_index; - ++m_index; -} - -bool TestClassPropertyIterator::hasPrevious() const -{ - return m_index > 0; -} - -void TestClassPropertyIterator::previous() -{ - --m_index; - m_last = m_index; -} - -void TestClassPropertyIterator::toFront() -{ - m_index = 0; - m_last = -1; -} - -void TestClassPropertyIterator::toBack() -{ - m_index = m_props.size(); - m_last = -1; -} - -QScriptString TestClassPropertyIterator::name() const -{ - return m_props.keys().value(m_last); -} - -uint TestClassPropertyIterator::id() const -{ - QScriptString key = m_props.keys().value(m_last); - if (!key.isValid()) - return 0; - TestClass::CustomProperty *prop = m_props.value(key); - return prop->id; -} - -QScriptValue::PropertyFlags TestClassPropertyIterator::flags() const -{ - QScriptString key = m_props.keys().value(m_last); - if (!key.isValid()) - return 0; - TestClass::CustomProperty *prop = m_props.value(key); - return prop->pflags; -} - -class tst_QScriptClass : public QObject -{ - Q_OBJECT - -public: - tst_QScriptClass(); - virtual ~tst_QScriptClass(); - -public slots: - void init(); - void cleanup(); - -private slots: - void noSuchProperty(); - void property(); - void setProperty(); - void propertyFlags(); - void call(); - void hasInstance(); - void iterate(); -}; - -tst_QScriptClass::tst_QScriptClass() -{ -} - -tst_QScriptClass::~tst_QScriptClass() -{ -} - -void tst_QScriptClass::init() -{ -} - -void tst_QScriptClass::cleanup() -{ -} - -void tst_QScriptClass::noSuchProperty() -{ - QScriptEngine eng; - TestClass cls(&eng); - QScriptValue obj = eng.newObject(&cls); - QString propertyName = QString::fromLatin1("foo"); - QBENCHMARK { - (void)obj.property(propertyName); - } -} - -void tst_QScriptClass::property() -{ - QScriptEngine eng; - TestClass cls(&eng); - QScriptString foo = eng.toStringHandle("foo"); - cls.addCustomProperty(foo, QScriptClass::HandlesReadAccess, /*id=*/1, /*attributes=*/0, /*value=*/123); - QScriptValue obj = eng.newObject(&cls); - QBENCHMARK { - (void)obj.property(foo); - } -} - -void tst_QScriptClass::setProperty() -{ - QScriptEngine eng; - TestClass cls(&eng); - QScriptString foo = eng.toStringHandle("foo"); - cls.addCustomProperty(foo, QScriptClass::HandlesWriteAccess, /*id=*/1, /*attributes=*/0, /*value=*/123); - QScriptValue obj = eng.newObject(&cls); - QScriptValue value(456); - QBENCHMARK { - obj.setProperty(foo, value); - } -} - -void tst_QScriptClass::propertyFlags() -{ - QScriptEngine eng; - TestClass cls(&eng); - QScriptString foo = eng.toStringHandle("foo"); - cls.addCustomProperty(foo, QScriptClass::HandlesReadAccess, /*id=*/1, QScriptValue::ReadOnly, /*value=*/123); - QScriptValue obj = eng.newObject(&cls); - QBENCHMARK { - (void)obj.propertyFlags(foo); - } -} - -void tst_QScriptClass::call() -{ - QScriptEngine eng; - TestClass cls(&eng); - cls.setCallableMode(TestClass::CallableReturnsArgument); - QScriptValue obj = eng.newObject(&cls); - QScriptValue thisObject; - QScriptValueList args; - args.append(123); - QBENCHMARK { - (void)obj.call(thisObject, args); - } -} - -void tst_QScriptClass::hasInstance() -{ - QScriptEngine eng; - TestClass cls(&eng); - cls.setHasInstance(true); - QScriptValue obj = eng.newObject(&cls); - obj.setProperty("foo", 123); - QScriptValue plain = eng.newObject(); - plain.setProperty("foo", obj.property("foo")); - QBENCHMARK { - (void)plain.instanceOf(obj); - } -} - -void tst_QScriptClass::iterate() -{ - QScriptEngine eng; - TestClass cls(&eng); - cls.setIterationEnabled(true); - cls.addCustomProperty(eng.toStringHandle("foo"), QScriptClass::HandlesReadAccess, /*id=*/1, /*attributes=*/0, /*value=*/123); - cls.addCustomProperty(eng.toStringHandle("bar"), QScriptClass::HandlesReadAccess, /*id=*/2, /*attributes=*/0, /*value=*/456); - QScriptValue obj = eng.newObject(&cls); - QBENCHMARK { - QScriptValueIterator it(obj); - while (it.hasNext()) { - it.next(); - (void)it.scriptName(); - } - } -} - -QTEST_MAIN(tst_QScriptClass) -#include "tst_qscriptclass.moc" diff --git a/tests/benchmarks/qtestlib-simple/main.cpp b/tests/benchmarks/qtestlib-simple/main.cpp deleted file mode 100644 index a8dabe9..0000000 --- a/tests/benchmarks/qtestlib-simple/main.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <QtGui> -#include <QString> - -#include <qtest.h> - - -class tst_QHash : public QObject -{ - Q_OBJECT -private slots: - void foo1_data(); - void foo1(); - void foo2_data(); - void foo2(); - void foo3(); -}; - -void tst_QHash::foo1_data() -{ - QTest::addColumn<int>("x"); - QTest::addColumn<int>("y"); - QTest::newRow("tag1.1") << 16 << 17; - QTest::newRow("tag2.1") << 18 << 19; -} - -void tst_QHash::foo1() -{ - QFETCH(int, x); - QFETCH(int, y); - Q_UNUSED(x); - Q_UNUSED(y); - - QHash<int, int> testHash; - - QBENCHMARK { - testHash.insertMulti(1, 1); - } -} - -void tst_QHash::foo2_data() -{ - QTest::addColumn<int>("x"); - QTest::addColumn<int>("y"); - QTest::newRow("tag1.1") << 16 << 17; - QTest::newRow("tag2.1") << 18 << 19; -} - -void tst_QHash::foo2() -{ - QFETCH(int, x); - QFETCH(int, y); - Q_UNUSED(x); - Q_UNUSED(y); - - QHash<int, int> testHash; - - QBENCHMARK { - testHash.insertMulti(1, 1); - } - - QBENCHMARK { - testHash.insertMulti(1, 1); - } -} - -void tst_QHash::foo3() -{ - QHash<int, int> testHash; - - QBENCHMARK { - testHash.insertMulti(1, 1); - } -} - - -QTEST_MAIN(tst_QHash) -#include "main.moc" diff --git a/tests/benchmarks/qtestlib-simple/qtestlib-simple.pro b/tests/benchmarks/qtestlib-simple/qtestlib-simple.pro deleted file mode 100644 index 7c49883..0000000 --- a/tests/benchmarks/qtestlib-simple/qtestlib-simple.pro +++ /dev/null @@ -1,8 +0,0 @@ -load(qttest_p4) -TEMPLATE = app -TARGET = tst_qtestlib-simple -DEPENDPATH += . -INCLUDEPATH += . - -# Input -SOURCES += main.cpp diff --git a/tests/benchmarks/qtwidgets/advanced.ui b/tests/benchmarks/qtwidgets/advanced.ui deleted file mode 100644 index ce27374..0000000 --- a/tests/benchmarks/qtwidgets/advanced.ui +++ /dev/null @@ -1,319 +0,0 @@ -<ui version="4.0" > - <author></author> - <comment></comment> - <exportmacro></exportmacro> - <class>Advanced</class> - <widget class="QWidget" name="Advanced" > - <property name="objectName" > - <string notr="true" >Advanced</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>300</height> - </rect> - </property> - <layout class="QVBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QPushButton" name="pushButton" > - <property name="objectName" > - <string notr="true" >pushButton</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>80</width> - <height>23</height> - </rect> - </property> - <property name="text" > - <string/> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_2" > - <property name="objectName" > - <string notr="true" >pushButton_2</string> - </property> - <property name="geometry" > - <rect> - <x>87</x> - <y>1</y> - <width>80</width> - <height>23</height> - </rect> - </property> - <property name="text" > - <string>Text</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox" > - <property name="objectName" > - <string notr="true" >checkBox</string> - </property> - <property name="geometry" > - <rect> - <x>173</x> - <y>6</y> - <width>23</width> - <height>13</height> - </rect> - </property> - <property name="text" > - <string/> - </property> - <property name="icon" > - <iconset/> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioButton" > - <property name="objectName" > - <string notr="true" >radioButton</string> - </property> - <property name="geometry" > - <rect> - <x>202</x> - <y>6</y> - <width>22</width> - <height>12</height> - </rect> - </property> - <property name="text" > - <string/> - </property> - <property name="icon" > - <iconset/> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox_2" > - <property name="objectName" > - <string notr="true" >checkBox_2</string> - </property> - <property name="geometry" > - <rect> - <x>230</x> - <y>3</y> - <width>44</width> - <height>18</height> - </rect> - </property> - <property name="text" > - <string>Text</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioButton_2" > - <property name="objectName" > - <string notr="true" >radioButton_2</string> - </property> - <property name="geometry" > - <rect> - <x>280</x> - <y>3</y> - <width>43</width> - <height>18</height> - </rect> - </property> - <property name="text" > - <string>Text</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QGridLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item row="0" column="0" > - <widget class="QListWidget" name="listWidget" > - <property name="objectName" > - <string notr="true" >listWidget</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>186</width> - <height>91</height> - </rect> - </property> - </widget> - </item> - <item row="1" column="1" > - <widget class="QListWidget" name="listWidget_3" > - <property name="objectName" > - <string notr="true" >listWidget_3</string> - </property> - <property name="geometry" > - <rect> - <x>193</x> - <y>96</y> - <width>188</width> - <height>60</height> - </rect> - </property> - </widget> - </item> - <item row="1" column="0" > - <widget class="QTreeWidget" name="treeWidget_2" > - <property name="objectName" > - <string notr="true" >treeWidget_2</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>96</y> - <width>186</width> - <height>60</height> - </rect> - </property> - </widget> - </item> - <item row="0" column="1" > - <layout class="QVBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QListWidget" name="listWidget_2" > - <property name="objectName" > - <string notr="true" >listWidget_2</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>186</width> - <height>43</height> - </rect> - </property> - </widget> - </item> - <item> - <widget class="QTreeWidget" name="treeWidget" > - <property name="objectName" > - <string notr="true" >treeWidget</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>48</y> - <width>186</width> - <height>43</height> - </rect> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - <item> - <widget class="QTabWidget" name="tabWidget" > - <property name="objectName" > - <string notr="true" >tabWidget</string> - </property> - <property name="geometry" > - <rect> - <x>9</x> - <y>201</y> - <width>382</width> - <height>90</height> - </rect> - </property> - <property name="minimumSize" > - <size> - <width>0</width> - <height>90</height> - </size> - </property> - <property name="tabPosition" > - <enum>QTabWidget::North</enum> - </property> - <property name="tabShape" > - <enum>QTabWidget::Rounded</enum> - </property> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>380</width> - <height>63</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 1</string> - </attribute> - </widget> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>459</width> - <height>66</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 2</string> - </attribute> - </widget> - </widget> - </item> - </layout> - </widget> - <pixmapfunction></pixmapfunction> - <connections/> -</ui> diff --git a/tests/benchmarks/qtwidgets/icons/big.png b/tests/benchmarks/qtwidgets/icons/big.png Binary files differdeleted file mode 100644 index 6032804..0000000 --- a/tests/benchmarks/qtwidgets/icons/big.png +++ /dev/null diff --git a/tests/benchmarks/qtwidgets/icons/folder.png b/tests/benchmarks/qtwidgets/icons/folder.png Binary files differdeleted file mode 100644 index 981a25d..0000000 --- a/tests/benchmarks/qtwidgets/icons/folder.png +++ /dev/null diff --git a/tests/benchmarks/qtwidgets/icons/icon.bmp b/tests/benchmarks/qtwidgets/icons/icon.bmp Binary files differdeleted file mode 100644 index 196de6a..0000000 --- a/tests/benchmarks/qtwidgets/icons/icon.bmp +++ /dev/null diff --git a/tests/benchmarks/qtwidgets/icons/icon.png b/tests/benchmarks/qtwidgets/icons/icon.png Binary files differdeleted file mode 100644 index 8f9c562..0000000 --- a/tests/benchmarks/qtwidgets/icons/icon.png +++ /dev/null diff --git a/tests/benchmarks/qtwidgets/mainwindow.cpp b/tests/benchmarks/qtwidgets/mainwindow.cpp deleted file mode 100644 index bb19567..0000000 --- a/tests/benchmarks/qtwidgets/mainwindow.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" -#include <QSplitter> -#include <QHeaderView> - -StyleWidget::StyleWidget(QWidget *parent, Qt::WFlags f) - : QWidget(parent, f) -{ - QHBoxLayout *hbox = new QHBoxLayout(this); - QSplitter *spl = new QSplitter(this); - - // standard widgets - QWidget *leftWidget = new QWidget(this); - m_staWidget.setupUi(leftWidget); - - // advanced/system widgets - QGroupBox *rightWidget = new QGroupBox("Advanced", this); - QVBoxLayout *vbox = new QVBoxLayout(rightWidget); - QWidget *adv = new QWidget(rightWidget); - m_advWidget.setupUi(adv); - QWidget *sys = new QWidget(rightWidget); - m_sysWidget.setupUi(sys); - vbox->addWidget(adv); - vbox->addWidget(sys); - - spl->addWidget(leftWidget); - spl->addWidget(rightWidget); - - hbox->setMargin(4); - hbox->addWidget(spl); - - m_small1 = QIcon(":/icons/icon.bmp"); - m_small2 = QIcon(":/icons/icon.png"); - m_big = QIcon(":/icons/big.png"); - - addComboBoxItems(); - addTreeItems(); - addTreeListItems(); - addListItems(); - addTextEdit(); - setupOtherWidgets(); - setupButtons(); - - foreach(QWidget *w, qFindChildren<QWidget *>(parentWidget())) - w->setWhatsThis(w->metaObject()->className()); -} - -StyleWidget::~StyleWidget() -{ - -} - -void StyleWidget::addTextEdit() -{ - m_staWidget.textEdit->setPlainText( - "Some Text\nSome Text\nSome Text\nSome Text\nSome Text\nSome Text\nSome Text\nSome Text"); - m_staWidget.textEdit_2->setPlainText( - "Some Text, Some Text, Some Text, Some Text, Some Text, Some Text, Some Text, Some Text"); - m_staWidget.textEdit_3->setPlainText( - "Some Text, Some Text, Some Text, Some Text, Some Text, Some Text, Some Text, Some Text" \ - "Some Text\nSome Text\nSome Text\nSome Text\nSome Text\nSome Text\nSome Text\nSome Text\n"); -} - -void StyleWidget::addComboBoxItems() -{ - m_staWidget.comboBox->addItem("Item 1"); - m_staWidget.comboBox->addItem("Item 2"); - m_staWidget.comboBox->addItem("Item 3"); - m_staWidget.comboBox->addItem("Item 4"); - m_staWidget.comboBox->addItem("Item 5"); -} - -void StyleWidget::addListItems() -{ - m_staWidget.listWidget->addItem("Item 1"); - m_staWidget.listWidget->addItem("Item 2"); - m_staWidget.listWidget->addItem("Item 3"); - m_staWidget.listWidget->addItem("Item 4"); - m_staWidget.listWidget->addItem("Item 5"); - - QListWidgetItem *tmp = new QListWidgetItem("Item 1", m_staWidget.listWidget_2); - tmp->setCheckState(Qt::Checked); - tmp = new QListWidgetItem("Item 2", m_staWidget.listWidget_2); - tmp->setCheckState(Qt::Checked); - tmp = new QListWidgetItem("Item 3", m_staWidget.listWidget_2); - tmp->setCheckState(Qt::Checked); - tmp = new QListWidgetItem("Item 4", m_staWidget.listWidget_2); - tmp->setCheckState(Qt::Checked); - tmp = new QListWidgetItem("Item 5", m_staWidget.listWidget_2); - tmp->setCheckState(Qt::Checked); - - tmp = new QListWidgetItem("Item 1", m_advWidget.listWidget_3); - tmp->setCheckState(Qt::Checked); - tmp->setIcon(m_small1); - tmp = new QListWidgetItem("Item 2", m_advWidget.listWidget_3); - tmp->setCheckState(Qt::Checked); - tmp->setIcon(m_small1); - tmp = new QListWidgetItem("Item 3", m_advWidget.listWidget_3); - tmp->setCheckState(Qt::Checked); - tmp->setIcon(m_small1); - tmp = new QListWidgetItem("Item 4", m_advWidget.listWidget_3); - tmp->setCheckState(Qt::Checked); - tmp->setIcon(m_small1); - tmp = new QListWidgetItem("Item 5", m_advWidget.listWidget_3); - tmp->setCheckState(Qt::Checked); - tmp->setIcon(m_small1); - - m_advWidget.listWidget->setViewMode(QListView::IconMode); - QIcon folder(":/icons/folder.png"); - tmp = new QListWidgetItem("Item 1", m_advWidget.listWidget); - tmp->setIcon(folder); - tmp = new QListWidgetItem("Item 2", m_advWidget.listWidget); - tmp->setIcon(folder); - tmp = new QListWidgetItem("Item 3", m_advWidget.listWidget); - tmp->setIcon(folder); - tmp = new QListWidgetItem("Item 4", m_advWidget.listWidget); - tmp->setIcon(folder); - tmp = new QListWidgetItem("Item 5", m_advWidget.listWidget); - tmp->setIcon(folder); - - tmp = new QListWidgetItem("Item 1", m_advWidget.listWidget_2); - tmp->setIcon(m_small1); - tmp = new QListWidgetItem("Item 2", m_advWidget.listWidget_2); - tmp->setIcon(m_small1); - tmp = new QListWidgetItem("Item 3", m_advWidget.listWidget_2); - tmp->setIcon(m_small1); - tmp = new QListWidgetItem("Item 4", m_advWidget.listWidget_2); - tmp->setIcon(m_small1); - tmp = new QListWidgetItem("Item 5", m_advWidget.listWidget_2); - tmp->setIcon(m_small1); -} - -void StyleWidget::setupOtherWidgets() -{ - m_sysWidget.tableWidget->setRowCount(100); - m_sysWidget.tableWidget->setColumnCount(100); -} - -void StyleWidget::addTreeItems() -{ - //standard tree - m_staWidget.treeWidget_2->setColumnCount(1); - m_staWidget.treeWidget_2->header()->hide(); - - QTreeWidgetItem *tmp; - QTreeWidgetItem *subtmp; - QTreeWidgetItem *root1 = new QTreeWidgetItem(m_staWidget.treeWidget_2); - root1->setText(0, "Root 1"); - QTreeWidgetItem *root2 = new QTreeWidgetItem(m_staWidget.treeWidget_2); - root2->setText(0, "Root 2"); - - for (int i=1; i<=10; ++i) - { - tmp = new QTreeWidgetItem(root1); - tmp->setText(0, QString("Item %1").arg(i)); - for (int j=1; j<=5; ++j) - { - subtmp = new QTreeWidgetItem(tmp); - subtmp->setText(0, QString("Sub Item %1").arg(j)); - } - } - - // standard checked tree - m_staWidget.treeWidget_4->setColumnCount(1); - m_staWidget.treeWidget_4->header()->hide(); - - root1 = new QTreeWidgetItem(m_staWidget.treeWidget_4); - root1->setText(0, "Root 1"); - root1->setCheckState(0, Qt::Checked); - root2 = new QTreeWidgetItem(m_staWidget.treeWidget_4); - root2->setText(0, "Root 2"); - root2->setCheckState(0, Qt::Checked); - - for (int i=1; i<=10; ++i) - { - tmp = new QTreeWidgetItem(root1); - tmp->setText(0, QString("Item %1").arg(i)); - tmp->setCheckState(0, Qt::Checked); - for (int j=1; j<=5; ++j) - { - subtmp = new QTreeWidgetItem(tmp); - subtmp->setText(0, QString("Sub Item %1").arg(j)); - subtmp->setCheckState(0, Qt::Checked); - } - } - - // advanced (images) tree - m_advWidget.treeWidget_2->setColumnCount(1); - m_advWidget.treeWidget_2->header()->hide(); - - root1 = new QTreeWidgetItem(m_advWidget.treeWidget_2); - root1->setText(0, "Root 1"); - root1->setIcon(0, m_small1); - root2 = new QTreeWidgetItem(m_advWidget.treeWidget_2); - root2->setText(0, "Root 2"); - root2->setIcon(0, m_small1); - - for (int i=1; i<=10; ++i) - { - tmp = new QTreeWidgetItem(root1); - tmp->setText(0, QString("Item %1").arg(i)); - tmp->setIcon(0, m_small2); - for (int j=1; j<=5; ++j) - { - subtmp = new QTreeWidgetItem(tmp); - subtmp->setText(0, QString("Sub Item %1").arg(j)); - tmp->setIcon(0, m_small1); - } - } - -} - -void StyleWidget::addTreeListItems() -{ - //standard list - QTreeWidgetItem *tmp; - m_staWidget.treeWidget->setColumnCount(3); - m_staWidget.treeWidget->headerItem()->setText(0, "Col1"); - m_staWidget.treeWidget->headerItem()->setText(1, "Col2"); - m_staWidget.treeWidget->headerItem()->setText(2, "Col3"); - - for (int i=1; i<10; ++i) - { - tmp = new QTreeWidgetItem(m_staWidget.treeWidget); - tmp->setText(0, QString("Item%1").arg(i)); - tmp->setText(1, QString("Item%11").arg(i)); - tmp->setText(2, QString("Item%12").arg(i)); - } - - //standard checked list - m_staWidget.treeWidget_3->setColumnCount(3); - m_staWidget.treeWidget_3->headerItem()->setText(0, "Col1"); - m_staWidget.treeWidget_3->headerItem()->setText(1, "Col2"); - m_staWidget.treeWidget_3->headerItem()->setText(2, "Col3"); - - for (int i=1; i<10; ++i) - { - tmp = new QTreeWidgetItem(m_staWidget.treeWidget_3); - tmp->setText(0, QString("Item%1").arg(i)); - tmp->setCheckState(0, Qt::Checked); - tmp->setText(1, QString("Item%11").arg(i)); - tmp->setText(2, QString("Item%12").arg(i)); - } - - //with images - m_advWidget.treeWidget->setColumnCount(2); - m_advWidget.treeWidget->headerItem()->setText(0, "Col1"); - m_advWidget.treeWidget->headerItem()->setIcon(0, m_small2); - m_advWidget.treeWidget->headerItem()->setText(1, "Col2"); - m_advWidget.treeWidget->headerItem()->setIcon(1, m_small2); - - for (int i=1; i<10; ++i) - { - tmp = new QTreeWidgetItem(m_advWidget.treeWidget); - tmp->setText(0, QString("Item%1").arg(i)); - tmp->setIcon(0, m_small1); - tmp->setText(1, QString("Item%11").arg(i)); - } -} - -void StyleWidget::setupButtons() -{ - m_advWidget.pushButton->setIcon(m_small1); - m_advWidget.pushButton_2->setIcon(m_small1); - m_advWidget.checkBox->setIcon(m_small2); - m_advWidget.checkBox_2->setIcon(m_small2); - m_advWidget.radioButton->setIcon(m_small2); - m_advWidget.radioButton_2->setIcon(m_small2); - - // tab page images - m_advWidget.tabWidget->setTabIcon(0, m_small2); - m_advWidget.tabWidget->setTabIcon(1, m_small2); -} diff --git a/tests/benchmarks/qtwidgets/qtstyles.qrc b/tests/benchmarks/qtwidgets/qtstyles.qrc deleted file mode 100644 index 772891d..0000000 --- a/tests/benchmarks/qtwidgets/qtstyles.qrc +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/"> - <file name="icon.png">./icons/icon.png</file> - <file name="icon.bmp">./icons/icon.bmp</file> - <file name="big.png">./icons/big.png</file> - <file name="folder.png">./icons/folder.png</file> -</qresource> -</RCC> diff --git a/tests/benchmarks/qtwidgets/qtwidgets.pro b/tests/benchmarks/qtwidgets/qtwidgets.pro deleted file mode 100644 index ad5e7ac..0000000 --- a/tests/benchmarks/qtwidgets/qtwidgets.pro +++ /dev/null @@ -1,9 +0,0 @@ -load(qttest_p4) - -SOURCES += tst_qtwidgets.cpp mainwindow.cpp -HEADERS += mainwindow.h -QT += network -RESOURCES = qtstyles.qrc -FORMS += advanced.ui system.ui standard.ui - - diff --git a/tests/benchmarks/qtwidgets/standard.ui b/tests/benchmarks/qtwidgets/standard.ui deleted file mode 100644 index 9764a66..0000000 --- a/tests/benchmarks/qtwidgets/standard.ui +++ /dev/null @@ -1,1207 +0,0 @@ -<ui version="4.0" > - <author></author> - <comment></comment> - <exportmacro></exportmacro> - <class>Standard</class> - <widget class="QWidget" name="Standard" > - <property name="objectName" > - <string notr="true" >Standard</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>300</height> - </rect> - </property> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>0</number> - </property> - <item> - <widget class="QGroupBox" name="groupBox" > - <property name="objectName" > - <string notr="true" >groupBox</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>300</height> - </rect> - </property> - <property name="title" > - <string>Standard</string> - </property> - <layout class="QVBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <layout class="QVBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QCheckBox" name="checkBox" > - <property name="objectName" > - <string notr="true" >checkBox</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>114</width> - <height>3</height> - </rect> - </property> - <property name="text" > - <string>Enabled &CheckBox</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="checkBox_2" > - <property name="objectName" > - <string notr="true" >checkBox_2</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>121</x> - <y>1</y> - <width>116</width> - <height>3</height> - </rect> - </property> - <property name="text" > - <string>Disabled Check&Box</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>243</x> - <y>1</y> - <width>80</width> - <height>3</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QComboBox" name="comboBox" > - <property name="objectName" > - <string notr="true" >comboBox</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>41</width> - <height>3</height> - </rect> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_2" > - <property name="objectName" > - <string notr="true" >comboBox_2</string> - </property> - <property name="geometry" > - <rect> - <x>48</x> - <y>1</y> - <width>41</width> - <height>3</height> - </rect> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_3" > - <property name="objectName" > - <string notr="true" >comboBox_3</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>95</x> - <y>1</y> - <width>41</width> - <height>3</height> - </rect> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QPushButton" name="pushButton" > - <property name="objectName" > - <string notr="true" >pushButton</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>80</width> - <height>3</height> - </rect> - </property> - <property name="text" > - <string>&Enabled</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_2" > - <property name="objectName" > - <string notr="true" >pushButton_2</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>87</x> - <y>1</y> - <width>80</width> - <height>3</height> - </rect> - </property> - <property name="text" > - <string>Di&sabled</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>173</x> - <y>1</y> - <width>150</width> - <height>3</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QLabel" name="label" > - <property name="objectName" > - <string notr="true" >label</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>99</width> - <height>3</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Plain</enum> - </property> - <property name="text" > - <string>Label with some text.</string> - </property> - <property name="textFormat" > - <enum>Qt::AutoText</enum> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_2" > - <property name="objectName" > - <string notr="true" >label_2</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>106</x> - <y>1</y> - <width>139</width> - <height>3</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Plain</enum> - </property> - <property name="text" > - <string>Disabled label with some text.</string> - </property> - <property name="textFormat" > - <enum>Qt::AutoText</enum> - </property> - </widget> - </item> - <item> - <spacer> - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>251</x> - <y>1</y> - <width>72</width> - <height>3</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QLineEdit" name="lineEdit" > - <property name="objectName" > - <string notr="true" >lineEdit</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>135</width> - <height>3</height> - </rect> - </property> - <property name="text" > - <string>Enabled</string> - </property> - <property name="echoMode" > - <enum>QLineEdit::Normal</enum> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_2" > - <property name="objectName" > - <string notr="true" >lineEdit_2</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>142</x> - <y>1</y> - <width>134</width> - <height>3</height> - </rect> - </property> - <property name="text" > - <string>Disabled</string> - </property> - <property name="echoMode" > - <enum>QLineEdit::Normal</enum> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinBox" > - <property name="objectName" > - <string notr="true" >spinBox</string> - </property> - <property name="geometry" > - <rect> - <x>282</x> - <y>1</y> - <width>41</width> - <height>3</height> - </rect> - </property> - <property name="buttonSymbols" > - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QRadioButton" name="radioButton" > - <property name="objectName" > - <string notr="true" >radioButton</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>123</width> - <height>3</height> - </rect> - </property> - <property name="text" > - <string>Enabled RadioButton</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioButton_2" > - <property name="objectName" > - <string notr="true" >radioButton_2</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>130</x> - <y>1</y> - <width>125</width> - <height>3</height> - </rect> - </property> - <property name="text" > - <string>Disabled RadioButton</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>261</x> - <y>1</y> - <width>62</width> - <height>3</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QScrollBar" name="horizontalScrollBar" > - <property name="objectName" > - <string notr="true" >horizontalScrollBar</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>90</width> - <height>3</height> - </rect> - </property> - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize" > - <size> - <width>90</width> - <height>0</height> - </size> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QScrollBar" name="horizontalScrollBar_2" > - <property name="objectName" > - <string notr="true" >horizontalScrollBar_2</string> - </property> - <property name="geometry" > - <rect> - <x>97</x> - <y>1</y> - <width>30</width> - <height>3</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - <item> - <widget class="QScrollBar" name="verticalScrollBar" > - <property name="objectName" > - <string notr="true" >verticalScrollBar</string> - </property> - <property name="geometry" > - <rect> - <x>333</x> - <y>1</y> - <width>17</width> - <height>37</height> - </rect> - </property> - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>1</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - </widget> - </item> - <item> - <widget class="QSlider" name="slider" > - <property name="objectName" > - <string notr="true" >slider</string> - </property> - <property name="geometry" > - <rect> - <x>356</x> - <y>1</y> - <width>21</width> - <height>37</height> - </rect> - </property> - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>1</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="tickPosition" > - <enum>QSlider::TicksBelow</enum> - </property> - <property name="tickInterval" > - <number>0</number> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QSlider" name="slider_2" > - <property name="objectName" > - <string notr="true" >slider_2</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>6</y> - <width>90</width> - <height>16</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition" > - <enum>QSlider::NoTicks</enum> - </property> - </widget> - </item> - <item> - <widget class="QSlider" name="slider_3" > - <property name="objectName" > - <string notr="true" >slider_3</string> - </property> - <property name="geometry" > - <rect> - <x>97</x> - <y>3</y> - <width>89</width> - <height>21</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition" > - <enum>QSlider::TicksBelow</enum> - </property> - </widget> - </item> - <item> - <widget class="QSlider" name="slider_4" > - <property name="objectName" > - <string notr="true" >slider_4</string> - </property> - <property name="geometry" > - <rect> - <x>192</x> - <y>3</y> - <width>90</width> - <height>21</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition" > - <enum>QSlider::TicksAbove</enum> - </property> - </widget> - </item> - <item> - <widget class="QSlider" name="slider_5" > - <property name="objectName" > - <string notr="true" >slider_5</string> - </property> - <property name="geometry" > - <rect> - <x>288</x> - <y>1</y> - <width>89</width> - <height>26</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition" > - <enum>QSlider::TicksBothSides</enum> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QTextEdit" name="textEdit" > - <property name="objectName" > - <string notr="true" >textEdit</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>89</width> - <height>37</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Sunken</enum> - </property> - <property name="verticalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOn</enum> - </property> - <property name="horizontalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - </widget> - </item> - <item> - <widget class="QTextEdit" name="textEdit_2" > - <property name="objectName" > - <string notr="true" >textEdit_2</string> - </property> - <property name="geometry" > - <rect> - <x>96</x> - <y>1</y> - <width>90</width> - <height>37</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Sunken</enum> - </property> - <property name="verticalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="horizontalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOn</enum> - </property> - </widget> - </item> - <item> - <widget class="QTextEdit" name="textEdit_3" > - <property name="objectName" > - <string notr="true" >textEdit_3</string> - </property> - <property name="geometry" > - <rect> - <x>192</x> - <y>1</y> - <width>89</width> - <height>100</height> - </rect> - </property> - <property name="minimumSize" > - <size> - <width>0</width> - <height>100</height> - </size> - </property> - <property name="frameShape" > - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Sunken</enum> - </property> - <property name="verticalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOn</enum> - </property> - <property name="horizontalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOn</enum> - </property> - </widget> - </item> - <item> - <widget class="QTextEdit" name="textEdit_4" > - <property name="objectName" > - <string notr="true" >textEdit_4</string> - </property> - <property name="geometry" > - <rect> - <x>287</x> - <y>1</y> - <width>90</width> - <height>37</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Sunken</enum> - </property> - <property name="verticalScrollBarPolicy" > - <enum>Qt::ScrollBarAsNeeded</enum> - </property> - <property name="horizontalScrollBarPolicy" > - <enum>Qt::ScrollBarAsNeeded</enum> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QGroupBox" name="groupBox_2" > - <property name="objectName" > - <string notr="true" >groupBox_2</string> - </property> - <property name="geometry" > - <rect> - <x>11</x> - <y>132</y> - <width>378</width> - <height>39</height> - </rect> - </property> - <property name="title" > - <string>GroupBox</string> - </property> - <layout class="QVBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QProgressBar" name="progressBar" > - <property name="objectName" > - <string notr="true" >progressBar</string> - </property> - <property name="geometry" > - <rect> - <x>11</x> - <y>20</y> - <width>356</width> - <height>8</height> - </rect> - </property> - <property name="value" > - <number>50</number> - </property> - <property name="textVisible" > - <bool>false</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QListWidget" name="listWidget" > - <property name="objectName" > - <string notr="true" >listWidget</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>107</width> - <height>37</height> - </rect> - </property> - </widget> - </item> - <item> - <widget class="QListWidget" name="listWidget_2" > - <property name="objectName" > - <string notr="true" >listWidget_2</string> - </property> - <property name="geometry" > - <rect> - <x>114</x> - <y>1</y> - <width>107</width> - <height>37</height> - </rect> - </property> - </widget> - </item> - <item> - <widget class="QTabWidget" name="tabWidget" > - <property name="objectName" > - <string notr="true" >tabWidget</string> - </property> - <property name="geometry" > - <rect> - <x>227</x> - <y>1</y> - <width>150</width> - <height>37</height> - </rect> - </property> - <property name="minimumSize" > - <size> - <width>150</width> - <height>0</height> - </size> - </property> - <property name="tabPosition" > - <enum>QTabWidget::North</enum> - </property> - <property name="tabShape" > - <enum>QTabWidget::Rounded</enum> - </property> - <widget class="QWidget" name="" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>148</width> - <height>10</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 1</string> - </attribute> - </widget> - <widget class="QWidget" name="" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>116</width> - <height>56</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 2</string> - </attribute> - </widget> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>116</width> - <height>56</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 3</string> - </attribute> - </widget> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>146</width> - <height>36</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 4</string> - </attribute> - </widget> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QTabWidget" name="tabWidget_2" > - <property name="objectName" > - <string notr="true" >tabWidget_2</string> - </property> - <property name="geometry" > - <rect> - <x>11</x> - <y>214</y> - <width>378</width> - <height>90</height> - </rect> - </property> - <property name="minimumSize" > - <size> - <width>0</width> - <height>90</height> - </size> - </property> - <property name="tabPosition" > - <enum>QTabWidget::North</enum> - </property> - <property name="tabShape" > - <enum>QTabWidget::Rounded</enum> - </property> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>376</width> - <height>63</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 1</string> - </attribute> - </widget> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>424</width> - <height>66</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 2</string> - </attribute> - </widget> - </widget> - </item> - <item> - <layout class="QGridLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item row="0" column="1" > - <widget class="QTreeWidget" name="treeWidget_2" > - <property name="objectName" > - <string notr="true" >treeWidget_2</string> - </property> - <property name="geometry" > - <rect> - <x>192</x> - <y>1</y> - <width>185</width> - <height>18</height> - </rect> - </property> - </widget> - </item> - <item row="1" column="0" > - <widget class="QTreeWidget" name="treeWidget_3" > - <property name="objectName" > - <string notr="true" >treeWidget_3</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>20</y> - <width>185</width> - <height>18</height> - </rect> - </property> - </widget> - </item> - <item row="0" column="0" > - <widget class="QTreeWidget" name="treeWidget" > - <property name="objectName" > - <string notr="true" >treeWidget</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>185</width> - <height>18</height> - </rect> - </property> - </widget> - </item> - <item row="1" column="1" > - <widget class="QTreeWidget" name="treeWidget_4" > - <property name="objectName" > - <string notr="true" >treeWidget_4</string> - </property> - <property name="geometry" > - <rect> - <x>192</x> - <y>20</y> - <width>185</width> - <height>18</height> - </rect> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <pixmapfunction></pixmapfunction> - <connections/> -</ui> diff --git a/tests/benchmarks/qtwidgets/system.ui b/tests/benchmarks/qtwidgets/system.ui deleted file mode 100644 index a641e0e..0000000 --- a/tests/benchmarks/qtwidgets/system.ui +++ /dev/null @@ -1,658 +0,0 @@ -<ui version="4.0" > - <author></author> - <comment></comment> - <exportmacro></exportmacro> - <class>System</class> - <widget class="QWidget" name="System" > - <property name="objectName" > - <string notr="true" >System</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>604</height> - </rect> - </property> - <layout class="QVBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <layout class="QGridLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item row="1" column="1" > - <widget class="QToolButton" name="toolButton" > - <property name="objectName" > - <string notr="true" >toolButton</string> - </property> - <property name="geometry" > - <rect> - <x>340</x> - <y>138</y> - <width>15</width> - <height>19</height> - </rect> - </property> - <property name="text" > - <string>...</string> - </property> - </widget> - </item> - <item row="1" column="0" > - <widget class="QFrame" name="horizontalLine" > - <property name="objectName" > - <string notr="true" >horizontalLine</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>146</y> - <width>333</width> - <height>3</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::HLine</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Sunken</enum> - </property> - </widget> - </item> - <item row="0" column="2" > - <widget class="QFrame" name="verticalLine" > - <property name="objectName" > - <string notr="true" >verticalLine</string> - </property> - <property name="geometry" > - <rect> - <x>361</x> - <y>1</y> - <width>3</width> - <height>131</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::VLine</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Sunken</enum> - </property> - </widget> - </item> - <item row="0" column="0" colspan="2" > - <layout class="QGridLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item row="1" column="0" > - <widget class="QDateTimeEdit" name="dateTimeEdit_2" > - <property name="objectName" > - <string notr="true" >dateTimeEdit_2</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>108</y> - <width>113</width> - <height>20</height> - </rect> - </property> - <property name="buttonSymbols" > - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> - </widget> - </item> - <item row="0" column="0" > - <widget class="QDateTimeEdit" name="dateTimeEdit" > - <property name="objectName" > - <string notr="true" >dateTimeEdit</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>41</y> - <width>113</width> - <height>20</height> - </rect> - </property> - <property name="buttonSymbols" > - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> - </widget> - </item> - <item row="0" column="1" > - <widget class="QDial" name="dial" > - <property name="objectName" > - <string notr="true" >dial</string> - </property> - <property name="geometry" > - <rect> - <x>120</x> - <y>1</y> - <width>114</width> - <height>100</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="1" column="1" > - <widget class="QLCDNumber" name="lcdNumber" > - <property name="objectName" > - <string notr="true" >lcdNumber</string> - </property> - <property name="geometry" > - <rect> - <x>120</x> - <y>107</y> - <width>114</width> - <height>23</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::Box</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Raised</enum> - </property> - <property name="mode" > - <enum>QLCDNumber::Dec</enum> - </property> - <property name="segmentStyle" > - <enum>QLCDNumber::Outline</enum> - </property> - </widget> - </item> - <item row="1" column="2" > - <widget class="QLCDNumber" name="lcdNumber_2" > - <property name="objectName" > - <string notr="true" >lcdNumber_2</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>240</x> - <y>107</y> - <width>113</width> - <height>23</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::Box</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Raised</enum> - </property> - <property name="mode" > - <enum>QLCDNumber::Dec</enum> - </property> - <property name="segmentStyle" > - <enum>QLCDNumber::Outline</enum> - </property> - </widget> - </item> - <item row="0" column="2" > - <widget class="QDial" name="dial_2" > - <property name="objectName" > - <string notr="true" >dial_2</string> - </property> - <property name="enabled" > - <bool>false</bool> - </property> - <property name="geometry" > - <rect> - <x>240</x> - <y>1</y> - <width>113</width> - <height>100</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QTableWidget" name="tableWidget" > - <property name="objectName" > - <string notr="true" >tableWidget</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>256</width> - <height>193</height> - </rect> - </property> - </widget> - </item> - <item> - <widget class="QToolBox" name="toolBox" > - <property name="objectName" > - <string notr="true" >toolBox</string> - </property> - <property name="geometry" > - <rect> - <x>263</x> - <y>1</y> - <width>118</width> - <height>193</height> - </rect> - </property> - <property name="frameShape" > - <enum>QFrame::Box</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Plain</enum> - </property> - <property name="currentIndex" > - <number>0</number> - </property> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>98</width> - <height>119</height> - </rect> - </property> - <attribute name="label" > - <string>Tool Page 1</string> - </attribute> - </widget> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>115</width> - <height>56</height> - </rect> - </property> - <attribute name="label" > - <string>Tool Page 2</string> - </attribute> - </widget> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QTabWidget" name="tabWidget" > - <property name="objectName" > - <string notr="true" >tabWidget</string> - </property> - <property name="geometry" > - <rect> - <x>9</x> - <y>375</y> - <width>382</width> - <height>220</height> - </rect> - </property> - <property name="tabShape" > - <enum>QTabWidget::Rounded</enum> - </property> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>378</width> - <height>196</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 1</string> - </attribute> - <layout class="QGridLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item row="0" column="0" > - <layout class="QVBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QComboBox" name="comboBox_3" > - <property name="objectName" > - <string notr="true" >comboBox_3</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>332</width> - <height>20</height> - </rect> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QPushButton" name="pushButton_5" > - <property name="objectName" > - <string notr="true" >pushButton_5</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>1</y> - <width>80</width> - <height>23</height> - </rect> - </property> - <property name="text" > - <string>&Enabled</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_6" > - <property name="objectName" > - <string notr="true" >pushButton_6</string> - </property> - <property name="geometry" > - <rect> - <x>87</x> - <y>1</y> - <width>80</width> - <height>23</height> - </rect> - </property> - <property name="text" > - <string>Di&sabled</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>173</x> - <y>1</y> - <width>158</width> - <height>23</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="objectName" > - <string notr="true" /> - </property> - <property name="margin" > - <number>1</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QRadioButton" name="radioButton_3" > - <property name="objectName" > - <string notr="true" >radioButton_3</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>2</y> - <width>123</width> - <height>18</height> - </rect> - </property> - <property name="text" > - <string>Enabled RadioButton</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radioButton_4" > - <property name="objectName" > - <string notr="true" >radioButton_4</string> - </property> - <property name="geometry" > - <rect> - <x>130</x> - <y>2</y> - <width>125</width> - <height>18</height> - </rect> - </property> - <property name="text" > - <string>Disabled RadioButton</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>261</x> - <y>1</y> - <width>70</width> - <height>20</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QProgressBar" name="progressBar" > - <property name="objectName" > - <string notr="true" >progressBar</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>86</y> - <width>332</width> - <height>22</height> - </rect> - </property> - <property name="value" > - <number>24</number> - </property> - </widget> - </item> - <item> - <widget class="QScrollBar" name="horizontalScrollBar" > - <property name="objectName" > - <string notr="true" >horizontalScrollBar</string> - </property> - <property name="geometry" > - <rect> - <x>1</x> - <y>114</y> - <width>332</width> - <height>17</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </item> - <item row="0" column="1" > - <widget class="QScrollBar" name="verticalScrollBar" > - <property name="objectName" > - <string notr="true" >verticalScrollBar</string> - </property> - <property name="geometry" > - <rect> - <x>349</x> - <y>9</y> - <width>17</width> - <height>132</height> - </rect> - </property> - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>1</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - </widget> - </item> - <item row="1" column="0" > - <spacer> - <property name="objectName" > - <string notr="true" /> - </property> - <property name="geometry" > - <rect> - <x>9</x> - <y>147</y> - <width>334</width> - <height>40</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" > - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <widget class="QWidget" name="widget" > - <property name="objectName" > - <string notr="true" >widget</string> - </property> - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>377</width> - <height>187</height> - </rect> - </property> - <attribute name="title" > - <string>Tab Page 2</string> - </attribute> - </widget> - </widget> - </item> - </layout> - </widget> - <pixmapfunction></pixmapfunction> - <connections/> -</ui> diff --git a/tests/benchmarks/qscriptclass/qscriptclass.pro b/tests/benchmarks/script/qscriptclass/qscriptclass.pro index f0ffeb7..f0ffeb7 100644 --- a/tests/benchmarks/qscriptclass/qscriptclass.pro +++ b/tests/benchmarks/script/qscriptclass/qscriptclass.pro diff --git a/tests/benchmarks/script/qscriptclass/tst_qscriptclass.cpp b/tests/benchmarks/script/qscriptclass/tst_qscriptclass.cpp new file mode 100644 index 0000000..6ab78b1 --- /dev/null +++ b/tests/benchmarks/script/qscriptclass/tst_qscriptclass.cpp @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtScript> + +Q_DECLARE_METATYPE(QScriptContext*) +Q_DECLARE_METATYPE(QScriptValue) +Q_DECLARE_METATYPE(QScriptValueList) + +// We want reliable numbers so we don't want to rely too much +// on the number of iterations done by testlib. +// this also make the results of valgrind more interesting +const int iterationNumber = 5000; + +class tst_QScriptClass : public QObject +{ + Q_OBJECT + +private slots: + void noSuchProperty(); + void property(); + void setProperty(); + void propertyFlags(); + void call(); + void hasInstance(); + void iterate(); +}; + +// Test the overhead of checking for an inexisting property of a QScriptClass +void tst_QScriptClass::noSuchProperty() +{ + QScriptEngine eng; + QScriptClass cls(&eng); + QScriptValue obj = eng.newObject(&cls); + QString propertyName = QString::fromLatin1("foo"); + QBENCHMARK { + for (int i = 0; i < iterationNumber; ++i) + (void)obj.property(propertyName); + } + Q_ASSERT(!obj.property(propertyName).isValid()); +} + + +class FooScriptClass : public QScriptClass +{ +public: + FooScriptClass(QScriptEngine *engine) + : QScriptClass(engine) + { + foo = engine->toStringHandle("foo"); + } + + QueryFlags queryProperty(const QScriptValue &, + const QScriptString &, + QueryFlags flags, + uint *id) + { + *id = 1; + return flags; + } + + QScriptValue property(const QScriptValue &, + const QScriptString &, + uint) + { + return QScriptValue(engine(), 35); + } + + void setProperty(QScriptValue &, const QScriptString &, + uint, const QScriptValue &) + {} + + QScriptValue::PropertyFlags propertyFlags(const QScriptValue &, const QScriptString &, uint) + { + return QScriptValue::Undeletable; + } +private: + QScriptString foo; +}; + +// Test the overhead of getting a value of QScriptClass accross the Javascript engine +void tst_QScriptClass::property() +{ + QScriptEngine eng; + FooScriptClass cls(&eng); + QScriptValue obj = eng.newObject(&cls); + QScriptString foo = eng.toStringHandle("foo"); + QBENCHMARK { + for (int i = 0; i < iterationNumber; ++i) + (void)obj.property(foo); + } +} + +// Test the overhead of setting a value on QScriptClass accross the Javascript engine +void tst_QScriptClass::setProperty() +{ + QScriptEngine eng; + FooScriptClass cls(&eng); + QScriptValue obj = eng.newObject(&cls); + QScriptValue value(456); + QScriptString foo = eng.toStringHandle("foo"); + QBENCHMARK { + for (int i = 0; i < iterationNumber; ++i) + obj.setProperty(foo, value); + } +} + +// Test the time taken to get the propeties flags accross the engine +void tst_QScriptClass::propertyFlags() +{ + QScriptEngine eng; + FooScriptClass cls(&eng); + QScriptValue obj = eng.newObject(&cls); + QScriptString foo = eng.toStringHandle("foo"); + QBENCHMARK { + for (int i = 0; i < iterationNumber; ++i) + (void)obj.propertyFlags(foo); + } +} + + + +class ExtensionScriptClass : public QScriptClass +{ +public: + ExtensionScriptClass(QScriptEngine *engine) + : QScriptClass(engine) + { + } + + bool supportsExtension(Extension) const + { + return true; + } + + QVariant extension(Extension, const QVariant &argument = QVariant()) + { + Q_UNUSED(argument); + return QVariant(); + } +}; + +// Check the overhead of the extension "call" +void tst_QScriptClass::call() +{ + QScriptEngine eng; + ExtensionScriptClass cls(&eng); + QScriptValue obj = eng.newObject(&cls); + QScriptValue thisObject; + QScriptValueList args; + args.append(123); + QBENCHMARK { + for (int i = 0; i < iterationNumber; ++i) + (void)obj.call(thisObject, args); + } +} + +// Check the overhead of the extension "instanceOf" +void tst_QScriptClass::hasInstance() +{ + QScriptEngine eng; + ExtensionScriptClass cls(&eng); + QScriptValue obj = eng.newObject(&cls); + obj.setProperty("foo", 123); + QScriptValue plain = eng.newObject(); + plain.setProperty("foo", obj.property("foo")); + QBENCHMARK { + for (int i = 0; i < iterationNumber; ++i) + (void)plain.instanceOf(obj); + } +} + + + +static const int iteratorValuesNumber = 100; +class TestClassPropertyIterator : public QScriptClassPropertyIterator +{ +public: + TestClassPropertyIterator(const QScriptValue &object, QVector<QScriptString> names) + : QScriptClassPropertyIterator(object) + , m_index(0) + , names(names) + { + } + + bool hasNext() const + { + return m_index < iteratorValuesNumber - 1; + } + void next() { ++m_index; } + + bool hasPrevious() const { return m_index > 0; } + void previous() { --m_index; } + + void toFront() { m_index = 0; } + void toBack() { m_index = iteratorValuesNumber - 1; } + + QScriptString name() const { return names[m_index]; } + uint id() const { return m_index; } + QScriptValue::PropertyFlags flags() const { return 0; } + +private: + int m_index; + QVector<QScriptString> names; +}; + + +class IteratorScriptClass : public QScriptClass +{ +public: + IteratorScriptClass(QScriptEngine *engine) + : QScriptClass(engine) + { + for (int i = 0; i < iteratorValuesNumber; ++i) + names.append(engine->toStringHandle(QString("property%1").arg(i))); + } + + QScriptClassPropertyIterator *newIterator(const QScriptValue &object) + { + return new TestClassPropertyIterator(object, names); + } +private: + QVector<QScriptString> names; + friend class TestClassPropertyIterator; +}; + +// Measure the performance of the interface to iterate over QScriptClassPropertyIterator +void tst_QScriptClass::iterate() +{ + QScriptEngine eng; + IteratorScriptClass cls(&eng); + QScriptValue obj = eng.newObject(&cls); + int iterationNumberIterate = iterationNumber / iteratorValuesNumber; + QBENCHMARK { + for (int i = 0; i < iterationNumberIterate; ++i) { + QScriptValueIterator it(obj); + while (it.hasNext()) { + it.next(); + (void)it.scriptName(); + } + } + } +} + +QTEST_MAIN(tst_QScriptClass) +#include "tst_qscriptclass.moc" diff --git a/tests/benchmarks/qscriptengine/qscriptengine.pro b/tests/benchmarks/script/qscriptengine/qscriptengine.pro index df6dbb3..df6dbb3 100644 --- a/tests/benchmarks/qscriptengine/qscriptengine.pro +++ b/tests/benchmarks/script/qscriptengine/qscriptengine.pro diff --git a/tests/benchmarks/qscriptengine/tst_qscriptengine.cpp b/tests/benchmarks/script/qscriptengine/tst_qscriptengine.cpp index 6c6f0b1..6c6f0b1 100644 --- a/tests/benchmarks/qscriptengine/tst_qscriptengine.cpp +++ b/tests/benchmarks/script/qscriptengine/tst_qscriptengine.cpp diff --git a/tests/benchmarks/qscriptvalue/qscriptvalue.pro b/tests/benchmarks/script/qscriptvalue/qscriptvalue.pro index 04ea324..04ea324 100644 --- a/tests/benchmarks/qscriptvalue/qscriptvalue.pro +++ b/tests/benchmarks/script/qscriptvalue/qscriptvalue.pro diff --git a/tests/benchmarks/qscriptvalue/tst_qscriptvalue.cpp b/tests/benchmarks/script/qscriptvalue/tst_qscriptvalue.cpp index 3bfc21c..3bfc21c 100644 --- a/tests/benchmarks/qscriptvalue/tst_qscriptvalue.cpp +++ b/tests/benchmarks/script/qscriptvalue/tst_qscriptvalue.cpp diff --git a/tests/benchmarks/script/script.pro b/tests/benchmarks/script/script.pro new file mode 100644 index 0000000..8d689b6 --- /dev/null +++ b/tests/benchmarks/script/script.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qscriptclass \ + qscriptengine \ + qscriptvalue diff --git a/tests/benchmarks/qsvgrenderer/data/tiger.svg b/tests/benchmarks/svg/qsvgrenderer/data/tiger.svg index 983e570..983e570 100644 --- a/tests/benchmarks/qsvgrenderer/data/tiger.svg +++ b/tests/benchmarks/svg/qsvgrenderer/data/tiger.svg diff --git a/tests/benchmarks/qsvgrenderer/qsvgrenderer.pro b/tests/benchmarks/svg/qsvgrenderer/qsvgrenderer.pro index 8222a09..8222a09 100644 --- a/tests/benchmarks/qsvgrenderer/qsvgrenderer.pro +++ b/tests/benchmarks/svg/qsvgrenderer/qsvgrenderer.pro diff --git a/tests/benchmarks/qsvgrenderer/qsvgrenderer.qrc b/tests/benchmarks/svg/qsvgrenderer/qsvgrenderer.qrc index bdf4a31..bdf4a31 100644 --- a/tests/benchmarks/qsvgrenderer/qsvgrenderer.qrc +++ b/tests/benchmarks/svg/qsvgrenderer/qsvgrenderer.qrc diff --git a/tests/benchmarks/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/benchmarks/svg/qsvgrenderer/tst_qsvgrenderer.cpp index 895ffe0..895ffe0 100644 --- a/tests/benchmarks/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/benchmarks/svg/qsvgrenderer/tst_qsvgrenderer.cpp diff --git a/tests/benchmarks/svg/svg.pro b/tests/benchmarks/svg/svg.pro new file mode 100644 index 0000000..cdc2ca5 --- /dev/null +++ b/tests/benchmarks/svg/svg.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qsvgrenderer diff --git a/tests/manual/bearerex/bearerex.cpp b/tests/manual/bearerex/bearerex.cpp new file mode 100644 index 0000000..19246a2 --- /dev/null +++ b/tests/manual/bearerex/bearerex.cpp @@ -0,0 +1,561 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bearerex.h" + +#include <QtNetwork> + +Q_DECLARE_METATYPE(QNetworkConfiguration) + +BearerEx::BearerEx(QWidget* parent) + : QMainWindow(parent) +{ + setupUi(this); + + createMenus(); + + connect(&m_NetworkConfigurationManager, SIGNAL(updateCompleted()), this, SLOT(configurationsUpdateCompleted())); + connect(&m_NetworkConfigurationManager, SIGNAL(configurationAdded(const QNetworkConfiguration&)), + this, SLOT(configurationAdded(const QNetworkConfiguration&))); + connect(&m_NetworkConfigurationManager, SIGNAL(configurationRemoved(const QNetworkConfiguration&)), + this, SLOT(configurationRemoved(const QNetworkConfiguration&))); + connect(&m_NetworkConfigurationManager, SIGNAL(onlineStateChanged(bool)), + this, SLOT(onlineStateChanged(bool))); + connect(&m_NetworkConfigurationManager, SIGNAL(configurationChanged(const QNetworkConfiguration&)), + this, SLOT(configurationChanged(const QNetworkConfiguration&))); + showConfigurations(); +} + +void BearerEx::createMenus() +{ + QAction* act1 = new QAction(tr("Show Details"), this); + menuBar()->addAction(act1); + connect(act1, SIGNAL(triggered()), this, SLOT(on_showDetailsButton_clicked())); + + QAction* exitAct = new QAction(tr("Exit"), this); + menuBar()->addAction(exitAct); + connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); +} + +void BearerEx::showConfigurations() +{ + listWidget->clear(); + QListWidgetItem* listItem; + + QNetworkConfiguration defaultConfig = m_NetworkConfigurationManager.defaultConfiguration(); + if (defaultConfig.type() == QNetworkConfiguration::UserChoice) { + listItem = new QListWidgetItem(); + QFont font = listItem->font(); + font.setBold(true); + font.setUnderline(true); + listItem->setFont(font); + listItem->setText(" UserChoice"); + listItem->setData(Qt::UserRole, qVariantFromValue(defaultConfig)); + listWidget->addItem(listItem); + } + + QList<QNetworkConfiguration> configurations = m_NetworkConfigurationManager.allConfigurations(); + for (int i=0; i<configurations.count(); i++) + { + listItem = new QListWidgetItem(); + QString text; + if (configurations[i].type() == QNetworkConfiguration::InternetAccessPoint) { + text.append("(IAP,"); + } else if (configurations[i].type() == QNetworkConfiguration::ServiceNetwork) { + text.append("(SNAP,"); + } + + if ((configurations[i].state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + text.append("Act) "); + } else if ((configurations[i].state() & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) { + text.append("Disc) "); + } else { + text.append("Def) "); + } + text.append(configurations[i].name()); + + if (defaultConfig.isValid() && defaultConfig == configurations[i]) { + QFont font = listItem->font(); + font.setBold(true); + font.setUnderline(true); + listItem->setFont(font); + } + listItem->setText(text); + listItem->setData(Qt::UserRole, qVariantFromValue(configurations[i])); + listWidget->addItem(listItem); + } +} + +void BearerEx::on_updateConfigurationsButton_clicked() +{ + m_NetworkConfigurationManager.updateConfigurations(); +} + +void BearerEx::on_updateListButton_clicked() +{ + showConfigurations(); +} + +void BearerEx::on_showDetailsButton_clicked() +{ + QListWidgetItem* item = listWidget->currentItem(); + if (!item) { + return; + } + + QNetworkConfiguration networkConfiguration = qVariantValue<QNetworkConfiguration>(item->data(Qt::UserRole)); + DetailedInfoDialog infoDialog(&networkConfiguration,this); + infoDialog.exec(); +} + +void BearerEx::on_createSessionButton_clicked() +{ + QListWidgetItem* item = listWidget->currentItem(); + if (!item) { + return; + } + QNetworkConfiguration networkConfiguration = qVariantValue<QNetworkConfiguration>(item->data(Qt::UserRole)); + int newTabIndex = mainTabWidget->count(); + SessionTab* newTab = new SessionTab(&networkConfiguration,&m_NetworkConfigurationManager,eventListWidget,newTabIndex-1); + QString label = QString("S")+QString::number(newTabIndex-1); + mainTabWidget->insertTab(newTabIndex,newTab,label); + mainTabWidget->setCurrentIndex(newTabIndex); +} + +void BearerEx::on_clearEventListButton_clicked() +{ + eventListWidget->clear(); +} + +void BearerEx::configurationAdded(const QNetworkConfiguration& config) +{ + QListWidgetItem* listItem = new QListWidgetItem(); + listItem->setText(QString("Added: ")+config.name()); + eventListWidget->addItem(listItem); +} + +void BearerEx::configurationRemoved(const QNetworkConfiguration& config) +{ + QListWidgetItem* listItem = new QListWidgetItem(); + listItem->setText(QString("Removed: ")+config.name()); + eventListWidget->addItem(listItem); +} + +void BearerEx::onlineStateChanged(bool isOnline) +{ + QListWidgetItem* listItem = new QListWidgetItem(); + QFont font = listItem->font(); + font.setBold(true); + listItem->setFont(font); + if (isOnline) { + listItem->setText(QString("> Online")); + } else { + listItem->setText(QString("< Offline")); + } + eventListWidget->addItem(listItem); +} + +void BearerEx::configurationChanged(const QNetworkConfiguration & config) +{ + QListWidgetItem* listItem = new QListWidgetItem(); + QString state; + switch (config.state()) + { + case QNetworkConfiguration::Undefined: + state = "Undef : "; + break; + case QNetworkConfiguration::Defined: + state = "Def : "; + break; + case QNetworkConfiguration::Discovered: + state = "Disc : "; + break; + case QNetworkConfiguration::Active: + state = "Act : "; + break; + } + listItem->setText(state+config.name()); + eventListWidget->addItem(listItem); +} + +void BearerEx::configurationsUpdateCompleted() +{ + QMessageBox msgBox; + msgBox.setStandardButtons(QMessageBox::Close); + msgBox.setText("Configurations update completed."); + msgBox.exec(); +} + +DetailedInfoDialog::DetailedInfoDialog(QNetworkConfiguration* apNetworkConfiguration, QWidget * parent) + : QDialog(parent) +{ + setupUi(this); + + tableWidget->setColumnCount(2); + int rowCount = 2; + + if (apNetworkConfiguration->type() == QNetworkConfiguration::ServiceNetwork) { + rowCount = rowCount + apNetworkConfiguration->children().count(); + } + + tableWidget->setRowCount(rowCount); + tableWidget->setColumnWidth(1,250); + tableWidget->setItem(0, 0, new QTableWidgetItem(tr("Name"))); + tableWidget->setItem(0, 1, new QTableWidgetItem(apNetworkConfiguration->name())); + tableWidget->setItem(1, 0, new QTableWidgetItem(tr("Id"))); + tableWidget->setItem(1, 1, new QTableWidgetItem(apNetworkConfiguration->identifier())); + if (apNetworkConfiguration->type() == QNetworkConfiguration::ServiceNetwork) { + for (int i=0; i<apNetworkConfiguration->children().count(); i++) { + tableWidget->setItem(i+2, 0, new QTableWidgetItem(QString("IAP")+QString::number(i+1))); + tableWidget->setItem(i+2, 1, new QTableWidgetItem(apNetworkConfiguration->children()[i].name())); + } + } + + tableWidget->setFocusPolicy(Qt::NoFocus); + +#ifdef Q_OS_SYMBIAN + this->showMaximized(); +#endif +} + +SessionTab::SessionTab(QNetworkConfiguration* apNetworkConfiguration, + QNetworkConfigurationManager* configManager, + QListWidget* eventListWidget, + int index, + BearerEx * parent) + : QWidget(parent), m_http(0), m_eventListWidget(eventListWidget), + m_index(index), m_httpRequestOngoing(false), m_alrEnabled (false) +{ + setupUi(this); + + m_ConfigManager = configManager; + m_NetworkSession = new QNetworkSession(*apNetworkConfiguration); + + // Update initial Session state to UI + newState(m_NetworkSession->state()); + + connect(m_NetworkSession, SIGNAL(newConfigurationActivated()), this, SLOT(newConfigurationActivated())); + connect(m_NetworkSession, SIGNAL(stateChanged(QNetworkSession::State)), + this, SLOT(stateChanged(QNetworkSession::State))); + connect(m_NetworkSession, SIGNAL(opened()), this, SLOT(opened())); + connect(m_NetworkSession, SIGNAL(closed()), this, SLOT(closed())); + connect(m_NetworkSession, SIGNAL(error(QNetworkSession::SessionError)), this, SLOT(error(QNetworkSession::SessionError))); + + if (apNetworkConfiguration->type() == QNetworkConfiguration::InternetAccessPoint) { + snapLabel->hide(); + snapLineEdit->hide(); + alrButton->hide(); + iapLineEdit->setText(apNetworkConfiguration->name()+" ("+apNetworkConfiguration->identifier()+")"); + } else if (apNetworkConfiguration->type() == QNetworkConfiguration::ServiceNetwork) { + snapLineEdit->setText(apNetworkConfiguration->name()+" ("+apNetworkConfiguration->identifier()+")"); + } + bearerLineEdit->setText(apNetworkConfiguration->bearerName()); + sentRecDataLineEdit->setText(QString::number(m_NetworkSession->bytesWritten())+ + QString(" / ")+ + QString::number(m_NetworkSession->bytesReceived())); + snapLineEdit->setFocusPolicy(Qt::NoFocus); + iapLineEdit->setFocusPolicy(Qt::NoFocus); + bearerLineEdit->setFocusPolicy(Qt::NoFocus); + sentRecDataLineEdit->setFocusPolicy(Qt::NoFocus); + stateLineEdit->setFocusPolicy(Qt::NoFocus); +} + +SessionTab::~SessionTab() +{ + delete m_NetworkSession; + delete m_http; +} + +void SessionTab::on_createQHttpButton_clicked() +{ + if (m_httpRequestOngoing) { + return; + } + + if (m_http) { + disconnect(m_http, 0, 0, 0); + delete m_http; + } + m_http = new QHttp(this); + createQHttpButton->setText("Recreate QHttp"); + connect(m_http, SIGNAL(done(bool)), this, SLOT(done(bool))); +} + +void SessionTab::on_sendRequestButton_clicked() +{ + if (m_http) { + QString urlstring("http://www.google.com"); + QUrl url(urlstring); + m_http->setHost(url.host(), QHttp::ConnectionModeHttp, url.port() == -1 ? 0 : url.port()); + m_http->get(urlstring); + m_httpRequestOngoing = true; + } else { + QMessageBox msgBox; + msgBox.setStandardButtons(QMessageBox::Close); + msgBox.setText("QHttp not created.\nCreate QHttp First."); + msgBox.exec(); + } +} + +void SessionTab::on_openSessionButton_clicked() +{ + m_NetworkSession->open(); + if (m_NetworkSession->isOpen()) { + newState(m_NetworkSession->state()); + } +} + +void SessionTab::on_closeSessionButton_clicked() +{ + m_NetworkSession->close(); + if (!m_NetworkSession->isOpen()) { + newState(m_NetworkSession->state()); + } +} + +void SessionTab::on_stopConnectionButton_clicked() +{ + m_NetworkSession->stop(); +} + +void SessionTab::on_alrButton_clicked() +{ + if (!m_alrEnabled) { + connect(m_NetworkSession, SIGNAL(preferredConfigurationChanged(const QNetworkConfiguration&, bool)), + this, SLOT(preferredConfigurationChanged(const QNetworkConfiguration&, bool))); + alrButton->setText("Disable ALR"); + m_alrEnabled = true; + } else { + disconnect(m_NetworkSession, SIGNAL(preferredConfigurationChanged(const QNetworkConfiguration&, bool)), 0, 0); + alrButton->setText("Enable ALR"); + m_alrEnabled = false; + } +} + +void SessionTab::on_deleteSessionButton_clicked() +{ + setWindowTitle("Bearer Example"); + delete this; +} + +void SessionTab::newConfigurationActivated() +{ + QMessageBox msgBox; + msgBox.setText("New configuration activated."); + msgBox.setInformativeText("Do you want to accept new configuration?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + if (msgBox.exec() == QMessageBox::Yes) { + m_NetworkSession->accept(); + iapLineEdit->setText(m_config.name()+" ("+m_config.identifier()+")"); + } else { + m_NetworkSession->reject(); + } +} + +void SessionTab::preferredConfigurationChanged(const QNetworkConfiguration& config, bool /*isSeamless*/) +{ + m_config = config; + QMessageBox msgBox; + msgBox.setText("Roaming to new configuration."); + msgBox.setInformativeText("Do you want to migrate to "+config.name()+"?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + if (msgBox.exec() == QMessageBox::Yes) { + m_NetworkSession->migrate(); + } else { + m_NetworkSession->ignore(); + } +} + +void SessionTab::opened() +{ + QListWidgetItem* listItem = new QListWidgetItem(); + QFont font = listItem->font(); + font.setBold(true); + listItem->setFont(font); + listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+QString("Opened")); + m_eventListWidget->addItem(listItem); + + QVariant identifier = m_NetworkSession->property("ActiveConfiguration"); + if (!identifier.isNull()) { + QString configId = identifier.toString(); + QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId); + if (config.isValid()) { + iapLineEdit->setText(config.name()+" ("+config.identifier()+")"); + } + } + + if (m_NetworkSession->configuration().type() == QNetworkConfiguration::UserChoice) { + QVariant identifier = m_NetworkSession->property("UserChoiceConfiguration"); + if (!identifier.isNull()) { + QString configId = identifier.toString(); + QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId); + if (config.isValid() && (config.type() == QNetworkConfiguration::ServiceNetwork)) { + snapLineEdit->setText(config.name()); + } + } + } +} + +void SessionTab::closed() +{ + QListWidgetItem* listItem = new QListWidgetItem(); + QFont font = listItem->font(); + font.setBold(true); + listItem->setFont(font); + listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+QString("Closed")); + m_eventListWidget->addItem(listItem); +} + +QString SessionTab::stateString(QNetworkSession::State state) +{ + QString stateString; + switch (state) + { + case QNetworkSession::Invalid: + stateString = "Invalid"; + break; + case QNetworkSession::NotAvailable: + stateString = "NotAvailable"; + break; + case QNetworkSession::Connecting: + stateString = "Connecting"; + break; + case QNetworkSession::Connected: + stateString = "Connected"; + break; + case QNetworkSession::Closing: + stateString = "Closing"; + break; + case QNetworkSession::Disconnected: + stateString = "Disconnected"; + break; + case QNetworkSession::Roaming: + stateString = "Roaming"; + break; + } + return stateString; +} + +void SessionTab::stateChanged(QNetworkSession::State state) +{ + newState(state); + + QListWidgetItem* listItem = new QListWidgetItem(); + listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+stateString(state)); + m_eventListWidget->addItem(listItem); +} + +void SessionTab::newState(QNetworkSession::State state) +{ + QVariant identifier = m_NetworkSession->property("ActiveConfiguration"); + if (state == QNetworkSession::Connected && !identifier.isNull()) { + QString configId = identifier.toString(); + QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId); + if (config.isValid()) { + iapLineEdit->setText(config.name()+" ("+config.identifier()+")"); + bearerLineEdit->setText(config.bearerName()); + } + } else { + bearerLineEdit->setText(m_NetworkSession->configuration().bearerName()); + } + + QString active; + if (m_NetworkSession->isOpen()) { + active = " (O)"; + } + stateLineEdit->setText(stateString(state)+active); +} + +void SessionTab::error(QNetworkSession::SessionError error) +{ + QListWidgetItem* listItem = new QListWidgetItem(); + QMessageBox msgBox; + msgBox.setStandardButtons(QMessageBox::Close); + + QString errorString; + switch (error) + { + case QNetworkSession::UnknownSessionError: + errorString = "UnknownSessionError"; + break; + case QNetworkSession::SessionAbortedError: + errorString = "SessionAbortedError"; + break; + case QNetworkSession::RoamingError: + errorString = "RoamingError"; + break; + case QNetworkSession::OperationNotSupportedError: + errorString = "OperationNotSupportedError"; + break; + case QNetworkSession::InvalidConfigurationError: + errorString = "InvalidConfigurationError"; + break; + } + listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+errorString); + m_eventListWidget->addItem(listItem); + + msgBox.setText(errorString); + msgBox.exec(); +} + +void SessionTab::done(bool error) +{ + m_httpRequestOngoing = false; + + QMessageBox msgBox; + msgBox.setStandardButtons(QMessageBox::Close); + if (error) { + msgBox.setText("HTTP request failed."); + } else { + QString result(m_http->readAll()); + msgBox.setText(QString("HTTP request finished successfully.\nReceived ")+QString::number(result.length())+QString(" bytes.")); + } + msgBox.exec(); + + sentRecDataLineEdit->setText(QString::number(m_NetworkSession->bytesWritten())+ + QString(" / ")+ + QString::number(m_NetworkSession->bytesReceived())); +} + +// End of file + diff --git a/tests/manual/bearerex/bearerex.h b/tests/manual/bearerex/bearerex.h new file mode 100644 index 0000000..2875d6a --- /dev/null +++ b/tests/manual/bearerex/bearerex.h @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ACCESSPOINTMANAGEREX_H +#define ACCESSPOINTMANAGEREX_H + +#include <QtGui> + +#include "ui_bearerex.h" +#include "ui_detailedinfodialog.h" +#include "ui_sessiondialog.h" + +#include "qnetworkconfigmanager.h" +#include "qnetworksession.h" +#include "xqlistwidget.h" + +QT_BEGIN_NAMESPACE +class QHttp; +QT_END_NAMESPACE + +class SessionTab; + +QT_USE_NAMESPACE + +class BearerEx : public QMainWindow, public Ui::BearerExMainWindow +{ + Q_OBJECT + +public: + BearerEx(QWidget* parent = 0); + void createMenus(); + void showConfigurations(); + +private Q_SLOTS: + void on_updateConfigurationsButton_clicked(); + void on_updateListButton_clicked(); + void on_showDetailsButton_clicked(); + void on_createSessionButton_clicked(); + void on_clearEventListButton_clicked(); + + void configurationsUpdateCompleted(); + void configurationAdded(const QNetworkConfiguration& config); + void configurationRemoved(const QNetworkConfiguration& config); + void onlineStateChanged(bool isOnline); + void configurationChanged(const QNetworkConfiguration & config); + +private: + QNetworkConfigurationManager m_NetworkConfigurationManager; + QAction* m_openAction; +}; + +class DetailedInfoDialog : public QDialog, public Ui::DetailedInfoDialog +{ + Q_OBJECT + +public: + DetailedInfoDialog(QNetworkConfiguration* apNetworkConfiguration = 0, QWidget* parent = 0); +}; + + +class SessionTab : public QWidget, public Ui::SessionTab +{ + Q_OBJECT + +public: + SessionTab(QNetworkConfiguration* apNetworkConfiguration = 0, QNetworkConfigurationManager* configManager = 0, + QListWidget* eventListWidget = 0, int index = 0, BearerEx* parent = 0); + ~SessionTab(); + + QString stateString(QNetworkSession::State state); + +private Q_SLOTS: + void on_createQHttpButton_clicked(); + void on_sendRequestButton_clicked(); + void on_openSessionButton_clicked(); + void on_closeSessionButton_clicked(); + void on_stopConnectionButton_clicked(); + void on_deleteSessionButton_clicked(); + void on_alrButton_clicked(); + void done(bool error); + + void newConfigurationActivated(); + void preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless); + void stateChanged(QNetworkSession::State state); + void newState(QNetworkSession::State state); + void opened(); + void closed(); + void error(QNetworkSession::SessionError error); + +private: //data + QHttp* m_http; + QNetworkSession* m_NetworkSession; + QNetworkConfigurationManager* m_ConfigManager; + QListWidget* m_eventListWidget; + QNetworkConfiguration m_config; + int m_index; + bool m_httpRequestOngoing; + bool m_alrEnabled; +}; + +#endif // ACCESSPOINTMANAGEREX_H + +// End of file + diff --git a/tests/manual/bearerex/bearerex.pro b/tests/manual/bearerex/bearerex.pro new file mode 100644 index 0000000..927f982 --- /dev/null +++ b/tests/manual/bearerex/bearerex.pro @@ -0,0 +1,20 @@ +TEMPLATE = app +TARGET = BearerEx + +QT += core \ + gui \ + network + +FORMS += sessiondialog.ui \ + bearerex.ui \ + detailedinfodialog.ui + +# Example headers and sources +HEADERS += bearerex.h \ + xqlistwidget.h + +SOURCES += bearerex.cpp \ + main.cpp \ + xqlistwidget.cpp + +symbian:TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData
\ No newline at end of file diff --git a/tests/manual/bearerex/bearerex.ui b/tests/manual/bearerex/bearerex.ui new file mode 100644 index 0000000..e5ab62f --- /dev/null +++ b/tests/manual/bearerex/bearerex.ui @@ -0,0 +1,95 @@ +<ui version="4.0" > + <class>BearerExMainWindow</class> + <widget class="QMainWindow" name="BearerExMainWindow" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>360</width> + <height>640</height> + </rect> + </property> + <property name="windowTitle" > + <string>Bearer Example</string> + </property> + <widget class="QWidget" name="centralwidget" > + <layout class="QVBoxLayout" name="verticalLayout" > + <item> + <widget class="QTabWidget" name="mainTabWidget" > + <widget class="QWidget" name="tab" > + <attribute name="title" > + <string>Main</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2" > + <item> + <widget class="QLabel" name="label" > + <property name="text" > + <string>Network Configurations</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="listWidget" /> + </item> + <item> + <layout class="QGridLayout" name="gridLayout" > + <item row="0" column="0" > + <widget class="QPushButton" name="updateConfigurationsButton" > + <property name="text" > + <string>Update Configs</string> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QPushButton" name="updateListButton" > + <property name="text" > + <string>Update List</string> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QPushButton" name="createSessionButton" > + <property name="text" > + <string>Create Session</string> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QPushButton" name="showDetailsButton" > + <property name="text" > + <string>Show Details</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_2" > + <attribute name="title" > + <string>Events</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3" > + <item> + <widget class="QListWidget" name="eventListWidget" /> + </item> + <item> + <widget class="QPushButton" name="clearEventListButton" > + <property name="text" > + <string>Clear</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/manual/bearerex/detailedinfodialog.ui b/tests/manual/bearerex/detailedinfodialog.ui new file mode 100644 index 0000000..c4a21fa --- /dev/null +++ b/tests/manual/bearerex/detailedinfodialog.ui @@ -0,0 +1,54 @@ +<ui version="4.0" > + <class>DetailedInfoDialog</class> + <widget class="QDialog" name="DetailedInfoDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>308</width> + <height>396</height> + </rect> + </property> + <property name="windowTitle" > + <string>Bearer Example</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout" > + <item> + <widget class="QLabel" name="label" > + <property name="text" > + <string>Detailed information</string> + </property> + </widget> + </item> + <item> + <widget class="QTableWidget" name="tableWidget" /> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox" > + <property name="standardButtons" > + <set>QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DetailedInfoDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel" > + <x>205</x> + <y>371</y> + </hint> + <hint type="destinationlabel" > + <x>223</x> + <y>8</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/tests/manual/bearerex/main.cpp b/tests/manual/bearerex/main.cpp new file mode 100644 index 0000000..20b167e --- /dev/null +++ b/tests/manual/bearerex/main.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> + +#include "bearerex.h" + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + BearerEx bearerEx; +#ifdef Q_OS_SYMBIAN + bearerEx.showMaximized(); +#else + bearerEx.show(); +#endif + return app.exec(); +} + +// End of file + diff --git a/tests/manual/bearerex/sessiondialog.ui b/tests/manual/bearerex/sessiondialog.ui new file mode 100644 index 0000000..fcf2136 --- /dev/null +++ b/tests/manual/bearerex/sessiondialog.ui @@ -0,0 +1,139 @@ +<ui version="4.0" > + <class>SessionTab</class> + <widget class="QWidget" name="SessionTab" > + <layout class="QVBoxLayout" name="verticalLayout" > + <item> + <layout class="QFormLayout" name="formLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="snapLabel" > + <property name="text" > + <string>SNAP</string> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QLineEdit" name="snapLineEdit" > + <property name="readOnly" > + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="iapLabel" > + <property name="text" > + <string>IAP</string> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QLineEdit" name="iapLineEdit" > + <property name="enabled" > + <bool>true</bool> + </property> + <property name="readOnly" > + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="bearerLabel" > + <property name="text" > + <string>Bearer</string> + </property> + </widget> + </item> + <item row="2" column="1" > + <widget class="QLineEdit" name="bearerLineEdit" > + <property name="readOnly" > + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="0" > + <widget class="QLabel" name="sentRecDataLabel" > + <property name="text" > + <string>Sent/Rec.</string> + </property> + </widget> + </item> + <item row="3" column="1" > + <widget class="QLineEdit" name="sentRecDataLineEdit" > + <property name="readOnly" > + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="0" > + <widget class="QLabel" name="stateLabel" > + <property name="text" > + <string>State</string> + </property> + </widget> + </item> + <item row="4" column="1" > + <widget class="QLineEdit" name="stateLineEdit" > + <property name="readOnly" > + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QGridLayout" name="gridLayout" > + <item row="0" column="0" > + <widget class="QPushButton" name="openSessionButton" > + <property name="text" > + <string>Open Session</string> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QPushButton" name="closeSessionButton" > + <property name="text" > + <string>Close Session</string> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QPushButton" name="stopConnectionButton" > + <property name="text" > + <string>Stop Conn.</string> + </property> + </widget> + </item> + <item row="2" column="0" > + <widget class="QPushButton" name="createQHttpButton" > + <property name="text" > + <string>Create QHttp</string> + </property> + </widget> + </item> + <item row="2" column="1" > + <widget class="QPushButton" name="sendRequestButton" > + <property name="text" > + <string>Send Test Req.</string> + </property> + </widget> + </item> + <item row="3" column="0" > + <widget class="QPushButton" name="alrButton" > + <property name="text" > + <string>Enable ALR</string> + </property> + </widget> + </item> + <item row="3" column="1" > + <widget class="QPushButton" name="deleteSessionButton" > + <property name="text" > + <string>Delete Session</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/benchmarks/qtwidgets/tst_qtwidgets.cpp b/tests/manual/bearerex/xqlistwidget.cpp index 8d2a31b..8104779 100644 --- a/tests/benchmarks/qtwidgets/tst_qtwidgets.cpp +++ b/tests/manual/bearerex/xqlistwidget.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -39,29 +39,29 @@ ** ****************************************************************************/ -#include <qtest.h> -#include <QtGui> -#include <QtNetwork> +#include "xqlistwidget.h" -#include "mainwindow.h" - -class tst_QtWidgets: public QObject -{ - Q_OBJECT - -private slots: - void snapshot(); -}; +XQListWidget::XQListWidget(QWidget* parent) : QListWidget(parent) +{ +} -void tst_QtWidgets::snapshot() +void XQListWidget::keyPressEvent(QKeyEvent* event) { - QBENCHMARK { - StyleWidget widget(0, Qt::X11BypassWindowManagerHint); - widget.show(); - QApplication::processEvents(); + switch (event->key()) + { + case Qt::Key_Left: + { + focusPreviousChild(); + break; + } + case Qt::Key_Right: + { + focusNextChild(); + break; + } + default: + { + QListWidget::keyPressEvent(event); + } } } - -QTEST_MAIN(tst_QtWidgets) - -#include "tst_qtwidgets.moc" diff --git a/tests/manual/bearerex/xqlistwidget.h b/tests/manual/bearerex/xqlistwidget.h new file mode 100644 index 0000000..0649c2b --- /dev/null +++ b/tests/manual/bearerex/xqlistwidget.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef XQLISTWIDGET_H +#define XQLISTWIDGET_H + +#include <QListWidget> +#include <QKeyEvent> + +class XQListWidget: public QListWidget +{ +public: + XQListWidget(QWidget* parent = 0); + +protected: + void keyPressEvent(QKeyEvent* event); +}; + +#endif // XQLISTWIDGET_H + + diff --git a/tests/manual/networkmanager/README b/tests/manual/networkmanager/README new file mode 100644 index 0000000..4bc7171 --- /dev/null +++ b/tests/manual/networkmanager/README @@ -0,0 +1,2 @@ +This application serves as prototype/test-bed for NetworkManager development. The excellent (non-existing) documentation +for the various NetworkManager interfaces makes this harder than it should be. diff --git a/tests/manual/networkmanager/dialog.ui b/tests/manual/networkmanager/dialog.ui new file mode 100644 index 0000000..1301908 --- /dev/null +++ b/tests/manual/networkmanager/dialog.ui @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>919</width> + <height>657</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Connections</string> + </property> + </widget> + </item> + <item> + <widget class="QTreeWidget" name="cons"> + <column> + <property name="text"> + <string>Path</string> + </property> + </column> + <column> + <property name="text"> + <string>State</string> + </property> + </column> + <column> + <property name="text"> + <string>Id</string> + </property> + </column> + <column> + <property name="text"> + <string>Settings</string> + </property> + </column> + </widget> + </item> + </layout> + </item> + <item row="1" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Devices:</string> + </property> + </widget> + </item> + <item> + <widget class="QTreeWidget" name="devicesTreeWidget"> + <column> + <property name="text"> + <string>Path</string> + </property> + </column> + <column> + <property name="text"> + <string>Managed</string> + </property> + </column> + <column> + <property name="text"> + <string>Interface</string> + </property> + </column> + <column> + <property name="text"> + <string>Driver</string> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + </column> + <column> + <property name="text"> + <string>State</string> + </property> + </column> + <column> + <property name="text"> + <string>IP4 Address</string> + </property> + </column> + <column> + <property name="text"> + <string>IP4 Config</string> + </property> + </column> + <column> + <property name="text"> + <string>Hostname</string> + </property> + </column> + <column> + <property name="text"> + <string>Domains</string> + </property> + </column> + </widget> + </item> + </layout> + </item> + <item row="2" column="0"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>908</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="0"> + <widget class="QTreeWidget" name="accessPointsTreeWidget"> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>SSID</string> + </property> + </column> + <column> + <property name="text"> + <string>Strength</string> + </property> + </column> + <column> + <property name="text"> + <string>Wpa</string> + </property> + </column> + <column> + <property name="text"> + <string>Rsn</string> + </property> + </column> + <column> + <property name="text"> + <string>Freq</string> + </property> + </column> + <column> + <property name="text"> + <string>Hardware Address</string> + </property> + </column> + <column> + <property name="text"> + <string>Mode</string> + </property> + </column> + <column> + <property name="text"> + <string>Max Bitrate</string> + </property> + </column> + </widget> + </item> + <item row="4" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QPushButton" name="startButton"> + <property name="text"> + <string>Start</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="stopButton"> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="scanButton"> + <property name="text"> + <string>Scan</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="updateButton"> + <property name="text"> + <string>Update</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/manual/networkmanager/networkmanager.pro b/tests/manual/networkmanager/networkmanager.pro new file mode 100644 index 0000000..84289d3 --- /dev/null +++ b/tests/manual/networkmanager/networkmanager.pro @@ -0,0 +1,9 @@ +SOURCES += networkmanagertest.cpp nmview.cpp +HEADERS += nmview.h +TARGET = tst_networkmanagertest + +QT = core network dbus gui + +requires(contains(QT_CONFIG,dbus)) + +FORMS += dialog.ui diff --git a/tests/manual/networkmanager/networkmanagertest.cpp b/tests/manual/networkmanager/networkmanagertest.cpp new file mode 100644 index 0000000..8a6c5fa --- /dev/null +++ b/tests/manual/networkmanager/networkmanagertest.cpp @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDBusConnection> +#include <QDBusError> +#include <QDBusInterface> +#include <QDBusMessage> +#include <QDBusReply> +#include <QtDBus> +#include <QHostAddress> +#include <QDebug> +#include <NetworkManager/NetworkManager.h> +#include <QApplication> +#include <QMainWindow> +#include "nmview.h" + +#include <arpa/inet.h> + +typedef QMap< QString, QMap<QString,QVariant> > SettingsMap; +Q_DECLARE_METATYPE(SettingsMap) + +void printConnectionDetails(const QString& service) +{ + QDBusConnection dbc = QDBusConnection::systemBus(); + if (!dbc.isConnected()) { + qWarning() << "Unable to connect to D-Bus:" << dbc.lastError(); + return; + } + QDBusInterface allCons(service, NM_DBUS_PATH_SETTINGS, NM_DBUS_IFACE_SETTINGS, dbc); + if (allCons.isValid()) { + QDBusReply<QList<QDBusObjectPath> > reply = allCons.call("ListConnections"); + if ( reply.isValid() ) { + qWarning() << "Known connections:"; + QList<QDBusObjectPath> list = reply.value(); + foreach(QDBusObjectPath path, list) { + qWarning() << " " << path.path(); + QDBusInterface sysIface(NM_DBUS_SERVICE_SYSTEM_SETTINGS, path.path(), NM_DBUS_IFACE_SETTINGS_CONNECTION, dbc); + if (sysIface.isValid()) { + QDBusMessage r = sysIface.call("GetSettings"); + QDBusReply< SettingsMap > rep = sysIface.call("GetSettings"); + qWarning() << " GetSettings:" << r.arguments() << r.signature() << rep.isValid() << sysIface.lastError(); + QMap< QString, QMap<QString,QVariant> > map = rep.value(); + QList<QString> list = map.keys(); + foreach (QString key, list) { + QMap<QString,QVariant> innerMap = map[key]; + qWarning() << " Key: " << key; + QMap<QString,QVariant>::const_iterator i = innerMap.constBegin(); + while (i != innerMap.constEnd()) { + QString k = i.key(); + qWarning() << " Key: " << k << " Entry: " << i.value(); + if (k == "addresses" && i.value().canConvert<QDBusArgument>()) { + QDBusArgument arg = i.value().value<QDBusArgument>(); + arg.beginArray(); + while (!arg.atEnd()) { + QDBusVariant addr; + arg >> addr; + uint ip = addr.variant().toUInt(); + qWarning() << ip; + qWarning() << " " << QHostAddress(htonl(ip)).toString(); + } + + } + i++; + } + } + } + } + } + } + + +} + +void readConnectionManagerDetails() +{ + qDBusRegisterMetaType<SettingsMap>(); + QDBusConnection dbc = QDBusConnection::systemBus(); + if (!dbc.isConnected()) { + qWarning() << "Unable to connect to D-Bus:" << dbc.lastError(); + return; + } + + QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbc); + if (!iface.isValid()) { + qWarning() << "Could not find NetworkManager"; + return; + } + + uint state = iface.property("State").toUInt(); + switch(state) { + case NM_STATE_UNKNOWN: + qWarning() << "State: Unknown"; break; + case NM_STATE_ASLEEP: + qWarning() << "State: Asleep"; break; + case NM_STATE_CONNECTING: + qWarning() << "State: Connecting"; break; + case NM_STATE_CONNECTED: + qWarning() << "State: Connected"; break; + case NM_STATE_DISCONNECTED: + qWarning() << "State: Disconnected"; break; + } + //get list of network devices + QDBusReply<QList<QDBusObjectPath> > reply = iface.call("GetDevices"); + if ( reply.isValid() ) { + qWarning() << "Current devices:"; + QList<QDBusObjectPath> list = reply.value(); + foreach(QDBusObjectPath path, list) { + qWarning() << " " << path.path(); + QDBusInterface devIface(NM_DBUS_SERVICE, path.path(), NM_DBUS_INTERFACE_DEVICE, dbc); + if (devIface.isValid()) { + qWarning() << " Managed: " << devIface.property("Managed").toBool(); + qWarning() << " Interface: " << devIface.property("Interface").toString(); + qWarning() << " HAL UDI: " << devIface.property("Udi").toString(); + qWarning() << " Driver: " << devIface.property("Driver").toString(); + QVariant v = devIface.property("DeviceType"); + switch(v.toUInt()) { + case DEVICE_TYPE_UNKNOWN: + qWarning() << " DeviceType: Unknown" ; + break; + case DEVICE_TYPE_802_3_ETHERNET: + qWarning() << " DeviceType: Ethernet" ; + break; + case DEVICE_TYPE_802_11_WIRELESS: + qWarning() << " DeviceType: Wireless" ; + break; + case DEVICE_TYPE_GSM: + qWarning() << " DeviceType: GSM" ; + break; + case DEVICE_TYPE_CDMA: + qWarning() << " DeviceType: CDMA" ; + break; + + } + v = devIface.property("State"); + switch(v.toUInt()) { + case NM_DEVICE_STATE_UNKNOWN: + qWarning() << " State: Unknown" ; break; + case NM_DEVICE_STATE_UNMANAGED: + qWarning() << " State: Unmanaged" ; break; + case NM_DEVICE_STATE_UNAVAILABLE: + qWarning() << " State: Unavailable" ; break; + case NM_DEVICE_STATE_DISCONNECTED: + qWarning() << " State: Disconnected" ; break; + case NM_DEVICE_STATE_PREPARE: + qWarning() << " State: Preparing" ; break; + case NM_DEVICE_STATE_CONFIG: + qWarning() << " State: Being configured" ; break; + case NM_DEVICE_STATE_NEED_AUTH: + qWarning() << " State: Awaiting secrets" ; break; + case NM_DEVICE_STATE_IP_CONFIG: + qWarning() << " State: IP requested" ; break; + case NM_DEVICE_STATE_ACTIVATED: + qWarning() << " State: Activated" ; break; + case NM_DEVICE_STATE_FAILED: + qWarning() << " State: FAILED" ; break; + } + quint32 ip = devIface.property("Ip4Address").toUInt(); + qWarning() << " IP4Address: " << QHostAddress(htonl(ip)).toString(); + if (v.toUInt() == NM_DEVICE_STATE_ACTIVATED) { + QString path = devIface.property("Ip4Config").value<QDBusObjectPath>().path(); + qWarning() << " IP4Config: " << path; + QDBusInterface ipIface(NM_DBUS_SERVICE, path, NM_DBUS_INTERFACE_IP4_CONFIG, dbc); + if (ipIface.isValid()) { + qWarning() << " Hostname: " << ipIface.property("Hostname").toString(); + qWarning() << " Domains: " << ipIface.property("Domains").toStringList(); + qWarning() << " NisDomain: " << ipIface.property("NisDomain").toString(); + QDBusArgument arg= ipIface.property("Addresses").value<QDBusArgument>(); + //qWarning() << " " << arg.currentType(); + qWarning() << " Addresses: " << ipIface.property("Addresses"); + qWarning() << " Nameservers: " << ipIface.property("Nameservers"); + qWarning() << " NisServers: " << ipIface.property("NisServers"); + } + + } + + } + } + } + + //get list of active connections + QVariant prop = iface.property("ActiveConnections"); + QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >(); + QString activePath; + if ( connections.count() ) + qWarning() << "Active connections:"; + foreach(QDBusObjectPath path, connections) { + qWarning() << " " << path.path(); + activePath = path.path(); + QString serviceName; + QDBusInterface conIface(NM_DBUS_SERVICE, path.path(), NM_DBUS_INTERFACE_ACTIVE_CONNECTION, dbc); + if (conIface.isValid()) { + qWarning() << " default connection: " << conIface.property("Default").toBool(); + serviceName = conIface.property("ServiceName").toString(); + qWarning() << " service name: " << serviceName; + qWarning() << " connection path: " << conIface.property("Connection").value<QDBusObjectPath>().path(); + qWarning() << " specific object:" << conIface.property("SpecificObject").value<QDBusObjectPath>().path(); + qWarning() << " sharedServiceName: " << conIface.property("SharedServiceName").toString(); + QList<QDBusObjectPath> devs = conIface.property("Devices").value<QList<QDBusObjectPath> >(); + qWarning() << " devices: "; + foreach(QDBusObjectPath p, devs) + qWarning() << " " << path.path(); + QVariant v = conIface.property("State"); + switch (v.toInt()) { + case NM_ACTIVE_CONNECTION_STATE_UNKNOWN: + qWarning()<< " State: unknown"; break; + case NM_ACTIVE_CONNECTION_STATE_ACTIVATING: + qWarning()<< " State: activating"; break; + case NM_ACTIVE_CONNECTION_STATE_ACTIVATED: + qWarning()<< " State: activated"; break; + } + } else { + qWarning() << conIface.lastError(); + } + + } + + printConnectionDetails(NM_DBUS_SERVICE_SYSTEM_SETTINGS); + printConnectionDetails(NM_DBUS_SERVICE_USER_SETTINGS); + + + //turn active connection off + /*QDBusObjectPath dbop("/org/freedesktop/NetworkManager/ActiveConnection/1"); + QVariant asd = QVariant::fromValue(dbop); + iface.call(QLatin1String("DeactivateConnection"), asd); + qWarning() << iface.lastError();*/ + + /*QDBusObjectPath p1device("/org/freedesktop/Hal/devices/net_00_60_6e_82_02_65"); + QVariant p1v = QVariant::fromValue(p1device); + QDBusObjectPath p1con("/org/freedesktop/NetworkManagerSettings/0"); + QVariant p1c = QVariant::fromValue(p1con); + QDBusObjectPath p1sp(""); + QVariant p1sp1 = QVariant::fromValue(p1sp); + iface.call(QLatin1String("ActivateConnection"), + QString("/org/freedesktop/NetworkManagerSystemSettings"), p1c,p1v, p1v ); + qWarning() << iface.lastError(); + */ +} + +int main( int argc, char** argv) +{ + QApplication app(argc, argv); + //readConnectionManagerDetails(); + QMainWindow main; + NMView view; + main.setCentralWidget(&view); + main.show(); + return app.exec(); + +} diff --git a/tests/manual/networkmanager/nmview.cpp b/tests/manual/networkmanager/nmview.cpp new file mode 100644 index 0000000..9e28ff0 --- /dev/null +++ b/tests/manual/networkmanager/nmview.cpp @@ -0,0 +1,1028 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nmview.h" + +#include <QLabel> +#include <QLayout> +#include <QListWidget> +#include <QDebug> +#include <QPushButton> + +#include <QtDBus> +#include <QtNetwork> +#include <NetworkManager/NetworkManager.h> +#include <arpa/inet.h> + +#include <QDBusConnection> +#include <QDBusError> +#include <QDBusInterface> +#include <QDBusMessage> +#include <QDBusReply> + +#include <QHostAddress> +#include <QNetworkInterface> +#include <QTreeWidgetItem> +#include <QMessageBox> + +//#include "ui_dialog.h" + +#include <qnetworkconfiguration.h> +#include <qnetworkconfigmanager.h> +#include <qnetworksession.h> +#include <QtNetwork/private/qnetworkmanagerservice_p.h> + +//static QDBusConnection dbc = QDBusConnection::systemBus(); +//typedef QMap< QString, QMap<QString,QVariant> > SettingsMap; +//Q_DECLARE_METATYPE(SettingsMap) + + +NMView::NMView(QDialog* parent) + : QDialog(parent, 0), dbc(QDBusConnection::systemBus()) +{ + init(); + + if (!dbc.isConnected()) { + qWarning() << "Unable to connect to D-Bus:" << dbc.lastError(); + return; + } + updateConnections(); + getDevices(); +} + +NMView::~NMView() +{ +} +void NMView::init() +{ + setupUi(this); + sess = 0; +// readSettings(); + connect(startButton, SIGNAL(clicked()), this, SLOT(activate())); + connect(stopButton, SIGNAL(clicked()), this, SLOT(deactivate())); + connect(scanButton, SIGNAL(clicked()), this, SLOT(findAccessPoints())); + connect(updateButton, SIGNAL(clicked()), this, SLOT(update())); + + connect(cons, SIGNAL(itemActivated(QTreeWidgetItem*, int)), + this,SLOT(connectionItemActivated(QTreeWidgetItem*, int))); + + + connect(devicesTreeWidget, SIGNAL(itemActivated(QTreeWidgetItem*, int)), + this, SLOT(deviceItemActivated(QTreeWidgetItem*, int))); + + cons->header()->setResizeMode(QHeaderView::ResizeToContents); + devicesTreeWidget->header()->setResizeMode(QHeaderView::ResizeToContents); + accessPointsTreeWidget->header()->setResizeMode(QHeaderView::ResizeToContents); +// accessPointsTreeWidget->header()->setResizeMode(QHeaderView::ResizeToContents); + + manager = new QNetworkConfigurationManager(this); + + connect(manager, SIGNAL(updateCompleted()), this, SLOT(updateCompleted())); + + connect(manager, SIGNAL(configurationAdded(const QNetworkConfiguration &)), + this, SLOT(configurationAdded(const QNetworkConfiguration&))); + + devicesTreeWidget->header()->hideSection(0); + devicesTreeWidget->header()->hideSection(1); + devicesTreeWidget->header()->hideSection(3); + devicesTreeWidget->header()->hideSection(5); + devicesTreeWidget->header()->hideSection(6); + devicesTreeWidget->header()->hideSection(7); + devicesTreeWidget->header()->hideSection(8); + devicesTreeWidget->header()->hideSection(9); +} + +void NMView::updateConnections() +{ + cons->clear(); + manager->updateConfigurations(); + QList<QNetworkConfiguration> configs = manager->allConfigurations(); + foreach(QNetworkConfiguration p, configs) { + QStringList strlist; + strlist << p.name(); + strlist << stateToString(p.state()); + strlist << p.identifier(); + strlist << typeToString(p.type()); + QTreeWidgetItem *item; + item = new QTreeWidgetItem(strlist); + cons->insertTopLevelItem(0, item); + } + cons->sortItems ( 1, Qt::AscendingOrder); +} + +void NMView::getActiveConnections() +{ + QList<QNetworkConfiguration> configs = manager->allConfigurations(QNetworkConfiguration::Active); + foreach(QNetworkConfiguration p, configs) { + qWarning() << __FUNCTION__ << p.name() << p.identifier(); + } + +// QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbc); +// if (!iface.isValid()) { +// qWarning() << "Could not find NetworkManager"; +// return; +// } + +// QVariant prop = iface.property("ActiveConnections"); +// QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >(); +// foreach(QDBusObjectPath path, connections) { +// QDBusInterface conDetails(NM_DBUS_SERVICE, path.path(), NM_DBUS_INTERFACE_ACTIVE_CONNECTION, dbc); +// if (conDetails.isValid()) { +// QString desc = path.path(); +// conDetails.property("Connection Path").value<QDBusObjectPath>().path(); + +// QList<QDBusObjectPath> devices = conDetails.property("Devices").value<QList<QDBusObjectPath> >(); +// +// foreach(QDBusObjectPath devpath, devices) { +// QDBusInterface devIface(NM_DBUS_SERVICE, devpath.path(), NM_DBUS_INTERFACE_DEVICE, dbc); +// desc += " "+devIface.property("Interface").toString(); +// desc += " "+QHostAddress(htonl(devIface.property("Ip4Address").toUInt())).toString(); + +// } + +// qWarning() << conDetails.property("Connection").value<QDBusObjectPath>().path() << path.path(); + +// QListWidgetItem* item = new QListWidgetItem(desc, activeCons); +// item->setData(Qt::UserRole, path.path()); +// } +// } +} + +void NMView::update() +{ +// QNetworkManagerInterface *dbIface; +// dbIface = new QNetworkManagerInterface; +// QList <QDBusObjectPath> connections = dbIface->activeConnections(); +// +// foreach(QDBusObjectPath conpath, connections) { +// QNetworkManagerConnectionActive *aConn; +// aConn = new QNetworkManagerConnectionActive(conpath.path()); +// // in case of accesspoint, specificObject will hold the accessPOintObjectPath +// qWarning() << aConn->connection().path() << aConn->specificObject().path() << aConn->devices().count(); +// QList <QDBusObjectPath> devs = aConn->devices(); +// foreach(QDBusObjectPath device, devs) { +// qWarning() << " " << device.path(); +// } +// } + + QStringList connectionServices; + connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS; + connectionServices << NM_DBUS_SERVICE_USER_SETTINGS; + foreach (QString service, connectionServices) { + QDBusInterface allCons(service, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_IFACE_SETTINGS, + dbc); + if (allCons.isValid()) { + QDBusReply<QList<QDBusObjectPath> > reply = allCons.call("ListConnections"); + if ( reply.isValid() ) { + QList<QDBusObjectPath> list = reply.value(); + foreach(QDBusObjectPath path, list) { + QDBusInterface sysIface(service, + path.path(), + NM_DBUS_IFACE_SETTINGS_CONNECTION, + dbc); + if (sysIface.isValid()) { + qWarning() << ""; + qWarning() << path.path(); + + // QDBusMessage r = sysIface.call("GetSettings"); + QDBusReply< QNmSettingsMap > rep = sysIface.call("GetSettings"); + + QMap< QString, QMap<QString,QVariant> > map = rep.value(); + QList<QString> list = map.keys(); + foreach (QString key, list) { + QMap<QString,QVariant> innerMap = map[key]; + qWarning() << " Key: " << key; + QMap<QString,QVariant>::const_iterator i = innerMap.constBegin(); + + while (i != innerMap.constEnd()) { + QString k = i.key(); + qWarning() << " Key: " << k << " Entry: " << i.value(); + i++; + }//end innerMap + }//end foreach key + }//end settings connection + } // foreach path + } //end ListConnections + } //end settingsInterface + }// end services + QDBusInterface iface(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + dbc); + if (iface.isValid()) { + QVariant prop = iface.property("ActiveConnections"); + QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >(); + foreach(QDBusObjectPath conpath, connections) { + qWarning() << "Active connection" << conpath.path(); + QDBusInterface conDetails(NM_DBUS_SERVICE, + conpath.path(), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + dbc); + if (conDetails.isValid()) { + + QVariant prop = conDetails.property("Connection"); + QDBusObjectPath connection = prop.value<QDBusObjectPath>(); + qWarning() << conDetails.property("Default").toBool() << connection.path(); + +// QVariant Sprop = conDetails.property("Devices"); +// QList<QDBusObjectPath> so = Sprop.value<QList<QDBusObjectPath> >(); +// foreach(QDBusObjectPath device, so) { +// if(device.path() == devicePath) { +// path = connection.path(); +// } +// break; +// } + } + } + } +qWarning() << ""; +} + +void NMView::deactivate() +{ + QList<QNetworkConfiguration> configs = manager->allConfigurations(QNetworkConfiguration::Active); + foreach(QNetworkConfiguration p, configs) { + qWarning() << "Active cons" << p.name(); + if(p.name() == cons->currentItem()->text(0) + && p.identifier() == cons->currentItem()->text(2)) { + qWarning() <<__FUNCTION__<< p.name(); + if(!sess) { + sess = new QNetworkSession(p); + + connect(sess, SIGNAL(stateChanged(QNetworkSession::State)), + this, SLOT(stateChanged(QNetworkSession::State))); + + connect(sess, SIGNAL(error(QNetworkSession::SessionError)), + this, SLOT(networkSessionError(QNetworkSession::SessionError))); + } + sess->close(); + delete sess; + sess = 0; + } + } +} + +void NMView::activate() +{ + qWarning() << __FUNCTION__ << cons->currentItem()->text(0); + + QList<QNetworkConfiguration> configs = manager->allConfigurations(); + foreach(QNetworkConfiguration p, configs) { + if(p.name() == cons->currentItem()->text(0)) { + + sess = new QNetworkSession(p); + + connect(sess, SIGNAL(newConfigurationActivated()), + this, SLOT(getActiveConnections())); + + connect(sess, SIGNAL(stateChanged(QNetworkSession::State)), + this, SLOT(stateChanged(QNetworkSession::State))); + + connect(sess, SIGNAL(error(QNetworkSession::SessionError)), + this, SLOT(networkSessionError(QNetworkSession::SessionError))); + + sess->open(); + } + } +} + +void NMView::getDevices() +{ + qWarning() << ""; + qWarning() << __FUNCTION__; + devicesTreeWidget->clear(); + //qDBusRegisterMetaType<SettingsMap>(); + + if (!dbc.isConnected()) { + qWarning() << "Unable to connect to D-Bus:" << dbc.lastError(); + return; + } + QDBusInterface iface(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + dbc); +//NetworkManager interface + if (!iface.isValid()) { + qWarning() << "Could not find NetworkManager"; + return; + } + +// uint state = iface.property("State").toUInt(); +// switch(state) { +// case NM_STATE_UNKNOWN: +// qWarning() << "State: Unknown"; break; +// case NM_STATE_ASLEEP: +// qWarning() << "State: Asleep"; break; +// case NM_STATE_CONNECTING: +// qWarning() << "State: Connecting"; break; +// case NM_STATE_CONNECTED: +// qWarning() << "State: Connected"; break; +// case NM_STATE_DISCONNECTED: +// qWarning() << "State: Disconnected"; break; +// } + + //get list of network devices + QTreeWidgetItem *item; + QDBusReply<QList<QDBusObjectPath> > reply = iface.call("GetDevices"); + if ( reply.isValid() ) { +// qWarning() << "Current devices:"; + QList<QDBusObjectPath> list = reply.value(); + foreach(QDBusObjectPath path, list) { + QStringList devicesList; + qWarning() << " " << path.path(); + devicesList << path.path(); + + QDBusInterface devIface(NM_DBUS_SERVICE, + path.path(), + NM_DBUS_INTERFACE_DEVICE, + dbc); + if (devIface.isValid()) { + + + + ////// connect the dbus signal +// /*if(*/dbc.connect(NM_DBUS_SERVICE, +// path.path(), +// NM_DBUS_INTERFACE_DEVICE, +// "StateChanged", +// this,SLOT(deviceStateChanged(quint32))); +// { +// qWarning() << "XXXXXXXXXX dbus connect successful" << path.path(); +// } + + + // qWarning() << " Managed: " << devIface.property("Managed").toBool(); + devicesList << devIface.property("Managed").toString(); + // qWarning() << " Interface: " << devIface.property("Interface").toString(); + devicesList << devIface.property("Interface").toString(); + // qWarning() << " HAL UDI: " << devIface.property("Udi").toString(); + // qWarning() << " Driver: " << devIface.property("Driver").toString(); + devicesList << devIface.property("Driver").toString(); + + QString x = deviceTypeToString(devIface.property("DeviceType").toUInt()); + // qWarning() << " Type:" << x; + devicesList << x; + + if( devIface.property("DeviceType").toUInt() == DEVICE_TYPE_802_11_WIRELESS) { + qWarning() << "Device is WIFI"; + // // findAccessPoints(path.path()); + } + + QVariant v = devIface.property("State"); + x = deviceStateToString(v.toUInt()); +// qWarning() << " State:" << x; + devicesList << x; + + quint32 ip = devIface.property("Ip4Address").toUInt(); +// qWarning() << " IP4Address: " << QHostAddress(htonl(ip)).toString(); + devicesList << QHostAddress(htonl(ip)).toString(); + + + if (v.toUInt() == NM_DEVICE_STATE_ACTIVATED) { + QString path = devIface.property("Ip4Config").value<QDBusObjectPath>().path(); +// qWarning() << " IP4Config: " << path; + devicesList << path; + QDBusInterface ipIface(NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_IP4_CONFIG, + dbc); + if (ipIface.isValid()) { + // qWarning() << " Hostname: " << ipIface.property("Hostname").toString(); + devicesList << ipIface.property("Hostname").toString(); +// qWarning() << " Domains: " << ipIface.property("Domains").toStringList(); + devicesList << ipIface.property("Domains").toStringList().join(", "); +// qWarning() << " NisDomain: " << ipIface.property("NisDomain").toString(); + QDBusArgument arg= ipIface.property("Addresses").value<QDBusArgument>(); +// qWarning() << " Addresses: " << ipIface.property("Addresses"); +// qWarning() << " Nameservers: " << ipIface.property("Nameservers"); +// qWarning() << " NisServers: " << ipIface.property("NisServers"); + } + + } + + } + item = new QTreeWidgetItem(devicesList); + devicesTreeWidget->insertTopLevelItem(0, item); + } + } + + +// netconfig(); + +} + +void NMView::readSettings() +{ + QDBusInterface settingsiface(NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_IFACE_SETTINGS, + dbc); + //NetworkManagerSettings interface + if (settingsiface.isValid()) { + QDBusReply<QList<QDBusObjectPath> > reply = settingsiface.call("ListConnections"); + if ( reply.isValid() ) { + QList<QDBusObjectPath> list = reply.value(); + foreach(QDBusObjectPath path, list) { + qWarning() <<__FUNCTION__ << path.path(); + + } + } + } + + QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbc); + if (!iface.isValid()) { + qWarning() << "Could not find NetworkManager"; + return; + } + + // QStringList list = item->text().split(" -> "); + + QVariant prop = iface.property("ActiveConnections"); + QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >(); + foreach(QDBusObjectPath path, connections) { + QDBusInterface conDetails(NM_DBUS_SERVICE, + path.path(), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + dbc); + + if (conDetails.isValid()) { + QString desc = path.path(); + qWarning() << desc; + //if ( item->text(0) == conDetails.property("Connection").value<QDBusObjectPath>().path() ) { + // QListWidgetItem* item = new QTreeWidgetItem( desc, + // cons); + // item->setData(Qt::UserRole, desc); + // activeItemActivated( item ); + //} + } + } +} + +void NMView::printConnectionDetails(const QString& service) +{ + Q_UNUSED(service); + +// +// qWarning() << __FUNCTION__ << service; +// +// QDBusConnection dbc = QDBusConnection::systemBus(); +// if (!dbc.isConnected()) { +// qWarning() << "Unable to connect to D-Bus:" << dbc.lastError(); +// return; +// } +// QDBusInterface allCons(service, +// NM_DBUS_PATH_SETTINGS, +// NM_DBUS_IFACE_SETTINGS, +// dbc); +// +// if (allCons.isValid()) { +// QDBusReply<QList<QDBusObjectPath> > reply = allCons.call("ListConnections"); +// +// if ( reply.isValid() ) { +// qWarning() << "Known connections:"; +// QList<QDBusObjectPath> list = reply.value(); +// +// foreach(QDBusObjectPath path, list) { +// qWarning() << " " << path.path(); +// +// QDBusInterface sysIface(NM_DBUS_SERVICE_SYSTEM_SETTINGS, +// path.path(), +// NM_DBUS_IFACE_SETTINGS_CONNECTION, +// dbc); +// +// if (sysIface.isValid()) { +// QDBusMessage r = sysIface.call("GetSettings"); +// QDBusReply< QSettingsMap > rep = sysIface.call("GetSettings"); +// +// qWarning() << " GetSettings:" << r.arguments() << r.signature() << rep.isValid() << sysIface.lastError(); +// +// QMap< QString, QMap<QString,QVariant> > map = rep.value(); +// QList<QString> list = map.keys(); +// +// foreach (QString key, list) { +// QMap<QString,QVariant> innerMap = map[key]; +// qWarning() << " Key: " << key; +// QMap<QString,QVariant>::const_iterator i = innerMap.constBegin(); +// +// while (i != innerMap.constEnd()) { +// QString k = i.key(); +// qWarning() << " Key: " << k << " Entry: " << i.value(); +// +// if (k == "addresses" && i.value().canConvert<QDBusArgument>()) { +// QDBusArgument arg = i.value().value<QDBusArgument>(); +// arg.beginArray(); +// +// while (!arg.atEnd()) { +// QDBusVariant addr; +// arg >> addr; +// uint ip = addr.variant().toUInt(); +// qWarning() << ip; +// qWarning() << " " << QHostAddress(htonl(ip)).toString(); +// } +// +// } +// i++; +// } +// } +// } +// } +// } +// } + qWarning() << ""; +} + +void NMView::getNetworkDevices() +{ + +} + +void NMView::connectionItemActivated( QTreeWidgetItem * item, int col ) +{ + Q_UNUSED(col); + + qWarning() <<__FUNCTION__<< item->text(0); + QDBusInterface iface(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + dbc); + if (!iface.isValid()) { + qWarning() << "Could not find NetworkManager"; + return; + } + QVariant prop = iface.property("ActiveConnections"); + QList<QDBusObjectPath> connections = prop.value<QList<QDBusObjectPath> >(); + foreach(QDBusObjectPath path, connections) { + QDBusInterface conDetails(NM_DBUS_SERVICE, + path.path(), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + dbc); + + if (conDetails.isValid()) { + QString desc = path.path(); + qWarning() << desc; + if ( item->text(0) == conDetails.property("Connection").value<QDBusObjectPath>().path() ) { +// QListWidgetItem* item = new QTreeWidgetItem( desc, +// cons); +// item->setData(Qt::UserRole, desc); +// activeItemActivated( item ); + } + } + } +} + + + +void NMView::deviceItemActivated( QTreeWidgetItem * item , int section) +{ + Q_UNUSED(item); + Q_UNUSED(section); + + // qWarning() << item->text(section) << item->text(4); + //if(item->text(4) == "Wireless") findAccessPoints(item->text(0)); +} + + +void NMView::netconfig() +{ +// qWarning() << __FUNCTION__; + +// qDBusRegisterMetaType<SettingsMap>(); + QDBusConnection dbc = QDBusConnection::systemBus(); + if (!dbc.isConnected()) { + qWarning() << "Unable to connect to D-Bus:" << dbc.lastError(); + return; + } + + QDBusInterface iface(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_IFACE_SETTINGS_CONNECTION, + dbc); + if (!iface.isValid()) { + qWarning() << "Could not find NetworkManager Settings"; + return; + } else { + QDBusReply<QList<QDBusObjectPath> > reply = iface.call("ListConnections"); + QList<QDBusObjectPath> list = reply.value(); +// qWarning() << reply.value(); + foreach(QDBusObjectPath path, list) { + qWarning() << " " << path.path(); + } + } +} + + +void NMView::findAccessPoints() +{ + accessPointsTreeWidget->clear(); + + QDBusInterface iface(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + dbc); + + QDBusReply<QList<QDBusObjectPath> > reply = iface.call("GetDevices"); + if ( reply.isValid() ) { + QList<QDBusObjectPath> list = reply.value(); + foreach(QDBusObjectPath path, list) { + QDBusInterface devIface(NM_DBUS_SERVICE, + path.path(), + NM_DBUS_INTERFACE_DEVICE, + dbc); + if (devIface.isValid()) { + + if( devIface.property("DeviceType").toUInt() == DEVICE_TYPE_802_11_WIRELESS) { + +// qWarning() <<"deviface"<< devIface.path(); + QDBusInterface wififace(NM_DBUS_SERVICE, + devIface.path(), + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + dbc); + if (!wififace.isValid()) { + qWarning() << "Could not find NetworkManager wireless interface"; + return; + } + +///////////////////////// +// if(dbc.connect(NM_DBUS_SERVICE, +// path.path(), +// NM_DBUS_INTERFACE_DEVICE_WIRELESS, +// "PropertiesChanged", +// this,SLOT(aPPropertiesChanged( QMap<QString,QVariant>))) ) { +// qWarning() << "PropertiesChanged connect"; +// } else { +// qWarning() << "NOT connect"; + +// } +///////////////////////// + qWarning() <<"wififace"<< wififace.path(); + QDBusReply<QList<QDBusObjectPath> > reply2 = wififace.call("GetAccessPoints"); + if ( reply2.isValid() ) { + QTreeWidgetItem *item; + QList<QDBusObjectPath> list2 = reply2.value(); + foreach(QDBusObjectPath path2, list2) { + QDBusInterface accessPointIface(NM_DBUS_SERVICE, + path2.path(), + NM_DBUS_INTERFACE_ACCESS_POINT, + dbc); + if (accessPointIface.isValid()) { +//// qWarning() <<"path2" << path2.path(); + +// if(dbc.connect(NM_DBUS_SERVICE, //signal strength +// path2.path(), +// NM_DBUS_INTERFACE_ACCESS_POINT, +// "PropertiesChanged", +// this,SLOT(aPPropertiesChanged( QMap<QString,QVariant>))) ) { +// qWarning() << "PropertiesChanged connect"; +// } else { +// qWarning() << "NOT connect"; +// +// } + + QStringList accessPoints; + accessPoints << accessPointIface.property("Ssid").toString(); + accessPoints << QString::number(accessPointIface.property("Strength").toInt()); + accessPoints << securityCapabilitiesToString(accessPointIface.property("WpaFlags" ).toInt()); + accessPoints << securityCapabilitiesToString(accessPointIface.property("RsnFlags" ).toInt()); + accessPoints << accessPointIface.property("Frequency" ).toString(); + accessPoints << accessPointIface.property("HwAddress" ).toString(); + accessPoints << deviceModeToString(accessPointIface.property("Mode" ).toInt()); + accessPoints << accessPointIface.property("MaxBitrate" ).toString(); + //HwAddress + // if(accessPointIface.property("Flags" ).toInt() == NM_802_11_AP_FLAGS_PRIVACY ) { + // qWarning() << "Secure"; + // } + item = new QTreeWidgetItem(accessPoints); + accessPointsTreeWidget->insertTopLevelItem(0, item); + } + } + } + } + } + } + } +} + +QString NMView::deviceStateToString(int state) +{ + QString ret; + switch(state) { + case NM_DEVICE_STATE_UNKNOWN: + ret = "Unknown"; + break; + case NM_DEVICE_STATE_UNMANAGED: + ret = "Unmanaged"; + break; + case NM_DEVICE_STATE_UNAVAILABLE: + ret = "Unavailable"; + break; + case NM_DEVICE_STATE_DISCONNECTED: + ret = "Disconnected"; + break; + case NM_DEVICE_STATE_PREPARE: + ret = "Preparing to connect"; + break; + case NM_DEVICE_STATE_CONFIG: + ret = "Being configured"; + break; + case NM_DEVICE_STATE_NEED_AUTH: + ret = "Awaiting secrets"; + break; + case NM_DEVICE_STATE_IP_CONFIG: + ret = "IP requested"; + break; + case NM_DEVICE_STATE_ACTIVATED: + ret = "Activated"; + break; + case NM_DEVICE_STATE_FAILED: + ret = "FAILED"; + break; + }; + return ret; +} + +QString NMView::deviceTypeToString(int device) +{ + QString ret; + switch(device) { + case DEVICE_TYPE_UNKNOWN: + ret = "Unknown"; + break; + case DEVICE_TYPE_802_3_ETHERNET: + ret = "Ethernet"; + break; + case DEVICE_TYPE_802_11_WIRELESS: + ret = "Wireless"; + break; + case DEVICE_TYPE_GSM: + ret = "GSM"; + break; + case DEVICE_TYPE_CDMA: + ret = "CDMA"; + break; + }; + return ret; +} + +QString NMView::securityCapabilitiesToString(int caps) +{ + int check = caps; +// qWarning() << __FUNCTION__<< caps; + QString ret; + if( check == 0 ) + ret += "None."; + if( (check & NM_802_11_AP_SEC_PAIR_WEP40)) + ret += " 40-bit WEP encryption. "; + if( (check & NM_802_11_AP_SEC_PAIR_WEP104) ) + ret += " 104-bit WEP encryption. "; + if( (check & NM_802_11_AP_SEC_PAIR_TKIP) ) + ret += " TKIP encryption. "; + if( (check & NM_802_11_AP_SEC_PAIR_CCMP) ) + ret += " CCMP encryption. "; + if( (check & NM_802_11_AP_SEC_GROUP_WEP40)) + ret += " 40-bit WEP cipher. "; + if( (check & NM_802_11_AP_SEC_GROUP_WEP104)) + ret += " 104-bit WEP cipher. "; + if( (check & NM_802_11_AP_SEC_GROUP_TKIP) ) + ret += " TKIP cipher. "; + if( (check & NM_802_11_AP_SEC_GROUP_CCMP) ) + ret += " CCMP cipher. "; + if( (check & NM_802_11_AP_SEC_KEY_MGMT_PSK)) + ret += " PSK key management. "; + if( (check & NM_802_11_AP_SEC_KEY_MGMT_802_1X) ) + ret += " 802.1x key management. "; + return ret; +} + +QString NMView::deviceModeToString(int mode) +{ + QString ret; + switch (mode) { + case NM_802_11_MODE_UNKNOWN: + ret = "Unknown"; + break; + case NM_802_11_MODE_ADHOC: + ret = " (Adhoc)."; + break; + case NM_802_11_MODE_INFRA: + ret = " (Infrastructure)"; + }; + return ret; +} + +void NMView::netManagerState(quint32 state) +{ + qWarning() << __FUNCTION__ << state;// << old << reason; + switch(state) { + case NM_STATE_UNKNOWN: + qWarning() << "The NetworkManager daemon is in an unknown state. "; + break; + case NM_STATE_ASLEEP: + qWarning() << "The NetworkManager daemon is asleep and all interfaces managed by it are inactive. "; + break; + case NM_STATE_CONNECTING: + qWarning() << "The NetworkManager daemon is connecting a device. FIXME: What does this mean when one device is active and another is connecting? "; + break; + case NM_STATE_CONNECTED: + qWarning() <<"The NetworkManager daemon is connected. "; + break; + case NM_STATE_DISCONNECTED: + qWarning() << "The NetworkManager daemon is disconnected."; + break; + + }; +} + +void NMView::deviceStateChanged(quint32 state) +{ + qWarning() << __FUNCTION__ << state; + switch(state) { + case NM_DEVICE_STATE_UNKNOWN : + qWarning() <<"The device is in an unknown state. "; + break; + case NM_DEVICE_STATE_UNMANAGED: + qWarning() <<"The device is not managed by NetworkManager."; + break; + case NM_DEVICE_STATE_UNAVAILABLE: + qWarning() <<"The device cannot be used (carrier off, rfkill, etc)."; + break; + case NM_DEVICE_STATE_DISCONNECTED: + qWarning() <<"The device is not connected."; + break; + case NM_DEVICE_STATE_PREPARE: + qWarning() <<"The device is preparing to connect."; + break; + case NM_DEVICE_STATE_CONFIG: + qWarning() <<"The device is being configured."; + break; + case NM_DEVICE_STATE_NEED_AUTH: + qWarning() <<"The device is awaiting secrets necessary to continue connection."; + break; + case NM_DEVICE_STATE_IP_CONFIG: + qWarning() <<"The IP settings of the device are being requested and configured."; + break; + case NM_DEVICE_STATE_ACTIVATED: + qWarning() <<"The device is active."; + break; + case NM_DEVICE_STATE_FAILED: + qWarning() <<"The device is in a failure state following an attempt to activate it."; + break; + }; +} + +void NMView::updateCompleted() +{ + qWarning() << __FUNCTION__; +} + +void NMView::newConfigurationActivated() +{ + qWarning() << __FUNCTION__; + getActiveConnections(); +} + +void NMView::stateChanged(QNetworkSession::State state) +{ + // QString stateStringstr; + switch (state) { + case QNetworkSession::Invalid: + stateString = "Invalid session"; + break; + case QNetworkSession::NotAvailable: + stateString = "Session is defined but not yet discovered"; + break; + case QNetworkSession::Connecting: + stateString = "Session is being established"; + break; + case QNetworkSession::Connected: + stateString = "Session is active and can be used for socket operations"; + cons->currentItem()->setText(1, "Active"); + break; + case QNetworkSession::Closing: + stateString = "Session is being shutdown"; + break; + case QNetworkSession::Disconnected: + qWarning() << __FUNCTION__; + manager->updateConfigurations(); + stateString = "Session disconnected"; + cons->currentItem()->setText(1,"Discovered") ; + break; + case QNetworkSession::Roaming: + stateString = "session is roaming from one AP to another"; + break; + }; + qWarning() << __FUNCTION__ << state << stateString; +} + +QString NMView::stateToString(int state) +{ + switch (state) { + case QNetworkConfiguration::Undefined: + return "Undefined"; + break; + case QNetworkConfiguration::Defined: + return "Defined"; + break; + case QNetworkConfiguration::Discovered: + return "Discovered"; + break; + case QNetworkConfiguration::Active: + return "Active"; + break; + }; + return ""; +} + +void NMView::configurationAdded(const QNetworkConfiguration &config) +{ + qWarning() << __FUNCTION__<< config.name() << config.identifier(); +} + +QString NMView::typeToString(int type) +{ + switch(type) { + case QNetworkConfiguration::InternetAccessPoint: + return "Internet AccessPoint"; + break; + case QNetworkConfiguration::ServiceNetwork: + return "Service Network"; + break; + }; + return QString(); +} + +void NMView::aPPropertiesChanged( QMap<QString,QVariant> map) +{ + //QMap<QString, QVariant>::const_iterator iterator = d->values.find(type + QLatin1String("Path")) + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + if( i.key() == "State") { + qWarning() << __FUNCTION__ << i.key() << ": " << i.value().toUInt(); +// deviceStateChanged(i.value().toUInt()); + } else if( i.key() == "ActiveAccessPoint") { + qWarning() << __FUNCTION__ << i.key() << ": " << i.value().value<QDBusObjectPath>().path(); + } else if( i.key() == "Strength") + qWarning() << __FUNCTION__ << i.key() << ": " << i.value().toUInt(); + else + qWarning() << __FUNCTION__ << i.key() << ": " << i.value(); + } +} + +void NMView::networkSessionError(QNetworkSession::SessionError error) +{ + QString errorStr; + switch(error) { + case QNetworkSession::RoamingError: + errorStr = "Roaming error"; + break; + case QNetworkSession::SessionAbortedError: + errorStr = "Session aborted by user or system"; + break; + default: + case QNetworkSession::UnknownSessionError: + errorStr = "Unidentified Error"; + break; + }; + + QMessageBox::warning(this, tr("NMView"), errorStr, QMessageBox::Ok); +} diff --git a/tests/manual/networkmanager/nmview.h b/tests/manual/networkmanager/nmview.h new file mode 100644 index 0000000..41ee04f --- /dev/null +++ b/tests/manual/networkmanager/nmview.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QWidget> +#include <QDBusConnection> +#include <qnetworkconfigmanager.h> +#include <qnetworksession.h> +#include <qnetworkconfiguration.h> + +#include "ui_dialog.h" + +QT_USE_NAMESPACE + +QT_BEGIN_NAMESPACE +class QListWidget; +class QTreeWidget; +class QTreeWidgetItem; +QT_END_NAMESPACE + +class NMView : public QDialog, private Ui::Dialog +{ + Q_OBJECT +public: + NMView(QDialog* parent = 0); + virtual ~NMView(); + +private: + void init(); + QString stateString; + + QDBusConnection dbc; + void printConnectionDetails(const QString&); + + QString deviceStateToString(int state); + QString deviceTypeToString(int device); + QString securityCapabilitiesToString(int caps); + QString deviceModeToString(int mode); +//QDBusInterface getInterface(); + QNetworkConfigurationManager *manager; + QNetworkSession *sess; + QString stateToString(int state); + QString typeToString(int type); + +private slots: + void update(); + void deactivate(); + void activate(); + void getActiveConnections(); + void updateConnections(); + void getDevices(); + // void readConnectionManagerDetails(); + void getNetworkDevices(); + void connectionItemActivated( QTreeWidgetItem *, int); +// void activeItemActivated( QListWidgetItem *); + void deviceItemActivated( QTreeWidgetItem *, int); + void netconfig(); + void findAccessPoints(); + + void netManagerState(quint32); + void readSettings(); + void updateCompleted(); + void newConfigurationActivated(); + + void stateChanged(QNetworkSession::State); + void deviceStateChanged(quint32 state); + + void configurationAdded(const QNetworkConfiguration &config); + void aPPropertiesChanged( QMap<QString,QVariant> map); + void networkSessionError(QNetworkSession::SessionError); + +}; diff --git a/tests/manual/networkmanager/startdlg.cpp b/tests/manual/networkmanager/startdlg.cpp new file mode 100644 index 0000000..e34b5e9 --- /dev/null +++ b/tests/manual/networkmanager/startdlg.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "startdlg.h" +#include <NetworkManager/NetworkManager.h> + + +StartDialog::StartDialog(QWidget * parent) + :QDialog(parent) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + box = new QComboBox(); + layout->addWidget(box); + + QHBoxLayout* hbox = new QHBoxLayout(); + QPushButton* start = new QPushButton("Start"); + connect(start, SIGNAL(clicked()), this, SLOT(accept())); + QPushButton* cancel = new QPushButton("Cancel"); + connect(cancel, SIGNAL(clicked()), this, SLOT(reject())); + + + hbox->addWidget(start); + hbox->addWidget(cancel); + + layout->addLayout(hbox); + + QDBusConnection dbc = QDBusConnection::systemBus(); + if (!dbc.isConnected()) { + qWarning() << "Unable to connect to D-Bus:" << dbc.lastError(); + return; + } + QDBusInterface iface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, dbc); + if (!iface.isValid()) { + qWarning() << "Could not find NetworkManager"; + return; + } + QDBusReply<QList<QDBusObjectPath> > reply = iface.call("GetDevices"); + if ( reply.isValid() ) { + QList<QDBusObjectPath> list = reply.value(); + foreach(QDBusObjectPath path, list) { + QDBusInterface devIface(NM_DBUS_SERVICE, path.path(), NM_DBUS_INTERFACE_DEVICE, dbc); + if ( devIface.isValid() ) { + box->addItem(devIface.property("Interface").toString(), QVariant(path.path())); + } + } + } +} + +QString StartDialog::device() const +{ + return dev; +} + +void StartDialog::accept() +{ + dev = box->itemData(box->currentIndex(), Qt::UserRole).toString(); + QDialog::accept(); +} diff --git a/tests/manual/networkmanager/startdlg.h b/tests/manual/networkmanager/startdlg.h new file mode 100644 index 0000000..32c8557 --- /dev/null +++ b/tests/manual/networkmanager/startdlg.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDialog> +#include <QtDBus> +#include <QtGui> + +class StartDialog : public QDialog +{ + Q_OBJECT +public: + StartDialog(QWidget* parent = 0); + + QString device() const; + +public slots: + void accept(); +private: + QString dev; + QComboBox* box; +}; diff --git a/tests/tests.pro b/tests/tests.pro index 7fbc8a9..75ca120 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -1,2 +1,3 @@ TEMPLATE = subdirs -SUBDIRS = auto +SUBDIRS = auto \ + benchmarks diff --git a/tools/designer/src/lib/shared/actionrepository.cpp b/tools/designer/src/lib/shared/actionrepository.cpp index e3ff2c1..1076ff4 100644 --- a/tools/designer/src/lib/shared/actionrepository.cpp +++ b/tools/designer/src/lib/shared/actionrepository.cpp @@ -77,18 +77,12 @@ static inline QAction *actionOfItem(const QStandardItem* item) return qvariant_cast<QAction*>(item->data(qdesigner_internal::ActionModel::ActionRole)); } -static QIcon fixActionIcon(const QIcon &icon) -{ - if (icon.isNull()) - return qdesigner_internal::emptyIcon(); - return icon; -} - namespace qdesigner_internal { // ----------- ActionModel ActionModel::ActionModel(QWidget *parent ) : QStandardItemModel(parent), + m_emptyIcon(emptyIcon()), m_core(0) { QStringList headers; @@ -127,7 +121,7 @@ void ActionModel::update(int row) for (int i = 0; i < NumColumns; i++) list += item(row, i); - setItems(m_core, actionOfItem(list.front()), list); + setItems(m_core, actionOfItem(list.front()), m_emptyIcon, list); } void ActionModel::remove(int row) @@ -150,7 +144,7 @@ QModelIndex ActionModel::addAction(QAction *action) item->setFlags(flags); items.push_back(item); } - setItems(m_core, action, items); + setItems(m_core, action, m_emptyIcon, items); appendRow(items); return indexFromItem(items.front()); } @@ -185,7 +179,9 @@ PropertySheetKeySequenceValue ActionModel::actionShortCut(const QDesignerPropert return qvariant_cast<PropertySheetKeySequenceValue>(sheet->property(index)); } -void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, QStandardItemList &sl) +void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, + const QIcon &defaultIcon, + QStandardItemList &sl) { // Tooltip, mostly for icon view mode @@ -200,7 +196,10 @@ void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, QStandardItem *item = sl[NameColumn]; item->setText(action->objectName()); - item->setIcon(fixActionIcon(action->icon())); + QIcon icon = action->icon(); + if (icon.isNull()) + icon = defaultIcon; + item->setIcon(icon); item->setToolTip(firstTooltip); item->setWhatsThis(firstTooltip); // Used diff --git a/tools/designer/src/lib/shared/actionrepository_p.h b/tools/designer/src/lib/shared/actionrepository_p.h index 65adc5d..6e17e7b 100644 --- a/tools/designer/src/lib/shared/actionrepository_p.h +++ b/tools/designer/src/lib/shared/actionrepository_p.h @@ -59,6 +59,7 @@ #include <QtGui/QTreeView> #include <QtGui/QListView> #include <QtGui/QStackedWidget> +#include <QtGui/QIcon> QT_BEGIN_NAMESPACE @@ -110,10 +111,14 @@ signals: void resourceImageDropped(const QString &path, QAction *action); private: + typedef QList<QStandardItem *> QStandardItemList; + void initializeHeaders(); + static void setItems(QDesignerFormEditorInterface *core, QAction *a, + const QIcon &defaultIcon, + QStandardItemList &sl); - typedef QList<QStandardItem *> QStandardItemList; - static void setItems(QDesignerFormEditorInterface *core, QAction *a, QStandardItemList &sl); + const QIcon m_emptyIcon; QDesignerFormEditorInterface *m_core; }; diff --git a/tools/designer/src/lib/shared/iconloader.cpp b/tools/designer/src/lib/shared/iconloader.cpp index df0bb7e..ed312b8 100644 --- a/tools/designer/src/lib/shared/iconloader.cpp +++ b/tools/designer/src/lib/shared/iconloader.cpp @@ -70,8 +70,7 @@ QDESIGNER_SHARED_EXPORT QIcon createIconSet(const QString &name) QDESIGNER_SHARED_EXPORT QIcon emptyIcon() { - static const QIcon empty_icon(QLatin1String(":/trolltech/formeditor/images/emptyicon.png")); - return empty_icon; + return QIcon(QLatin1String(":/trolltech/formeditor/images/emptyicon.png")); } } // namespace qdesigner_internal diff --git a/tools/designer/src/lib/shared/qdesigner_menu.cpp b/tools/designer/src/lib/shared/qdesigner_menu.cpp index c83abad..ba512e4 100644 --- a/tools/designer/src/lib/shared/qdesigner_menu.cpp +++ b/tools/designer/src/lib/shared/qdesigner_menu.cpp @@ -88,6 +88,7 @@ static inline void extendClickableArea(QRect *subMenuRect, Qt::LayoutDirection d QDesignerMenu::QDesignerMenu(QWidget *parent) : QMenu(parent), + m_subMenuPixmap(QPixmap(QLatin1String(":/trolltech/formeditor/images/submenu.png"))), m_currentIndex(0), m_addItem(new SpecialMenuAction(this)), m_addSeparator(new SpecialMenuAction(this)), @@ -550,11 +551,10 @@ void QDesignerMenu::deleteAction(QAction *a) QRect QDesignerMenu::subMenuPixmapRect(QAction *action) const { - static const QPixmap pm(QLatin1String(":/trolltech/formeditor/images/submenu.png")); const QRect g = actionGeometry(action); - const int x = layoutDirection() == Qt::LeftToRight ? (g.right() - pm.width() - 2) : 2; - const int y = g.top() + (g.height() - pm.height())/2 + 1; - return QRect(x, y, pm.width(), pm.height()); + const int x = layoutDirection() == Qt::LeftToRight ? (g.right() - m_subMenuPixmap.width() - 2) : 2; + const int y = g.top() + (g.height() - m_subMenuPixmap.height())/2 + 1; + return QRect(x, y, m_subMenuPixmap.width(), m_subMenuPixmap.height()); } bool QDesignerMenu::hasSubMenuPixmap(QAction *action) const @@ -591,8 +591,7 @@ void QDesignerMenu::paintEvent(QPaintEvent *event) p.fillRect(g, lg); } else if (hasSubMenuPixmap(a)) { - static const QPixmap pm(QLatin1String(":/trolltech/formeditor/images/submenu.png")); - p.drawPixmap(subMenuPixmapRect(a).topLeft(), pm); + p.drawPixmap(subMenuPixmapRect(a).topLeft(), m_subMenuPixmap); } } diff --git a/tools/designer/src/lib/shared/qdesigner_menu_p.h b/tools/designer/src/lib/shared/qdesigner_menu_p.h index 9c9a311..ae1e0e7 100644 --- a/tools/designer/src/lib/shared/qdesigner_menu_p.h +++ b/tools/designer/src/lib/shared/qdesigner_menu_p.h @@ -57,6 +57,7 @@ #include <QtGui/QAction> #include <QtGui/QMenu> +#include <QtGui/QPixmap> #include <QtCore/QHash> QT_BEGIN_NAMESPACE @@ -183,6 +184,7 @@ protected: private: bool hideSubMenuOnCursorKey(); bool showSubMenuOnCursorKey(); + const QPixmap m_subMenuPixmap; QPoint m_startPosition; int m_currentIndex; diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp index 6572059..4e2b473 100644 --- a/tools/linguist/linguist/messagemodel.cpp +++ b/tools/linguist/linguist/messagemodel.cpp @@ -584,12 +584,16 @@ void MultiContextItem::putMessageItem(int pos, MessageItem *m) m_messageLists.last()[pos] = m; } -void MultiContextItem::appendMessageItem(MessageItem *m) +void MultiContextItem::appendMessageItems(const QList<MessageItem *> &m) { + QList<MessageItem *> nullItems = m; // Basically, just a reservation + for (int i = 0; i < nullItems.count(); ++i) + nullItems[i] = 0; for (int i = 0; i < m_messageLists.count() - 1; ++i) - m_messageLists[i].append(0); - m_messageLists.last().append(m); - m_multiMessageList.append(MultiMessageItem(m)); + m_messageLists[i] += nullItems; + m_messageLists.last() += m; + foreach (MessageItem *mi, m) + m_multiMessageList.append(MultiMessageItem(mi)); } void MultiContextItem::removeMultiMessageItem(int pos) @@ -710,33 +714,43 @@ void MultiDataModel::append(DataModel *dm, bool readWrite) m_msgModel->endInsertColumns(); } m_msgModel->endInsertColumns(); + int appendedContexts = 0; for (int i = 0; i < dm->contextCount(); ++i) { ContextItem *c = dm->contextItem(i); int mcx = findContextIndex(c->context()); if (mcx >= 0) { MultiContextItem *mc = multiContextItem(mcx); mc->assignLastModel(c, readWrite); + QList<MessageItem *> appendItems; for (int j = 0; j < c->messageCount(); ++j) { MessageItem *m = c->messageItem(j); int msgIdx = mc->findMessage(m->text(), m->comment()); - if (msgIdx >= 0) { + if (msgIdx >= 0) mc->putMessageItem(msgIdx, m); - } else { - int msgCnt = mc->messageCount(); - m_msgModel->beginInsertRows(m_msgModel->createIndex(mcx, 0, 0), msgCnt, msgCnt); - mc->appendMessageItem(m); - m_msgModel->endInsertRows(); - ++m_numMessages; - } + else + appendItems << m; + } + if (!appendItems.isEmpty()) { + int msgCnt = mc->messageCount(); + m_msgModel->beginInsertRows(m_msgModel->createIndex(mcx, 0, 0), + msgCnt, msgCnt + appendItems.size() - 1); + mc->appendMessageItems(appendItems); + m_msgModel->endInsertRows(); + m_numMessages += appendItems.size(); } } else { - MultiContextItem item(modelCount() - 1, c, readWrite); - m_msgModel->beginInsertRows(QModelIndex(), contextCount(), contextCount()); - m_multiContextList.append(item); - m_msgModel->endInsertRows(); - m_numMessages += item.messageCount(); + m_multiContextList << MultiContextItem(modelCount() - 1, c, readWrite); + m_numMessages += c->messageCount(); + ++appendedContexts; } } + if (appendedContexts) { + // Do that en block to avoid itemview inefficiency. It doesn't hurt that we + // announce the availability of the data "long" after it was actually added. + m_msgModel->beginInsertRows(QModelIndex(), + contextCount() - appendedContexts, contextCount() - 1); + m_msgModel->endInsertRows(); + } dm->setWritable(readWrite); updateCountsOnAdd(modelCount() - 1, readWrite); connect(dm, SIGNAL(modifiedChanged()), SLOT(onModifiedChanged())); diff --git a/tools/linguist/linguist/messagemodel.h b/tools/linguist/linguist/messagemodel.h index 3e0107e..7d98873 100644 --- a/tools/linguist/linguist/messagemodel.h +++ b/tools/linguist/linguist/messagemodel.h @@ -332,7 +332,7 @@ private: void removeModel(int pos); void moveModel(int oldPos, int newPos); // newPos is *before* removing at oldPos void putMessageItem(int pos, MessageItem *m); - void appendMessageItem(MessageItem *m); + void appendMessageItems(const QList<MessageItem *> &m); void removeMultiMessageItem(int pos); void incrementFinishedCount() { ++m_finishedCount; } void decrementFinishedCount() { --m_finishedCount; } diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index a77e713..1a5cdee 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -174,11 +174,7 @@ int main(int argc, char *argv[]) } if(loglevel > 0) outstream << "Connecting to target via " << serialPortName << endl; -#ifdef Q_OS_WIN - launcher->setTrkServerName(QString("\\\\.\\") + serialPortName); -#else launcher->setTrkServerName(serialPortName); -#endif launcher->setFileName(QString("c:\\sys\\bin\\") + exeFile); launcher->setCommandLineArgs(cmdLine); diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro index 2c1be98..7bed3e5 100644 --- a/tools/runonphone/runonphone.pro +++ b/tools/runonphone/runonphone.pro @@ -4,7 +4,7 @@ QT -= gui CONFIG += console CONFIG -= app_bundle -include(trk/trk.pri) +include(symbianutils/symbianutils.pri) SOURCES += main.cpp \ trksignalhandler.cpp @@ -12,6 +12,8 @@ SOURCES += main.cpp \ HEADERS += trksignalhandler.h \ serenum.h +DEFINES += SYMBIANUTILS_INCLUDE_PRI + windows { SOURCES += serenum_win.cpp LIBS += -lsetupapi \ diff --git a/tools/runonphone/trk/bluetoothlistener.cpp b/tools/runonphone/symbianutils/bluetoothlistener.cpp index 8d45fb5..df04288 100644 --- a/tools/runonphone/trk/bluetoothlistener.cpp +++ b/tools/runonphone/symbianutils/bluetoothlistener.cpp @@ -184,7 +184,7 @@ bool BluetoothListener::start(const QString &device, QString *errorMessage) return true; } -void BluetoothListener::slotStdOutput() +void BluetoothListener::slotStdOutput() { emitMessage(QString::fromLocal8Bit(d->process.readAllStandardOutput())); } diff --git a/tools/runonphone/trk/bluetoothlistener.h b/tools/runonphone/symbianutils/bluetoothlistener.h index 027f286..36894e7 100644 --- a/tools/runonphone/trk/bluetoothlistener.h +++ b/tools/runonphone/symbianutils/bluetoothlistener.h @@ -42,6 +42,8 @@ #ifndef BLUETOOTHLISTENER_H #define BLUETOOTHLISTENER_H +#include "symbianutils_global.h" + #include <QtCore/QObject> #include <QtCore/QProcess> @@ -53,7 +55,7 @@ struct BluetoothListenerPrivate; * The rfcomm command is used. It process can be started in the background * while connection attempts (TrkDevice::open()) are made in the foreground. */ -class BluetoothListener : public QObject +class SYMBIANUTILS_EXPORT BluetoothListener : public QObject { Q_OBJECT Q_DISABLE_COPY(BluetoothListener) diff --git a/tools/runonphone/trk/bluetoothlistener_gui.cpp b/tools/runonphone/symbianutils/bluetoothlistener_gui.cpp index 6ffdaef..5994eb5 100644 --- a/tools/runonphone/trk/bluetoothlistener_gui.cpp +++ b/tools/runonphone/symbianutils/bluetoothlistener_gui.cpp @@ -50,7 +50,7 @@ namespace trk { -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartCommunication(BaseCommunicationStarter &starter, const QString &msgBoxTitle, const QString &msgBoxText, @@ -88,7 +88,7 @@ PromptStartCommunicationResult return PromptStartCommunicationConnected; } -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartSerial(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage) @@ -98,7 +98,7 @@ PromptStartCommunicationResult return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); } -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartBluetooth(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage) diff --git a/tools/runonphone/trk/bluetoothlistener_gui.h b/tools/runonphone/symbianutils/bluetoothlistener_gui.h index d673ffe..10e7145 100644 --- a/tools/runonphone/trk/bluetoothlistener_gui.h +++ b/tools/runonphone/symbianutils/bluetoothlistener_gui.h @@ -42,6 +42,8 @@ #ifndef BLUETOOTHLISTENER_GUI_H #define BLUETOOTHLISTENER_GUI_H +#include "symbianutils_global.h" + #include <QtCore/QtGlobal> QT_BEGIN_NAMESPACE @@ -62,7 +64,7 @@ enum PromptStartCommunicationResult { PromptStartCommunicationError }; -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartCommunication(BaseCommunicationStarter &starter, const QString &msgBoxTitle, const QString &msgBoxText, @@ -71,14 +73,14 @@ PromptStartCommunicationResult // Convenience to start a serial connection (messages prompting // to launch Trk). -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartSerial(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage); // Convenience to start blue tooth connection (messages // prompting to connect). -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartBluetooth(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage); diff --git a/tools/runonphone/trk/callback.h b/tools/runonphone/symbianutils/callback.h index edc2c74..3996d73 100644 --- a/tools/runonphone/trk/callback.h +++ b/tools/runonphone/symbianutils/callback.h @@ -42,7 +42,7 @@ #ifndef DEBUGGER_CALLBACK_H #define DEBUGGER_CALLBACK_H -#include <QtCore/QtGlobal> +#include "symbianutils_global.h" namespace trk { namespace Internal { diff --git a/tools/runonphone/trk/communicationstarter.cpp b/tools/runonphone/symbianutils/communicationstarter.cpp index e5e556e..cdee49f 100644 --- a/tools/runonphone/trk/communicationstarter.cpp +++ b/tools/runonphone/symbianutils/communicationstarter.cpp @@ -58,7 +58,6 @@ struct BaseCommunicationStarterPrivate { int intervalMS; int attempts; int n; - QString device; QString errorString; BaseCommunicationStarter::State state; }; @@ -70,7 +69,6 @@ BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommu intervalMS(1000), attempts(-1), n(0), - device(QLatin1String("/dev/rfcomm0")), state(BaseCommunicationStarter::TimedOut) { } @@ -108,7 +106,7 @@ BaseCommunicationStarter::StartResult BaseCommunicationStarter::start() // Before we instantiate timers, and such, try to open the device, // which should succeed if another listener is already running in // 'Watch' mode - if (d->trkDevice->open(d->device , &(d->errorString))) + if (d->trkDevice->open(&(d->errorString))) return ConnectionSucceeded; // Pull up resources for next attempt d->n = 0; @@ -155,12 +153,7 @@ void BaseCommunicationStarter::setAttempts(int a) QString BaseCommunicationStarter::device() const { - return d->device; -} - -void BaseCommunicationStarter::setDevice(const QString &dv) -{ - d->device = dv; + return d->trkDevice->port(); } QString BaseCommunicationStarter::errorString() const @@ -175,20 +168,20 @@ void BaseCommunicationStarter::slotTimer() if (d->attempts >= 0 && d->n >= d->attempts) { stopTimer(); d->errorString = tr("%1: timed out after %n attempts using an interval of %2ms.", 0, d->n) - .arg(d->device).arg(d->intervalMS); + .arg(d->trkDevice->port()).arg(d->intervalMS); d->state = TimedOut; emit timeout(); } else { // Attempt n to connect? - if (d->trkDevice->open(d->device , &(d->errorString))) { + if (d->trkDevice->open(&(d->errorString))) { stopTimer(); - const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->device).arg(d->n); + const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->trkDevice->port()).arg(d->n); emit message(msg); d->state = Connected; emit connected(); } else { const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...") - .arg(d->device).arg(d->n).arg(d->errorString); + .arg(d->trkDevice->port()).arg(d->n).arg(d->errorString); emit message(msg); } } @@ -228,13 +221,11 @@ BluetoothListener *ConsoleBluetoothStarter::createListener() bool ConsoleBluetoothStarter::startBluetooth(const TrkDevicePtr &trkDevice, QObject *listenerParent, - const QString &device, int attempts, QString *errorMessage) { // Set up a console starter to print to stdout. ConsoleBluetoothStarter starter(trkDevice, listenerParent); - starter.setDevice(device); starter.setAttempts(attempts); switch (starter.start()) { case Started: diff --git a/tools/runonphone/trk/communicationstarter.h b/tools/runonphone/symbianutils/communicationstarter.h index 34cf398..0a060ee 100644 --- a/tools/runonphone/trk/communicationstarter.h +++ b/tools/runonphone/symbianutils/communicationstarter.h @@ -42,6 +42,8 @@ #ifndef COMMUNICATIONSTARTER_H #define COMMUNICATIONSTARTER_H +#include "symbianutils_global.h" + #include <QtCore/QSharedPointer> #include <QtCore/QObject> @@ -60,7 +62,7 @@ struct BaseCommunicationStarterPrivate; * The base class can be used as is to prompt the user to launch App TRK for a * serial communication as this requires no further resource setup. */ -class BaseCommunicationStarter : public QObject { +class SYMBIANUTILS_EXPORT BaseCommunicationStarter : public QObject { Q_OBJECT Q_DISABLE_COPY(BaseCommunicationStarter) public: @@ -78,7 +80,6 @@ public: void setAttempts(int a); QString device() const; - void setDevice(const QString &); State state() const; QString errorString() const; @@ -117,7 +118,7 @@ private: * implement as a factory function that creates and sets up the * listener (mode, message connection, etc). */ -class AbstractBluetoothStarter : public BaseCommunicationStarter { +class SYMBIANUTILS_EXPORT AbstractBluetoothStarter : public BaseCommunicationStarter { Q_OBJECT Q_DISABLE_COPY(AbstractBluetoothStarter) public: @@ -134,13 +135,12 @@ protected: /* ConsoleBluetoothStarter: Convenience class for console processes. Creates a * listener in "Listen" mode with the messages redirected to standard output. */ -class ConsoleBluetoothStarter : public AbstractBluetoothStarter { +class SYMBIANUTILS_EXPORT ConsoleBluetoothStarter : public AbstractBluetoothStarter { Q_OBJECT Q_DISABLE_COPY(ConsoleBluetoothStarter) public: static bool startBluetooth(const TrkDevicePtr& trkDevice, QObject *listenerParent, - const QString &device, int attempts, QString *errorMessage); diff --git a/tools/runonphone/trk/launcher.cpp b/tools/runonphone/symbianutils/launcher.cpp index 1796fc5..408829b 100644 --- a/tools/runonphone/trk/launcher.cpp +++ b/tools/runonphone/symbianutils/launcher.cpp @@ -41,6 +41,7 @@ #include "launcher.h" #include "trkutils.h" +#include "trkutils_p.h" #include "trkdevice.h" #include "bluetoothlistener.h" @@ -66,7 +67,6 @@ struct LauncherPrivate { explicit LauncherPrivate(const TrkDevicePtr &d); TrkDevicePtr m_device; - QString m_trkServerName; QByteArray m_trkReadBuffer; Launcher::State m_state; @@ -130,12 +130,12 @@ void Launcher::addStartupActions(trk::Launcher::Actions startupActions) void Launcher::setTrkServerName(const QString &name) { - d->m_trkServerName = name; + d->m_device->setPort(name); } QString Launcher::trkServerName() const { - return d->m_trkServerName; + return d->m_device->port(); } TrkDevicePtr Launcher::trkDevice() const @@ -190,7 +190,7 @@ bool Launcher::startServer(QString *errorMessage) errorMessage->clear(); if (d->m_verbose) { const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6") - .arg(d->m_trkServerName, d->m_fileName, + .arg(trkServerName(), d->m_fileName, d->m_commandLineArgs.join(QString(QLatin1Char(' '))), d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName); logMessage(msg); @@ -212,7 +212,7 @@ bool Launcher::startServer(QString *errorMessage) qWarning("No remote executable given for running."); return false; } - if (!d->m_device->isOpen() && !d->m_device->open(d->m_trkServerName, errorMessage)) + if (!d->m_device->isOpen() && !d->m_device->open(errorMessage)) return false; if (d->m_closeDevice) { connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); @@ -595,17 +595,19 @@ void Launcher::handleSupportMask(const TrkResult &result) return; const char *data = result.data.data() + 1; - QByteArray str; + QString str = QLatin1String("SUPPORTED: "); for (int i = 0; i < 32; ++i) { //str.append(" [" + formatByte(data[i]) + "]: "); - for (int j = 0; j < 8; ++j) - if (data[i] & (1 << j)) - str.append(QByteArray::number(i * 8 + j, 16) + " "); + for (int j = 0; j < 8; ++j) { + if (data[i] & (1 << j)) { + str.append(QString::number(i * 8 + j, 16)); + str.append(QLatin1Char(' ')); + } + } } - logMessage("SUPPORTED: " + str); + logMessage(str); } - void Launcher::cleanUp() { // @@ -614,9 +616,7 @@ void Launcher::cleanUp() // Sub Cmd: Delete Process //ProcessID: 0x0000071F (1823) // [41 24 00 00 00 00 07 1F] - QByteArray ba; - appendByte(&ba, 0x00); - appendByte(&ba, 0x00); + QByteArray ba(2, char(0)); appendInt(&ba, d->m_session.pid); d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(), ba, "Delete process"); @@ -669,7 +669,7 @@ void Launcher::copyFileToRemote() { emit copyingStarted(); QByteArray ba; - appendByte(&ba, 0x10); + ba.append(char(10)); appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); } @@ -678,7 +678,7 @@ void Launcher::installRemotePackageSilently() { emit installingStarted(); QByteArray ba; - appendByte(&ba, 'C'); + ba.append('C'); appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); } @@ -705,7 +705,7 @@ QByteArray Launcher::startProcessMessage(const QString &executable, // It's not started yet QByteArray ba; appendShort(&ba, 0, TargetByteOrder); // create new process - appendByte(&ba, 0); // options - currently unused + ba.append(char(0)); // options - currently unused if(arguments.isEmpty()) { appendString(&ba, executable.toLocal8Bit(), TargetByteOrder); return ba; diff --git a/tools/runonphone/trk/launcher.h b/tools/runonphone/symbianutils/launcher.h index 8dc6ebe..2b23fd8 100644 --- a/tools/runonphone/trk/launcher.h +++ b/tools/runonphone/symbianutils/launcher.h @@ -56,7 +56,7 @@ struct LauncherPrivate; typedef QSharedPointer<TrkDevice> TrkDevicePtr; -class Launcher : public QObject +class SYMBIANUTILS_EXPORT Launcher : public QObject { Q_OBJECT Q_DISABLE_COPY(Launcher) diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.cpp b/tools/runonphone/symbianutils/symbiandevicemanager.cpp new file mode 100644 index 0000000..f663816 --- /dev/null +++ b/tools/runonphone/symbianutils/symbiandevicemanager.cpp @@ -0,0 +1,331 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbiandevicemanager.h" + +#include <QtCore/QSettings> +#include <QtCore/QStringList> +#include <QtCore/QFileInfo> +#include <QtCore/QtDebug> +#include <QtCore/QTextStream> +#include <QtCore/QSharedData> +#include <QtCore/QScopedPointer> + +namespace SymbianUtils { + +enum { debug = 0 }; + +static const char REGKEY_CURRENT_CONTROL_SET[] = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"; +static const char USBSER[] = "Services/usbser/Enum"; + +const char *SymbianDeviceManager::linuxBlueToothDeviceRootC = "/dev/rfcomm"; + +// ------------- SymbianDevice +class SymbianDeviceData : public QSharedData { +public: + SymbianDeviceData() : type(SerialPortCommunication) {} + + QString portName; + QString friendlyName; + QString deviceDesc; + QString manufacturer; + DeviceCommunicationType type; +}; + +SymbianDevice::SymbianDevice(SymbianDeviceData *data) : + m_data(data) +{ + +} + +SymbianDevice::SymbianDevice() : + m_data(new SymbianDeviceData) +{ +} +SymbianDevice::SymbianDevice(const SymbianDevice &rhs) : + m_data(rhs.m_data) +{ +} + +SymbianDevice &SymbianDevice::operator=(const SymbianDevice &rhs) +{ + if (this != &rhs) + m_data = rhs.m_data; + return *this; +} + +SymbianDevice::~SymbianDevice() +{ +} + +QString SymbianDevice::portName() const +{ + return m_data->portName; +} + +QString SymbianDevice::friendlyName() const +{ + return m_data->friendlyName; +} + +QString SymbianDevice::deviceDesc() const +{ + return m_data->deviceDesc; +} + +QString SymbianDevice::manufacturer() const +{ + return m_data->manufacturer; +} + +DeviceCommunicationType SymbianDevice::type() const +{ + return m_data->type; +} + +bool SymbianDevice::isNull() const +{ + return !m_data->portName.isEmpty(); +} + +QString SymbianDevice::toString() const +{ + QString rc; + QTextStream str(&rc); + format(str); + return rc; +} + +void SymbianDevice::format(QTextStream &str) const +{ + str << (m_data->type == BlueToothCommunication ? "Bluetooth: " : "Serial: ") + << m_data->portName; + if (!m_data->friendlyName.isEmpty()) { + str << " (" << m_data->friendlyName; + if (!m_data->deviceDesc.isEmpty()) + str << " / " << m_data->deviceDesc; + str << ')'; + } + if (!m_data->manufacturer.isEmpty()) + str << " [" << m_data->manufacturer << ']'; +} + +// Compare by port and friendly name +int SymbianDevice::compare(const SymbianDevice &rhs) const +{ + if (const int prc = m_data->portName.compare(rhs.m_data->portName)) + return prc; + if (const int frc = m_data->friendlyName.compare(rhs.m_data->friendlyName)) + return frc; + return 0; +} + +QDebug operator<<(QDebug d, const SymbianDevice &cd) +{ + d.nospace() << cd.toString(); + return d; +} + +// ------------- SymbianDeviceManagerPrivate +struct SymbianDeviceManagerPrivate { + SymbianDeviceManagerPrivate() : m_initialized(false) {} + + bool m_initialized; + SymbianDeviceManager::SymbianDeviceList m_devices; +}; + +SymbianDeviceManager::SymbianDeviceManager(QObject *parent) : + QObject(parent), + d(new SymbianDeviceManagerPrivate) +{ +} + +SymbianDeviceManager::~SymbianDeviceManager() +{ + delete d; +} + +SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::devices() const +{ + if (!d->m_initialized) + const_cast<SymbianDeviceManager*>(this)->update(false); + return d->m_devices; +} + +QString SymbianDeviceManager::toString() const +{ + QString rc; + QTextStream str(&rc); + const int count = d->m_devices.size(); + for (int i = 0; i < count; i++) { + str << '#' << i << ' '; + d->m_devices.at(i).format(str); + str << '\n'; + } + return rc; +} + +QString SymbianDeviceManager::friendlyNameForPort(const QString &port) const +{ + foreach (const SymbianDevice &device, d->m_devices) { + if (device.portName() == port) + return device.friendlyName(); + } + return QString(); +} + +void SymbianDeviceManager::update() +{ + update(true); +} + +void SymbianDeviceManager::update(bool emitSignals) +{ + typedef SymbianDeviceList::iterator SymbianDeviceListIterator; + + if (debug) + qDebug(">SerialDeviceLister::update(%d)\n%s", int(emitSignals), + qPrintable(toString())); + + d->m_initialized = true; + // Get ordered new list + SymbianDeviceList newDevices = serialPorts() + blueToothDevices(); + if (newDevices.size() > 1) + qStableSort(newDevices.begin(), newDevices.end()); + if (d->m_devices == newDevices) // Happy, nothing changed. + return; + // Merge the lists and emit the respective added/removed signals, assuming + // no one can plug a different device on the same port at the speed of lightning + if (!d->m_devices.isEmpty()) { + // Find deleted devices + for (SymbianDeviceListIterator oldIt = d->m_devices.begin(); oldIt != d->m_devices.end(); ) { + if (newDevices.contains(*oldIt)) { + ++oldIt; + } else { + const SymbianDevice toBeDeleted = *oldIt; + oldIt = d->m_devices.erase(oldIt); + if (emitSignals) + emit deviceRemoved(toBeDeleted); + } + } + } + if (!newDevices.isEmpty()) { + // Find new devices and insert in order + foreach(const SymbianDevice &newDevice, newDevices) { + if (!d->m_devices.contains(newDevice)) { + d->m_devices.append(newDevice); + if (emitSignals) + emit deviceAdded(newDevice); + } + } + if (d->m_devices.size() > 1) + qStableSort(d->m_devices.begin(), d->m_devices.end()); + } + if (emitSignals) + emit updated(); + + if (debug) + qDebug("<SerialDeviceLister::update\n%s\n", qPrintable(toString())); +} + +SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::serialPorts() const +{ + SymbianDeviceList rc; +#ifdef Q_OS_WIN + const QSettings registry(REGKEY_CURRENT_CONTROL_SET, QSettings::NativeFormat); + const QString usbSerialRootKey = QLatin1String(USBSER) + QLatin1Char('/'); + const int count = registry.value(usbSerialRootKey + QLatin1String("Count")).toInt(); + for (int i = 0; i < count; ++i) { + QString driver = registry.value(usbSerialRootKey + QString::number(i)).toString(); + if (driver.contains(QLatin1String("JAVACOMM"))) { + driver.replace(QLatin1Char('\\'), QLatin1Char('/')); + const QString driverRootKey = QLatin1String("Enum/") + driver + QLatin1Char('/'); + if (debug > 1) + qDebug() << "SerialDeviceLister::serialPorts(): Checking " << i << count + << REGKEY_CURRENT_CONTROL_SET << usbSerialRootKey << driverRootKey; + QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData); + device->type = SerialPortCommunication; + device->friendlyName = registry.value(driverRootKey + QLatin1String("FriendlyName")).toString(); + device->portName = registry.value(driverRootKey + QLatin1String("Device Parameters/PortName")).toString(); + device->deviceDesc = registry.value(driverRootKey + QLatin1String("DeviceDesc")).toString(); + device->manufacturer = registry.value(driverRootKey + QLatin1String("Mfg")).toString(); + rc.append(SymbianDevice(device.take())); + } + } +#endif + return rc; +} + +SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices() const +{ + SymbianDeviceList rc; +#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) + // Bluetooth devices are created on connection. List the existing ones + // or at least the first one. + const QString prefix = QLatin1String(linuxBlueToothDeviceRootC); + const QString friendlyFormat = QLatin1String("Bluetooth device (%1)"); + for (int d = 0; d < 4; d++) { + QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData); + device->type = BlueToothCommunication; + device->portName = prefix + QString::number(d); + if (d == 0 || QFileInfo(device->portName).exists()) { + device->friendlyName = friendlyFormat.arg(device->portName); + rc.push_back(SymbianDevice(device.take())); + } + } +#endif + return rc; +} + +Q_GLOBAL_STATIC(SymbianDeviceManager, symbianDeviceManager) + +SymbianDeviceManager *SymbianDeviceManager::instance() +{ + return symbianDeviceManager(); +} + +QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm) +{ + d.nospace() << sdm.toString(); + return d; +} + +} // namespace SymbianUtilsInternal diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.h b/tools/runonphone/symbianutils/symbiandevicemanager.h new file mode 100644 index 0000000..dcf131a --- /dev/null +++ b/tools/runonphone/symbianutils/symbiandevicemanager.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANDEVICEMANAGER_H +#define SYMBIANDEVICEMANAGER_H + +#include "symbianutils_global.h" + +#include <QtCore/QObject> +#include <QtCore/QExplicitlySharedDataPointer> + +QT_BEGIN_NAMESPACE +class QDebug; +class QTextStream; +QT_END_NAMESPACE + +namespace SymbianUtils { + +struct SymbianDeviceManagerPrivate; +class SymbianDeviceData; + +enum DeviceCommunicationType { + SerialPortCommunication = 0, + BlueToothCommunication = 1 +}; + +// SymbianDevice, explicitly shared. +class SYMBIANUTILS_EXPORT SymbianDevice { + explicit SymbianDevice(SymbianDeviceData *data); + friend class SymbianDeviceManager; +public: + SymbianDevice(); + SymbianDevice(const SymbianDevice &rhs); + SymbianDevice &operator=(const SymbianDevice &rhs); + ~SymbianDevice(); + int compare(const SymbianDevice &rhs) const; + + DeviceCommunicationType type() const; + bool isNull() const; + QString portName() const; + QString friendlyName() const; + + // Windows only. + QString deviceDesc() const; + QString manufacturer() const; + + void format(QTextStream &str) const; + QString toString() const; + +private: + QExplicitlySharedDataPointer<SymbianDeviceData> m_data; +}; + +QDebug operator<<(QDebug d, const SymbianDevice &); + +inline bool operator==(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) == 0; } +inline bool operator!=(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) != 0; } +inline bool operator<(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) < 0; } + +/* SymbianDeviceManager: Singleton that maintains a list of Symbian devices. + * and emits change signals. + * On Windows, the update slot must be connected to a signal + * emitted from an event handler listening for WM_DEVICECHANGE. */ +class SYMBIANUTILS_EXPORT SymbianDeviceManager : public QObject +{ + Q_OBJECT +public: + typedef QList<SymbianDevice> SymbianDeviceList; + + static const char *linuxBlueToothDeviceRootC; + + // Do not use this constructor, it is just public for Q_GLOBAL_STATIC + explicit SymbianDeviceManager(QObject *parent = 0); + virtual ~SymbianDeviceManager(); + + // Singleton access. + static SymbianDeviceManager *instance(); + + SymbianDeviceList devices() const; + QString toString() const; + + QString friendlyNameForPort(const QString &port) const; + +public slots: + void update(); + +signals: + void deviceRemoved(const SymbianDevice &d); + void deviceAdded(const SymbianDevice &d); + void updated(); + +private: + void update(bool emitSignals); + SymbianDeviceList serialPorts() const; + SymbianDeviceList blueToothDevices() const; + + SymbianDeviceManagerPrivate *d; +}; + +QDebug operator<<(QDebug d, const SymbianDeviceManager &); + +} // namespace SymbianUtils + +#endif // SYMBIANDEVICEMANAGER_H diff --git a/tools/runonphone/trk/trk.pri b/tools/runonphone/symbianutils/symbianutils.pri index 2ce17c0..6309517 100644 --- a/tools/runonphone/trk/trk.pri +++ b/tools/runonphone/symbianutils/symbianutils.pri @@ -1,18 +1,22 @@ INCLUDEPATH *= $$PWD # Input -HEADERS += $$PWD/callback.h \ +HEADERS += $$PWD/symbianutils_global.h \ + $$PWD/callback.h \ $$PWD/trkutils.h \ + $$PWD/trkutils_p.h \ $$PWD/trkdevice.h \ $$PWD/launcher.h \ $$PWD/bluetoothlistener.h \ - $$PWD/communicationstarter.h + $$PWD/communicationstarter.h \ + $$PWD/symbiandevicemanager.h SOURCES += $$PWD/trkutils.cpp \ $$PWD/trkdevice.cpp \ $$PWD/launcher.cpp \ $$PWD/bluetoothlistener.cpp \ - $$PWD/communicationstarter.cpp + $$PWD/communicationstarter.cpp \ + $$PWD/symbiandevicemanager.cpp # Tests/trklauncher is a console application contains(QT, gui) { diff --git a/tools/runonphone/symbianutils/symbianutils_global.h b/tools/runonphone/symbianutils/symbianutils_global.h new file mode 100644 index 0000000..a6ffbe7 --- /dev/null +++ b/tools/runonphone/symbianutils/symbianutils_global.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANUTILS_GLOBAL_H +#define SYMBIANUTILS_GLOBAL_H + +#include <QtCore/qglobal.h> + +#if defined(SYMBIANUTILS_BUILD_LIB) +# define SYMBIANUTILS_EXPORT Q_DECL_EXPORT +#elif defined(SYMBIANUTILS_BUILD_STATIC_LIB) || defined(SYMBIANUTILS_INCLUDE_PRI) +# define SYMBIANUTILS_EXPORT +#else +# define SYMBIANUTILS_EXPORT Q_DECL_IMPORT +#endif + +#endif // SYMBIANUTILS_GLOBAL_H diff --git a/tools/runonphone/trk/trkdevice.cpp b/tools/runonphone/symbianutils/trkdevice.cpp index fe3261b..b327ab3 100644 --- a/tools/runonphone/trk/trkdevice.cpp +++ b/tools/runonphone/symbianutils/trkdevice.cpp @@ -41,6 +41,7 @@ #include "trkdevice.h" #include "trkutils.h" +#include "trkutils_p.h" #include <QtCore/QString> #include <QtCore/QDebug> @@ -516,7 +517,7 @@ static inline bool overlappedSyncWrite(HANDLE file, bool WriterThread::write(const QByteArray &data, QString *errorMessage) { if (verboseTrk) - qDebug() << "Write raw data: " << data.toHex(); + qDebug() << "Write raw data: " << stringFromArray(data).toLatin1(); QMutexLocker locker(&m_context->mutex); #ifdef Q_OS_WIN DWORD charsWritten; @@ -856,8 +857,8 @@ void UnixReaderThread::terminate() { // Trigger select() by writing to the pipe char c = 0; - int written = write(m_terminatePipeFileDescriptors[1], &c, 1); - // FIXME: Use result. + const int written = write(m_terminatePipeFileDescriptors[1], &c, 1); + Q_UNUSED(written) wait(); } @@ -882,6 +883,7 @@ struct TrkDevicePrivate QByteArray trkReadBuffer; int verbose; QString errorString; + QString port; }; /////////////////////////////////////////////////////////////////////// @@ -913,13 +915,19 @@ TrkDevice::~TrkDevice() delete d; } -bool TrkDevice::open(const QString &port, QString *errorMessage) +bool TrkDevice::open(QString *errorMessage) { if (d->verbose) - qDebug() << "Opening" << port << "is open: " << isOpen() << " serialFrame=" << serialFrame(); + qDebug() << "Opening" << port() << "is open: " << isOpen() << " serialFrame=" << serialFrame(); + if (d->port.isEmpty()) { + *errorMessage = QLatin1String("Internal error: No port set on TrkDevice"); + return false; + } + close(); #ifdef Q_OS_WIN - d->deviceContext->device = CreateFile(port.toStdWString().c_str(), + const QString fullPort = QLatin1String("\\\\.\\") + d->port; + d->deviceContext->device = CreateFile(reinterpret_cast<const WCHAR*>(fullPort.utf16()), GENERIC_READ | GENERIC_WRITE, 0, NULL, @@ -928,7 +936,7 @@ bool TrkDevice::open(const QString &port, QString *errorMessage) NULL); if (INVALID_HANDLE_VALUE == d->deviceContext->device) { - *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port, winErrorMessage(GetLastError())); + *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port(), winErrorMessage(GetLastError())); return false; } memset(&d->deviceContext->readOverlapped, 0, sizeof(OVERLAPPED)); @@ -940,9 +948,9 @@ bool TrkDevice::open(const QString &port, QString *errorMessage) return false; } #else - d->deviceContext->file.setFileName(port); + d->deviceContext->file.setFileName(d->port); if (!d->deviceContext->file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { - *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(port, d->deviceContext->file.errorString()); + *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(d->port, d->deviceContext->file.errorString()); return false; } @@ -981,7 +989,7 @@ bool TrkDevice::open(const QString &port, QString *errorMessage) d->writerThread->start(); if (d->verbose) - qDebug() << "Opened" << port; + qDebug() << "Opened" << d->port; return true; } @@ -1015,6 +1023,16 @@ bool TrkDevice::isOpen() const #endif } +QString TrkDevice::port() const +{ + return d->port; +} + +void TrkDevice::setPort(const QString &p) +{ + d->port = p; +} + QString TrkDevice::errorString() const { return d->errorString; @@ -1061,8 +1079,13 @@ void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, const QByteArray &data, const QVariant &cookie) { if (!d->writerThread.isNull()) { - if (d->verbose > 1) - qDebug() << "Sending " << code << data.toHex(); + if (d->verbose > 1) { + QByteArray msg = "Sending: "; + msg += QByteArray::number(code, 16); + msg += ": "; + msg += stringFromArray(data).toLatin1(); + qDebug("%s", msg.data()); + } d->writerThread->queueTrkMessage(code, callback, data, cookie); } } diff --git a/tools/runonphone/trk/trkdevice.h b/tools/runonphone/symbianutils/trkdevice.h index e04f791..78012fd 100644 --- a/tools/runonphone/trk/trkdevice.h +++ b/tools/runonphone/symbianutils/trkdevice.h @@ -42,6 +42,7 @@ #ifndef TRKDEVICE_H #define TRKDEVICE_H +#include "symbianutils_global.h" #include "callback.h" #include <QtCore/QObject> @@ -74,18 +75,22 @@ enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f }; typedef trk::Callback<const TrkResult &> TrkCallback; -class TrkDevice : public QObject +class SYMBIANUTILS_EXPORT TrkDevice : public QObject { Q_OBJECT Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) Q_PROPERTY(bool verbose READ verbose WRITE setVerbose) + Q_PROPERTY(QString port READ port WRITE setPort) public: explicit TrkDevice(QObject *parent = 0); virtual ~TrkDevice(); - bool open(const QString &port, QString *errorMessage); + bool open(QString *errorMessage); bool isOpen() const; + QString port() const; + void setPort(const QString &p); + QString errorString() const; bool serialFrame() const; diff --git a/tools/runonphone/trk/trkutils.cpp b/tools/runonphone/symbianutils/trkutils.cpp index 3a96053..9b43c96 100644 --- a/tools/runonphone/trk/trkutils.cpp +++ b/tools/runonphone/symbianutils/trkutils.cpp @@ -86,7 +86,7 @@ void Session::reset() trkAppVersion.reset(); } -QString formatCpu(int major, int minor) +static QString formatCpu(int major, int minor) { //: CPU description of an S60 device //: %1 major verison, %2 minor version @@ -143,14 +143,46 @@ QString Session::deviceDescription(unsigned verbose) const return msg.arg(formatTrkVersion(trkAppVersion)); } +// -------------- + +QByteArray decode7d(const QByteArray &ba) +{ + QByteArray res; + res.reserve(ba.size()); + for (int i = 0; i < ba.size(); ++i) { + byte c = byte(ba.at(i)); + if (c == 0x7d) { + ++i; + c = 0x20 ^ byte(ba.at(i)); + } + res.append(c); + } + return res; +} + +QByteArray encode7d(const QByteArray &ba) +{ + QByteArray res; + res.reserve(ba.size() + 2); + for (int i = 0; i < ba.size(); ++i) { + byte c = byte(ba.at(i)); + if (c == 0x7e || c == 0x7d) { + res.append(0x7d); + res.append(0x20 ^ c); + } else { + res.append(c); + } + } + return res; +} // FIXME: Use the QByteArray based version below? -QString stringFromByte(byte c) +static inline QString stringFromByte(byte c) { - return QString("%1 ").arg(c, 2, 16, QChar('0')); + return QString::fromLatin1("%1").arg(c, 2, 16, QChar('0')); } -QString stringFromArray(const QByteArray &ba, int maxLen) +SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen) { QString str; QString ascii; @@ -170,7 +202,7 @@ QString stringFromArray(const QByteArray &ba, int maxLen) return str + " " + ascii; } -QByteArray hexNumber(uint n, int digits) +SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits) { QByteArray ba = QByteArray::number(n, 16); if (digits == 0 || ba.size() == digits) @@ -178,7 +210,7 @@ QByteArray hexNumber(uint n, int digits) return QByteArray(digits - ba.size(), '0') + ba; } -QByteArray hexxNumber(uint n, int digits) +SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits) { return "0x" + hexNumber(n, digits); } @@ -200,9 +232,13 @@ void TrkResult::clear() QString TrkResult::toString() const { - QString res = stringFromByte(code) + "[" + stringFromByte(token); - res.chop(1); - return res + "] " + stringFromArray(data); + QString res = stringFromByte(code); + res += QLatin1String(" ["); + res += stringFromByte(token); + res += QLatin1Char(']'); + res += QLatin1Char(' '); + res += stringFromArray(data); + return res; } QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame) @@ -303,12 +339,12 @@ bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByt return true; } -ushort extractShort(const char *data) +SYMBIANUTILS_EXPORT ushort extractShort(const char *data) { return byte(data[0]) * 256 + byte(data[1]); } -uint extractInt(const char *data) +SYMBIANUTILS_EXPORT uint extractInt(const char *data) { uint res = byte(data[0]); res *= 256; res += byte(data[1]); @@ -317,7 +353,7 @@ uint extractInt(const char *data) return res; } -QString quoteUnprintableLatin1(const QByteArray &ba) +SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba) { QString res; char buf[10]; @@ -333,49 +369,7 @@ QString quoteUnprintableLatin1(const QByteArray &ba) return res; } -QByteArray decode7d(const QByteArray &ba) -{ - QByteArray res; - res.reserve(ba.size()); - for (int i = 0; i < ba.size(); ++i) { - byte c = byte(ba.at(i)); - if (c == 0x7d) { - ++i; - c = 0x20 ^ byte(ba.at(i)); - } - res.append(c); - } - //if (res != ba) - // logMessage("DECODED: " << stringFromArray(ba) - // << " -> " << stringFromArray(res)); - return res; -} - -QByteArray encode7d(const QByteArray &ba) -{ - QByteArray res; - res.reserve(ba.size() + 2); - for (int i = 0; i < ba.size(); ++i) { - byte c = byte(ba.at(i)); - if (c == 0x7e || c == 0x7d) { - res.append(0x7d); - res.append(0x20 ^ c); - } else { - res.append(c); - } - } - //if (res != ba) - // logMessage("ENCODED: " << stringFromArray(ba) - // << " -> " << stringFromArray(res)); - return res; -} - -void appendByte(QByteArray *ba, byte b) -{ - ba->append(b); -} - -void appendShort(QByteArray *ba, ushort s, Endianness endian) +SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness endian) { if (endian == BigEndian) { ba->append(s / 256); @@ -386,7 +380,7 @@ void appendShort(QByteArray *ba, ushort s, Endianness endian) } } -void appendInt(QByteArray *ba, uint i, Endianness endian) +SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness endian) { const uchar b3 = i % 256; i /= 256; const uchar b2 = i % 256; i /= 256; diff --git a/tools/runonphone/trk/trkutils.h b/tools/runonphone/symbianutils/trkutils.h index 328dd2b..3a485c7 100644 --- a/tools/runonphone/trk/trkutils.h +++ b/tools/runonphone/symbianutils/trkutils.h @@ -42,19 +42,20 @@ #ifndef DEBUGGER_TRK_UTILS #define DEBUGGER_TRK_UTILS +#include "symbianutils_global.h" #include <QtCore/QByteArray> #include <QtCore/QHash> #include <QtCore/QStringList> #include <QtCore/QVariant> -typedef unsigned char byte; - QT_BEGIN_NAMESPACE class QDateTime; QT_END_NAMESPACE namespace trk { +typedef unsigned char byte; + enum Command { TrkPing = 0x00, TrkConnect = 0x01, @@ -85,17 +86,14 @@ enum Command { TrkNotifyProcessorReset = 0xa7 }; -QByteArray decode7d(const QByteArray &ba); -QByteArray encode7d(const QByteArray &ba); - inline byte extractByte(const char *data) { return *data; } -ushort extractShort(const char *data); -uint extractInt(const char *data); +SYMBIANUTILS_EXPORT ushort extractShort(const char *data); +SYMBIANUTILS_EXPORT uint extractInt(const char *data); -QString quoteUnprintableLatin1(const QByteArray &ba); +SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba); // produces "xx xx xx " -QString stringFromArray(const QByteArray &ba, int maxLen = - 1); +SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen = - 1); enum Endianness { @@ -104,13 +102,11 @@ enum Endianness TargetByteOrder = BigEndian, }; -void appendByte(QByteArray *ba, byte b); -void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); -void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); -void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true); -void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder); +SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); +SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); +SYMBIANUTILS_EXPORT void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true); -struct Library +struct SYMBIANUTILS_EXPORT Library { Library() {} @@ -119,7 +115,7 @@ struct Library uint dataseg; }; -struct TrkAppVersion +struct SYMBIANUTILS_EXPORT TrkAppVersion { TrkAppVersion(); void reset(); @@ -130,7 +126,7 @@ struct TrkAppVersion int protocolMinor; }; -struct Session +struct SYMBIANUTILS_EXPORT Session { Session(); void reset(); @@ -163,7 +159,7 @@ struct Session QStringList modules; }; -struct TrkResult +struct SYMBIANUTILS_EXPORT TrkResult { TrkResult(); void clear(); @@ -179,15 +175,10 @@ struct TrkResult bool isDebugOutput; }; -// returns a QByteArray containing optionally -// the serial frame [0x01 0x90 <len>] and 0x7e encoded7d(ba) 0x7e -QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); -ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame); -bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0); -QByteArray errorMessage(byte code); -QByteArray hexNumber(uint n, int digits = 0); -QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too -uint swapEndian(uint in); +SYMBIANUTILS_EXPORT QByteArray errorMessage(byte code); +SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits = 0); +SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too +SYMBIANUTILS_EXPORT uint swapEndian(uint in); } // namespace trk diff --git a/tools/runonphone/symbianutils/trkutils_p.h b/tools/runonphone/symbianutils/trkutils_p.h new file mode 100644 index 0000000..12b0109 --- /dev/null +++ b/tools/runonphone/symbianutils/trkutils_p.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DEBUGGER_TRK_PRIVATE_UTILS +#define DEBUGGER_TRK_PRIVATE_UTILS + +#include "trkutils.h" +#include "symbianutils_global.h" + +QT_BEGIN_NAMESPACE +class QDateTime; +QT_END_NAMESPACE + +namespace trk { + +void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder); +// returns a QByteArray containing optionally +// the serial frame [0x01 0x90 <len>] and 0x7e encoded7d(ba) 0x7e +QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); +bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0); + +} // namespace trk + +#endif // DEBUGGER_TRK_PRIVATE_UTILS diff --git a/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp b/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp index b84de11..0b14292 100644 --- a/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp +++ b/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp @@ -93,15 +93,23 @@ QtCursorDatabase::QtCursorDatabase() QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-busy.png"))); } +void QtCursorDatabase::clear() +{ + m_cursorNames.clear(); + m_cursorIcons.clear(); + m_valueToCursorShape.clear(); + m_cursorShapeToValue.clear(); +} + void QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon) { if (m_cursorShapeToValue.contains(shape)) return; - int value = m_cursorNames.count(); + const int value = m_cursorNames.count(); m_cursorNames.append(name); - m_cursorIcons[value] = icon; - m_valueToCursorShape[value] = shape; - m_cursorShapeToValue[shape] = value; + m_cursorIcons.insert(value, icon); + m_valueToCursorShape.insert(value, shape); + m_cursorShapeToValue.insert(shape, value); } QStringList QtCursorDatabase::cursorShapeNames() const diff --git a/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h b/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h index b60fb94..baa7a4a 100644 --- a/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h +++ b/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h @@ -68,6 +68,7 @@ class QtCursorDatabase { public: QtCursorDatabase(); + void clear(); QStringList cursorShapeNames() const; QMap<int, QIcon> cursorShapeIcons() const; diff --git a/tools/shared/qtpropertybrowser/qtpropertymanager.cpp b/tools/shared/qtpropertybrowser/qtpropertymanager.cpp index 67ab2fb..d9ff10a 100644 --- a/tools/shared/qtpropertybrowser/qtpropertymanager.cpp +++ b/tools/shared/qtpropertybrowser/qtpropertymanager.cpp @@ -1391,16 +1391,54 @@ void QtStringPropertyManager::uninitializeProperty(QtProperty *property) } // QtBoolPropertyManager +// Return an icon containing a check box indicator +static QIcon drawCheckBox(bool value) +{ + QStyleOptionButton opt; + opt.state |= value ? QStyle::State_On : QStyle::State_Off; + opt.state |= QStyle::State_Enabled; + const QStyle *style = QApplication::style(); + // Figure out size of an indicator and make sure it is not scaled down in a list view item + // by making the pixmap as big as a list view icon and centering the indicator in it. + // (if it is smaller, it can't be helped) + const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt); + const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt); + const int listViewIconSize = indicatorWidth; + const int pixmapWidth = indicatorWidth; + const int pixmapHeight = qMax(indicatorHeight, listViewIconSize); + + opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight); + QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight); + pixmap.fill(Qt::transparent); + { + // Center? + const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0; + const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0; + QPainter painter(&pixmap); + painter.translate(xoff, yoff); + style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter); + } + return QIcon(pixmap); +} class QtBoolPropertyManagerPrivate { QtBoolPropertyManager *q_ptr; Q_DECLARE_PUBLIC(QtBoolPropertyManager) public: + QtBoolPropertyManagerPrivate(); QMap<const QtProperty *, bool> m_values; + const QIcon m_checkedIcon; + const QIcon m_uncheckedIcon; }; +QtBoolPropertyManagerPrivate::QtBoolPropertyManagerPrivate() : + m_checkedIcon(drawCheckBox(true)), + m_uncheckedIcon(drawCheckBox(false)) +{ +} + /*! \class QtBoolPropertyManager \internal @@ -1471,36 +1509,6 @@ QString QtBoolPropertyManager::valueText(const QtProperty *property) const return it.value() ? trueText : falseText; } -// Return an icon containing a check box indicator -static QIcon drawCheckBox(bool value) -{ - QStyleOptionButton opt; - opt.state |= value ? QStyle::State_On : QStyle::State_Off; - opt.state |= QStyle::State_Enabled; - const QStyle *style = QApplication::style(); - // Figure out size of an indicator and make sure it is not scaled down in a list view item - // by making the pixmap as big as a list view icon and centering the indicator in it. - // (if it is smaller, it can't be helped) - const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt); - const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt); - const int listViewIconSize = indicatorWidth; - const int pixmapWidth = indicatorWidth; - const int pixmapHeight = qMax(indicatorHeight, listViewIconSize); - - opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight); - QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight); - pixmap.fill(Qt::transparent); - { - // Center? - const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0; - const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0; - QPainter painter(&pixmap); - painter.translate(xoff, yoff); - style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter); - } - return QIcon(pixmap); -} - /*! \reimp */ @@ -1510,9 +1518,7 @@ QIcon QtBoolPropertyManager::valueIcon(const QtProperty *property) const if (it == d_ptr->m_values.constEnd()) return QIcon(); - static const QIcon checkedIcon = drawCheckBox(true); - static const QIcon uncheckedIcon = drawCheckBox(false); - return it.value() ? checkedIcon : uncheckedIcon; + return it.value() ? d_ptr->m_checkedIcon : d_ptr->m_uncheckedIcon; } /*! @@ -6287,7 +6293,15 @@ void QtColorPropertyManager::uninitializeProperty(QtProperty *property) // QtCursorPropertyManager -Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase) +// Make sure icons are removed as soon as QApplication is destroyed, otherwise, +// handles are leaked on X11. +static void clearCursorDatabase(); +Q_GLOBAL_STATIC_WITH_INITIALIZER(QtCursorDatabase, cursorDatabase, qAddPostRoutine(clearCursorDatabase)) + +static void clearCursorDatabase() +{ + cursorDatabase()->clear(); +} class QtCursorPropertyManagerPrivate { diff --git a/translations/qt_de.ts b/translations/qt_de.ts index 8cbf402..6447451 100644 --- a/translations/qt_de.ts +++ b/translations/qt_de.ts @@ -7572,7 +7572,7 @@ Bitte wählen Sie einen anderen Dateinamen.</translation> <location line="+2"/> <source>Play movie in full-screen mode</source> <comment>Media controller element</comment> - <translation>FIlm im Vollbildmodus abspielen</translation> + <translation>Film im Vollbildmodus abspielen</translation> </message> <message> <location line="+2"/> @@ -8245,7 +8245,7 @@ Bitte wählen Sie einen anderen Dateinamen.</translation> <message> <location filename="../src/xmlpatterns/api/qcoloringmessagehandler.cpp" line="+87"/> <source>Warning in %1, at line %2, column %3: %4</source> - <translation>Fehler in %1, bei Zeile %2, Spalte %3: %4</translation> + <translation>Warnung in %1, bei Zeile %2, Spalte %3: %4</translation> </message> <message> <location line="+7"/> @@ -9466,7 +9466,7 @@ Bitte wählen Sie einen anderen Dateinamen.</translation> <location line="-470"/> <location line="+451"/> <source>%1 is not allowed to derive from %2 by list as the latter defines it as final.</source> - <translation>%1 darf nicht durch Listen von %2 abgeleitet werden, da sie letzterer sie als final deklariert.</translation> + <translation>%1 darf nicht durch Listen von %2 abgeleitet werden, da letzterer sie als final deklariert.</translation> </message> <message> <location line="-431"/> @@ -9917,7 +9917,7 @@ Bitte wählen Sie einen anderen Dateinamen.</translation> <message> <location line="+6"/> <source>Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model.</source> - <translation>Der komplexe Typ % kann nicht durch Erweiterung von %2 abgeleitet werden, da letzterer ein '%3'-Element in seinem Inhaltsmodell hat.</translation> + <translation>Der komplexe Typ %1 kann nicht durch Erweiterung von %2 abgeleitet werden, da letzterer ein '%3'-Element in seinem Inhaltsmodell hat.</translation> </message> <message> <location line="+101"/> diff --git a/util/qlalr/cppgenerator.cpp b/util/qlalr/cppgenerator.cpp index a95f5e4..f52a86f 100644 --- a/util/qlalr/cppgenerator.cpp +++ b/util/qlalr/cppgenerator.cpp @@ -457,7 +457,7 @@ void CppGenerator::generateDecl (QTextStream &out) out << "class " << grammar.table_name << endl << "{" << endl << "public:" << endl - << " enum {" << endl; + << " enum VariousConstants {" << endl; foreach (Name t, grammar.terminals) { |