From cffcdbc7c606ea5cdbf9cffe4be39b4e6c56526f Mon Sep 17 00:00:00 2001 From: Patrick Franz Date: Sun, 29 Jan 2023 00:34:49 +0100 Subject: [PATCH] Import qt6-positioning_6.4.2.orig.tar.xz [dgit import orig qt6-positioning_6.4.2.orig.tar.xz] --- .QT-ENTERPRISE-LICENSE-AGREEMENT | 1977 ++++++ .cmake.conf | 4 + .qmake.conf | 6 + .tag | 1 + CMakeLists.txt | 21 + LICENSES/BSD-3-Clause.txt | 9 + LICENSES/CC0-1.0.txt | 121 + LICENSES/GFDL-1.3-no-invariants-only.txt | 451 ++ LICENSES/GPL-2.0-only.txt | 339 ++ LICENSES/GPL-3.0-only.txt | 674 +++ LICENSES/LGPL-3.0-only.txt | 165 + LICENSES/LicenseRef-Qt-Commercial.txt | 8 + LICENSES/Qt-GPL-exception-1.0.txt | 22 + cmake/FindGconf.cmake | 14 + cmake/FindGypsy.cmake | 14 + coin/module_config.yaml | 12 + conanfile.py | 53 + config.tests/gypsy/CMakeLists.txt | 30 + config.tests/gypsy/main.cpp | 19 + config.tests/winrt/CMakeLists.txt | 36 + config.tests/winrt/main.cpp | 22 + configure.json | 5 + dependencies.yaml | 10 + dist/changes-5.10.0 | 62 + dist/changes-5.10.1 | 26 + dist/changes-5.11.0 | 116 + dist/changes-5.11.1 | 40 + dist/changes-5.11.2 | 38 + dist/changes-5.11.3 | 32 + dist/changes-5.12.0 | 52 + dist/changes-5.12.1 | 56 + dist/changes-5.12.2 | 33 + dist/changes-5.12.3 | 33 + dist/changes-5.12.4 | 20 + dist/changes-5.12.5 | 20 + dist/changes-5.13.0 | 46 + dist/changes-5.13.1 | 20 + dist/changes-5.13.2 | 20 + dist/changes-5.14.0 | 47 + dist/changes-5.14.1 | 20 + dist/changes-5.14.2 | 20 + dist/changes-5.15.0 | 51 + dist/changes-5.15.1 | 20 + dist/changes-5.15.2 | 48 + dist/changes-5.2.1 | 53 + dist/changes-5.3.0 | 74 + dist/changes-5.3.1 | 57 + dist/changes-5.3.2 | 50 + dist/changes-5.4.0 | 54 + dist/changes-5.4.1 | 29 + dist/changes-5.4.2 | 28 + dist/changes-5.5.0 | 40 + dist/changes-5.5.1 | 54 + dist/changes-5.6.0 | 69 + dist/changes-5.6.1 | 38 + dist/changes-5.6.2 | 55 + dist/changes-5.6.3 | 38 + dist/changes-5.7.0 | 53 + dist/changes-5.7.1 | 45 + dist/changes-5.8.0 | 70 + dist/changes-5.9.0 | 131 + dist/changes-5.9.1 | 43 + dist/changes-5.9.2 | 56 + dist/changes-5.9.3 | 41 + dist/changes-5.9.4 | 31 + examples/CMakeLists.txt | 7 + examples/examples.pro | 5 + examples/positioning/CMakeLists.txt | 12 + examples/positioning/geoflickr/CMakeLists.txt | 73 + .../geoflickr/doc/images/qml-flickr-1.jpg | Bin 0 -> 66794 bytes .../geoflickr/doc/src/geoflickr.qdoc | 64 + examples/positioning/geoflickr/flickr-90.qml | 14 + examples/positioning/geoflickr/flickr.qml | 100 + examples/positioning/geoflickr/flickr.qrc | 30 + .../geoflickr/flickrcommon/Progress.qml | 35 + .../geoflickr/flickrcommon/RestModel.qml | 27 + .../geoflickr/flickrcommon/ScrollBar.qml | 43 + .../geoflickr/flickrcommon/Slider.qml | 39 + .../geoflickr/flickrmobile/Button.qml | 41 + .../geoflickr/flickrmobile/GeoTab.qml | 135 + .../geoflickr/flickrmobile/GridDelegate.qml | 77 + .../geoflickr/flickrmobile/ImageDetails.qml | 119 + .../geoflickr/flickrmobile/ListDelegate.qml | 29 + .../geoflickr/flickrmobile/TitleBar.qml | 40 + .../geoflickr/flickrmobile/ToolBar.qml | 27 + .../geoflickr/flickrmobile/images/gloss.png | Bin 0 -> 889 bytes .../flickrmobile/images/lineedit.png | Bin 0 -> 1307 bytes .../flickrmobile/images/lineedit.sci | 5 + .../geoflickr/flickrmobile/images/moon.png | Bin 0 -> 2366 bytes .../geoflickr/flickrmobile/images/quit.png | Bin 0 -> 1785 bytes .../geoflickr/flickrmobile/images/star.png | Bin 0 -> 259 bytes .../geoflickr/flickrmobile/images/stripes.png | Bin 0 -> 159 bytes .../geoflickr/flickrmobile/images/sun.png | Bin 0 -> 8110 bytes .../flickrmobile/images/titlebar.png | Bin 0 -> 1327 bytes .../flickrmobile/images/titlebar.sci | 5 + .../flickrmobile/images/toolbutton.png | Bin 0 -> 2550 bytes .../flickrmobile/images/toolbutton.sci | 5 + .../geoflickr/flickrmobile/nmealog.txt | 1403 +++++ examples/positioning/geoflickr/geoflickr.pro | 15 + .../geoflickr/geoflickr.qmlproject | 16 + .../geoflickr/qmllocationflickr.cpp | 21 + .../logfilepositionsource/CMakeLists.txt | 47 + .../clientapplication.cpp | 25 + .../logfilepositionsource/clientapplication.h | 27 + .../doc/src/logfilepositionsource.qdoc | 70 + .../logfilepositionsource/logfile.qrc | 5 + .../logfilepositionsource.cpp | 89 + .../logfilepositionsource.h | 41 + .../logfilepositionsource.pro | 16 + .../logfilepositionsource/main.cpp | 15 + .../logfilepositionsource/simplelog.txt | 156 + examples/positioning/positioning.pro | 9 + .../positioning/satelliteinfo/CMakeLists.txt | 42 + .../doc/images/example-satelliteinfo.png | Bin 0 -> 27371 bytes .../satelliteinfo/doc/src/satelliteinfo.qdoc | 110 + examples/positioning/satelliteinfo/main.cpp | 24 + .../satelliteinfo/satelliteinfo.pro | 26 + .../satelliteinfo/satelliteinfo.qml | 269 + .../satelliteinfo/satelliteinfo.qrc | 5 + .../satelliteinfo/satellitemodel.cpp | 277 + .../satelliteinfo/satellitemodel.h | 93 + .../positioning/weatherinfo/CMakeLists.txt | 71 + examples/positioning/weatherinfo/appmodel.cpp | 467 ++ examples/positioning/weatherinfo/appmodel.h | 143 + .../components/BigForecastIcon.qml | 45 + .../weatherinfo/components/ForecastIcon.qml | 52 + .../weatherinfo/components/WeatherIcon.qml | 17 + .../doc/images/example-weatherinfo.png | Bin 0 -> 70264 bytes .../weatherinfo/doc/src/weatherinfo.qdoc | 140 + .../positioning/weatherinfo/icons/README.txt | 5 + .../weatherinfo/icons/qt_attribution.json | 28 + .../weatherinfo/icons/weather-few-clouds.png | Bin 0 -> 79488 bytes .../weatherinfo/icons/weather-fog.png | Bin 0 -> 43896 bytes .../weatherinfo/icons/weather-haze.png | Bin 0 -> 130030 bytes .../weatherinfo/icons/weather-icy.png | Bin 0 -> 49362 bytes .../weatherinfo/icons/weather-overcast.png | Bin 0 -> 60290 bytes .../icons/weather-showers-scattered.png | Bin 0 -> 76000 bytes .../weatherinfo/icons/weather-showers.png | Bin 0 -> 76340 bytes .../weatherinfo/icons/weather-sleet.png | Bin 0 -> 87168 bytes .../weatherinfo/icons/weather-snow.png | Bin 0 -> 70939 bytes .../weatherinfo/icons/weather-storm.png | Bin 0 -> 93207 bytes .../icons/weather-sunny-very-few-clouds.png | Bin 0 -> 65731 bytes .../weatherinfo/icons/weather-sunny.png | Bin 0 -> 59084 bytes .../icons/weather-thundershower.png | Bin 0 -> 105643 bytes .../positioning/weatherinfo/ios/Info.plist | 39 + examples/positioning/weatherinfo/main.cpp | 27 + .../weatherinfo/openweathermapbackend.cpp | 218 + .../weatherinfo/openweathermapbackend.h | 38 + .../weatherinfo/providerbackend.cpp | 6 + .../positioning/weatherinfo/providerbackend.h | 43 + .../weatherinfo/weatherapibackend.cpp | 219 + .../weatherinfo/weatherapibackend.h | 33 + .../positioning/weatherinfo/weatherinfo.pro | 34 + .../positioning/weatherinfo/weatherinfo.qml | 161 + .../positioning/weatherinfo/weatherinfo.qrc | 21 + .../QtPositioning/private/qclipperutils_p.h | 1 + .../private/qdoublematrix4x4_p.h | 1 + .../QtPositioning/private/qdoublevector2d_p.h | 1 + .../QtPositioning/private/qdoublevector3d_p.h | 1 + .../QtPositioning/private/qgeoaddress_p.h | 1 + .../QtPositioning/private/qgeocircle_p.h | 1 + .../QtPositioning/private/qgeocoordinate_p.h | 1 + .../private/qgeocoordinateobject_p.h | 1 + .../QtPositioning/private/qgeolocation_p.h | 1 + .../6.4.2/QtPositioning/private/qgeopath_p.h | 1 + .../QtPositioning/private/qgeopolygon_p.h | 1 + .../private/qgeopositioninfo_p.h | 1 + .../private/qgeopositioninfosource_p.h | 1 + .../QtPositioning/private/qgeorectangle_p.h | 1 + .../private/qgeosatelliteinfo_p.h | 1 + .../private/qgeosatelliteinfosource_p.h | 1 + .../6.4.2/QtPositioning/private/qgeoshape_p.h | 1 + .../QtPositioning/private/qlocationutils_p.h | 1 + .../private/qnmeapositioninfosource_p.h | 1 + .../private/qnmeasatelliteinfosource_p.h | 1 + .../private/qpositioningglobal_p.h | 1 + .../QtPositioning/private/qwebmercator_p.h | 1 + include/QtPositioning/QGeoAddress | 1 + include/QtPositioning/QGeoAreaMonitorInfo | 1 + include/QtPositioning/QGeoAreaMonitorSource | 1 + include/QtPositioning/QGeoCircle | 1 + include/QtPositioning/QGeoCoordinate | 1 + include/QtPositioning/QGeoLocation | 1 + include/QtPositioning/QGeoPath | 1 + include/QtPositioning/QGeoPolygon | 1 + include/QtPositioning/QGeoPositionInfo | 1 + include/QtPositioning/QGeoPositionInfoSource | 1 + .../QGeoPositionInfoSourceFactory | 1 + include/QtPositioning/QGeoRectangle | 1 + include/QtPositioning/QGeoSatelliteInfo | 1 + include/QtPositioning/QGeoSatelliteInfoSource | 1 + include/QtPositioning/QGeoShape | 1 + include/QtPositioning/QNmeaPositionInfoSource | 1 + .../QtPositioning/QNmeaSatelliteInfoSource | 1 + include/QtPositioning/QtPositioning | 23 + include/QtPositioning/QtPositioningVersion | 1 + include/QtPositioning/headers.pri | 6 + include/QtPositioning/qgeoaddress.h | 1 + include/QtPositioning/qgeoareamonitorinfo.h | 1 + include/QtPositioning/qgeoareamonitorsource.h | 1 + include/QtPositioning/qgeocircle.h | 1 + include/QtPositioning/qgeocoordinate.h | 1 + include/QtPositioning/qgeolocation.h | 1 + include/QtPositioning/qgeopath.h | 1 + include/QtPositioning/qgeopolygon.h | 1 + include/QtPositioning/qgeopositioninfo.h | 1 + .../QtPositioning/qgeopositioninfosource.h | 1 + .../qgeopositioninfosourcefactory.h | 1 + include/QtPositioning/qgeorectangle.h | 1 + include/QtPositioning/qgeosatelliteinfo.h | 1 + .../QtPositioning/qgeosatelliteinfosource.h | 1 + include/QtPositioning/qgeoshape.h | 1 + .../QtPositioning/qnmeapositioninfosource.h | 1 + .../QtPositioning/qnmeasatelliteinfosource.h | 1 + include/QtPositioning/qpositioningglobal.h | 1 + include/QtPositioning/qtpositioningversion.h | 9 + .../private/locationsingleton_p.h | 1 + .../private/qdeclarativegeoaddress_p.h | 1 + .../private/qdeclarativegeolocation_p.h | 1 + .../private/qdeclarativepluginparameter_p.h | 1 + .../private/qdeclarativeposition_p.h | 1 + .../private/qdeclarativepositionsource_p.h | 1 + .../private/qpositioningquickglobal_p.h | 1 + .../private/qpositioningquickmodule_p.h | 1 + .../private/qquickgeocoordinateanimation_p.h | 1 + .../qquickgeocoordinateanimation_p_p.h | 1 + include/QtPositioningQuick/QtPositioningQuick | 6 + .../QtPositioningQuickVersion | 1 + include/QtPositioningQuick/headers.pri | 6 + .../qpositioningquickglobal.h | 1 + .../qtpositioningquickversion.h | 9 + src/3rdparty/clip2tri/CMakeLists.txt | 31 + src/3rdparty/clip2tri/LICENSE | 21 + src/3rdparty/clip2tri/clip2tri.cpp | 406 ++ src/3rdparty/clip2tri/clip2tri.h | 102 + src/3rdparty/clip2tri/qt_attribution.json | 13 + src/3rdparty/clipper/CMakeLists.txt | 25 + src/3rdparty/clipper/LICENSE | 48 + src/3rdparty/clipper/clipper.cpp | 4629 +++++++++++++++ src/3rdparty/clipper/clipper.h | 404 ++ src/3rdparty/clipper/qt_attribution.json | 13 + src/3rdparty/poly2tri/AUTHORS | 8 + src/3rdparty/poly2tri/CMakeLists.txt | 30 + src/3rdparty/poly2tri/LICENSE | 27 + src/3rdparty/poly2tri/common/shapes.cpp | 363 ++ src/3rdparty/poly2tri/common/shapes.h | 325 + src/3rdparty/poly2tri/common/utils.h | 127 + src/3rdparty/poly2tri/poly2tri.h | 39 + src/3rdparty/poly2tri/qt_attribution.json | 13 + .../poly2tri/sweep/advancing_front.cpp | 109 + src/3rdparty/poly2tri/sweep/advancing_front.h | 118 + src/3rdparty/poly2tri/sweep/cdt.cpp | 72 + src/3rdparty/poly2tri/sweep/cdt.h | 105 + src/3rdparty/poly2tri/sweep/sweep.cpp | 814 +++ src/3rdparty/poly2tri/sweep/sweep.h | 285 + src/3rdparty/poly2tri/sweep/sweep_context.cpp | 216 + src/3rdparty/poly2tri/sweep/sweep_context.h | 186 + src/CMakeLists.txt | 10 + src/plugins/CMakeLists.txt | 5 + src/plugins/position/CMakeLists.txt | 21 + src/plugins/position/android/CMakeLists.txt | 4 + .../position/android/jar/AndroidManifest.xml | 6 + .../position/android/jar/CMakeLists.txt | 17 + .../qt/android/positioning/QtPositioning.java | 622 ++ .../position/android/src/CMakeLists.txt | 23 + .../position/android/src/jnipositioning.cpp | 716 +++ .../position/android/src/jnipositioning.h | 28 + src/plugins/position/android/src/plugin.json | 9 + .../android/src/positionfactory_android.cpp | 27 + .../android/src/positionfactory_android.h | 22 + .../src/qgeopositioninfosource_android.cpp | 259 + .../src/qgeopositioninfosource_android_p.h | 66 + .../src/qgeosatelliteinfosource_android.cpp | 186 + .../src/qgeosatelliteinfosource_android_p.h | 62 + .../position/corelocation/CMakeLists.txt | 36 + src/plugins/position/corelocation/plugin.json | 9 + .../corelocation/qgeopositioninfosource_cl.mm | 294 + .../qgeopositioninfosource_cl_p.h | 71 + .../qgeopositioninfosourcefactory_cl.h | 22 + .../qgeopositioninfosourcefactory_cl.mm | 25 + src/plugins/position/geoclue2/CMakeLists.txt | 31 + .../position/geoclue2/geocluetypes.cpp | 28 + src/plugins/position/geoclue2/geocluetypes.h | 27 + .../org.freedesktop.GeoClue2.Client.xml | 122 + .../org.freedesktop.GeoClue2.Location.xml | 96 + .../org.freedesktop.GeoClue2.Manager.xml | 60 + src/plugins/position/geoclue2/plugin.json | 9 + .../qgeopositioninfosource_geoclue2.cpp | 430 ++ .../qgeopositioninfosource_geoclue2_p.h | 64 + ...qgeopositioninfosourcefactory_geoclue2.cpp | 35 + .../qgeopositioninfosourcefactory_geoclue2.h | 32 + src/plugins/position/gypsy/CMakeLists.txt | 24 + src/plugins/position/gypsy/plugin.json | 9 + .../qgeopositioninfosourcefactory_gypsy.cpp | 30 + .../qgeopositioninfosourcefactory_gypsy.h | 23 + .../gypsy/qgeosatelliteinfosource_gypsy.cpp | 406 ++ .../gypsy/qgeosatelliteinfosource_gypsy_p.h | 107 + src/plugins/position/nmea/CMakeLists.txt | 22 + src/plugins/position/nmea/plugin.json | 9 + .../qgeopositioninfosourcefactory_nmea.cpp | 472 ++ .../nmea/qgeopositioninfosourcefactory_nmea.h | 27 + src/plugins/position/nmea/qiopipe.cpp | 164 + src/plugins/position/nmea/qiopipe_p.h | 78 + .../position/positionpoll/CMakeLists.txt | 20 + src/plugins/position/positionpoll/plugin.json | 9 + .../positionpoll/positionpollfactory.cpp | 35 + .../positionpoll/positionpollfactory.h | 26 + .../positionpoll/qgeoareamonitor_polling.cpp | 474 ++ .../positionpoll/qgeoareamonitor_polling.h | 64 + src/plugins/position/winrt/CMakeLists.txt | 29 + src/plugins/position/winrt/plugin.json | 9 + .../winrt/qgeopositioninfosource_winrt.cpp | 642 ++ .../winrt/qgeopositioninfosource_winrt_p.h | 91 + .../qgeopositioninfosourcefactory_winrt.cpp | 37 + .../qgeopositioninfosourcefactory_winrt.h | 26 + src/positioning/CMakeLists.txt | 68 + src/positioning/configure.cmake | 28 + src/positioning/configure.json | 48 + src/positioning/doc/images/permissions.png | Bin 0 -> 19306 bytes src/positioning/doc/qtpositioning.qdocconf | 53 + src/positioning/doc/snippets/CMakeLists.txt | 1 + .../doc/snippets/cpp/CMakeLists.txt | 20 + src/positioning/doc/snippets/cpp/cppqml.cpp | 71 + src/positioning/doc/snippets/cpp/main.cpp | 8 + .../doc/snippets/doc_src_qtpositioning.qml | 10 + src/positioning/doc/src/cpp-position.qdoc | 170 + .../doc/src/cpp-qml-positioning.qdoc | 90 + .../doc/src/external-resources.qdoc | 47 + src/positioning/doc/src/plugins/geoclue2.qdoc | 62 + src/positioning/doc/src/plugins/gypsy.qdoc | 91 + src/positioning/doc/src/plugins/nmea.qdoc | 177 + src/positioning/doc/src/qml-position.qdoc | 88 + src/positioning/doc/src/qt6-changes.qdoc | 209 + .../doc/src/qtpositioning-android.qdoc | 58 + .../doc/src/qtpositioning-examples.qdoc | 14 + .../doc/src/qtpositioning-ios.qdoc | 53 + .../doc/src/qtpositioning-plugins.qdoc | 90 + .../doc/src/qtpositioning-qml.qdoc | 47 + src/positioning/doc/src/qtpositioning.qdoc | 119 + src/positioning/qclipperutils.cpp | 120 + src/positioning/qclipperutils_p.h | 85 + src/positioning/qdoublematrix4x4.cpp | 1076 ++++ src/positioning/qdoublematrix4x4_p.h | 910 +++ src/positioning/qdoublevector2d.cpp | 85 + src/positioning/qdoublevector2d_p.h | 226 + src/positioning/qdoublevector3d.cpp | 108 + src/positioning/qdoublevector3d_p.h | 266 + src/positioning/qgeoaddress.cpp | 742 +++ src/positioning/qgeoaddress.h | 87 + src/positioning/qgeoaddress_p.h | 50 + src/positioning/qgeoareamonitorinfo.cpp | 406 ++ src/positioning/qgeoareamonitorinfo.h | 103 + src/positioning/qgeoareamonitorsource.cpp | 398 ++ src/positioning/qgeoareamonitorsource.h | 75 + src/positioning/qgeocircle.cpp | 445 ++ src/positioning/qgeocircle.h | 54 + src/positioning/qgeocircle_p.h | 60 + src/positioning/qgeocoordinate.cpp | 759 +++ src/positioning/qgeocoordinate.h | 125 + src/positioning/qgeocoordinate_p.h | 60 + src/positioning/qgeocoordinateobject.cpp | 60 + src/positioning/qgeocoordinateobject_p.h | 63 + src/positioning/qgeolocation.cpp | 248 + src/positioning/qgeolocation.h | 65 + src/positioning/qgeolocation_p.h | 47 + src/positioning/qgeopath.cpp | 742 +++ src/positioning/qgeopath.h | 65 + src/positioning/qgeopath_p.h | 224 + src/positioning/qgeopolygon.cpp | 686 +++ src/positioning/qgeopolygon.h | 64 + src/positioning/qgeopolygon_p.h | 101 + src/positioning/qgeopositioninfo.cpp | 418 ++ src/positioning/qgeopositioninfo.h | 122 + src/positioning/qgeopositioninfo_p.h | 42 + src/positioning/qgeopositioninfosource.cpp | 605 ++ src/positioning/qgeopositioninfosource.h | 93 + src/positioning/qgeopositioninfosource_p.h | 60 + .../qgeopositioninfosourcefactory.cpp | 54 + .../qgeopositioninfosourcefactory.h | 30 + src/positioning/qgeorectangle.cpp | 935 +++ src/positioning/qgeorectangle.h | 87 + src/positioning/qgeorectangle_p.h | 53 + src/positioning/qgeosatelliteinfo.cpp | 401 ++ src/positioning/qgeosatelliteinfo.h | 118 + src/positioning/qgeosatelliteinfo_p.h | 41 + src/positioning/qgeosatelliteinfosource.cpp | 390 ++ src/positioning/qgeosatelliteinfosource.h | 73 + src/positioning/qgeosatelliteinfosource_p.h | 37 + src/positioning/qgeoshape.cpp | 415 ++ src/positioning/qgeoshape.h | 97 + src/positioning/qgeoshape_p.h | 58 + src/positioning/qlocationutils.cpp | 602 ++ src/positioning/qlocationutils_p.h | 314 + src/positioning/qnmeapositioninfosource.cpp | 931 +++ src/positioning/qnmeapositioninfosource.h | 61 + src/positioning/qnmeapositioninfosource_p.h | 153 + src/positioning/qnmeasatelliteinfosource.cpp | 876 +++ src/positioning/qnmeasatelliteinfosource.h | 68 + src/positioning/qnmeasatelliteinfosource_p.h | 146 + src/positioning/qpositioningglobal.h | 10 + src/positioning/qpositioningglobal_p.h | 21 + src/positioning/qwebmercator.cpp | 100 + src/positioning/qwebmercator_p.h | 39 + src/positioningquick/CMakeLists.txt | 50 + src/positioningquick/locationsingleton.cpp | 359 ++ src/positioningquick/locationsingleton_p.h | 78 + src/positioningquick/positioningplugin.cpp | 525 ++ .../qdeclarativegeoaddress.cpp | 346 ++ .../qdeclarativegeoaddress_p.h | 93 + .../qdeclarativegeolocation.cpp | 212 + .../qdeclarativegeolocation_p.h | 78 + .../qdeclarativepluginparameter.cpp | 114 + .../qdeclarativepluginparameter_p.h | 63 + src/positioningquick/qdeclarativeposition.cpp | 645 ++ src/positioningquick/qdeclarativeposition_p.h | 184 + .../qdeclarativepositionsource.cpp | 872 +++ .../qdeclarativepositionsource_p.h | 186 + .../qpositioningquickglobal.h | 20 + .../qpositioningquickglobal_p.h | 26 + .../qpositioningquickmodule.cpp | 4 + .../qpositioningquickmodule_p.h | 115 + .../qquickgeocoordinateanimation.cpp | 263 + .../qquickgeocoordinateanimation_p.h | 68 + .../qquickgeocoordinateanimation_p_p.h | 46 + sync.profile | 6 + tests/CMakeLists.txt | 7 + .../positioning_backend/CMakeLists.txt | 28 + .../positioning_backend/logwidget.cpp | 21 + .../positioning_backend/logwidget.h | 22 + .../applications/positioning_backend/main.cpp | 29 + .../positioning_backend/widget.cpp | 163 + .../applications/positioning_backend/widget.h | 45 + .../positioning_backend/widget.ui | 334 ++ tests/auto/CMakeLists.txt | 35 + .../QtPositioning.5.10.0.linux-gcc-amd64.txt | 4773 +++++++++++++++ .../QtPositioning.5.11.0.linux-gcc-amd64.txt | 4773 +++++++++++++++ .../QtPositioning.5.12.0.linux-gcc-amd64.txt | 4838 +++++++++++++++ .../QtPositioning.5.13.0.linux-gcc-amd64.txt | 5208 ++++++++++++++++ .../QtPositioning.5.14.0.linux-gcc-amd64.txt | 5268 ++++++++++++++++ .../QtPositioning.5.15.0.linux-gcc-amd64.txt | 5278 +++++++++++++++++ .../QtPositioning.5.3.0.linux-gcc-amd64.txt | 3822 ++++++++++++ .../QtPositioning.5.4.0.linux-gcc-amd64.txt | 3854 ++++++++++++ .../QtPositioning.5.6.0.linux-gcc-amd64.txt | 4118 +++++++++++++ .../QtPositioning.5.7.0.linux-gcc-amd64.txt | 4400 ++++++++++++++ .../QtPositioning.5.8.0.linux-gcc-amd64.txt | 4425 ++++++++++++++ .../QtPositioning.5.9.0.linux-gcc-amd64.txt | 4446 ++++++++++++++ tests/auto/cmake/CMakeLists.txt | 44 + .../declarative_geolocation/CMakeLists.txt | 16 + tests/auto/declarative_geolocation/main.cpp | 23 + .../tst_declarativegeolocation.qml | 136 + .../declarative_positioning_core/BLACKLIST | 6 + .../CMakeLists.txt | 44 + .../declarative_positioning_core/factory.cpp | 25 + .../declarative_positioning_core/factory.h | 30 + .../declarative_positioning_core/main.cpp | 24 + .../tst_address.qml | 70 + .../tst_coordinate.qml | 379 ++ .../tst_geoshape.qml | 275 + .../tst_position.qml | 27 + .../tst_positionsource.qml | 420 ++ tests/auto/doublevectors/CMakeLists.txt | 16 + .../auto/doublevectors/tst_doublevectors.cpp | 268 + tests/auto/dummypositionplugin/CMakeLists.txt | 21 + tests/auto/dummypositionplugin/plugin.cpp | 130 + tests/auto/dummypositionplugin/plugin.json | 9 + tests/auto/positionplugin/CMakeLists.txt | 21 + tests/auto/positionplugin/plugin.cpp | 223 + tests/auto/positionplugin/plugin.json | 9 + tests/auto/positionplugintest/CMakeLists.txt | 23 + .../positionplugintest/tst_positionplugin.cpp | 84 + .../qdeclarativegeolocation/CMakeLists.txt | 9 + .../tst_qdeclarativegeolocation.cpp | 156 + .../auto/qdeclarativeposition/CMakeLists.txt | 8 + .../tst_qdeclarativeposition.cpp | 219 + .../auto/qdeclarativepositionsource/BLACKLIST | 49 + .../qdeclarativepositionsource/CMakeLists.txt | 18 + .../tst_qdeclarativepositionsource.cpp | 509 ++ tests/auto/qgeoaddress/CMakeLists.txt | 16 + tests/auto/qgeoaddress/tst_qgeoaddress.cpp | 622 ++ tests/auto/qgeoareamonitor/CMakeLists.txt | 33 + .../qgeoareamonitor/logfilepositionsource.cpp | 107 + .../qgeoareamonitor/logfilepositionsource.h | 56 + .../positionconsumerthread.cpp | 48 + .../qgeoareamonitor/positionconsumerthread.h | 49 + tests/auto/qgeoareamonitor/simplelog.txt | 87 + .../qgeoareamonitor/tst_qgeoareamonitor.cpp | 952 +++ tests/auto/qgeocircle/CMakeLists.txt | 16 + tests/auto/qgeocircle/tst_qgeocircle.cpp | 448 ++ tests/auto/qgeocoordinate/CMakeLists.txt | 14 + .../qgeocoordinate/tst_qgeocoordinate.cpp | 975 +++ .../auto/qgeocoordinateobject/CMakeLists.txt | 8 + .../tst_qgeocoordinateobject.cpp | 74 + tests/auto/qgeolocation/CMakeLists.txt | 14 + tests/auto/qgeolocation/tst_qgeolocation.cpp | 387 ++ tests/auto/qgeolocation/tst_qgeolocation.h | 65 + tests/auto/qgeopath/CMakeLists.txt | 16 + tests/auto/qgeopath/tst_qgeopath.cpp | 367 ++ tests/auto/qgeopolygon/CMakeLists.txt | 16 + tests/auto/qgeopolygon/tst_qgeopolygon.cpp | 384 ++ tests/auto/qgeopositioninfo/CMakeLists.txt | 16 + .../qgeopositioninfo/tst_qgeopositioninfo.cpp | 395 ++ .../qgeopositioninfosource/CMakeLists.txt | 27 + .../testqgeopositioninfosource.cpp | 782 +++ .../testqgeopositioninfosource_p.h | 104 + .../tst_qgeopositioninfosource.cpp | 12 + tests/auto/qgeorectangle/CMakeLists.txt | 16 + .../auto/qgeorectangle/tst_qgeorectangle.cpp | 2394 ++++++++ tests/auto/qgeosatelliteinfo/CMakeLists.txt | 16 + .../tst_qgeosatelliteinfo.cpp | 413 ++ .../qgeosatelliteinfosource/CMakeLists.txt | 22 + .../testqgeosatelliteinfosource.cpp | 741 +++ .../testqgeosatelliteinfosource_p.h | 92 + .../tst_qgeosatelliteinfosource.cpp | 12 + tests/auto/qgeoshape/CMakeLists.txt | 14 + tests/auto/qgeoshape/tst_qgeoshape.cpp | 218 + .../qnmeapositioninfosource/CMakeLists.txt | 7 + .../dummy/CMakeLists.txt | 23 + .../dummy/tst_dummynmeapositioninfosource.cpp | 124 + .../realtime/CMakeLists.txt | 26 + .../tst_qnmeapositioninfosource_realtime.cpp | 19 + .../realtime_generic/CMakeLists.txt | 37 + ...meapositioninfosource_realtime_generic.cpp | 52 + .../simulation/CMakeLists.txt | 26 + ...tst_qnmeapositioninfosource_simulation.cpp | 18 + .../simulation_generic/CMakeLists.txt | 41 + ...apositioninfosource_simulation_generic.cpp | 39 + .../tst_qnmeapositioninfosource.cpp | 591 ++ .../tst_qnmeapositioninfosource.h | 157 + .../qnmeasatelliteinfosource/CMakeLists.txt | 4 + .../dummy/CMakeLists.txt | 16 + .../tst_dummynmeasatelliteinfosource.cpp | 146 + .../generic_realtime/CMakeLists.txt | 18 + ...tst_nmeasatelliteinfosource_generic_rt.cpp | 68 + .../generic_simulation/CMakeLists.txt | 18 + ...st_nmeasatelliteinfosource_generic_sim.cpp | 70 + .../nmea/CMakeLists.txt | 14 + .../nmea/tst_nmeasatelliteinfosource.cpp | 531 ++ .../CMakeLists.txt | 9 + .../tst_qquickgeocoordinateanimation.cpp | 28 + tests/auto/utils/qlocationtestutils.cpp | 89 + tests/auto/utils/qlocationtestutils_p.h | 150 + tests/auto/utils/qnmeaproxyfactory.cpp | 105 + tests/auto/utils/qnmeaproxyfactory.h | 71 + tests/benchmarks/CMakeLists.txt | 7 + tests/benchmarks/README | 81 + .../qgeoareamonitorinfo/CMakeLists.txt | 12 + .../tst_bench_qgeoareamonitorinfo.cpp | 230 + .../qgeopositioninfo/CMakeLists.txt | 12 + .../tst_bench_qgeopositioninfo.cpp | 228 + .../qgeosatelliteinfo/CMakeLists.txt | 12 + .../tst_bench_qgeosatelliteinfo.cpp | 223 + tests/global/global.cfg | 5 + 552 files changed, 120990 insertions(+) create mode 100644 .QT-ENTERPRISE-LICENSE-AGREEMENT create mode 100644 .cmake.conf create mode 100644 .qmake.conf create mode 100644 .tag create mode 100644 CMakeLists.txt create mode 100644 LICENSES/BSD-3-Clause.txt create mode 100644 LICENSES/CC0-1.0.txt create mode 100644 LICENSES/GFDL-1.3-no-invariants-only.txt create mode 100644 LICENSES/GPL-2.0-only.txt create mode 100644 LICENSES/GPL-3.0-only.txt create mode 100644 LICENSES/LGPL-3.0-only.txt create mode 100644 LICENSES/LicenseRef-Qt-Commercial.txt create mode 100644 LICENSES/Qt-GPL-exception-1.0.txt create mode 100644 cmake/FindGconf.cmake create mode 100644 cmake/FindGypsy.cmake create mode 100644 coin/module_config.yaml create mode 100644 conanfile.py create mode 100644 config.tests/gypsy/CMakeLists.txt create mode 100644 config.tests/gypsy/main.cpp create mode 100644 config.tests/winrt/CMakeLists.txt create mode 100644 config.tests/winrt/main.cpp create mode 100644 configure.json create mode 100644 dependencies.yaml create mode 100644 dist/changes-5.10.0 create mode 100644 dist/changes-5.10.1 create mode 100644 dist/changes-5.11.0 create mode 100644 dist/changes-5.11.1 create mode 100644 dist/changes-5.11.2 create mode 100644 dist/changes-5.11.3 create mode 100644 dist/changes-5.12.0 create mode 100644 dist/changes-5.12.1 create mode 100644 dist/changes-5.12.2 create mode 100644 dist/changes-5.12.3 create mode 100644 dist/changes-5.12.4 create mode 100644 dist/changes-5.12.5 create mode 100644 dist/changes-5.13.0 create mode 100644 dist/changes-5.13.1 create mode 100644 dist/changes-5.13.2 create mode 100644 dist/changes-5.14.0 create mode 100644 dist/changes-5.14.1 create mode 100644 dist/changes-5.14.2 create mode 100644 dist/changes-5.15.0 create mode 100644 dist/changes-5.15.1 create mode 100644 dist/changes-5.15.2 create mode 100644 dist/changes-5.2.1 create mode 100644 dist/changes-5.3.0 create mode 100644 dist/changes-5.3.1 create mode 100644 dist/changes-5.3.2 create mode 100644 dist/changes-5.4.0 create mode 100644 dist/changes-5.4.1 create mode 100644 dist/changes-5.4.2 create mode 100644 dist/changes-5.5.0 create mode 100644 dist/changes-5.5.1 create mode 100644 dist/changes-5.6.0 create mode 100644 dist/changes-5.6.1 create mode 100644 dist/changes-5.6.2 create mode 100644 dist/changes-5.6.3 create mode 100644 dist/changes-5.7.0 create mode 100644 dist/changes-5.7.1 create mode 100644 dist/changes-5.8.0 create mode 100644 dist/changes-5.9.0 create mode 100644 dist/changes-5.9.1 create mode 100644 dist/changes-5.9.2 create mode 100644 dist/changes-5.9.3 create mode 100644 dist/changes-5.9.4 create mode 100644 examples/CMakeLists.txt create mode 100644 examples/examples.pro create mode 100644 examples/positioning/CMakeLists.txt create mode 100644 examples/positioning/geoflickr/CMakeLists.txt create mode 100644 examples/positioning/geoflickr/doc/images/qml-flickr-1.jpg create mode 100644 examples/positioning/geoflickr/doc/src/geoflickr.qdoc create mode 100644 examples/positioning/geoflickr/flickr-90.qml create mode 100644 examples/positioning/geoflickr/flickr.qml create mode 100644 examples/positioning/geoflickr/flickr.qrc create mode 100644 examples/positioning/geoflickr/flickrcommon/Progress.qml create mode 100644 examples/positioning/geoflickr/flickrcommon/RestModel.qml create mode 100644 examples/positioning/geoflickr/flickrcommon/ScrollBar.qml create mode 100644 examples/positioning/geoflickr/flickrcommon/Slider.qml create mode 100644 examples/positioning/geoflickr/flickrmobile/Button.qml create mode 100644 examples/positioning/geoflickr/flickrmobile/GeoTab.qml create mode 100644 examples/positioning/geoflickr/flickrmobile/GridDelegate.qml create mode 100644 examples/positioning/geoflickr/flickrmobile/ImageDetails.qml create mode 100644 examples/positioning/geoflickr/flickrmobile/ListDelegate.qml create mode 100644 examples/positioning/geoflickr/flickrmobile/TitleBar.qml create mode 100644 examples/positioning/geoflickr/flickrmobile/ToolBar.qml create mode 100644 examples/positioning/geoflickr/flickrmobile/images/gloss.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/lineedit.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/lineedit.sci create mode 100644 examples/positioning/geoflickr/flickrmobile/images/moon.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/quit.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/star.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/stripes.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/sun.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/titlebar.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/titlebar.sci create mode 100644 examples/positioning/geoflickr/flickrmobile/images/toolbutton.png create mode 100644 examples/positioning/geoflickr/flickrmobile/images/toolbutton.sci create mode 100644 examples/positioning/geoflickr/flickrmobile/nmealog.txt create mode 100644 examples/positioning/geoflickr/geoflickr.pro create mode 100644 examples/positioning/geoflickr/geoflickr.qmlproject create mode 100644 examples/positioning/geoflickr/qmllocationflickr.cpp create mode 100644 examples/positioning/logfilepositionsource/CMakeLists.txt create mode 100644 examples/positioning/logfilepositionsource/clientapplication.cpp create mode 100644 examples/positioning/logfilepositionsource/clientapplication.h create mode 100644 examples/positioning/logfilepositionsource/doc/src/logfilepositionsource.qdoc create mode 100644 examples/positioning/logfilepositionsource/logfile.qrc create mode 100644 examples/positioning/logfilepositionsource/logfilepositionsource.cpp create mode 100644 examples/positioning/logfilepositionsource/logfilepositionsource.h create mode 100644 examples/positioning/logfilepositionsource/logfilepositionsource.pro create mode 100644 examples/positioning/logfilepositionsource/main.cpp create mode 100644 examples/positioning/logfilepositionsource/simplelog.txt create mode 100644 examples/positioning/positioning.pro create mode 100644 examples/positioning/satelliteinfo/CMakeLists.txt create mode 100644 examples/positioning/satelliteinfo/doc/images/example-satelliteinfo.png create mode 100644 examples/positioning/satelliteinfo/doc/src/satelliteinfo.qdoc create mode 100644 examples/positioning/satelliteinfo/main.cpp create mode 100644 examples/positioning/satelliteinfo/satelliteinfo.pro create mode 100644 examples/positioning/satelliteinfo/satelliteinfo.qml create mode 100644 examples/positioning/satelliteinfo/satelliteinfo.qrc create mode 100644 examples/positioning/satelliteinfo/satellitemodel.cpp create mode 100644 examples/positioning/satelliteinfo/satellitemodel.h create mode 100644 examples/positioning/weatherinfo/CMakeLists.txt create mode 100644 examples/positioning/weatherinfo/appmodel.cpp create mode 100644 examples/positioning/weatherinfo/appmodel.h create mode 100644 examples/positioning/weatherinfo/components/BigForecastIcon.qml create mode 100644 examples/positioning/weatherinfo/components/ForecastIcon.qml create mode 100644 examples/positioning/weatherinfo/components/WeatherIcon.qml create mode 100644 examples/positioning/weatherinfo/doc/images/example-weatherinfo.png create mode 100644 examples/positioning/weatherinfo/doc/src/weatherinfo.qdoc create mode 100644 examples/positioning/weatherinfo/icons/README.txt create mode 100644 examples/positioning/weatherinfo/icons/qt_attribution.json create mode 100644 examples/positioning/weatherinfo/icons/weather-few-clouds.png create mode 100644 examples/positioning/weatherinfo/icons/weather-fog.png create mode 100644 examples/positioning/weatherinfo/icons/weather-haze.png create mode 100644 examples/positioning/weatherinfo/icons/weather-icy.png create mode 100644 examples/positioning/weatherinfo/icons/weather-overcast.png create mode 100644 examples/positioning/weatherinfo/icons/weather-showers-scattered.png create mode 100644 examples/positioning/weatherinfo/icons/weather-showers.png create mode 100644 examples/positioning/weatherinfo/icons/weather-sleet.png create mode 100644 examples/positioning/weatherinfo/icons/weather-snow.png create mode 100644 examples/positioning/weatherinfo/icons/weather-storm.png create mode 100644 examples/positioning/weatherinfo/icons/weather-sunny-very-few-clouds.png create mode 100644 examples/positioning/weatherinfo/icons/weather-sunny.png create mode 100644 examples/positioning/weatherinfo/icons/weather-thundershower.png create mode 100644 examples/positioning/weatherinfo/ios/Info.plist create mode 100644 examples/positioning/weatherinfo/main.cpp create mode 100644 examples/positioning/weatherinfo/openweathermapbackend.cpp create mode 100644 examples/positioning/weatherinfo/openweathermapbackend.h create mode 100644 examples/positioning/weatherinfo/providerbackend.cpp create mode 100644 examples/positioning/weatherinfo/providerbackend.h create mode 100644 examples/positioning/weatherinfo/weatherapibackend.cpp create mode 100644 examples/positioning/weatherinfo/weatherapibackend.h create mode 100644 examples/positioning/weatherinfo/weatherinfo.pro create mode 100644 examples/positioning/weatherinfo/weatherinfo.qml create mode 100644 examples/positioning/weatherinfo/weatherinfo.qrc create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qclipperutils_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qdoublematrix4x4_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qdoublevector2d_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qdoublevector3d_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeoaddress_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeocircle_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeocoordinate_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeocoordinateobject_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeolocation_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeopath_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeopolygon_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeopositioninfo_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeopositioninfosource_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeorectangle_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeosatelliteinfo_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeosatelliteinfosource_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qgeoshape_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qlocationutils_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qnmeapositioninfosource_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qnmeasatelliteinfosource_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qpositioningglobal_p.h create mode 100644 include/QtPositioning/6.4.2/QtPositioning/private/qwebmercator_p.h create mode 100644 include/QtPositioning/QGeoAddress create mode 100644 include/QtPositioning/QGeoAreaMonitorInfo create mode 100644 include/QtPositioning/QGeoAreaMonitorSource create mode 100644 include/QtPositioning/QGeoCircle create mode 100644 include/QtPositioning/QGeoCoordinate create mode 100644 include/QtPositioning/QGeoLocation create mode 100644 include/QtPositioning/QGeoPath create mode 100644 include/QtPositioning/QGeoPolygon create mode 100644 include/QtPositioning/QGeoPositionInfo create mode 100644 include/QtPositioning/QGeoPositionInfoSource create mode 100644 include/QtPositioning/QGeoPositionInfoSourceFactory create mode 100644 include/QtPositioning/QGeoRectangle create mode 100644 include/QtPositioning/QGeoSatelliteInfo create mode 100644 include/QtPositioning/QGeoSatelliteInfoSource create mode 100644 include/QtPositioning/QGeoShape create mode 100644 include/QtPositioning/QNmeaPositionInfoSource create mode 100644 include/QtPositioning/QNmeaSatelliteInfoSource create mode 100644 include/QtPositioning/QtPositioning create mode 100644 include/QtPositioning/QtPositioningVersion create mode 100644 include/QtPositioning/headers.pri create mode 100644 include/QtPositioning/qgeoaddress.h create mode 100644 include/QtPositioning/qgeoareamonitorinfo.h create mode 100644 include/QtPositioning/qgeoareamonitorsource.h create mode 100644 include/QtPositioning/qgeocircle.h create mode 100644 include/QtPositioning/qgeocoordinate.h create mode 100644 include/QtPositioning/qgeolocation.h create mode 100644 include/QtPositioning/qgeopath.h create mode 100644 include/QtPositioning/qgeopolygon.h create mode 100644 include/QtPositioning/qgeopositioninfo.h create mode 100644 include/QtPositioning/qgeopositioninfosource.h create mode 100644 include/QtPositioning/qgeopositioninfosourcefactory.h create mode 100644 include/QtPositioning/qgeorectangle.h create mode 100644 include/QtPositioning/qgeosatelliteinfo.h create mode 100644 include/QtPositioning/qgeosatelliteinfosource.h create mode 100644 include/QtPositioning/qgeoshape.h create mode 100644 include/QtPositioning/qnmeapositioninfosource.h create mode 100644 include/QtPositioning/qnmeasatelliteinfosource.h create mode 100644 include/QtPositioning/qpositioningglobal.h create mode 100644 include/QtPositioning/qtpositioningversion.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/locationsingleton_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativegeoaddress_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativegeolocation_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativepluginparameter_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativeposition_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativepositionsource_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qpositioningquickglobal_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qpositioningquickmodule_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qquickgeocoordinateanimation_p.h create mode 100644 include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qquickgeocoordinateanimation_p_p.h create mode 100644 include/QtPositioningQuick/QtPositioningQuick create mode 100644 include/QtPositioningQuick/QtPositioningQuickVersion create mode 100644 include/QtPositioningQuick/headers.pri create mode 100644 include/QtPositioningQuick/qpositioningquickglobal.h create mode 100644 include/QtPositioningQuick/qtpositioningquickversion.h create mode 100644 src/3rdparty/clip2tri/CMakeLists.txt create mode 100644 src/3rdparty/clip2tri/LICENSE create mode 100644 src/3rdparty/clip2tri/clip2tri.cpp create mode 100644 src/3rdparty/clip2tri/clip2tri.h create mode 100644 src/3rdparty/clip2tri/qt_attribution.json create mode 100644 src/3rdparty/clipper/CMakeLists.txt create mode 100644 src/3rdparty/clipper/LICENSE create mode 100644 src/3rdparty/clipper/clipper.cpp create mode 100644 src/3rdparty/clipper/clipper.h create mode 100644 src/3rdparty/clipper/qt_attribution.json create mode 100644 src/3rdparty/poly2tri/AUTHORS create mode 100644 src/3rdparty/poly2tri/CMakeLists.txt create mode 100644 src/3rdparty/poly2tri/LICENSE create mode 100644 src/3rdparty/poly2tri/common/shapes.cpp create mode 100644 src/3rdparty/poly2tri/common/shapes.h create mode 100644 src/3rdparty/poly2tri/common/utils.h create mode 100644 src/3rdparty/poly2tri/poly2tri.h create mode 100644 src/3rdparty/poly2tri/qt_attribution.json create mode 100644 src/3rdparty/poly2tri/sweep/advancing_front.cpp create mode 100644 src/3rdparty/poly2tri/sweep/advancing_front.h create mode 100644 src/3rdparty/poly2tri/sweep/cdt.cpp create mode 100644 src/3rdparty/poly2tri/sweep/cdt.h create mode 100644 src/3rdparty/poly2tri/sweep/sweep.cpp create mode 100644 src/3rdparty/poly2tri/sweep/sweep.h create mode 100644 src/3rdparty/poly2tri/sweep/sweep_context.cpp create mode 100644 src/3rdparty/poly2tri/sweep/sweep_context.h create mode 100644 src/CMakeLists.txt create mode 100644 src/plugins/CMakeLists.txt create mode 100644 src/plugins/position/CMakeLists.txt create mode 100644 src/plugins/position/android/CMakeLists.txt create mode 100644 src/plugins/position/android/jar/AndroidManifest.xml create mode 100644 src/plugins/position/android/jar/CMakeLists.txt create mode 100644 src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java create mode 100644 src/plugins/position/android/src/CMakeLists.txt create mode 100644 src/plugins/position/android/src/jnipositioning.cpp create mode 100644 src/plugins/position/android/src/jnipositioning.h create mode 100644 src/plugins/position/android/src/plugin.json create mode 100644 src/plugins/position/android/src/positionfactory_android.cpp create mode 100644 src/plugins/position/android/src/positionfactory_android.h create mode 100644 src/plugins/position/android/src/qgeopositioninfosource_android.cpp create mode 100644 src/plugins/position/android/src/qgeopositioninfosource_android_p.h create mode 100644 src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp create mode 100644 src/plugins/position/android/src/qgeosatelliteinfosource_android_p.h create mode 100644 src/plugins/position/corelocation/CMakeLists.txt create mode 100644 src/plugins/position/corelocation/plugin.json create mode 100644 src/plugins/position/corelocation/qgeopositioninfosource_cl.mm create mode 100644 src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h create mode 100644 src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.h create mode 100644 src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm create mode 100644 src/plugins/position/geoclue2/CMakeLists.txt create mode 100644 src/plugins/position/geoclue2/geocluetypes.cpp create mode 100644 src/plugins/position/geoclue2/geocluetypes.h create mode 100644 src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Client.xml create mode 100644 src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Location.xml create mode 100644 src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Manager.xml create mode 100644 src/plugins/position/geoclue2/plugin.json create mode 100644 src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp create mode 100644 src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2_p.h create mode 100644 src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.cpp create mode 100644 src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.h create mode 100644 src/plugins/position/gypsy/CMakeLists.txt create mode 100644 src/plugins/position/gypsy/plugin.json create mode 100644 src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp create mode 100644 src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h create mode 100644 src/plugins/position/gypsy/qgeosatelliteinfosource_gypsy.cpp create mode 100644 src/plugins/position/gypsy/qgeosatelliteinfosource_gypsy_p.h create mode 100644 src/plugins/position/nmea/CMakeLists.txt create mode 100644 src/plugins/position/nmea/plugin.json create mode 100644 src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp create mode 100644 src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.h create mode 100644 src/plugins/position/nmea/qiopipe.cpp create mode 100644 src/plugins/position/nmea/qiopipe_p.h create mode 100644 src/plugins/position/positionpoll/CMakeLists.txt create mode 100644 src/plugins/position/positionpoll/plugin.json create mode 100644 src/plugins/position/positionpoll/positionpollfactory.cpp create mode 100644 src/plugins/position/positionpoll/positionpollfactory.h create mode 100644 src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp create mode 100644 src/plugins/position/positionpoll/qgeoareamonitor_polling.h create mode 100644 src/plugins/position/winrt/CMakeLists.txt create mode 100644 src/plugins/position/winrt/plugin.json create mode 100644 src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp create mode 100644 src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h create mode 100644 src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp create mode 100644 src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h create mode 100644 src/positioning/CMakeLists.txt create mode 100644 src/positioning/configure.cmake create mode 100644 src/positioning/configure.json create mode 100644 src/positioning/doc/images/permissions.png create mode 100644 src/positioning/doc/qtpositioning.qdocconf create mode 100644 src/positioning/doc/snippets/CMakeLists.txt create mode 100644 src/positioning/doc/snippets/cpp/CMakeLists.txt create mode 100644 src/positioning/doc/snippets/cpp/cppqml.cpp create mode 100644 src/positioning/doc/snippets/cpp/main.cpp create mode 100644 src/positioning/doc/snippets/doc_src_qtpositioning.qml create mode 100644 src/positioning/doc/src/cpp-position.qdoc create mode 100644 src/positioning/doc/src/cpp-qml-positioning.qdoc create mode 100644 src/positioning/doc/src/external-resources.qdoc create mode 100644 src/positioning/doc/src/plugins/geoclue2.qdoc create mode 100644 src/positioning/doc/src/plugins/gypsy.qdoc create mode 100644 src/positioning/doc/src/plugins/nmea.qdoc create mode 100644 src/positioning/doc/src/qml-position.qdoc create mode 100644 src/positioning/doc/src/qt6-changes.qdoc create mode 100644 src/positioning/doc/src/qtpositioning-android.qdoc create mode 100644 src/positioning/doc/src/qtpositioning-examples.qdoc create mode 100644 src/positioning/doc/src/qtpositioning-ios.qdoc create mode 100644 src/positioning/doc/src/qtpositioning-plugins.qdoc create mode 100644 src/positioning/doc/src/qtpositioning-qml.qdoc create mode 100644 src/positioning/doc/src/qtpositioning.qdoc create mode 100644 src/positioning/qclipperutils.cpp create mode 100644 src/positioning/qclipperutils_p.h create mode 100644 src/positioning/qdoublematrix4x4.cpp create mode 100644 src/positioning/qdoublematrix4x4_p.h create mode 100644 src/positioning/qdoublevector2d.cpp create mode 100644 src/positioning/qdoublevector2d_p.h create mode 100644 src/positioning/qdoublevector3d.cpp create mode 100644 src/positioning/qdoublevector3d_p.h create mode 100644 src/positioning/qgeoaddress.cpp create mode 100644 src/positioning/qgeoaddress.h create mode 100644 src/positioning/qgeoaddress_p.h create mode 100644 src/positioning/qgeoareamonitorinfo.cpp create mode 100644 src/positioning/qgeoareamonitorinfo.h create mode 100644 src/positioning/qgeoareamonitorsource.cpp create mode 100644 src/positioning/qgeoareamonitorsource.h create mode 100644 src/positioning/qgeocircle.cpp create mode 100644 src/positioning/qgeocircle.h create mode 100644 src/positioning/qgeocircle_p.h create mode 100644 src/positioning/qgeocoordinate.cpp create mode 100644 src/positioning/qgeocoordinate.h create mode 100644 src/positioning/qgeocoordinate_p.h create mode 100644 src/positioning/qgeocoordinateobject.cpp create mode 100644 src/positioning/qgeocoordinateobject_p.h create mode 100644 src/positioning/qgeolocation.cpp create mode 100644 src/positioning/qgeolocation.h create mode 100644 src/positioning/qgeolocation_p.h create mode 100644 src/positioning/qgeopath.cpp create mode 100644 src/positioning/qgeopath.h create mode 100644 src/positioning/qgeopath_p.h create mode 100644 src/positioning/qgeopolygon.cpp create mode 100644 src/positioning/qgeopolygon.h create mode 100644 src/positioning/qgeopolygon_p.h create mode 100644 src/positioning/qgeopositioninfo.cpp create mode 100644 src/positioning/qgeopositioninfo.h create mode 100644 src/positioning/qgeopositioninfo_p.h create mode 100644 src/positioning/qgeopositioninfosource.cpp create mode 100644 src/positioning/qgeopositioninfosource.h create mode 100644 src/positioning/qgeopositioninfosource_p.h create mode 100644 src/positioning/qgeopositioninfosourcefactory.cpp create mode 100644 src/positioning/qgeopositioninfosourcefactory.h create mode 100644 src/positioning/qgeorectangle.cpp create mode 100644 src/positioning/qgeorectangle.h create mode 100644 src/positioning/qgeorectangle_p.h create mode 100644 src/positioning/qgeosatelliteinfo.cpp create mode 100644 src/positioning/qgeosatelliteinfo.h create mode 100644 src/positioning/qgeosatelliteinfo_p.h create mode 100644 src/positioning/qgeosatelliteinfosource.cpp create mode 100644 src/positioning/qgeosatelliteinfosource.h create mode 100644 src/positioning/qgeosatelliteinfosource_p.h create mode 100644 src/positioning/qgeoshape.cpp create mode 100644 src/positioning/qgeoshape.h create mode 100644 src/positioning/qgeoshape_p.h create mode 100644 src/positioning/qlocationutils.cpp create mode 100644 src/positioning/qlocationutils_p.h create mode 100644 src/positioning/qnmeapositioninfosource.cpp create mode 100644 src/positioning/qnmeapositioninfosource.h create mode 100644 src/positioning/qnmeapositioninfosource_p.h create mode 100644 src/positioning/qnmeasatelliteinfosource.cpp create mode 100644 src/positioning/qnmeasatelliteinfosource.h create mode 100644 src/positioning/qnmeasatelliteinfosource_p.h create mode 100644 src/positioning/qpositioningglobal.h create mode 100644 src/positioning/qpositioningglobal_p.h create mode 100644 src/positioning/qwebmercator.cpp create mode 100644 src/positioning/qwebmercator_p.h create mode 100644 src/positioningquick/CMakeLists.txt create mode 100644 src/positioningquick/locationsingleton.cpp create mode 100644 src/positioningquick/locationsingleton_p.h create mode 100644 src/positioningquick/positioningplugin.cpp create mode 100644 src/positioningquick/qdeclarativegeoaddress.cpp create mode 100644 src/positioningquick/qdeclarativegeoaddress_p.h create mode 100644 src/positioningquick/qdeclarativegeolocation.cpp create mode 100644 src/positioningquick/qdeclarativegeolocation_p.h create mode 100644 src/positioningquick/qdeclarativepluginparameter.cpp create mode 100644 src/positioningquick/qdeclarativepluginparameter_p.h create mode 100644 src/positioningquick/qdeclarativeposition.cpp create mode 100644 src/positioningquick/qdeclarativeposition_p.h create mode 100644 src/positioningquick/qdeclarativepositionsource.cpp create mode 100644 src/positioningquick/qdeclarativepositionsource_p.h create mode 100644 src/positioningquick/qpositioningquickglobal.h create mode 100644 src/positioningquick/qpositioningquickglobal_p.h create mode 100644 src/positioningquick/qpositioningquickmodule.cpp create mode 100644 src/positioningquick/qpositioningquickmodule_p.h create mode 100644 src/positioningquick/qquickgeocoordinateanimation.cpp create mode 100644 src/positioningquick/qquickgeocoordinateanimation_p.h create mode 100644 src/positioningquick/qquickgeocoordinateanimation_p_p.h create mode 100644 sync.profile create mode 100644 tests/CMakeLists.txt create mode 100644 tests/applications/positioning_backend/CMakeLists.txt create mode 100644 tests/applications/positioning_backend/logwidget.cpp create mode 100644 tests/applications/positioning_backend/logwidget.h create mode 100644 tests/applications/positioning_backend/main.cpp create mode 100644 tests/applications/positioning_backend/widget.cpp create mode 100644 tests/applications/positioning_backend/widget.h create mode 100644 tests/applications/positioning_backend/widget.ui create mode 100644 tests/auto/CMakeLists.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.10.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.11.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.13.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.14.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.15.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.3.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.4.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.6.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.7.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.8.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPositioning.5.9.0.linux-gcc-amd64.txt create mode 100644 tests/auto/cmake/CMakeLists.txt create mode 100644 tests/auto/declarative_geolocation/CMakeLists.txt create mode 100644 tests/auto/declarative_geolocation/main.cpp create mode 100644 tests/auto/declarative_geolocation/tst_declarativegeolocation.qml create mode 100644 tests/auto/declarative_positioning_core/BLACKLIST create mode 100644 tests/auto/declarative_positioning_core/CMakeLists.txt create mode 100644 tests/auto/declarative_positioning_core/factory.cpp create mode 100644 tests/auto/declarative_positioning_core/factory.h create mode 100644 tests/auto/declarative_positioning_core/main.cpp create mode 100644 tests/auto/declarative_positioning_core/tst_address.qml create mode 100644 tests/auto/declarative_positioning_core/tst_coordinate.qml create mode 100644 tests/auto/declarative_positioning_core/tst_geoshape.qml create mode 100644 tests/auto/declarative_positioning_core/tst_position.qml create mode 100644 tests/auto/declarative_positioning_core/tst_positionsource.qml create mode 100644 tests/auto/doublevectors/CMakeLists.txt create mode 100644 tests/auto/doublevectors/tst_doublevectors.cpp create mode 100644 tests/auto/dummypositionplugin/CMakeLists.txt create mode 100644 tests/auto/dummypositionplugin/plugin.cpp create mode 100644 tests/auto/dummypositionplugin/plugin.json create mode 100644 tests/auto/positionplugin/CMakeLists.txt create mode 100644 tests/auto/positionplugin/plugin.cpp create mode 100644 tests/auto/positionplugin/plugin.json create mode 100644 tests/auto/positionplugintest/CMakeLists.txt create mode 100644 tests/auto/positionplugintest/tst_positionplugin.cpp create mode 100644 tests/auto/qdeclarativegeolocation/CMakeLists.txt create mode 100644 tests/auto/qdeclarativegeolocation/tst_qdeclarativegeolocation.cpp create mode 100644 tests/auto/qdeclarativeposition/CMakeLists.txt create mode 100644 tests/auto/qdeclarativeposition/tst_qdeclarativeposition.cpp create mode 100644 tests/auto/qdeclarativepositionsource/BLACKLIST create mode 100644 tests/auto/qdeclarativepositionsource/CMakeLists.txt create mode 100644 tests/auto/qdeclarativepositionsource/tst_qdeclarativepositionsource.cpp create mode 100644 tests/auto/qgeoaddress/CMakeLists.txt create mode 100644 tests/auto/qgeoaddress/tst_qgeoaddress.cpp create mode 100644 tests/auto/qgeoareamonitor/CMakeLists.txt create mode 100644 tests/auto/qgeoareamonitor/logfilepositionsource.cpp create mode 100644 tests/auto/qgeoareamonitor/logfilepositionsource.h create mode 100644 tests/auto/qgeoareamonitor/positionconsumerthread.cpp create mode 100644 tests/auto/qgeoareamonitor/positionconsumerthread.h create mode 100644 tests/auto/qgeoareamonitor/simplelog.txt create mode 100644 tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp create mode 100644 tests/auto/qgeocircle/CMakeLists.txt create mode 100644 tests/auto/qgeocircle/tst_qgeocircle.cpp create mode 100644 tests/auto/qgeocoordinate/CMakeLists.txt create mode 100644 tests/auto/qgeocoordinate/tst_qgeocoordinate.cpp create mode 100644 tests/auto/qgeocoordinateobject/CMakeLists.txt create mode 100644 tests/auto/qgeocoordinateobject/tst_qgeocoordinateobject.cpp create mode 100644 tests/auto/qgeolocation/CMakeLists.txt create mode 100644 tests/auto/qgeolocation/tst_qgeolocation.cpp create mode 100644 tests/auto/qgeolocation/tst_qgeolocation.h create mode 100644 tests/auto/qgeopath/CMakeLists.txt create mode 100644 tests/auto/qgeopath/tst_qgeopath.cpp create mode 100644 tests/auto/qgeopolygon/CMakeLists.txt create mode 100644 tests/auto/qgeopolygon/tst_qgeopolygon.cpp create mode 100644 tests/auto/qgeopositioninfo/CMakeLists.txt create mode 100644 tests/auto/qgeopositioninfo/tst_qgeopositioninfo.cpp create mode 100644 tests/auto/qgeopositioninfosource/CMakeLists.txt create mode 100644 tests/auto/qgeopositioninfosource/testqgeopositioninfosource.cpp create mode 100644 tests/auto/qgeopositioninfosource/testqgeopositioninfosource_p.h create mode 100644 tests/auto/qgeopositioninfosource/tst_qgeopositioninfosource.cpp create mode 100644 tests/auto/qgeorectangle/CMakeLists.txt create mode 100644 tests/auto/qgeorectangle/tst_qgeorectangle.cpp create mode 100644 tests/auto/qgeosatelliteinfo/CMakeLists.txt create mode 100644 tests/auto/qgeosatelliteinfo/tst_qgeosatelliteinfo.cpp create mode 100644 tests/auto/qgeosatelliteinfosource/CMakeLists.txt create mode 100644 tests/auto/qgeosatelliteinfosource/testqgeosatelliteinfosource.cpp create mode 100644 tests/auto/qgeosatelliteinfosource/testqgeosatelliteinfosource_p.h create mode 100644 tests/auto/qgeosatelliteinfosource/tst_qgeosatelliteinfosource.cpp create mode 100644 tests/auto/qgeoshape/CMakeLists.txt create mode 100644 tests/auto/qgeoshape/tst_qgeoshape.cpp create mode 100644 tests/auto/qnmeapositioninfosource/CMakeLists.txt create mode 100644 tests/auto/qnmeapositioninfosource/dummy/CMakeLists.txt create mode 100644 tests/auto/qnmeapositioninfosource/dummy/tst_dummynmeapositioninfosource.cpp create mode 100644 tests/auto/qnmeapositioninfosource/realtime/CMakeLists.txt create mode 100644 tests/auto/qnmeapositioninfosource/realtime/tst_qnmeapositioninfosource_realtime.cpp create mode 100644 tests/auto/qnmeapositioninfosource/realtime_generic/CMakeLists.txt create mode 100644 tests/auto/qnmeapositioninfosource/realtime_generic/tst_qnmeapositioninfosource_realtime_generic.cpp create mode 100644 tests/auto/qnmeapositioninfosource/simulation/CMakeLists.txt create mode 100644 tests/auto/qnmeapositioninfosource/simulation/tst_qnmeapositioninfosource_simulation.cpp create mode 100644 tests/auto/qnmeapositioninfosource/simulation_generic/CMakeLists.txt create mode 100644 tests/auto/qnmeapositioninfosource/simulation_generic/tst_qnmeapositioninfosource_simulation_generic.cpp create mode 100644 tests/auto/qnmeapositioninfosource/tst_qnmeapositioninfosource.cpp create mode 100644 tests/auto/qnmeapositioninfosource/tst_qnmeapositioninfosource.h create mode 100644 tests/auto/qnmeasatelliteinfosource/CMakeLists.txt create mode 100644 tests/auto/qnmeasatelliteinfosource/dummy/CMakeLists.txt create mode 100644 tests/auto/qnmeasatelliteinfosource/dummy/tst_dummynmeasatelliteinfosource.cpp create mode 100644 tests/auto/qnmeasatelliteinfosource/generic_realtime/CMakeLists.txt create mode 100644 tests/auto/qnmeasatelliteinfosource/generic_realtime/tst_nmeasatelliteinfosource_generic_rt.cpp create mode 100644 tests/auto/qnmeasatelliteinfosource/generic_simulation/CMakeLists.txt create mode 100644 tests/auto/qnmeasatelliteinfosource/generic_simulation/tst_nmeasatelliteinfosource_generic_sim.cpp create mode 100644 tests/auto/qnmeasatelliteinfosource/nmea/CMakeLists.txt create mode 100644 tests/auto/qnmeasatelliteinfosource/nmea/tst_nmeasatelliteinfosource.cpp create mode 100644 tests/auto/qquickgeocoordinateanimation/CMakeLists.txt create mode 100644 tests/auto/qquickgeocoordinateanimation/tst_qquickgeocoordinateanimation.cpp create mode 100644 tests/auto/utils/qlocationtestutils.cpp create mode 100644 tests/auto/utils/qlocationtestutils_p.h create mode 100644 tests/auto/utils/qnmeaproxyfactory.cpp create mode 100644 tests/auto/utils/qnmeaproxyfactory.h create mode 100644 tests/benchmarks/CMakeLists.txt create mode 100644 tests/benchmarks/README create mode 100644 tests/benchmarks/qgeoareamonitorinfo/CMakeLists.txt create mode 100644 tests/benchmarks/qgeoareamonitorinfo/tst_bench_qgeoareamonitorinfo.cpp create mode 100644 tests/benchmarks/qgeopositioninfo/CMakeLists.txt create mode 100644 tests/benchmarks/qgeopositioninfo/tst_bench_qgeopositioninfo.cpp create mode 100644 tests/benchmarks/qgeosatelliteinfo/CMakeLists.txt create mode 100644 tests/benchmarks/qgeosatelliteinfo/tst_bench_qgeosatelliteinfo.cpp create mode 100644 tests/global/global.cfg diff --git a/.QT-ENTERPRISE-LICENSE-AGREEMENT b/.QT-ENTERPRISE-LICENSE-AGREEMENT new file mode 100644 index 0000000..8d68b15 --- /dev/null +++ b/.QT-ENTERPRISE-LICENSE-AGREEMENT @@ -0,0 +1,1977 @@ +QT LICENSE AGREEMENT +Agreement version 4.4.1 + +This Qt License Agreement ("Agreement") is a legal agreement for the licensing +of Licensed Software (as defined below) between The Qt Company (as defined +below) and the Licensee who has accepted the terms of this Agreement by signing +this Agreement or by downloading or using the Licensed Software or in any other +appropriate means. + +Capitalized terms used herein are defined in Section 1. + +WHEREAS: + (A) Licensee wishes to use the Licensed Software for the purpose of + developing and distributing Applications and/or Devices (each as defined + below); + (B) The Qt Company is willing to grant the Licensee a right to use Licensed + Software for such a purpose pursuant to term and conditions of this + Agreement; and + (C) Parties wish to enable that their respective Affiliates also can sell + and purchase licenses to serve Licensee Affiliates' needs to use Licensed + Software pursuant to terms of the Agreement. Any such license purchases by + Licensee Affiliates from The Qt Company or its Affiliates will create + contractual relationship directly between the relevant The Qt Company and + the respective ordering Licensee Affiliate "Acceding Agreement"). + Accordingly, Licensee shall not be a party to any such Acceding Agreement, + and no rights or obligations are created to the Licensee thereunder but all + rights and obligations under such Acceding Agreement are vested and borne + solely by the ordering Licensee Affiliate and the relevant The Qt Company + as a contracting parties under such Acceding Agreement. + +NOW, THEREFORE, THE PARTIES HEREBY AGREE AS FOLLOWS: + +1. DEFINITIONS + +"Affiliate" of a Party shall mean an entity + (i) which is directly or indirectly controlling such Party; + (ii) which is under the same direct or indirect ownership or control as + such Party; or + (iii) which is directly or indirectly owned or controlled by such Party. +For these purposes, an entity shall be treated as being controlled by another +if that other entity has fifty percent (50 %) or more of the votes in such +entity, is able to direct its affairs and/or to control the composition of its +board of directors or equivalent body. + +"Add-on Products" shall mean The Qt Company's specific add-on software products +which are not licensed as part of The Qt Company's standard product offering, +but shall be included into the scope of Licensed Software only if so +specifically agreed between the Parties. + +"Agreement Term" shall mean the validity period of this Agreement, as set forth +in Section 12. + +"Applications" shall mean software products created using the Licensed +Software, which include the Redistributables, or part thereof. + +"Contractor(s)" shall mean third party consultants, distributors and +contractors performing services to the Licensee under applicable contractual +arrangement. + +"Customer(s)" shall mean Licensee's customers to whom Licensee, directly or +indirectly, distributes copies of the Redistributables as integrated or +incorporated into Applications or Devices. + +"Data Protection Legislation" shall mean the General Data Protection Regulation +(EU 2016/679) (GDPR) and any national implementing laws, regulations and +secondary legislation, as may be amended or updated from time to time, as well +as any other data protection laws or regulations applicable in relevant +territory. + +"Deployment Platforms" shall mean target operating systems and/or hardware +specified in the License Certificate, on which the Redistributables can be +distributed pursuant to the terms and conditions of this Agreement. + +"Designated User(s)" shall mean the employee(s) of Licensee or Licensee's +Affiliates acting within the scope of their employment or Licensee's +Contractors acting within the scope of their services on behalf of Licensee. + +"Development License" shall mean the license needed by the Licensee for each +Designated User to use the Licensed Software under the license grant described +in Section 3.1 of this Agreement. Development Licenses are available per +respective Licensed Software products, each product having its designated scope +and purpose of use. + +"Development License Term" shall mean the agreed validity period of the +Development License or QA Tools license during which time the relevant Licensed +Software product can be used pursuant to this Agreement. Agreed Development +License Term, as ordered and paid for by the Licensee, shall be memorialized in +the applicable License Certificate. + +"Development Platforms" shall mean those host operating systems specified in +the License Certificate, in which the Licensed Software can be used under the +Development License. + +"Devices" shall mean + (1) hardware devices or products that + i. are manufactured and/or distributed by the Licensee, its Affiliates, + Contractors or Customers, and + ii. incorporate, integrate or link to Applications such that + substantial functionality of such unit, when used by an End User, + is provided by Application(s) or otherwise depends on the Licensed + Software, regardless of whether the Application is developed by + Licensee or its Contractors; or + (2) Applications designed for the hardware devices specified in item (1). + + Devices covered by this Agreement shall be specified in Appendix 2 or in a + quote. + +"Distribution License(s)" shall mean a royalty-bearing license required for any +kind of sale, trade, exchange, loan, lease, rental or other distribution by or +on behalf of Licensee to a third party of Redistributables in connection with +Devices pursuant to license grant described in Section 3.3 of this Agreement. +Distribution Licensed are sold separately for each type of Device respectively +and cannot be used for any type of Devices at Licensee's discretion. + +"Distribution License Packs" shall mean set of prepaid Distribution Licenses +for distribution of Redistributables, as defined in The Qt Company's standard +price list, quote, Purchase Order confirmation or in an Appendix 2 hereto, as +the case may be. + +"End User" shall mean the final end user of the Application or a Device. + +"Evaluation License Term" shall mean a time period specified in the License +Certificate for the Licensee to use the relevant Licensed Software for +evaluation purposes according to Section 3.6 herein. + +"Intellectual Property Rights" shall mean patents (including utility models), +design patents, and designs (whether or not capable of registration), chip +topography rights and other like protection, copyrights, trademarks, service +marks, trade names, logos or other words or symbols and any other form of +statutory protection of any kind and applications for any of the foregoing as +well as any trade secrets. + +"License Certificate" shall mean a certificate generated by The Qt Company for +each Designated User respectively upon them downloading the Licensed Software, +which will be available under respective Designated User's Qt Account at +account.qt.io. License Certificates will specify relevant information +pertaining the Licensed Software purchased by Licensee and Designated User's +license to the Licensed Software. + +"License Fee" shall mean the fee charged to the Licensee for rights granted +under the terms of this Agreement. + +"Licensed Software" shall mean specified product of commercially licensed +version of Qt Software and/or QA Tools defined in Appendix 1 and/or Appendix 3, +which Licensee has purchased and which is provided to Licensee under the terms +of this Agreement. Licensed Software shall include corresponding online or +electronic documentation, associated media and printed materials, including the +source code (where applicable), example programs and the documentation. +Licensed Software does not include Third Party Software (as defined in Section +4) or Open Source Qt. The Qt Company may, in the course of its development +activities, at its free and absolute discretion and without any obligation to +send or publish any notifications to the Licensee or in general, make changes, +additions or deletions in the components and functionalities of the Licensed +Software, provided that no such changes, additions or deletions will affect +the already released version of the Licensed Software, but only upcoming +version(s). + +"Licensee" shall mean the individual or legal entity that is party to this +Agreement. + +"Licensee's Records" shall mean books and records that contain information +bearing on Licensee's compliance with this Agreement, Licensee's use of Open +Source Qt and/or the payments due to The Qt Company under this Agreement, +including, but not limited to user information, assembly logs, sales records +and distribution records. + +"Modified Software" shall have the meaning as set forth in Section 2.3. + +"Online Services" shall mean any services or access to systems made available +by The Qt Company to the Licensee over the Internet relating to the Licensed +Software or for the purpose of use by the Licensee of the Licensed Software or +Support. Use of any such Online Services is discretionary for the Licensee and +some of them may be subject to additional fees. + +"Open Source Qt" shall mean Qt Software available under the terms of the GNU +Lesser General Public License, version 2.1 or later ("LGPL") or the GNU General +Public License, version 2.0 or later ("GPL"). For clarity, Open Source Qt shall +not be provided, governed or used under this Agreement. + +"Party" or "Parties" shall mean Licensee and/or The Qt Company. + +"Permitted Software" shall mean (i) third party open source software products +that are generally available for public in source code form and free of any +charge under any of the licenses approved by Open Source Initiative as listed +on https://opensource.org/licenses, which may include parts of Open Source Qt +or be developed using Open Source Qt; and (ii) software The Qt Company has made +available via its Qt Marketplace online distribution channel. + +"Pre-Release Code" shall have the meaning as set forth in Section 4. + +"Prohibited Combination" shall mean any effort to use, combine, incorporate, +link or integrate Licensed Software with any software created with or +incorporating Open Source Qt, or use Licensed Software for creation of any such +software. + +"Purchase Order" shall have the meaning as set forth in Section 10.2. + +"QA Tools" shall mean software libraries and tools as defined in Appendix 1 +depending on which product(s) the Licensee has purchased under the Agreement. + +"Qt Software" shall mean the software libraries and tools of The Qt Company, +which The Qt Company makes available under commercial and/or open source +licenses. + +"Redistributables" shall mean the portions of the Licensed Software set forth +in Appendix 1 that may be distributed pursuant to the terms of this Agreement +in object code form only, including any relevant documentation. Where relevant, +any reference to Licensed Software in this Agreement shall include and refer +also to Redistributables. + +"Renewal Term" shall mean an extension of previous Development License Term as +agreed between the Parties. + +"Submitted Modified Software" shall have the meaning as set forth in Section +2.3. + +"Support" shall mean standard developer support that is provided by The Qt +Company to assist Designated Users in using the Licensed Software in accordance +with this Agreement and the Support Terms. + +"Support Terms" shall mean The Qt Company's standard support terms specified in +Appendix 9 hereto. + +"Taxes" shall have the meaning set forth in Section 10.5. + +"The Qt Company" shall mean: + (i) in the event Licensee is an individual residing in the United States or + a legal entity incorporated in the United States or having its + headquarters in the United States, The Qt Company Inc., a Delaware + corporation with its office at 3031 Tisch Way, 110 Plaza West, + San Jose, CA 95128, USA.; or + (ii) in the event the Licensee is an individual residing outside of the + United States or a legal entity incorporated outside of the United + States or having its registered office outside of the United States, + The Qt Company Ltd., a Finnish company with its registered office at + Miestentie 7, 02150 Espoo, Finland. + +"Third-Party Software" shall have the meaning set forth in Section 4. + +"Updates" shall mean a release or version of the Licensed Software containing +bug fixes, error corrections and other changes that are generally made +available to users of the Licensed Software that have contracted for Support. +Updates are generally depicted as a change to the digits following the decimal +in the Licensed Software version number. The Qt Company shall make Updates +available to the Licensee under the Support. Updates shall be considered as +part of the Licensed Software hereunder. + +"Upgrades" shall mean a release or version of the Licensed Software containing +enhancements and new features and are generally depicted as a change to the +first digit of the Licensed Software version number. In the event Upgrades are +provided to the Licensee under this Agreement, they shall be considered as part +of the Licensed Software hereunder. + +2. OWNERSHIP + +2.1. Ownership of The Qt Company + +The Licensed Software is protected by copyright laws and international +copyright treaties, as well as other intellectual property laws and treaties. +The Licensed Software is licensed, not sold. + +All of The Qt Company's Intellectual Property Rights are and shall remain the +exclusive property of The Qt Company or its licensors respectively. No rights +to The Qt Company's Intellectual Property Rights are assigned or granted to +Licensee under this Agreement, except when and to the extent expressly +specified herein. + +2.2. Ownership of Licensee + +All the Licensee's Intellectual Property Rights are and shall remain the +exclusive property of the Licensee or its licensors respectively. + +All Intellectual Property Rights to the Modified Software, Applications and +Devices shall remain with the Licensee and no rights thereto shall be granted +by the Licensee to The Qt Company under this Agreement (except as set forth in +Section 2.3 below). + +2.3. Modified Software + +Licensee may create bug-fixes, error corrections, patches or modifications to +the Licensed Software ("Modified Software"). Such Modified Software may break +the source or binary compatibility with the Licensed Software (including +without limitation through changing the application programming interfaces +("API") or by adding, changing or deleting any variable, method, or class +signature in the Licensed Software and/or any inter-process protocols, +services or standards in the Licensed Software libraries). To the extent that +Licensee's Modified Software so breaks source or binary compatibility with the +Licensed Software, Licensee acknowledges that The Qt Company's ability to +provide Support may be prevented or limited and Licensee's ability to make use +of Updates may be restricted. + +Licensee may, at its sole and absolute discretion, choose to submit Modified +Software to The Qt Company ("Submitted Modified Software") in connection with +Licensee's Support request, service request or otherwise. In the event +Licensee does so, then, Licensee hereby grants The Qt Company a sublicensable, +assignable, irrevocable, perpetual, worldwide, non-exclusive, royalty-free and +fully paid-up license, under all of Licensee's Intellectual Property Rights, to +reproduce, adapt, translate, modify, and prepare derivative works of, publicly +display, publicly perform, sublicense, make available and distribute such +Submitted Modified Software as The Qt Company sees fit at its free and absolute +discretion. + +3. LICENSES GRANTED + +3.1. Development with Licensed Software + +Subject to the terms of this Agreement, The Qt Company grants to Licensee a +worldwide, non-exclusive, non-transferable license, valid for each Development +License Term, to use, modify and copy the Licensed Software by Designated +Users on the Development Platforms for the sole purposes of designing, +developing, demonstrating and testing Application(s) and/or Devices, and to +provide thereto related support and other related services to Customers. Each +Application and/or Device can only include, incorporate or integrate +contributions by such Designated Users who are duly licensed for the applicable +Development Platform(s) and Deployment Platform(s) (i.e have a valid license +for the appropriate Licensed Software product). + +Licensee may install copies of the Licensed Software on five (5) computers per +Designated User, provided that only the Designated Users who have a valid +Development License may use the Licensed Software. + +Licensee may at any time designate another Designated User to replace a +then-current Designated User by notifying The Qt Company in writing, where such +replacement is due to termination of employment, change of job duties, long +time absence or other such permanent reason affecting Designated User's need +for Licensed Software. + +Upon expiry of the initially agreed Development License Term, the respective +Development License Term shall be automatically extended to one or more Renewal +Term(s), unless and until either Party notifies the other Party in writing, or +any other method acceptable to The Qt Company (it being specifically +acknowledged and understood that verbal notification is explicitly deemed +inadequate in all circumstances), that it does not wish to continue the +Development License Term, such notification to be provided to the other Party +no less than thirty (30) days before expiry of the respective Development +License Term. The Qt Company shall, in good time before the due date for the +above notification, remind the Licensee on the coming Renewal Term. Unless +otherwise agreed between the Parties, Renewal Term shall be 12 months. + +Any such Renewal Term shall be subject to License Fees agreed between the +Parties or, if no advance agreement exists, subject to The Qt Company's +standard list pricing applicable at the commencement date of any such +Renewal Term. + +The Qt Company may either request the Licensee to place a purchase order +corresponding to a quote by The Qt Company, or use Licensee's stored Credit +Card information in the Qt Account to automatically charge the Licensee for the +relevant Renewal Term. + +3.2. Distribution of Applications + +Subject to the terms of this Agreement, The Qt Company grants to Licensee a +worldwide, non-exclusive, non-transferable, revocable (for cause pursuant to +this Agreement), right and license, valid for the Agreement Term, to + (i) distribute, by itself or through its Contractors, Redistributables as + installed, incorporated or integrated into Applications for execution + on the Deployment Platforms, and + (ii) grant perpetual and irrevocable sublicenses to Redistributables, as + distributed hereunder, for Customers solely to the extent necessary in + order for the Customers to use the Applications for their respective + intended purposes. + +Right to distribute the Redistributables as part of an Application as provided +herein is not royalty-bearing but is conditional upon the Application having +been created, updated and maintained under a valid and duly paid Development +Licenses. + +3.3. Distribution of Devices + +Subject to the terms of this Agreement, The Qt Company grants to Licensee a +worldwide, non-exclusive, non-transferable, revocable (for cause pursuant to +this Agreement), right and license, valid for the Agreement Term, to + (i) distribute, by itself or through one or more tiers of Contractors, + Redistributables as installed, incorporated or integrated, or intended + to be installed, incorporated or integrated into Devices for execution + on the Deployment Platforms, and + (ii) grant perpetual and irrevocable sublicenses to Redistributables, as + distributed hereunder, for Customers solely to the extent necessary in + order for the Customers to use the Devices for their respective + intended purposes. + +Right to distribute the Devices as provided herein is conditional upon + (i) the Devices having been created, updated and maintained under a valid + and duly paid Development Licenses, and + (ii) the Licensee having acquired corresponding Distribution Licenses at + the time of distribution of any Devices to Customers. + +3.4. Further Requirements + +The licenses granted above in this Section 3 by The Qt Company to Licensee are +conditional and subject to Licensee's compliance with the following terms: + (i) Licensee acknowledges that The Qt Company has separate products of + Licensed Software for the purpose of Applications and Devices + respectively, where development and distribution of Devices is only + allowed using the correct designated product. Licensee shall make sure + and bear the burden of proof that Licensee is using a correct product + of Licensed Software entitling Licensee to development and distribution + of Devices; + (ii) Licensee shall not remove or alter any copyright, trademark or other + proprietary rights notice(s) contained in any portion of the Licensed + Software; + (iii) Applications must add primary and substantial functionality to the + Licensed Software so as not to compete with the Licensed Software; + (iv) Applications may not pass on functionality which in any way makes it + possible for others to create software with the Licensed Software; + provided however that Licensee may use the Licensed Software's + scripting and QML ("Qt Quick") functionality solely in order to enable + scripting, themes and styles that augment the functionality and + appearance of the Application(s) without adding primary and substantial + functionality to the Application(s); + (v) Licensee shall not use Licensed Software in any manner or for any + purpose that infringes, misappropriates or otherwise violates any + Intellectual property or right of any third party, or that violates any + applicable law; + (vi) Licensee shall not use The Qt Company's or any of its suppliers' + names, logos, or trademarks to market Applications, except that + Licensee may use "Built with Qt" logo to indicate that Application(s) + or Device(s) was developed using the Licensed Software; + (vii) Licensee shall not distribute, sublicense or disclose source code of + Licensed Software to any third party (provided however that Licensee + may appoint employee(s) of Contractors and Affiliates as Designated + Users to use Licensed Software pursuant to this Agreement). Such right + may be available for the Licensee subject to a separate software + development kit ("SDK") license agreement to be concluded with The Qt + Company; + (viii) Licensee shall not grant the Customers a right to (a) make copies of + the Redistributables except when and to the extent required to use the + Applications and/or Devices for their intended purpose, (b) modify the + Redistributables or create derivative works thereof, (c) decompile, + disassemble or otherwise reverse engineer Redistributables, or (d) + redistribute any copy or portion of the Redistributables to any third + party, except as part of the onward sale of the Application or Device + on which the Redistributables are installed; + (ix) Licensee shall not and shall cause that its Affiliates or Contractors + shall not use Licensed Software in any Prohibited Combination, unless + Licensee has received an advance written permission from The Qt Company + to do so. Absent such written permission, any and all distribution by + the Licensee during the Agreement Term of a hardware device or product + a) which incorporate or integrate any part of Licensed Software or Open + Source Qt; or b) where substantial functionality is provided by + software built with Licensed Software or Open Source Qt or otherwise + depends on the Licensed Software or Open Source Qt, shall be considered + to be Device distribution under this Agreement and shall be dependent + on Licensee's compliance thereof (including but not limited to + obligation to pay applicable License Fees for such distribution). + Notwithstanding what is provided above in this sub-section (ix), + Licensee is entitled to use and combine Licensed Software with any + Permitted Software; + (x) Licensee shall cause all of its Affiliates, Contractors and Customers + entitled to make use of the licenses granted under this Agreement, to + be contractually bound to comply with the relevant terms of this + Agreement and not to use the Licensed Software beyond the terms hereof + and for any purposes other than operating within the scope of their + services for Licensee. Licensee shall be responsible for any and all + actions and omissions of its Affiliates and Contractors relating to the + Licensed Software and use thereof (including but not limited to payment + of all applicable License Fees); + (xi) Except when and to the extent explicitly provided in this Section 3, + Licensee shall not transfer, publish, disclose, display or otherwise + make available the Licensed Software; and + (xii) Licensee shall not attempt or enlist a third party to conduct or + attempt to conduct any of the above. + +Above terms shall not be applicable if and to the extent they conflict with any +mandatory provisions of any applicable laws. + +Any use of Licensed Software beyond the provisions of this Agreement is +strictly prohibited and requires an additional license from The Qt Company. + +3.5 QA Tools License + +Subject to the terms of this Agreement, The Qt Company grants to Licensee a +worldwide, non-exclusive, non-transferable license, valid for the Development +License Term, to use the QA Tools for Licensee's internal business purposes in +the manner provided below and in Appendix 1 hereto. + +Licensee may modify the QA Tools except for altering or removing any details of +ownership, copyright, trademark or other property right connected with the QA +Tools. + +Licensee shall not distribute the QA Tools or any part thereof, modified or +unmodified, separately or as part of any software package, Application or +Device. + +Upon expiry of the initially agreed Development License Term, the respective +Development License Term shall be automatically extended to one or more Renewal +Term(s), unless and until either Party notifies the other Party in writing, or +any other method acceptable to The Qt Company (it being specifically +acknowledged and understood that verbal notification is explicitly deemed +inadequate in all circumstances), that it does not wish to continue the +Development License Term, such notification to be provided to the other Party +no less than thirty (30) days before expiry of the respective Development +License Term. The Qt Company shall, in good time before the due date for the +above notification, remind the Licensee on the coming Renewal Term. Unless +otherwise agreed between the Parties, Renewal Term shall be 12 months. + +Any such Renewal Term shall be subject to License Fees agreed between the +Parties or, if no advance agreement exists, subject to The Qt Company's +standard list pricing applicable at the commencement date of any such +Renewal Term. + +3.6 Evaluation License + +Subject to the terms of this Agreement, The Qt Company grants to Licensee a +worldwide, non-exclusive, non-transferable license, valid for the Evaluation +License Term to use the Licensed Software solely for the Licensee's internal +use to evaluate and determine whether the Licensed Software meets Licensee's +business requirements, specifically excluding any commercial use of the +Licensed Software or any derived work thereof. + +Upon the expiry of the Evaluation License Term, Licensee must either +discontinue use of the relevant Licensed Software or acquire a commercial +Development License or QA Tools License specified herein. + +4. THIRD-PARTY SOFTWARE + +The Licensed Software may provide links or access to third party libraries or +code (collectively "Third-Party Software") to implement various functions. +Third-Party Software does not, however, comprise part of the Licensed Software, +but is provided to Licensee complimentary and use thereof is discretionary for +the Licensee. Third-Party Software will be listed in the ".../src/3rdparty" +source tree delivered with the Licensed Software or documented in the Licensed +Software, as such may be amended from time to time. Licensee acknowledges that +use or distribution of Third-Party Software is in all respects subject to +applicable license terms of applicable third-party right holders. + +5. PRE-RELEASE CODE + +The Licensed Software may contain pre-release code and functionality, or sample +code marked or otherwise stated with appropriate designation such as +"Technology Preview", "Alpha", "Beta", "Sample", "Example" etc. +("Pre-Release Code"). + +Such Pre-Release Code may be present complimentary for the Licensee, in order +to provide experimental support or information for new platforms or +preliminary versions of one or more new functionalities or for other similar +reasons. The Pre-Release Code may not be at the level of performance and +compatibility of a final, generally available, product offering. The +Pre-Release Code may not operate correctly, may contain errors and may be +substantially modified by The Qt Company prior to the first commercial +product release, if any. The Qt Company is under no obligation to make +Pre-Release Code commercially available, or provide any Support or Updates +relating thereto. The Qt Company assumes no liability whatsoever regarding +any Pre-Release Code, but any use thereof is exclusively at Licensee's own risk +and expense. + +For clarity, unless Licensed Software specifies different license terms for the +respective Pre-Release Code, the Licensee is entitled to use such pre-release +code pursuant to Section 3, just like other Licensed Software. + +6. LIMITED WARRANTY AND WARRANTY DISCLAIMER + +The Qt Company hereby represents and warrants that (i) it has the power and +authority to grant the rights and licenses granted to Licensee under this +Agreement, and (ii) Licensed Software will operate materially in accordance +with its specifications. + +Except as set forth above, the Licensed Software is licensed to Licensee "as +is" and Licensee's exclusive remedy and The Qt Company's entire liability for +errors in the Licensed Software shall be limited, at The Qt Company's option, +to correction of the error, replacement of the Licensed Software or return of +the applicable fees paid for the defective Licensed Software for the time +period during which the License is not able to utilize the Licensed Software +under the terms of this Agreement. + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE QT COMPANY ON BEHALF OF +ITSELF AND ITS LICENSORS, SUPPLIERS AND AFFILIATES, DISCLAIMS ALL OTHER +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +NON-INFRINGEMENT WITH REGARD TO THE LICENSED SOFTWARE. THE QT COMPANY DOES NOT +WARRANT THAT THE LICENSED SOFTWARE WILL SATISFY LICENSEE'S REQUIREMENTS OR THAT +IT WILL OPERATE WITHOUT DEFECT OR ERROR OR THAT THE OPERATION THEREOF WILL BE +UNINTERRUPTED. + +7. LIMITATION OF LIABILITY + +EXCEPT FOR (I) CASES OF GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT, AND (II) +BREACH OF CONFIDENTIALITY, AND TO THE EXTENT PERMITTED BY APPLICABLE LAW, IN NO +EVENT SHALL EITHER PARTY BE LIABLE TO THE OTHER PARTY FOR ANY LOSS OF PROFIT, +LOSS OF DATA, LOSS OF BUSINESS OR GOODWILL OR ANY OTHER INDIRECT, SPECIAL, +CONSEQUENTIAL, INCIDENTAL OR PUNITIVE COST, DAMAGES OR EXPENSE OF ANY KIND, +HOWSOEVER ARISING UNDER OR IN CONNECTION WITH THIS AGREEMENT. + +EXCEPT FOR (I) CASES OF GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT, AND (II) +BREACH OF CONFIDENTIALITY, AND TO THE EXTENT PERMITTED BY APPLICABLE LAW, IN NO +EVENT SHALL EITHER PARTY'S TOTAL AGGREGATE LIABILITY UNDER THIS AGREEMENT +EXCEED THE AGGREGATE LICENSE FEES PAID OR PAYABLE TO THE QT COMPANY BY LICENSEE +DURING THE DEVELOPMENT LICENSE TERM DURING WHICH THE EVENT RESULTING IN SUCH +LIABILITY OCCURRED. + +THE PROVISIONS OF THIS SECTION 7 ALLOCATE THE RISKS UNDER THIS AGREEMENT +BETWEEN THE QT COMPANY AND LICENSEE AND THE PARTIES HAVE RELIED UPON THE +LIMITATIONS SET FORTH HEREIN IN DETERMINING WHETHER TO ENTER INTO THIS +AGREEMENT. + +NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS AGREEMENT, LICENSEE SHALL +ALWAYS BE LIABLE TO PAY THE APPLICABLE LICENSE FEES CORRESPONDING TO ITS +ACTUAL USE OF LICENSED SOFTWARE. + +8. SUPPORT, UPDATES AND ONLINE SERVICES + +Upon due payment of the agreed License Fees the Licensee will be eligible to +receive Support and Updates and to use the Online Services during the agreed +Development License Term or other agreed fixed time period. Support is +provided according to agreed support level and subject to applicable +requirements and restrictions, as specified in the Support Terms. + +Unless otherwise decided by The Qt Company at its free and absolute discretion, +Upgrades will not be included in the Support but may be available subject to +additional fees. + +From time to time The Qt Company may change the Support Terms, provided that +during the respective ongoing Support period the level of Support may not be +reduced without the consent of the Licensee. + +Unless otherwise agreed, The Qt Company shall not be responsible for providing +any service or support to Customers. + +9. CONFIDENTIALITY + +Each Party acknowledges that during the Agreement Term each Party may receive +information about the other Party's business, business methods, business plans, +customers, business relations, technology, and other information, including the +terms of this Agreement, that is confidential and of great value to the other +Party, and the value of which would be significantly reduced if disclosed to +third parties ("Confidential Information"). Accordingly, when a Party (the +"Receiving Party") receives Confidential Information from the other Party (the +"Disclosing Party"), the Receiving Party shall only disclose such information +to employees and Contractors on a need to know basis, and shall cause its +employees and employees of its Affiliates to: (i) maintain any and all +Confidential Information in confidence; (ii) not disclose the Confidential +Information to a third party without the Disclosing Party's prior written +approval; and (iii) not, directly or indirectly, use the Confidential +Information for any purpose other than for exercising its rights and +fulfilling its responsibilities pursuant to this Agreement. Each Party shall +take reasonable measures to protect the Confidential Information of the other +Party, which measures shall not be less than the measures taken by such Party +to protect its own confidential and proprietary information. + +Obligation of confidentiality shall not apply to information that (i) is or +becomes generally known to the public through no act or omission of the +Receiving Party; (ii) was in the Receiving Party's lawful possession prior to +the disclosure hereunder and was not subject to limitations on disclosure or +use; (iii) is developed independently by employees or Contractors of the +Receiving Party or other persons working for the Receiving Party who have not +had access to the Confidential Information of the Disclosing Party, as proven +by the written records of the Receiving Party; (iv) is lawfully disclosed to +the Receiving Party without restrictions, by a third party not under an +obligation of confidentiality; or (v) the Receiving Party is legally compelled +to disclose, in which case the Receiving Party shall notify the Disclosing +Party of such compelled disclosure and assert the privileged and confidential +nature of the information and cooperate fully with the Disclosing Party to +limit the scope of disclosure and the dissemination of disclosed Confidential +Information to the minimum extent necessary. + +The obligations under this Section 9 shall continue to remain in force for a +period of five (5) years after the last disclosure, and, with respect to trade +secrets, for so long as such trade secrets are protected under applicable trade +secret laws. + +10. FEES, DELIVERY AND PAYMENT + +10.1. License Fees + +License Fees are described in The Qt Company's standard price list, quote or +Purchase Order confirmation or in an Appendix 2 hereto, as the case may be. + +Unless otherwise expressly provided in this Agreement, the License Fees shall +not be refunded or claimed as a credit in any event or for any reason +whatsoever. + +10.2. Ordering Licenses + +Licensee may purchase Development Licenses, Distribution Licenses and QA Tools +Licenses pursuant to agreed pricing terms or, if no specific pricing terms have +been agreed upon, at The Qt Company's standard pricing terms applicable at the +time of purchase. + +Unless expressly otherwise agreed, any price or other term quoted to the +Licensee or specified herein shall only be valid for the thirty (30) days from +the effective date of this Agreement, Appendix 2 or the date of the quote, as +applicable. + +Licensee shall submit all purchase orders for Development Licenses and +Distribution Licenses to The Qt Company by email or any other method acceptable +to The Qt Company (each such order is referred to herein as a "Purchase Order") +for confirmation, whereupon the Purchase Order shall become binding between the +Parties. + +Licensee acknowledges and agrees that all Purchase Orders for Licensed Software +the Licensee makes during the Agreement Term shall be governed exclusively +under the terms of this Agreement. + +10.3. Distribution License Packs + +Unless otherwise agreed, Distribution Licenses shall be purchased by way of +Distribution License Packs. + +Upon due payment of the ordered Distribution License Pack(s), the Licensee will +have an account of Distribution Licenses available for distributing the +Redistributables in accordance with this Agreement. + +Each time Licensee distributes a copy of Redistributables, then one +Distribution License is used, and Licensee's account of available Distribution +Licenses is decreased accordingly. + +Licensee may distribute copies of the Redistributables so long as Licensee has +Distribution Licenses remaining on its account. + +10.4. Payment Terms + +License Fees and any other charges under this Agreement shall be paid by +Licensee no later than thirty (30) days from the date of the applicable invoice +from The Qt Company. + +The Qt Company will submit an invoice to Licensee after the date of this +Agreement and/or after The Qt Company receives a Purchase Order from Licensee. + +A late payment charge of the lower of (a) one percent per month; or (b) the +interest rate stipulated by applicable law, shall be charged on any unpaid +balances that remain past due and which have not been disputed by the Licensee +in good faith. + +10.5. Taxes + +All License Fees and other charges payable hereunder are gross amounts but +exclusive of any value added tax, use tax, sales tax, withholding tax and other +taxes, duties or tariffs ("Taxes") levied directly for the sale, delivery or +use of Licensed Software hereunder pursuant to any applicable law. Such +applicable Taxes shall be paid by Licensee to The Qt Company, or, where +applicable, in lieu of payment of such Taxes to The Qt Company, Licensee shall +provide an exemption certificate to The Qt Company and any applicable +authority. + +11. RECORD-KEEPING AND REPORTING OBLIGATIONS; AUDIT RIGHTS + +11.1. Licensee's Record-keeping + +Licensee shall at all times during the Agreement Term and for a period of two +(2) years thereafter maintain Licensee's Records in an accurate and up-to-date +form. Licensee's Records shall be adequate to reasonably enable The Qt Company +to determine Licensee's compliance with the provisions of this Agreement. The +records shall conform to general good accounting practices. + +Licensee shall, within thirty (30) days from receiving The Qt Company's request +to that effect, deliver to The Qt Company a report based on Licensee's Records, +such report to contain information, in sufficient detail, on (i) number and +identity of users working with Licensed Software or Open Source Qt, (ii) copies +of Redistributables distributed by Licensee during the most recent calendar +quarter and/or any other term specified by The Qt Company, , and (iii) any +other information pertaining to Licensee's compliance with the terms of this +Agreement (like e.g. information on products and/or projects relating to use of +Distribution Licenses), as The Qt Company may reasonably require from time to +time. + +11.2. The Qt Company's Audit Rights + +The Qt Company or an independent auditor acting on behalf of The Qt Company's, +may, upon at least thirty (30) days' prior written notice and at its expense, +audit Licensee with respect to the Licensee's use of the Licensed Software, but +not more frequently than once during each 6-month period. Such audit may be +conducted by mail, electronic means or through an in-person visit to Licensee's +place of business. Any possible in-person audit shall be conducted during +regular business hours at Licensee's facilities and shall not unreasonably +interfere with Licensee's business activities and shall be limited in scope to +verify Licensee's compliance with the terms of this Agreement. The Qt Company +or the independent auditor acting on behalf of The Qt Company shall be entitled +to inspect Licensee's Records and conduct necessary interviews of Licensee's +relevant employees and Contractors. All such Licensee's Records and use thereof +shall be subject to an obligation of confidentiality under this Agreement. + +If an audit reveals that Licensee is using the Licensed Software beyond scope +of the licenses Licensee has paid for, Licensee shall pay to The Qt Company any +amounts owed for such unauthorized use within 30 days from receipt of the +corresponding invoice from The Qt Company. + +In addition, in the event the audit reveals a material violation of the terms +of this Agreement (without limitation, either (i) underpayment of more than 10 +% of License Fees or 10,000 euros (whichever is more) or (ii) distribution of +products, which include or result from Prohibited Combination, shall be deemed +a material violation for purposes of this section), then the Licensee shall +pay The Qt Company's reasonable cost of conducting such audit. + +12. TERM AND TERMINATION + +12.1. Agreement Term + +This Agreement shall enter into force upon due acceptance by both Parties and +remain in force until terminated pursuant to the terms of this Section 12 +("Agreement Term"). + +12.2. Termination for breach and suspension of rights +Either Party shall have the right to terminate this Agreement upon thirty (30) +days prior written notice if the other Party commits a material breach of any +obligation of this Agreement and fails to remedy such breach within such notice +period. + +Instead of termination, The Qt Company shall have the right to suspend or +withhold grants of all rights to the Licensed Software hereunder, including but +not limited to the Development Licenses, Distribution License, and Support, +should Licensee fail to make payment in timely fashion or otherwise violates or +is reasonably suspected to violate its obligations or terms of this Agreement, +and where such violation or breach is not cured within ten (10) business days +following The Qt Company's written notice thereof. + +12.3. Termination for insolvency + +Either Party shall have the right to terminate this Agreement immediately upon +written notice in the event that the other Party becomes insolvent, files for +any form of bankruptcy, makes any assignment for the benefit of creditors, has +a receiver, administrative receiver or officer appointed over the whole or a +substantial part of its assets, ceases to conduct business, or an act +equivalent to any of the above occurs under the laws of the jurisdiction of the +other Party. + +12.4. Parties' Rights and Duties upon Termination + +Upon expiry or termination of the Agreement, Licensee shall cease and shall +cause all Designated Users (including those of its Affiliates' and +Contractors') to cease using the Licensed Software under this Agreement. For +clarity, a Development License of a Designated User or a QA Tools License, and +all rights relating thereto, shall always terminate at the expiry of the +respective Development License Term, even if the Agreement continues to remain +in force. + +Upon such termination the Licensee shall destroy or return to The Qt Company +all copies of the Licensed Software and all related materials and will certify +the same by Licensee's duly authorized officer to The Qt Company upon its +request, provided however that Licensee may retain and exploit such copies of +the Licensed Software as it may reasonably require in providing continued +support to Customers. + +Except when this Agreement is terminated by The Qt Company due to Licensee's +material breach as set forth in Section 12.2, the Licensee may continue +distribution of Applications and Devices under the terms of this Agreement +despite the termination of this Agreement. In such event the terms hereof will +continue to be applicable and govern any such distribution of Applications and +Devices beyond the expiry or termination of this Agreement. In case of +termination by The Qt Company due to Licensee's material breach, Licensee must +cease any distribution of Applications and Devices at the date of termination +of this Agreement. + +Expiry or termination of this Agreement for any reason whatsoever shall not +relieve Licensee of its obligation to pay any License Fees accrued or payable +to The Qt Company prior to the effective date of termination, and Licensee pay +to The Qt Company all such fees within 30 days from the effective date of +termination of this Agreement. + +Termination of this Agreement shall not affect any rights of Customers to +continue use of Applications and Devices (and therein incorporated +Redistributables). + +12.5. Extension of Rights under Special Circumstances + +In the event of The Qt Company choosing not to renew the Development License(s) +or QA Tools Licenses, as set forth in Section 3.1 and 3.5 respectively, and +where such decision of non-renewal is not due to any ongoing breach or alleged +breach (as reasonably determined by The Qt Company) by Licensee of the terms of +this Agreement or any applicable license terms of Open Source Qt, then all +valid and affected Development Licenses and QA Tools licenses possessed by the +Licensee at such date shall be extended to be valid in perpetuity under the +terms of this Agreement and Licensee is entitled to purchase additional +licenses as set forth in Section 10.2. + +In the event The Qt Company is declared bankrupt under a final, non-cancellable +decision by relevant court of law, and this Agreement is not, at the date of +expiry of the Development License(s) or QA Tools Licenses, assigned to party, +who has assumed The Qt Company's position as a legitimate licensor of Licensed +Software under this Agreement, then all valid Development Licenses and QA Tools +Licenses possessed by the Licensee at such date of expiry, and which the +Licensee has not notified for expiry, shall be extended to be valid in +perpetuity under the terms of this Agreement. + +For clarity, in case of an extension under this Section 12.5, any such +extension shall not apply to The Qt Company's Support obligations, but Support +shall be provided only up until the end of the respective fixed Development +License Term regardless of the extension of relevant Development License or QA +Tools License, unless otherwise agreed between the Parties. + +13. GOVERNING LAW AND LEGAL VENUE + +In the event this Agreement is in the name of The Qt Company Inc., a Delaware +Corporation, then: + (i) this Agreement shall be construed and interpreted in accordance with + the laws of the State of California, USA, excluding its choice of law + provisions; + (ii) the United Nations Convention on Contracts for the International Sale + of Goods will not apply to this Agreement; and + (iii) any dispute, claim or controversy arising out of or relating to this + Agreement or the breach, termination, enforcement, interpretation or + validity thereof, including the determination of the scope or + applicability of this Agreement to arbitrate, shall be determined by + arbitration in San Francisco, USA, before one arbitrator. The + arbitration shall be administered by JAMS pursuant to JAMS' Streamlined + Arbitration Rules and Procedures. Judgment on the Award may be entered + in any court having jurisdiction. This Section shall not preclude + parties from seeking provisional remedies in aid of arbitration from a + court of appropriate jurisdiction. + +In the event this Agreement is in the name of The Qt Company Ltd., a Finnish +Company, then: + (i) this Agreement shall be construed and interpreted in accordance with + the laws of Finland, excluding its choice of law provisions; + (ii) the United Nations Convention on Contracts for the International Sale + of Goods will not apply to this Agreement; and + (iii) any disputes, controversy or claim arising out of or relating to this + Agreement, or the breach, termination or validity thereof shall be + finally settled by arbitration in accordance with the Arbitration Rules + of International Chamber of Commerce. The arbitration tribunal shall + consist of one (1), or if either Party so requires, of three (3), + arbitrators. The award shall be final and binding and enforceable in + any court of competent jurisdiction. The arbitration shall be held in + Helsinki, Finland and the process shall be conducted in the English + language. This Section shall not preclude parties from seeking + provisional remedies in aid of arbitration from a court of appropriate + jurisdiction. + +14. GENERAL PROVISIONS + +14.1. No Assignment + +Except in the case of a merger or sale of substantially all of its corporate +assets, Licensee shall not be entitled to assign or transfer all or any of its +rights, benefits and obligations under this Agreement without the prior written +consent of The Qt Company, which shall not be unreasonably withheld or delayed. +The Qt Company shall be entitled to freely assign or transfer any of its +rights, benefits or obligations under this Agreement. + +14.2. No Third-Party Representations + +Licensee shall make no representations or warranties concerning the Licensed +Software on behalf of The Qt Company. Any representation or warranty Licensee +makes or purports to make on The Qt Company's behalf shall be void as to +The Qt Company. + +14.3. Surviving Sections + +Any terms and conditions that by their nature or otherwise reasonably should +survive termination of this Agreement shall so be deemed to survive. Such +sections include especially the following: 1, 2, 6, 7, 9, 11, 12.4, 13 and 14. + +14.4. Entire Agreement + +This Agreement, the Appendices hereto, the License Certificate and any +applicable quote and Purchase Order accepted by The Qt Company constitute the +complete agreement between the Parties and supersedes all prior or +contemporaneous discussions, representations, and proposals, written or oral, +with respect to the subject matters discussed herein. + +In the event of any conflict or inconsistency between this Agreement and any +Purchase Order, the terms of this Agreement will prevail over the terms of the +Purchase Order with respect to such conflict or inconsistency. + +Parties specifically acknowledge and agree that this Agreement prevails over +any click-to-accept or similar agreements the Designated Users may need to +accept online upon download of the Licensed Software, as may be required by +The Qt Company's applicable processes relating to Licensed Software. + +14.5. Modifications + +No modification of this Agreement shall be effective unless contained in a +writing executed by an authorized representative of each Party. No term or +condition contained in Licensee's Purchase Order ("Deviating Terms") shall +apply unless The Qt Company has expressly agreed such Deviating Terms in +writing. Unless and to the extent expressly agreed by The Qt Company, any such +Deviating Terms shall be deemed void and with no legal effect. For clarity, +delivery of the Licensed Software following the receipt of the Purchase Order +including Deviating Terms shall not constitute acceptance of such Deviating +Terms. + +14.6. Force Majeure + +Except for the payment obligations hereunder, neither Party shall be liable to +the other for any delay or non-performance of its obligations hereunder in the +event and to the extent that such delay or non-performance is due to an event +of act of God, terrorist attack or other similar unforeseeable catastrophic +event that prevents either Party for fulfilling its obligations under this +Agreement and which such Party cannot avoid or circumvent ("Force Majeure +Event"). If the Force Majeure Event results in a delay or non-performance of a +Party for a period of three (3) months or longer, then either Party shall have +the right to terminate this Agreement with immediate effect without any +liability (except for the obligations of payment arising prior to the event of +Force Majeure) towards the other Party. + +14.7. Notices + +Any notice given by one Party to the other shall be deemed properly given and +deemed received if specifically acknowledged by the receiving Party in writing +or when successfully delivered to the recipient by hand, fax, or special +courier during normal business hours on a business day to the addresses +specified for each Party on the signature page. Each communication and document +made or delivered by one Party to the other Party pursuant to this Agreement +shall be in the English language. + +14.8. Export Control + +Licensee acknowledges that the Redistributables, as incorporated in +Applications or Devices, may be subject to export control restrictions under +the applicable laws of respective countries. Licensee shall fully comply with +all applicable export license restrictions and requirements as well as with all +laws and regulations relating to the Redistributables and exercise of licenses +hereunder and shall procure all necessary governmental authorizations, +including without limitation, all necessary licenses, approvals, permissions or +consents, where necessary for the re-exportation of the Redistributables, +Applications and/or Devices. + +14.9. No Implied License + +There are no implied licenses or other implied rights granted under this +Agreement, and all rights, save for those expressly granted hereunder, shall +remain with The Qt Company and its licensors. In addition, no licenses or +immunities are granted to the combination of the Licensed Software with any +other software or hardware not delivered by The Qt Company under this +Agreement. + +14.10. Attorney Fees + +The prevailing Party in any action to enforce this Agreement shall be entitled +to recover its attorney's fees and costs in connection with such action, as to +be ordered by the relevant dispute resolution body. + +14.11. Privacy + +Licensee acknowledges and agrees that for the purpose of this Agreement, +The Qt Company may collect, use, transfer and disclose personal data pertaining +to Designated Users as well as any other employees and directors of the +Licensee and its Contractors relevant for carrying out the intent of this +Agreement. Such personal data will be primarily collected from the relevant +individuals but may be collected also from Licensee (e.g. in the course of +Licensee's reporting obligations). The Parties acknowledge that as +The Qt Company determines the purpose and means for such collection and +processing of the applicable personal data, The Qt Company shall be regarded as +the Data Controller under the applicable Data Protection Legislation. +The Qt Company shall process any such personal data in accordance with its +privacy and security policies and practices, which will comply with all +applicable requirements of the Data Protection Legislation. + +14.12. Severability + +If any provision of this Agreement shall be adjudged by any court of competent +jurisdiction to be unenforceable or invalid, that provision shall be limited or +eliminated to the minimum extent necessary so that this Agreement shall +otherwise remain in full force and effect and enforceable. + +14.13. Marketing Rights + +Parties have agreed upon Marketing Rights pursuant to Appendix 7, if any. + + + + +APPENDICES +The Agreement includes following Appendices 1-10, as applicable. +- Appendix 1: Licensed Software details +- Appendix 2: Pricing +- Appendix 3: Add-on Software details (optional) +- Appendix 4: Small business and startup Licenses (optional) +- Appendix 5: Non-commercial and educational Licenses (optional) +- Appendix 6: License Reporting (optional) +- Appendix 7: Marketing Rights (optional) +- Appendix 8: Intentionally left blank (optional) +- Appendix 9: Support Terms +- Appendix 10: Conversion from legacy Licenses to Subscription (optional) + + +APPENDIX 1: LICENSED SOFTWARE + +The modules and/or tools that are included in the latest publicly available +version of the respective product at the effective date of this Agreement- Qt +for Application Development Professional (ADP), Qt for Application Development +Enterprise (ADE), Qt for Device Creation Professional (DCP), Qt for Device +Creation Enterprise (DCE), - are marked with "X" in the below table. The +modules and tools are specific to each product version respectively and may +vary from version to version. Modules and tools included in the latest publicly +available version of the respective product at any given time are listed in +Appendix 1 of the latest version of this Agreement available at +www.qt.io/terms-conditions/. If a new version of Licensed Software does not +include a module or tool present in an older version which Licensee is entitled +to use under a valid license from The Qt Company, then Licensee will continue +to have such right during the Term of this Agreement. In the event a new +version of the Licensed Software adds modules or tools to any previous +version(s), Licensee's rights will extend to cover also such additional modules +and tools. + +Parts of the product that are permitted for distribution in object-code form +only ("Redistributables") are marked with "R" in the below table. + ++----------------------------------------------------------+ +| Modules / Tools | ADP | ADE | DCP | DCE | ++----------------------------------------------------------+ +| Active Qt | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt 3D | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt 5 Core Compatibility APIs | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Android Extras | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Bluetooth | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Canvas 3D | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Charts | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Concurrent | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Core | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Data Visualization | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt D-Bus | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt for Python | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt for WebAssembly | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Gamepad | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Graphical Effects | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt GUI | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Help | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Image Formats | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Location | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Lottie Animation | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Mac Extras | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Multimedia | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Multimedia Widgets | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Network | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Network Authorization | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt NFC | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt OpenGL | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt PDF | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Platform Headers | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Positioning | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Print Support | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Purchasing | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt QML | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick 3D | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Controls 1 | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Controls | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Dialogs | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Extras | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Layouts | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Test | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Timeline | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick WebGL | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Widgets | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Remote Objects | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Script | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Script Tools | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt SCXML | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Sensors | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Serial Bus | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Serial Port | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Shader Tools | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Speech | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt State Machine | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt SQL | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt SVG | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Test | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt UI Tools | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Virtual Keyboard | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Wayland Compositor | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt WebChannel | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt WebEngine | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt WebSockets | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt WebView | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Widgets | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Windows Extras | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt X11 Extras | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt XML | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt XML Patterns | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Designer (Qt Widget Designer) | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Linguist | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt Assistant | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| lupdate | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| lrelease | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| lconvert | X,R | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt MQTT | | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt KNX | | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt OPC UA | | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Qt CoAP | | X,R | X,R | X,R | ++----------------------------------------------------------+ +| Boot 2 Qt stacks | | | X,R | X,R | ++----------------------------------------------------------+ +| Qt OTA | | | X,R | X,R | ++----------------------------------------------------------+ +| Device Utilities | | | X,R | X,R | ++----------------------------------------------------------+ +| Qt Debugging Bridge (QBD) Daemon | | | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Ultralite Controls | | | X,R | X,R | ++----------------------------------------------------------+ +| Qt Quick Ultralite | | | X,R | X,R | ++----------------------------------------------------------+ +| Qt Safe Renderer (QSR) | | | | X,R | ++----------------------------------------------------------+ +| Qt Application Manager | | | | X,R | ++----------------------------------------------------------+ +| Qt Interface Framework | | | | X,R | ++----------------------------------------------------------+ +| Neptune Reference UI | | | | X,R | ++----------------------------------------------------------+ +| Qt for Android Automotive (QAA) | | | | X,R | ++----------------------------------------------------------+ +| Qt Creator | X | X | X | X | ++----------------------------------------------------------+ +| Qt Design Studio Professional | X | X | X | X | ++----------------------------------------------------------+ +| androiddeployqt | X | X | X | X | ++----------------------------------------------------------+ +| androidtestrunner | X | X | X | X | ++----------------------------------------------------------+ +| canbusutil | X | X | X | X | ++----------------------------------------------------------+ +| dumpcpp | X | X | X | X | ++----------------------------------------------------------+ +| dumpdoc | X | X | X | X | ++----------------------------------------------------------+ +| fixqt4headers.pl | X | X | X | X | ++----------------------------------------------------------+ +| idc | X | X | X | X | ++----------------------------------------------------------+ +| moc | X | X | X | X | ++----------------------------------------------------------+ +| pixeltool | X | X | X | X | ++----------------------------------------------------------+ +| qdbus | X | X | X | X | ++----------------------------------------------------------+ +| qdbuscpp2xml | X | X | X | X | ++----------------------------------------------------------+ +| qdbusviwer | X | X | X | X | ++----------------------------------------------------------+ +| qdbusxml2cpp | X | X | X | X | ++----------------------------------------------------------+ +| qdistancefieldgenerator | X | X | X | X | ++----------------------------------------------------------+ +| qdoc | X | X | X | X | ++----------------------------------------------------------+ +| qhelpgenerator | X | X | X | X | ++----------------------------------------------------------+ +| qlalr | X | X | X | X | ++----------------------------------------------------------+ +| qmake | X | X | X | X | ++----------------------------------------------------------+ +| qml | X | X | X | X | ++----------------------------------------------------------+ +| qmlcachegen | X | X | X | X | ++----------------------------------------------------------+ +| qmldom | X | X | X | X | ++----------------------------------------------------------+ +| qmleasing | X | X | X | X | ++----------------------------------------------------------+ +| qmlformat | X | X | X | X | ++----------------------------------------------------------+ +| qmllint | X | X | X | X | ++----------------------------------------------------------+ +| qmlpreview | X | X | X | X | ++----------------------------------------------------------+ +| qmlprofiler | X | X | X | X | ++----------------------------------------------------------+ +| qmlscene | X | X | X | X | ++----------------------------------------------------------+ +| qmltestrunner | X | X | X | X | ++----------------------------------------------------------+ +| qmltime | X | X | X | X | ++----------------------------------------------------------+ +| qmlviewer | X | X | X | X | ++----------------------------------------------------------+ +| qtdiag | X | X | X | X | ++----------------------------------------------------------+ +| qtpaths | X | X | X | X | ++----------------------------------------------------------+ +| qtplugininfo | X | X | X | X | ++----------------------------------------------------------+ +| qvkgen | X | X | X | X | ++----------------------------------------------------------+ +| rcc | X | X | X | X | ++----------------------------------------------------------+ +| tracegen | X | X | X | X | ++----------------------------------------------------------+ +| uic | X | X | X | X | ++----------------------------------------------------------+ +| windeployqt | X | X | X | X | ++----------------------------------------------------------+ +| Target toolchains | | | X | X | ++----------------------------------------------------------+ +| Qt Debugging Bridge Host Tools | | | X | X | ++----------------------------------------------------------+ +| qtconfig-gui | | | X | X | ++----------------------------------------------------------+ +| Qt Emulator | | | X | X | ++----------------------------------------------------------+ +| Qt Creator VxWorks plugin | | | X | X | ++----------------------------------------------------------+ +| Qt Creator plugin for Qt | | | | X | +| Application Manager | | | | | ++----------------------------------------------------------+ +| qmlinterfacegenerator | | | | X | ++----------------------------------------------------------+ +| qmltocpp | | | | X | ++----------------------------------------------------------+ +| qulfontcompiler | | | | X | ++----------------------------------------------------------+ +| Qt Deployment Server | | | | X | ++----------------------------------------------------------+ + + +Rights for Application and Device use cases + +Following table summarizes the rights afforded by different products of the +Licensed Software to create and distribute Applications and Devices as defined +in this Agreement (X marks for rights): + ++---------------------------------------------------------------+ +| | Applications | Devices | ++---------------------------------------------------------------+ +| ADP | X | | ++---------------------------------------------------------------+ +| ADE | X | | ++---------------------------------------------------------------+ +| DCP | X | X | ++---------------------------------------------------------------+ +| DCE | X | X | ++---------------------------------------------------------------+ + +Licensed Software: Designer tools and modules + +The modules and/or tools that are included in the respective product - Qt for +Design Studio Professional (DSP), Qt for Design Studio Enterprise (DSE) - are +marked with "X" in the below table. + +Designer tools provides no Redistributables. + ++---------------------------------------------+ +| | DSP | DSE | ++---------------------------------------------+ +| Qt Design Studio | X | X | ++---------------------------------------------+ +| Qt Design Bridges | | X | ++---------------------------------------------+ +| QML Live on host | X | X | ++---------------------------------------------+ +| QML Live on target | | X | ++---------------------------------------------+ +| Variant Management | | X | ++---------------------------------------------+ +| Shader creation tools | | X | ++---------------------------------------------+ +| Profiling tools | | X | ++---------------------------------------------+ +| Simulink support | | X | ++---------------------------------------------+ + + +Both DSP and DSE can be used to create an user interface for use cases covered +by ADP, ADE, DCP and DCE. + +Licensed Software: QA Tools + +The modules and/or tools that are included in the respective QA Tools product +- Squish (both Tester and execution Licenses), Coco or Test Center - are marked +with "X" in the below table. Optional features that will need additional +licenses are marked with "O". QA Tools include no Redistributables. + ++---------------------------------------------------------------------+ +| | Squish | Coco | Test Center | ++---------------------------------------------------------------------+ +| Squish IDE | X | | | ++---------------------------------------------------------------------+ +| QA Tool-specific command line tools | X | X | X | ++---------------------------------------------------------------------+ +| Coverage Browser | | X | | ++---------------------------------------------------------------------+ +| HTML interface | | | X | ++---------------------------------------------------------------------+ +| Qt Support Module | X | | | ++---------------------------------------------------------------------+ +| Java support module | X | | | ++---------------------------------------------------------------------+ +| Windows support module | X | | | ++---------------------------------------------------------------------+ +| iOS support module | X | | | ++---------------------------------------------------------------------+ +| Android support module | X | | | ++---------------------------------------------------------------------+ +| Web support module | X | | | ++---------------------------------------------------------------------+ +| macOS support module | X | | | ++---------------------------------------------------------------------+ +| VNC support module | X | | | ++---------------------------------------------------------------------+ +| MCU support module | X | | | ++---------------------------------------------------------------------+ +| C and C++ language module | | X | | ++---------------------------------------------------------------------+ +| C# language module | | X | | ++---------------------------------------------------------------------+ +| QML language module | | X | | ++---------------------------------------------------------------------+ +| Tester Cross-Compilation Add-On | O | O | | ++---------------------------------------------------------------------+ + +License capabilities for Squish + +License capabilities that are included in the Squish Tester and Execution +Licenses are marked with "X" in the below table. + ++-----------------------------------------------------------------------------+ +| | Squish Tester License | Squish Execution License | ++-----------------------------------------------------------------------------+ +| Ability to create, edit, | X | | +| and debug test cas | | | ++-----------------------------------------------------------------------------+ +| Ability to execute test | X | X | +| cases | | | ++-----------------------------------------------------------------------------+ + +Install and use capabilities for QA Tools + +Install and use capabilities that are included in the respective QA Tools +products are defined in the below table. + ++-----------------------------------------------------------------------------+ +| | Squish | Squish | Coco | Test | +| | Tester | Execution | License | Center | +| | License | License | | License | ++-----------------------------------------------------------------------------+ +| Number of installation | Unlimited | Unlimited | Unlimited | One(1) | +| instances per license | | | | | ++-----------------------------------------------------------------------------+ +| Number of concurrent | Limited by| Limited by | Limited by | Limited by | +| users | number of | number of | number of | number of | +| | Squish | Squish | Coco | Test Center | +| | Tester | Execution | Tester | Licenses | +| | Licenses | Licenses | Licenses | | ++-----------------------------------------------------------------------------+ + + +APPENDIX 2: PRICING + +Separate template + +APPENDIX 3: ADD-ON PRODUCTS TO LICENSED SOFTWARE + +Intentionally left blank. + +APPENDIX 4: SMALL BUSINESS AND STARTUP + +The provisions of this Appendix 4 are applicable for companies with an annual +revenue, including funding, equivalent to maximum of 250,000 USD (in applicable +currency) during the latest full calendar year, as evidenced by duly audited +records of the Licensee and approved by The Qt Company ("Start-up Company"). + +Start-up Companies are qualified for a discounted License Fee for maximum of +four (4) Development Licenses ("Start-up Development License") unless otherwise +agreed between the parties. + +Start-up Development License entitles the respective Designated User for +Support only for Install Support as defined in Appendix 9, Support Terms. + +Upon expiry of the respective Development License Term, the Start-up +Development Licenses shall be automatically extended, pursuant to Section 3.1 +of the Agreement, for a Renewal Term either as new Start-up Development +Licenses (if the Licensee still qualifies as a Start-up Company), or as normal +then standard list price Development Licenses (if the Licensee no longer +qualifies as a Start-up Company). + +APPENDIX 5: NON-COMMERCIAL AND EDUCATIONAL USE + +The provisions of this Appendix 5 are applicable for non-commercial use of the +Licensed Software by the Licensee. + +For the purpose of this Appendix 5, the following additional definitions +(replacing the relevant definition of the Agreement, where applicable) shall be +applicable: + +"Demo Units" shall mean (i) hardware development platform, which incorporates +the Licensed Software along with Licensee's software and/or hardware, and (ii) +prototype versions of Applications or Devices. + +"Designated User(s)" shall mean the employees and students of the Licensee. + +"Licensee Products" shall mean Applications and/or Devices. + +"Permitted Purpose" shall mean (i) Licensee's internal evaluation and testing +of Licensed Software, (ii) building Demo Units as well as (iii) educational +use. + +"Agreement Term" shall mean a period of twelve (12) months or any such other +period as may be agreed between the Parties. + +For the purpose of this Appendix 5, the following changes shall be agreed with +respect to relevant Sections of the Agreement: + I. Recital (A) shall be replaced in its entirety to read as follows: + "(A) Licensee wishes to use the Licensed Software for the Permitted + Purpose." + II. Section 3.1 shall be replaced in its entirety to read as follows: + "The Qt Company grants to Licensee a personal, non-exclusive, + non-transferable, revocable, royalty-free license, valid for the + Agreement Term, to use, modify and copy the Licensed Software solely + for the Permitted Purpose. Licensee may install copies of the Licensed + Software on five (5) computers per Designated User, provided that only + the Designated Users who have a valid Development License may use the + Licensed Software. Licensee may demonstrate the Demo Units, provided + that such demonstrations must be conducted by Licensee, and the Demo + Units must remain in Licensee's possession and under Licensee's control + at all times. + For clarity, this Agreement does not (i) entitle Licensee to use + Licensed Software to create Applications or Devices (other than + prototypes thereof) or (ii) carry any distribution rights to Licensee, + but such rights are subject to and conditional upon conclusion of a + separate license agreement with The Qt Company." + III. Sections 3.2, 3.3, 3.5, 3.6, 8 and 10 shall be deleted. + IV. Section 3.4 shall be replaced in its entirety to read as follows: + "Licensee shall not: + - remove or alter any copyright, trademark or other proprietary rights + notice contained in any portion of the Licensed Software; + - transfer, publish, sublicense, disclose, display or otherwise make + the Licensed Software available to any third party (except that + Licensee may demonstrate the Demo Units pursuant to Section 3.1); + - in any way combine, incorporate or integrate Licensed Software with, + or use Licensed Software for creation of, any software created with + or incorporating Open Source Qt; Licensee shall cause all Designated + Users who make use of the licenses granted under this Agreement, to + be contractually bound to comply with the relevant terms of this + Agreement and not to use the Licensed Software beyond the terms + hereof. Licensee shall be responsible for any and all actions and + omissions of its Designated Users relating to the Licensed Software + and use thereof. Any use of Licensed Software beyond the provisions + of this Agreement is strictly prohibited and requires an additional + license from The Qt Company." + V. Section 12 shall be replaced in its entirety to read as follows: + "This Agreement shall enter into force upon due acceptance by both + Parties and remain in force for the Agreement Term, unless and until + terminated pursuant to the terms of Section 12. + Upon termination of the Agreement, Licensee shall cease using the + Licensed Software. All other copies of Licensed Software in the + possession or control of Licensee must be erased or destroyed. An + officer of Licensee must, upon request, promptly deliver to The Qt + Company a written confirmation that this has occurred." + +Except for the modifications specified above, this Appendix carries no change +to the terms of the Agreement which shall remain in full force. + +APPENDIX 6: LICENSE REPORTING + +Separate template + +APPENDIX 7: MARKETING RIGHTS + +This Appendix 7 has the purpose to grant visibility through The Qt Company +marketing channels of the usage of Qt and related product and service in +Licensee product. Following related marketing right are agreed between the Qt +Company and the Licensee. + +1. LICENSEE NAME AND LICENSEE LOGO + +The Qt Company has the right to use Licensee name and Licensee logo in public +channel, in respect of the value proposition that the Qt company provided to +the Licensee. + +2. MARKETING CONTENT COOPERATION + +2.1. LICENSEE CASES + +The Licensee is open to collaborate on content creation for marketing and +communication purpose. The Licensee will nominate one responsible that will be +in charge to support The Qt company with this content creation, according to +content format paragraph, answering technical questions or sharing professional +picture or video of required content. The Qt Company will have the right to +advertise this in Content Format and Channel as mentioned in paragraph 3 and 4. + +2.2. FINAL PRODUCT REFERRAL + +Licensee agree that The Qt Company could connect their software product and +services with the Licensee device or application, that the Licensee has created +using The Qt Company technology and competence. Licensee will provide high +quality picture, and video of the created final product where the Qt technology +is running into. The Qt Company will have the right to advertise this in +Content Format and Channel as mentioned in paragraph 3 and 4. + +3. CONTENT FORMAT + +- Video +- Written Licensee case +- Press release +- Social media posts +- Emails +- Event booth Graphics +- Printed material + +4. CHANNELS + +- Social media +- The Qt Company resource center and website +- Email to the Qt company contact database +- Events +- Online webinars +- Public speech +- Public presentations + +APPENDIX 8: INTENTIONALLY LEFT BLANK + +APPENDIX 9: SUPPORT TERMS + +These Qt support terms and conditions ("Support Terms") set forth the legal +framework, where under The Qt Company ("The Qt Company") provides support +services (as herein defined) to the Licensee. + +1 DEFINITIONS + +"Application Code" shall mean a computer software program written strictly +using the Qt programming language, by or for the Licensee, with a user +interface, enabling the Licensee or their users to accomplish a specific task +and display any results of the task on the display monitor or screen. + +"Dedicated Contact" shall mean the employee of The Qt Company who will be the +first point of contact for all Designated Users' requests for Support. + +"Errors" shall mean an error, flaw, mistake, failure, or fault in Licensed +Software that prevents it from behaving as described in the relevant +documentation or as agreed between the Parties. + +"Extended Support" shall mean a continuation to the normal Support period, +which allows Designated Users to receive selected Support (Standard Support or +Premium Support) for a version of Licensed Software that is no longer generally +supported by The Qt Company. + +"Install Support" shall mean Support that is limited to installation related +Error(s) on Development Platforms specified as supported host platforms for +each Qt release under doc.qt.io. + +"Maintenance Release" shall mean a release or version of Licensed Software +containing bug fixes, error corrections and other changes targeted to +maintaining and improving product stability and quality. Maintenance Releases +are generally depicted as a change to the third digit of Licensed Software +version number. + +"Platforms" shall mean both Development Platforms and Deployment Platforms. +Supported host and target Platforms may vary from for each Qt release as +defined under doc.qt.io. + +"Premium Support" shall mean an upgraded level of Support that The Qt Company +provides pursuant to these Support Terms to Licensee if Licensee has purchased +Premium Support instead of Standard Support. Premium Support shall always be +purchased for all Designated User(s) in the respective development team of the +Licensee. + +"Response Time" shall mean the period of time from when Licensee notifies +TheQt Company about an Error or requests Support until The Qt Company provides +Licensee with a response that addresses (but not necessarily resolves) the +reported Error or provides the requested Support. + +"Standard Support" shall mean standard level of Support that The Qt Company +provides pursuant to these Support Terms to Licensee. + +"Support" shall mean developer assistance that is provided by The Qt Company +to assist eligible Designated Users in Licensed Software installation, usage +and functionality problem resolution for Error(s) and Error workarounds +pursuant to the terms of these Support Terms. Support for different products is +available as specified in the below table ("X" marking the Support that is +included in the license price, optional Add-on Support services are marked as +"O"): + ++-----------------------------------------------------------------------+ +| |ADP|ADE|DCP|DCE|DSP|DSE|Squish|Coco|Test Center| ++-----------------------------------------------------------------------+ +| Install Support | X | X | X | X | X | X | X | X | X | ++-----------------------------------------------------------------------+ +| Standard Support | | X | X | X | X | X | X | X | X | ++-----------------------------------------------------------------------+ +| Premium Support | | O | O | O | O | O | O | O | O | ++-----------------------------------------------------------------------+ +| Extended Support | | O | O | O | O | O | | | | ++-----------------------------------------------------------------------+ +| Tool Qualification Kit| | | | | | | O | O | | ++-----------------------------------------------------------------------+ + +"Support Validity Term" shall mean the Development License Term or any other +fixed time period agreed between the Parties during which time the Customer is +eligible to receive Support from The Qt Company. + +"Tool Qualification Kit" shall mean a customized set of documents and +validation test cases. + +2 SUPPORT SERVICES + +2.1 Support Services Provided by The Qt Company + +Subject to these Support Terms and during the Support Validity Term, The Qt +Company will via its web-based support user-interface, provide Designated +User(s) with Support for the Platforms which Customer has licensed under the +Agreement. +The Qt Company will make commercially reasonable efforts to solve any Errors +reported by Designated User(s). Resolution of an Error may be provided through +Designated User(s) themselves downloading of a later released version of the +applicable Licensed Software product(s) or providing the Designated User with a +temporary workaround addressing such Error. + +2.2 Licensee's Obligations + +To report an Error, the Designated User shall register the Error on The Qt +Company's web-based support user interface located at: +https://account.qt.io/login or at another location designated by The Qt Company. + +The Designated User must provide adequate information and documentation to The +Qt Company to enable it to recreate the Error or problem for which the +Designated User has sought assistance. +To ensure efficient handling of Errors, the Designated User must provide the +following information, where relevant: +- A clear, detailed description of the problem, question or suggestion; +- Identification of which Licensed Software product and version is affected; +- Identification of the operating environment (e.g. operating system, hardware + Platform, build tools, etc.) on which the problem exists; +- On Standard Support: A complete and compilable test case of not more than 500 + lines of code that demonstrates the problem; +- On Premium Support: A complete and compilable test case that demonstrates the + problem or access to Application Code source codes. + +Additional relevant content, such as screenshots, etc. +Additional content should be included as attachments. The preferred image +formats are JPEG and PNG. Compressed content should be included in zip or +tar.gz archives. Executable content and documents in platform specific formats +such as Microsoft Office' are not accepted. + +In order for The Qt Company to provide prompt handling of Errors, the +Designated User shall promptly respond to any requests from The Qt Company for +additional information. + +2.3 Support Limitations + +General limitations: + +Each version or release of the Licensed Software will be Supported under +Standard Support or Premium Support only for limited time period as set forth +in doc.qt.io. For example, regular releases of Qt Software are supported for +one (1) year from the release date of the version x.y.0 and Long Term Support +(LTS) Releases are supported for a period of three (3) years from the release +date of the LTS version x.y.0. + +The Qt Company shall only provide Support for Designated User(s). + +Support is made available for the entire development teams only: It is not +allowed to purchase Support only for some members of the development team, and +all Designated Users of the respective development team must be eligible for +the same level of Support. + +Support is not provided for snapshots, preview releases, beta releases or +release candidates. + +The Qt Company shall have no obligation to provide Support for hardware or +operating system specific problems or problems arising from improper use, +accident, neglect or modification of Qt. + +Limitations with Install Support: + +Support limited to Error(s) regarding installation and setting up of the Qt +development environment on host Platforms. + +Limitations with Standard Support: + +The Qt Company shall not provide Support for third-party software or problems +caused by third-party software even if such third-party software is distributed +together with Licensed Software product(s). + +The Qt Company shall only provide Support for Error(s) that are reported on and +can be reproduced on Platforms that are officially supported for the release of +the Licensed Software. + +Limitations with Premium support: + +The Qt Company shall not provide Support for third-party software or problems +caused by third-party software. However, if such third-party software is +distributed together with Licensed Software, The Qt Company will make +commercially reasonable efforts to solve such problems. + +The Qt Company shall only provide Support for Error(s) that can be reproduced +on Platforms that are officially supported for the release of the Licensed +Software. If the Error is on a Platform that is not supported, The Qt Company +will make commercially reasonable efforts to provide a solution on closest +corresponding supported Platform. + +Premium Support is optional and purchased for an agreed bucket of hours +("Bucket"). Hours can be used by any Designated User in the respective +development team. To encourage continuous usage of the Support, ten percent +(10%) of the purchased Bucket shall automatically expire (regardless of whether +such support hours are actually used or not by the Licensee) each month after +three (3) months from the purchase of the Premium Support. + +2.4 Extended Support + +Extended Support extends the Support Validity Term for a release of Licensed +Software that is no longer generally supported. + +Extended Support includes and is by default provided with Standard Support +rules and limitations, unless Extended Support is purchased with Premium +Support in which case Premium Support rules and limitations will apply. + +Extended Support is optional and purchased with annual fee and separately per +each Licensee product. Extended Support will need definition of (i) Licensee +product, (ii) used Platform(s) and (iii) Licensed Software version(s). + +2.5 Tool Qualification Kit + +The Qt Company shall provide set of customized documents and validation tests +that enable Licensee to qualify QA testing tool for the purpose of ISO 26262, +EN 50128, DO-330, IEC 61508, IEC 62304 or IEC 13485 certification Licensee end +to end solution. + +3 RESPONSE TIME + +In performing Support, The Qt Company shall commit to following, non-binding, +Response Times: + +Standard Support: Errors and Support requests will have a Response Time not to +exceed two (2) business days. + +Premium Support: Errors and Support requests will have a Response Time not to +exceed one (1) business day. + +For complex issues, The Qt Company may provide an initial response to the +Designated User and then follow up, without undue delay, with additional +communication before an Error is properly addressed or Support provided. + +4 ADDITIONAL SERVICES IN PREMIUM SUPPORT + +The Designated User(s) will be assigned a Dedicated Contact to handle requests +for Support. Dedicated Contact is subject to change in cases such as sick +leave, vacation and other similar reasons. + +The Designated User(s) can on request ask The Qt Company to access their +computer remotely in order to resolve problems directly. + +The Designated User(s) can request a session via Instant Messaging or phone +call in the support request to The Qt Company. + +Premium Support can assist Licensee in implementing new features, bug fixes +and accessing patches in Licensed Software or Application Code. + +All Support requests will be handled with high priority. + +5 MAINTENANCE RELEASES, UPDATES AND UPGRADES + +Under the Support the Customer is eligible for Maintenance Releases and Updates +that The Qt Company generally makes available to customers who has purchased +Support. Unless otherwise decided by The Company at its free and absolute +discretion, Upgrades will not be provided under the Support. + +The primary focus of Maintenance Releases is product quality. Therefore, each +Maintenance Release typically includes the following types of changes to the +previous version of Licensed Software: +- Bug fixes caused by changes to previously working code; +- Fixes related to build issues on supported Platforms; +- Error corrections specific to a single Platform that are not present on other + Platforms; +- Critical Error corrections such as crashes, data corruption, loss of data, + race conditions; and +- Updates to documentation and license information when deemed necessary by + The Qt Company. + +The primary focus of Updates is introducing new features to Licensed Software +and covering new platforms. Therefore, each Updates typically includes the +following types of changes to the previous version of Licensed Software: +- New platform support; +- New toolchain support; +- New features and Qt modules; + +6 WARRANTY DISCLAIMER + +The Qt Company makes no warranties that the Support provided will be successful +in resolving any difficulties or problems or in diagnosing faults reported by +Licensee. Support is provided to Licensee on an "as is" basis. To the maximum +extent permitted by applicable law, The Qt Company disclaims all warranties and +conditions, either express or implied, including, but not limited to, implied +warranties of merchantability and fitness for a particular purpose for the +Support provided by The Qt Company to Licensee. + +APPENDIX 10: CONVERSION TO SUBSCRIPTION + +Subject to the terms of this Appendix Licensee's current development licenses +("Current Licenses") for commercial version of Qt Software and the license +agreements governing such Current Licenses ("Existing Agreements") are being +replaced by this Agreement and subscription based Development Licenses +governed hereunder, as further specified below. + ++---------------------------------------------------------------------------+ +| Existing Agreement(s) | and | +| signing parties, version | | +| thereof | | ++---------------------------------------------------------------------------+ + +Parties hereby agree on conversion of Current Licenses listed in attached +Exhibit A to the subscription licenses listed in attached Exhibit B for use +through License Term. As of the date hereof, + +i. Licensee's Current Licenses as listed in Exhibit A shall terminate and be +replaced with the Subscription licenses listed in Exhibit B and; +ii. Existing Agreements are terminated. + +Prices for the conversion of Current Licenses are defined in Appendix 2 +Pricing or Quote. + +Notwithstanding anything in this Appendix to the contrary, and in addition to +any payments due pursuant to this Appendix, Licensee remains fully obligated to +fulfill any and all outstanding payment obligations to The Qt Company under any +applicable Existing Agreements. For the avoidance of doubt, if any payments +remain outstanding on the Current Licenses under the applicable terms Licensee +will continue to make such payments in accordance with the applicable order +documentation, notwithstanding the fact that the Current Licenses are being +converted to Development Licenses pursuant to this Appendix. diff --git a/.cmake.conf b/.cmake.conf new file mode 100644 index 0000000..7fc40b7 --- /dev/null +++ b/.cmake.conf @@ -0,0 +1,4 @@ +set(QT_REPO_MODULE_VERSION "6.4.2") +set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") + +set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_LEAN_HEADERS=1") diff --git a/.qmake.conf b/.qmake.conf new file mode 100644 index 0000000..424c652 --- /dev/null +++ b/.qmake.conf @@ -0,0 +1,6 @@ +load(qt_build_config) +CONFIG += warning_clean + +DEFINES += QT_NO_JAVA_STYLE_ITERATORS + +MODULE_VERSION = 6.4.2 diff --git a/.tag b/.tag new file mode 100644 index 0000000..a84a58f --- /dev/null +++ b/.tag @@ -0,0 +1 @@ +6d9979ac0c94006fbea7fe2a1633e09ccb14a441 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..520f931 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.16) + +include(.cmake.conf) +project(QtPositioning + VERSION "${QT_REPO_MODULE_VERSION}" + DESCRIPTION "Qt Positioning Libraries" + HOMEPAGE_URL "https://qt.io/" + LANGUAGES CXX C +) + +# Make sure we use the fixed BASE argument of qt_add_resource. +set(QT_USE_FIXED_QT_ADD_RESOURCE_BASE TRUE) + +find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Core) +find_package(Qt6 ${PROJECT_VERSION} QUIET CONFIG OPTIONAL_COMPONENTS Quick Qml Gui Widgets Network Test DBus SerialPort QuickTest) + +if(WASM) + message(NOTICE "Skipping the build as the condition \"NOT WASM\" is not met.") + return() +endif() +qt_build_repo() diff --git a/LICENSES/BSD-3-Clause.txt b/LICENSES/BSD-3-Clause.txt new file mode 100644 index 0000000..b91bbd8 --- /dev/null +++ b/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,9 @@ +Copyright (c) . + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSES/CC0-1.0.txt b/LICENSES/CC0-1.0.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/LICENSES/GFDL-1.3-no-invariants-only.txt b/LICENSES/GFDL-1.3-no-invariants-only.txt new file mode 100644 index 0000000..857214d --- /dev/null +++ b/LICENSES/GFDL-1.3-no-invariants-only.txt @@ -0,0 +1,451 @@ + + GNU Free Documentation License + Version 1.3, 3 November 2008 + + + Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The "publisher" means any person or entity that distributes copies of +the Document to the public. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no +other conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to +give them a chance to provide you with an updated version of the +Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other +documents released under this License, and replace the individual +copies of this License in the various documents with a single copy +that is included in the collection, provided that you follow the rules +of this License for verbatim copying of each of the documents in all +other respects. + +You may extract a single document from such a collection, and +distribute it individually under this License, provided you insert a +copy of this License into the extracted document, and follow this +License in all other respects regarding verbatim copying of that +document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions of the +GNU Free Documentation License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. See +https://www.gnu.org/licenses/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +11. RELICENSING + +"Massive Multiauthor Collaboration Site" (or "MMC Site") means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +"Massive Multiauthor Collaboration" (or "MMC") contained in the site +means any set of copyrightable works thus published on the MMC site. + +"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +"Incorporate" means to publish or republish a Document, in whole or in +part, as part of another Document. + +An MMC is "eligible for relicensing" if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole or +in part into the MMC, (1) had no cover texts or invariant sections, and +(2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/LICENSES/GPL-2.0-only.txt b/LICENSES/GPL-2.0-only.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSES/GPL-2.0-only.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/LICENSES/GPL-3.0-only.txt b/LICENSES/GPL-3.0-only.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/LICENSES/GPL-3.0-only.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSES/LGPL-3.0-only.txt b/LICENSES/LGPL-3.0-only.txt new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/LICENSES/LGPL-3.0-only.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/LICENSES/LicenseRef-Qt-Commercial.txt b/LICENSES/LicenseRef-Qt-Commercial.txt new file mode 100644 index 0000000..825b1f3 --- /dev/null +++ b/LICENSES/LicenseRef-Qt-Commercial.txt @@ -0,0 +1,8 @@ +Licensees holding valid commercial Qt licenses may use this software in +accordance with the the terms contained in a written agreement between +you and The Qt Company. Alternatively, the terms and conditions that were +accepted by the licensee when buying and/or downloading the +software do apply. + +For the latest licensing terms and conditions, see https://www.qt.io/terms-conditions. +For further information use the contact form at https://www.qt.io/contact-us. diff --git a/LICENSES/Qt-GPL-exception-1.0.txt b/LICENSES/Qt-GPL-exception-1.0.txt new file mode 100644 index 0000000..d0322bf --- /dev/null +++ b/LICENSES/Qt-GPL-exception-1.0.txt @@ -0,0 +1,22 @@ +The Qt Company GPL Exception 1.0 + +Exception 1: + +As a special exception you may create a larger work which contains the +output of this application and distribute that work under terms of your +choice, so long as the work is not otherwise derived from or based on +this application and so long as the work does not in itself generate +output that contains the output from this application in its original +or modified form. + +Exception 2: + +As a special exception, you have permission to combine this application +with Plugins licensed under the terms of your choice, to produce an +executable, and to copy and distribute the resulting executable under +the terms of your choice. However, the executable must be accompanied +by a prominent notice offering all users of the executable the entire +source code to this application, excluding the source code of the +independent modules, but including any changes you have made to this +application, under the terms of this license. + diff --git a/cmake/FindGconf.cmake b/cmake/FindGconf.cmake new file mode 100644 index 0000000..d2db910 --- /dev/null +++ b/cmake/FindGconf.cmake @@ -0,0 +1,14 @@ +find_package(PkgConfig QUIET) +if (PkgConfig_FOUND) + pkg_check_modules(Gconf gconf-2.0 IMPORTED_TARGET) + + if (TARGET PkgConfig::Gconf) + mark_as_advanced(Gconf_LIBRARIES Gconf_INCLUDE_DIRS) + if (NOT TARGET Gconf::Gconf) + add_library(Gconf::Gconf INTERFACE IMPORTED) + target_link_libraries(Gconf::Gconf INTERFACE PkgConfig::Gconf) + endif() + else() + set(Gconf_FOUND 0) + endif() +endif() diff --git a/cmake/FindGypsy.cmake b/cmake/FindGypsy.cmake new file mode 100644 index 0000000..3639568 --- /dev/null +++ b/cmake/FindGypsy.cmake @@ -0,0 +1,14 @@ +find_package(PkgConfig QUIET) +if (PkgConfig_FOUND) + pkg_check_modules(Gypsy gypsy IMPORTED_TARGET) + + if (TARGET PkgConfig::Gypsy) + mark_as_advanced(Gypsy_LIBRARIES Gypsy_INCLUDE_DIRS) + if (NOT TARGET Gypsy::Gypsy) + add_library(Gypsy::Gypsy INTERFACE IMPORTED) + target_link_libraries(Gypsy::Gypsy INTERFACE PkgConfig::Gypsy) + endif() + else() + set(Gypsy_FOUND 0) + endif() +endif() diff --git a/coin/module_config.yaml b/coin/module_config.yaml new file mode 100644 index 0000000..16d158c --- /dev/null +++ b/coin/module_config.yaml @@ -0,0 +1,12 @@ +version: 2 +accept_configuration: + condition: property + property: features + not_contains_value: Disable + +instructions: + Build: + - !include "{{qt/qtbase}}/coin_module_build_template_v2.yaml" + + Test: + - !include "{{qt/qtbase}}/coin_module_test_template_v3.yaml" diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 0000000..5fd70d2 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,53 @@ +# Copyright (C) 2021 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +from conans import ConanFile +import re +from pathlib import Path +from typing import List, Dict, Any + + +def _parse_qt_version_by_key(key: str) -> str: + with open(Path(__file__).parent.resolve() / ".cmake.conf") as f: + m = re.search(fr'{key} .*"(.*)"', f.read()) + return m.group(1) if m else "" + + +def _get_qt_minor_version() -> str: + return ".".join(_parse_qt_version_by_key("QT_REPO_MODULE_VERSION").split(".")[:2]) + + +class QtPositioning(ConanFile): + name = "qtpositioning" + license = "LGPL-3.0, GPL-2.0+, Commercial Qt License Agreement" + author = "The Qt Company " + url = "https://code.qt.io/cgit/qt/qtpositioning.git" + description = "Qt Positioning support." + topics = "qt", "qt6", "positioning" + settings = "os", "compiler", "arch", "build_type" + # for referencing the version number and prerelease tag and dependencies info + exports = ".cmake.conf", "dependencies.yaml" + exports_sources = "*", "!conan*.*" + python_requires = f"qt-conan-common/{_get_qt_minor_version()}@qt/everywhere" + python_requires_extend = "qt-conan-common.QtLeafModule" + + def get_qt_leaf_module_options(self) -> Dict[str, Any]: + """Implements abstractmethod from qt-conan-common.QtLeafModule""" + return {"force_nmea_plugin": ["yes", "no", None]} + + def get_qt_leaf_module_default_options(self) -> Dict[str, Any]: + """Implements abstractmethod from qt-conan-common.QtLeafModule""" + return {"force_nmea_plugin": "yes"} + + def override_qt_requirements(self) -> List[str]: + """Implements abstractmethod from qt-conan-common.QtLeafModule""" + requirements = ["qtbase", "qtdeclarative"] + if self.options.force_nmea_plugin: + requirements.append("qtserialport") + return requirements + + def is_qt_module_feature(self, option_name: str) -> bool: + """Implements abstractmethod from qt-conan-common.QtLeafModule""" + if option_name == "force_nmea_plugin": + return False + return True diff --git a/config.tests/gypsy/CMakeLists.txt b/config.tests/gypsy/CMakeLists.txt new file mode 100644 index 0000000..41b4646 --- /dev/null +++ b/config.tests/gypsy/CMakeLists.txt @@ -0,0 +1,30 @@ +# Generated from gypsy.pro. + +cmake_minimum_required(VERSION 3.16) +project(config_test_gypsy LANGUAGES C CXX) + +if(DEFINED QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_PREFIX_PATH) + set(CMAKE_SYSTEM_PREFIX_PATH "${QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_PREFIX_PATH}") +endif() +if(DEFINED QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_FRAMEWORK_PATH) + set(CMAKE_SYSTEM_FRAMEWORK_PATH "${QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_FRAMEWORK_PATH}") +endif() + +foreach(p ${QT_CONFIG_COMPILE_TEST_PACKAGES}) + find_package(${p}) +endforeach() + +if(QT_CONFIG_COMPILE_TEST_LIBRARIES) + link_libraries(${QT_CONFIG_COMPILE_TEST_LIBRARIES}) +endif() +if(QT_CONFIG_COMPILE_TEST_LIBRARY_TARGETS) + foreach(lib ${QT_CONFIG_COMPILE_TEST_LIBRARY_TARGETS}) + if(TARGET ${lib}) + link_libraries(${lib}) + endif() + endforeach() +endif() + +add_executable(${PROJECT_NAME} + main.cpp +) diff --git a/config.tests/gypsy/main.cpp b/config.tests/gypsy/main.cpp new file mode 100644 index 0000000..e215232 --- /dev/null +++ b/config.tests/gypsy/main.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include + +int main() +{ + GypsyControl *control = gypsy_control_get_default(); + GypsyDevice *device = gypsy_device_new("test"); + GypsySatellite *satellite = gypsy_satellite_new("test"); + + GConfClient *client = gconf_client_get_default(); + g_object_unref(client); + + return 0; +} diff --git a/config.tests/winrt/CMakeLists.txt b/config.tests/winrt/CMakeLists.txt new file mode 100644 index 0000000..828ab37 --- /dev/null +++ b/config.tests/winrt/CMakeLists.txt @@ -0,0 +1,36 @@ +# Generated from winrt.pro. + +cmake_minimum_required(VERSION 3.16) +project(config_test_winrt LANGUAGES C CXX) + +if(DEFINED QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_PREFIX_PATH) + set(CMAKE_SYSTEM_PREFIX_PATH "${QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_PREFIX_PATH}") +endif() +if(DEFINED QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_FRAMEWORK_PATH) + set(CMAKE_SYSTEM_FRAMEWORK_PATH "${QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_FRAMEWORK_PATH}") +endif() + +foreach(p ${QT_CONFIG_COMPILE_TEST_PACKAGES}) + find_package(${p}) +endforeach() + +if(QT_CONFIG_COMPILE_TEST_LIBRARIES) + link_libraries(${QT_CONFIG_COMPILE_TEST_LIBRARIES}) +endif() +if(QT_CONFIG_COMPILE_TEST_LIBRARY_TARGETS) + foreach(lib ${QT_CONFIG_COMPILE_TEST_LIBRARY_TARGETS}) + if(TARGET ${lib}) + link_libraries(${lib}) + endif() + endforeach() +endif() + +add_executable(${PROJECT_NAME} + main.cpp +) + +if(MSVC) + target_link_libraries(${PROJECT_NAME} PRIVATE + runtimeobject + ) +endif() diff --git a/config.tests/winrt/main.cpp b/config.tests/winrt/main.cpp new file mode 100644 index 0000000..3c9c549 --- /dev/null +++ b/config.tests/winrt/main.cpp @@ -0,0 +1,22 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include +#include + +using namespace Microsoft::WRL::Wrappers; +using namespace ABI::Windows::Devices::Geolocation; +using namespace ABI::Windows::Foundation; + +typedef IAsyncOperationCompletedHandler AccessHandler; + +int main(int, char**) +{ + IGeolocator *locator; + RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(), + reinterpret_cast(&locator)); + return 0; +} diff --git a/configure.json b/configure.json new file mode 100644 index 0000000..d54624a --- /dev/null +++ b/configure.json @@ -0,0 +1,5 @@ +{ + "subconfigs": [ + "src/positioning" + ] +} diff --git a/dependencies.yaml b/dependencies.yaml new file mode 100644 index 0000000..fa7ad76 --- /dev/null +++ b/dependencies.yaml @@ -0,0 +1,10 @@ +dependencies: + ../qtbase: + ref: e3e40c44d3f998a433a6a1080297c5f28e9a768f + required: true + ../qtdeclarative: + ref: 1b58f30087eedf42f16572d8ae1d6a5b18f3d698 + required: false + ../qtserialport: + ref: a29d4f9bb7f6145a6bfe0a0bb3889412a7032bfb + required: false diff --git a/dist/changes-5.10.0 b/dist/changes-5.10.0 new file mode 100644 index 0000000..1703cf6 --- /dev/null +++ b/dist/changes-5.10.0 @@ -0,0 +1,62 @@ +Qt 5.10 introduces many new features and improvements as well as bugfixes +over the 5.9.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.10 series is binary compatible with the 5.9.x series. +Applications compiled for 5.9 will continue to run with 5.10. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.10.0 Changes * +**************************************************************************** + + - This release contains only minor code improvements. + +QtLocation +---------- + + - Map: + * [QTBUG-55782] Added methods to add or remove MapItemViews at runtime. + * Visible region now returns a QGeoPolygon. + + - MapGestureArea: + * Added rotation and tilt scroll wheel actions. + + - MapPolyline: + * Added setPath overload taking a QGeoPath. + + - MapboxGL: + * Updated Mapbox GL Native to v1.1.0. + * [QTBUG-62002] Updated map styles. + * [QTBUG-61442] Fix MapParameter dynamic usage. + + - QDeclarativeGeoMap: + * Added setBearing overload to rotate the map around a given + QGeoCoordinate. + * Added alignCoordinateToPoint method to QDeclarativeGeoMap. + + - QDeclarativeGeoMapType: + * [QTBUG-58931] Added CameraCapabilities and metadata properties to + QDeclarativeGeoMapType. + + - QGeoRouteRequest/RouteQuery: + * Add TrafficFeature to the query features. + +QtPositioning +------------- + + - QGeoPath: + * Add ::size() to QGeoPath to retrieve the number of coordinates in the + path. + + - QGeoPolygon: + * Added QGeoPolygon shape. diff --git a/dist/changes-5.10.1 b/dist/changes-5.10.1 new file mode 100644 index 0000000..695c4e3 --- /dev/null +++ b/dist/changes-5.10.1 @@ -0,0 +1,26 @@ +Qt 5.10.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.10.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.10 series is binary compatible with the 5.9.x series. +Applications compiled for 5.9 will continue to run with 5.10. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +This release contains all fixes included in the Qt 5.9.4 release. + +**************************************************************************** +* Qt 5.10.1 Changes * +**************************************************************************** + + - This release contains only minor code improvements. diff --git a/dist/changes-5.11.0 b/dist/changes-5.11.0 new file mode 100644 index 0000000..aae6398 --- /dev/null +++ b/dist/changes-5.11.0 @@ -0,0 +1,116 @@ +Qt 5.11 introduces many new features and improvements as well as bugfixes +over the 5.10.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.11.0 Changes * +**************************************************************************** + +QtLocation +---------- + + - Qt.labs.location + * A new experimental QML plugin introduced, Qt.labs.location, which + offers two new categories of QML elements: Map Objects and the + Navigator type. Both are experimental, not supposed to work in every + setup (check documentation). This plugin can be disabled at configure + time, through the location-labs-plugin feature. + * Map objects are supposed to be QQuickItem-less equivalents of + Map Items. They are supposed to be easy to implement in plugins, and + to introduce minimal overhead. They come with a reference + implementation based on QSGNodes, that is supposed to work in all of the + currently offered raster based plugins. + At the present, the MapboxGL plugin does not offer map objects support. + * The Navigator type is a new QML api to expose turn-by-turn navigation + functions present in plugins. It requires a plugin supporting + one of the Navigation capabilities to actually work. + At the present, none of the open source plugins have these capabilities. + + - MapParameter + * MapParameter type now deprecated and re-registered under the DynamicParameter + name. + + - QGeoServiceProvider/QGeoServiceProviderFactory + * Added QGeoServiceProviderFactoryV2, capable of producing + QNavigationManagerEngine objects. + Note: QNavigationManagerEngine is private API. + + - QGeoPath + * The path property changed type, from QList to + QVariantList. This is binary-compatible with the previous release, + and source-compatible in QML. + It may, however, introduce source incompatibilities when using + the QObject property API in C++ (::property and ::setProperty), for + example in the generation of language bindings. + For the regular user-code, the use case was deemed as rare enough + (since QGeoShape has a public setter/getter for the path) to not cause + any problem. + As the beta phase passed without issues, this change was therefore left in place. + + - QGeoRoute + * QGeoRoute, QGeoRouteSegment and QGeoManeuver private implementation are + now (privately) exported and can be subclassed in plugins to provide + custom private implementations. + * QGeoRouteRequest now allows to specify extra parameters in QVariantMap form. + * RouteQuery (QDeclarativeGeoRouteQuery) now allows to specify extra parameters + through Map/DynamicParameters. + * Added extended attributes to QGeoManeuver/QDeclarativeGeoManeuver. + * [QTBUG-64066] Introduced new Waypoint QML type, intended to replace + QGeoCoordinate as mean to specify waypoints in a RouteQuery. + + - QPlace + * QPlace private implementation is now (privately) exported and can be + subclassed in plugins to provide custom private implementations. + * QPlaceContent::Type has a new value, CustomType. + + - QDeclarativeGeoMap + * [QTBUG-66315] Fixed a crash calling Map.clearMapItems before Map is + initialized. + * Fixed MapGestureArea not emitting when controlled with scroll wheel. + * [QTBUG-66880] Fixed clearData not triggering scene update. + * [QTBUG-67580] Fixed crash in QQuickGeoMapGestureArea. + * [QTBUG-67759] Fixed crash when calling clearData at startup. + + - Map Items + * [QTBUG-66758] Fixed re-set map items rendering stale geometry. + * [QTBUG-38459] Fixed the geometry of map items so that, if layers.enabled + is set to true, the scene graph renderer will not cut the items borders + anymore. + * [QTBUG-66692, QTBUG-66830] Fixed polyline geometry generation. + * [QTBUG-62086, QTBUG-65833] Fixed MapItemView not setting context data + upon item deletion. + * [QTBUG-67765] Fixed interaction with Map Items borders. + + - Plugins + * Mapbox: Added OnlinePlacesFeature, PlaceRecommendationsFeature, SearchSuggestionsFeature + and LocalizedPlacesFeature. + * Mapbox: Added OnlineGeocodingFeature, ReverseGeocodingFeature and LocalizedGeocodingFeature. + * Mapbox/OSM: OSRM backend now returns extended attributes for the maneuvers, such as + bearing_before, bearing_after, instruction, type and modifier. + * Mapbox/OSM: OSRM backend now uses Waypoint's bearing when sending a route request. + * Mapbox/OSM: Added OSRM's {leg,step}_index extra attribute to QGeoManeuver. + * Mapbox: Supported Mapbox Directions API voice & banner instructions. + * MapboxGL: Added map margins support via 'margins' map parameter. + * HERE: the plugin now uses Waypoint's bearing when sending a route request. + * OSM: supported the query limit parameter in the nominatim backend. + + +QtPositioning +---------- + + * [QTBUG-65937] Metatype for QGeoPositionInfo is now declared and registered. + This change introduces a potential source incompatibility, as existing user code may + contain the type registration already. diff --git a/dist/changes-5.11.1 b/dist/changes-5.11.1 new file mode 100644 index 0000000..4ce6df8 --- /dev/null +++ b/dist/changes-5.11.1 @@ -0,0 +1,40 @@ +Qt 5.11.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.11.1 Changes * +**************************************************************************** + +QtLocation +---------- + +* [QTBUG-63223] Fixed MapPolyline documentation. +* Fixed a crash in Map{Polyline,Polygon,Route}ObjectQsg. +* [QTBUG-68261] Changed nominatim default endpoint base URL to HTTPS. +* Bumped mapbox-gl-native to the latest version, fixing offline tiles support. +* [QTBUG-68121] Supported raster-dem source types in the MapboxGL plugin. +* [QTBUG-68358] Added missing route query parameters to the query in the mapbox plugin. +* [QTBUG-68366] Fixed MapItemView deleting wrong item after changing to use the delegate model internally. +* [QTBUG-68598] Supported dynamic QObject properties in QMapboxGLStyleChange. + + +QtPositioning +------------- + +* [QTBUG-64699] Fixed QGeoPositionInfo timestamp comparison in nmea source. diff --git a/dist/changes-5.11.2 b/dist/changes-5.11.2 new file mode 100644 index 0000000..ffc0b7d --- /dev/null +++ b/dist/changes-5.11.2 @@ -0,0 +1,38 @@ +Qt 5.11.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0 through 5.11.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.11.2 Changes * +**************************************************************************** + +QtLocation +---------- + +* [QTBUG-68086] Documented potential SSL dependency in OSM provider. +* [QTBUG-69031] Added Qt.labs.location::Navigator::trackPositionSource property. +* [QTBUG-69262] Improved the Clipper dependency attribution file. +* [QTBUG-59665] Removed indexing of offline data from OSM plugin. + + +QtPositioning +------------- + +* Reduced minimum NMEA update interval. +* [QTBUG-64699] NMEA sentences now combined by timestamp also in live mode. + diff --git a/dist/changes-5.11.3 b/dist/changes-5.11.3 new file mode 100644 index 0000000..9b09a0c --- /dev/null +++ b/dist/changes-5.11.3 @@ -0,0 +1,32 @@ +Qt 5.11.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0 through 5.11.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.11.3 Changes * +**************************************************************************** + + QtLocation + ---------- + + - [QTBUG-69617] Fixed Qt.labs.location not linking statically on iOS. + - [QTBUG-71355] Fixed crash when calling QGeoPath::length() on empty + QGeoPath instance. + - Fixed place search matching based on category in mapbox plugin. Previously, + the search results contained places which did not have any category set. + diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0 new file mode 100644 index 0000000..4fd5b69 --- /dev/null +++ b/dist/changes-5.12.0 @@ -0,0 +1,52 @@ +Qt 5.12 introduces many new features and improvements as well as bugfixes +over the 5.11.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* QtLocation * +**************************************************************************** + + + - Added QDeclarativeGeoRoute::equals to perform deep comparisons in QML. + - MapItemView now exposes add and remove transitions, so that they can + be changed (defaults are none for add, and item fade out for remove). + - Enabled incremental updates in PlaceSearchModel, which prevents previousPage or + nextPage from resetting the model, but rather appending the new data to it. + - [QTBUG-68966] Added Map.visibleArea property. + - [QTBUG-62683][QTBUG-62397] Enabled nesting of MapItemView. This required + a behavioral change, as MapItemView is now a MapItemGroup, not anymore a + plain QObject. Due to a bug, MapItemView was previously not a Qt Quick + Item, making it possible to create it as a child of any QObject. This + has now been fixed, so if you happen to have a MapItemView in your scene + which is not a child of a Qt Quick Item, you will get an error message. + - Enabled asynchronous incremental updates of QPlaceReply. + - Changed QDeclarativeGeoMapItemBase::geoShape property from read-only into R/W. + - Added support for route legs. + - [QTBUG-70499] Fixed HERE plugin requesting the route incorrectly. + - Added ESRI place search manager to the ESRI plugin. + +**************************************************************************** +* QtPositioning * +**************************************************************************** + + - Exposed mercatorToCoord and coordToMercator to QML. + - [QTBUG-62875] QGeoPath can now be cleared directly using clearPath. + - Added QGeoPolygon::perimeter property. + - Added holes support to QGeoPolygon. Currently visualized only when using + in a MapPolygon with the MapboxGL plugin. + - [QTBUG-43435] Added Geoclue2 position plugin. + - [QTBUG-52660] QtPositioning now properly checks for authorization on iOS. + diff --git a/dist/changes-5.12.1 b/dist/changes-5.12.1 new file mode 100644 index 0000000..2ea2eda --- /dev/null +++ b/dist/changes-5.12.1 @@ -0,0 +1,56 @@ +Qt 5.12.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* QtLocation * +**************************************************************************** + + + - Exposed support for chinese maps in the MapboxGL plugin. + - Fixed unstable rotation gesture on some platforms. + - [QTBUG-71607] Fixed MapPolyline drawing incorrectly at high zoom levels. + - [QTBUG-71607] Fixed missing geometry update when changing map items + border width. + - [QTBUG-71264] Fixed MapItemView removing wrong indices on model changes. + - Added QAbstractNavigator::setTrackPosition. + - [QTBUG-70254] Improved the initialization behavior of CategoryModel. + - [QTBUG-69512] Fixed compilation with GCC < 5.0. + - [QTBUG-72180] Fixed a regression in error handling inside + QGeoServiceProvider. + - [QTBUG-72462] Introduced a plugin parameter to decide U-Turn direction. + - Fixed MapItemView attempting to instantiate items when map not set. + +**************************************************************************** +* QtPositioning * +**************************************************************************** + + - [QTBUG-72291] Fixed horizontal accuracy comparison for competing position + results. + - [QTBUG-62682][QTBUG-68331] Enabled QVariant::save for QGeoCoordinate. + - Registered QGeoCoordinate debug streaming operator + + - [QTBUG-64689] Android: Implemented collection of vertical accuracy data. + - [QTBUG-66427] Android: Fixed + QGeoPositionInfoSource::supportedPositioningMethods(). + + - WinRT: Fixed setting of verticalAccuracy. + - [QTBUG-71194] WinRT: Made sure that Co(Un)Initialize is called. + - WinRT: Added categorized logging. + - WinRT: Fixed namespaced builds + - WinRT: Implemented minimumUpdateInterval. diff --git a/dist/changes-5.12.2 b/dist/changes-5.12.2 new file mode 100644 index 0000000..d9822a3 --- /dev/null +++ b/dist/changes-5.12.2 @@ -0,0 +1,33 @@ +Qt 5.12.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* QtLocation * +**************************************************************************** + + - [QTBUG-61509] Fixed crash when assigning a Component to MapQuickItem.sourceItem. + - [QTBUG-72935] Fixed QGeoRectangle::operator|=-. + - [QTBUG-71264] Fixed MapObjectView removing wrong indices on model changes. + +**************************************************************************** +* QtPositioning * +**************************************************************************** + + - Several improvements in the WinRT positioning plugin. + - Geoclue plugin re-enabled on all *BSD. diff --git a/dist/changes-5.12.3 b/dist/changes-5.12.3 new file mode 100644 index 0000000..f66e469 --- /dev/null +++ b/dist/changes-5.12.3 @@ -0,0 +1,33 @@ +Qt 5.12.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* QtPositioning * +**************************************************************************** + + - Documented QGeoPath::length behavior properly. + +**************************************************************************** +* UNSPECIFIED * +**************************************************************************** + + - Fixed incorrect indexing of Mapbox tiles in the cache. + - Fixed crash when destroying Maps containing MapItemViews. + - Added a notice to the MapViewer example to inform when a HTTPS-based map + is selected without SSL support. diff --git a/dist/changes-5.12.4 b/dist/changes-5.12.4 new file mode 100644 index 0000000..a285cd8 --- /dev/null +++ b/dist/changes-5.12.4 @@ -0,0 +1,20 @@ +Qt 5.12.4 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.3. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/changes-5.12.5 b/dist/changes-5.12.5 new file mode 100644 index 0000000..e8be931 --- /dev/null +++ b/dist/changes-5.12.5 @@ -0,0 +1,20 @@ +Qt 5.12.5 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.4. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/changes-5.13.0 b/dist/changes-5.13.0 new file mode 100644 index 0000000..564a37e --- /dev/null +++ b/dist/changes-5.13.0 @@ -0,0 +1,46 @@ +Qt 5.13 introduces many new features and improvements as well as bugfixes +over the 5.12.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* QtLocation * +**************************************************************************** + + - Added a GeoJSON parser which can be used to annotate maps with tracks, + polygonal boundaries, etc. + - GeoJSON returned in Nominatim queries is now converted into the corresponding + geoshapes using QGeoJson. + - GeoJSON returned in Nominatim queries is now converted into the corresponding + geoshapes using QGeoJson. + - Introduced Qt.labs.location QtLocationLabs singleton type, offering tech-preview + map related API. + - Added departure time attribute to route queries. + - Introduced QGeoMapObject::geoShape property. + - Additional navigation information now exposed via Navigator. + - Fixed crash when removing items from MapboxGL maps. + - Renamed MapIconObject.size to MapIconObject.iconSize. + - Added Map.fitViewportToGeoShape(shape, margins). + - Added Navigator currentRouteLeg property. + - Introduced extendedAttributes property to Geo Location types. + - Introduced extendedAttributes property to Geo Routes types. + +**************************************************************************** +* QtPositioning * +**************************************************************************** + +- Added holes support to QGeoPolygon, currently rendered only when using the + MapboxGL backend. + diff --git a/dist/changes-5.13.1 b/dist/changes-5.13.1 new file mode 100644 index 0000000..57ebdbe --- /dev/null +++ b/dist/changes-5.13.1 @@ -0,0 +1,20 @@ +Qt 5.13.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.13.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/changes-5.13.2 b/dist/changes-5.13.2 new file mode 100644 index 0000000..e3bb833 --- /dev/null +++ b/dist/changes-5.13.2 @@ -0,0 +1,20 @@ +Qt 5.13.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.13.0 through 5.13.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/changes-5.14.0 b/dist/changes-5.14.0 new file mode 100644 index 0000000..a2748e5 --- /dev/null +++ b/dist/changes-5.14.0 @@ -0,0 +1,47 @@ +Qt 5.14 introduces many new features and improvements as well as bugfixes +over the 5.13.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* QtLocation * +**************************************************************************** + + - [QTBUG-76867] Added property to disable the automatic fade-in/fade-out + behavior of MapItems on low zoom levels. + - Added QDeclarativeGeoServiceProviderRequirements + navigation property. + - Added notification signal to Map.visibleRegion property. + - Added automaticReroutingEnabled, isOnRoute and alternativeRoutes + properties to QDeclarativeNavigator. + - Added a recalculateRoutes invokable method to QDeclarativeNavigator. + + - Geoservice Plugins + * MapboxGL: Added support for image sources. + +**************************************************************************** +* QtPositioning * +**************************************************************************** + + - [QTBUG-66304] Exposed PluginParameter also from QtPositioning qml + plugin, to be used in PositionSource as replacement of environment + variables. + - [QTBUG-59274] Added Satellite info source capabilities to the serial nmea + plugin. + + + + + diff --git a/dist/changes-5.14.1 b/dist/changes-5.14.1 new file mode 100644 index 0000000..d008638 --- /dev/null +++ b/dist/changes-5.14.1 @@ -0,0 +1,20 @@ +Qt 5.14.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.14.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/changes-5.14.2 b/dist/changes-5.14.2 new file mode 100644 index 0000000..68a0051 --- /dev/null +++ b/dist/changes-5.14.2 @@ -0,0 +1,20 @@ +Qt 5.14.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.14.0 through 5.14.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/changes-5.15.0 b/dist/changes-5.15.0 new file mode 100644 index 0000000..f084e9e --- /dev/null +++ b/dist/changes-5.15.0 @@ -0,0 +1,51 @@ +Qt 5.15 introduces many new features and improvements as well as bugfixes +over the 5.14.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* QtPositioning * +**************************************************************************** + + - QGeoPolygon: + * Fixed contains method. + + - serialnmea plugin: + * [QTBUG-82819] Fixed serialnmea plugin initialization when used with serial port. + + - [QTBUG-81069] Fixed a dangling pointer issue in QML PositionSource API. + + - Fixed QGeoCoordinate::CoordinateFormat missing Q_ENUM. + + - Removed the usage of deprecated APIs from other Qt modules. + + +**************************************************************************** +* QtLocation * +**************************************************************************** + + - Added optional Argument to Map.fitViewportToMapItems. + + - Fixed a memory leak related to MapObjects.border. + + - Updated the 3rdparty library earcut. + + - Fixed Map*ObjectsQSG implementation triggering QSGBatchRenderer crashes. + + - Ported Map*ObjectPrivateQSG to the shader-based projection geometries. + + - Fixed segmentation fault due to null pointer usage in qdeclarativepolylinemapitem.cpp. + + - Removed the usage of deprecated APIs from other Qt modules. diff --git a/dist/changes-5.15.1 b/dist/changes-5.15.1 new file mode 100644 index 0000000..332ee9d --- /dev/null +++ b/dist/changes-5.15.1 @@ -0,0 +1,20 @@ +Qt 5.15.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.15.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/changes-5.15.2 b/dist/changes-5.15.2 new file mode 100644 index 0000000..1e66906 --- /dev/null +++ b/dist/changes-5.15.2 @@ -0,0 +1,48 @@ +Qt 5.15.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.15.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + https://doc.qt.io/qt-5.15/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + +**************************************************************************** +* Library * +**************************************************************************** + + +General +------- + + - [QTBUG-86248] The generated clipper2tri, clipper, poly2tri libraries have + been renamed to qt_clipper2tri, qt_clipper, qt_poly2tri. This avoids + conflicts for static builds. + +Third-Party Code +---------------- + + - Update and extend third-party documentation for Mapbox GL plugin + dependencies: libc++, Optional, Mapbox GL Native, Boost, CSS Color Parser, + cURL Parse Date, Earcut Polygon Triangulation Library, geojson-cpp, + geojson-vt-cpp, geometry.hpp, kdbush.hpp, polylabel, protozero, RapidJSON, + shelf-pack-cpp, supercluster.hpp, tao_tuple, unique_resource, variant, + Vector Tile Library, Wagyu Geometry Processing Library, nunicode. + + - Added actual license text of Boost Software License (used in Clipper Polygon + Clipping Library) + diff --git a/dist/changes-5.2.1 b/dist/changes-5.2.1 new file mode 100644 index 0000000..37a1f55 --- /dev/null +++ b/dist/changes-5.2.1 @@ -0,0 +1,53 @@ +Qt 5.2.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.2.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.2 + +The Qt version 5.2 series is binary compatible with the 5.1.x series. +Applications compiled for 5.1 will continue to run with 5.2. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* General * +**************************************************************************** + +General Improvements +-------------------- + + - [QTBUG-34910] Fixed too long weather status string in weatherinfo + example (UI change). + - [QTBUG-36187] Byte order marker removed from positionpoll plugin + which caused compile errors on some older compilers. + - Fixed make install rules for all examples. + - declarative_core unit test was fixed and re-enabled. + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - [QTBUG-33220] Removed QtQml dependency from QtPositioning. + +**************************************************************************** +* Plugin Specific Changes * +**************************************************************************** + +GeoClue +------- + + - Delay satellite provider until requested. + - Sets the default preferred positioning method to AllPositioningMethods. + - Fix for incorrect accuracy values reported by the plug-in. + diff --git a/dist/changes-5.3.0 b/dist/changes-5.3.0 new file mode 100644 index 0000000..1bf445a --- /dev/null +++ b/dist/changes-5.3.0 @@ -0,0 +1,74 @@ +Qt 5.3 introduces many new features and improvements as well as bugfixes +over the 5.2.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.3 + +The Qt version 5.3 series is binary compatible with the 5.2.x series. +Applications compiled for 5.2 will continue to run with 5.3. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* General * +**************************************************************************** + +General Improvements +-------------------- + + - New SatelliteInfo example added. The example displays the signal + strength of surrounding satellites. The example employs a demo mode on + those platforms which don't provide satellite information + + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - Position (QML): + * Added direction and vertical speed properties. + + - QGeoPositionInfoSource: + * iOS position backend added. + * [QTBUG-34102] Android backend added. Android devices can retrieve + their current position. Network- and Satellite-based providers are + supported. + + - QGeoSatelliteInfoSource: + * [QTBUG-34102] Android backend added. Android devices can retrieve + information about the currently accessible GPS and GLONASS satellites. + + - QGeoRectangle: + * Added QGeoRectangle(QList) constructor added. + * Improved class documentation. + + - QGeoShape: + * Added extendShape(QGeoCoordinate) function. + + - QNmeaPositionInfoSource: + * Added support for reporting position accuracy. + + +**************************************************************************** +* Plugin Specific Changes * +**************************************************************************** + +GeoClue +------- + - [QTBUG-36298] Reports direction of travel and + vertical speed attributes, if supported by the active Geoclue + provider. + - Fixed the emission of the updateTimeout() signal when + position updates do not arrive in a timely manner. + - Position info source provider no longer internally filters + position updates to the requested update interval. + diff --git a/dist/changes-5.3.1 b/dist/changes-5.3.1 new file mode 100644 index 0000000..8913770 --- /dev/null +++ b/dist/changes-5.3.1 @@ -0,0 +1,57 @@ +Qt 5.3.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.3.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.3 + +The Qt version 5.3 series is binary compatible with the 5.2.x series. +Applications compiled for 5.2 will continue to run with 5.3. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* General * +**************************************************************************** + +General Improvements +-------------------- + + - Added PLUGIN_CLASS_NAME variable to all plug-in based projects. This + enables the automatic static linking and deployment of this plug-ins. + + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - QGeoPositionInfoSource: + * WinRT backend added + + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Android +------- + + - [QTBUG-39082] Fixed crash on Galaxy S4 when running satellite and position + updates at the same time. + +iOS +--- + + - [QTBUG-38770] Added "classname" entry to all qmldir files enabling QML + plug-ins when doing static builds on iOS. + diff --git a/dist/changes-5.3.2 b/dist/changes-5.3.2 new file mode 100644 index 0000000..b1981f6 --- /dev/null +++ b/dist/changes-5.3.2 @@ -0,0 +1,50 @@ +Qt 5.3.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.3.0 and Qt 5.3.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.3 + +The Qt version 5.3 series is binary compatible with the 5.2.x series. +Applications compiled for 5.2 will continue to run with 5.3. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - [QTBUG-39843] [iOS] Fixed link error of positioncl and positionpoll + plug-in. + + - [QTBUG-40198] Fixed symbol clash between sensor and position plug-in. + This happened when using static builds of Qt (e.g. on iOS) and the + application used QtSensors and QtPositioning at the same time. + + - Improved weatherinfo example to not hang on the "Loading weather data" + screen if the current QGeoPositionInfoSource instance returned an error + during its startup. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +[iOS] + + - [QTBUG-38300] Fixed wrong value of QGeoPositionInfo attributes if those + attributes were not provided by the platforms CoreLocation framework. + +[Linux] + + - [QTBUG-40425] Fixed missing error report when failing to connect to GeoClue. + diff --git a/dist/changes-5.4.0 b/dist/changes-5.4.0 new file mode 100644 index 0000000..3a14766 --- /dev/null +++ b/dist/changes-5.4.0 @@ -0,0 +1,54 @@ +Qt 5.4 introduces many new features and improvements as well as bugfixes +over the 5.3.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.4 + +The Qt version 5.4 series is binary compatible with the 5.3.x series. +Applications compiled for 5.3 will continue to run with 5.4. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - Position: + * [QTBUG-39547] Added magneticVariation and magneticVariationValid + property to the QML Position type. + + - General: + * Weatherinfo end Flickr example improved. + + - QGeoCircle: + * [QTBUG-41447] Fixed contains() when rounding errors occur + + - QGeoCoordinate: + * [QTBUG-41739] Fixed toString() output in cases when rounding + of longitude/latitude is necessary. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Android +------- + + - [QTBUG-41873] Fixed wrong initialization of QGeoPositionInfoSource::error() + after class instantiation. + +iOS +--- + + - [QTBUG-41827] Fixed position retrieval on iOS 8. This was required due + to the new authorization scheme in CLLocationManager. + diff --git a/dist/changes-5.4.1 b/dist/changes-5.4.1 new file mode 100644 index 0000000..4876ab3 --- /dev/null +++ b/dist/changes-5.4.1 @@ -0,0 +1,29 @@ +Qt 5.4.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.4.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5.4 + +The Qt version 5.4 series is binary compatible with the 5.3.x series. +Applications compiled for 5.3 will continue to run with 5.4. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - PositionSource: + * Fixed a case where an NMEA source file, which is integrated + using qrc, was not loaded. diff --git a/dist/changes-5.4.2 b/dist/changes-5.4.2 new file mode 100644 index 0000000..4f256ef --- /dev/null +++ b/dist/changes-5.4.2 @@ -0,0 +1,28 @@ +Qt 5.4.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.4.0 and Qt 5.4.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5.4 + +The Qt version 5.4 series is binary compatible with the 5.3.x series. +Applications compiled for 5.3 will continue to run with 5.4. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - [QTBUG-44572] Fixed issue where the default timeout for position update + requests was not set on WinRT. diff --git a/dist/changes-5.5.0 b/dist/changes-5.5.0 new file mode 100644 index 0000000..737ce13 --- /dev/null +++ b/dist/changes-5.5.0 @@ -0,0 +1,40 @@ +Qt 5.5 introduces many new features and improvements as well as bugfixes +over the 5.4.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.5 series is binary compatible with the 5.4.x series. +Applications compiled for 5.4 will continue to run with 5.5. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - Added QGeoShape::center() function + - Converted QGeoShape, QGeoCircle, QGeoRectangle & QGeoCoordinate to Q_GADGET. + It simplifies the integration of the above classes into QML as the extensive + QML value type wrapper conversion is implicitly done by Qt QML. The existing + custom wrappers were removed. + - Fixed Debug stream operators for QGeoAreaMonitorInfo, QGeoCoordinate, + QGeoPositionInfo, QGeoSatelliteInfo & QGeoShape following a QDebug related + change in Qt Base. + - [QTBUG-44663] Added updateTimeout() signal to QML PositionSource type + - [QTBUG-44983] Fixed broken build of qtlocation repo when using qmake -r + on OS X + +QtLocation +---------- + + - First Technology Preview release of this module diff --git a/dist/changes-5.5.1 b/dist/changes-5.5.1 new file mode 100644 index 0000000..8b2ce35 --- /dev/null +++ b/dist/changes-5.5.1 @@ -0,0 +1,54 @@ +Qt 5.5.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.5.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5.5/ + +The Qt version 5.5 series is binary compatible with the 5.4.x series. +Applications compiled for 5.4 will continue to run with 5.5. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtLocation +----------- + + - Fixed change signal emission for Map.activeMapType property. + - Improved places-list and places-map examples. + - [QTBUG-47188] Fixed incorrect naming of OSM plugin's parameter. + The documentation mandates the osm prefix which was not used in + the case of the geocoding.host, useragent and routing.host parameters. + The required osm.places.host parameter was not handled at all. + - [QTBUG-47322] Added support for zoom level 19 to OSM plugin. + - Fixed an issue where the incorrect prefetch algorithm was used for map + tile fetching. + +QtPositioning +------------- + + - Improved minor documentation issues. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Windows +------- + + - Added missing QtQuick.Controls import to mapviewer example. + +Linux/gcc +--------- + + - [QTBUG-47427] Fixed compile issue in geoclue plugin when using gcc 4.5. diff --git a/dist/changes-5.6.0 b/dist/changes-5.6.0 new file mode 100644 index 0000000..1402343 --- /dev/null +++ b/dist/changes-5.6.0 @@ -0,0 +1,69 @@ +Qt 5.6 introduces many new features and improvements as well as bugfixes +over the 5.5.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - Removed Blackberry 10 support. + - [QTBUG-40702] Removed dependency towards libgeoclue. The plugin uses the + GeoClue DBus interface. + - Enabled Position plugin for OS X. Previously only the plugin was only working + for iOS. + - [QTBUG-48082] Added QtSerialPort based NMEA position plugin for Windows. + - Improved and fixed the WinRT position backend. Various changes on the WinRT + platform caused the necessity for such and update. + - Fixed endless requests towards Android's LocationManager when stopUpdates() was not + called in pair with startUpdates(). + +QtLocation +---------- + + - First stable release of the Qt Location API. The QML API changed significantly + compared to the Qt 5.5 release. The changes are documented in the official + module documentation under "API changes". + - Improved the Flick and Pinch implementation for QML Map. + - [QTBUG-44809] Fixed tile version handling + - Fixed crash during Map.setVisibleRegion while no plugin has been set. + - Improved error reporting in map, geocoding and routing model APIs. + - QTBUG[36919] Added means to prevent stealing of mouse/touch grabs on map. + - Improved coordinate related animation handling. Previously an animation along + the longitude always used a shortest path direction. Now it is possible to set + the direction for the animation. + - [QTBUG-46147] Fixed crash in QML Map element. + - [QTBUG-44311] Fixed bouncing Map flick on zoom level 2. + - [QTBUG-47020] & [QTBUG-47019] Improved Mouse and keyboard integration of QML Map + - [QTBUG-46388] Fixed Pinch when no MouseArea overlaps QML Map element. + - Fixed various unit test. + - Fixed a variety of minor documentation issues. + - Fixed dysfunctional tile cache for OSM plugin due to the server delivering JPEG + file when PNG files were expected. + - [QTBUG-41187] Unified the default tile cache location on disk. + - Fixed crash in gesture area while receiving wheel events. + - Fixed route requests with excluded areas for HERE plugin. + - Added support for custom map background color. + - Improved Map rendering performance throughout the QML API. + - [QTBUG-49772] Fixed weatherinfo example due to missing appid handling for + openweatermap.org. + - [QTBUG-47292] Added ability to clear the map cache. + - [QTBUG-50060] Improved performance of QML MapPolyline. + - [QTBUG-50240] Fixed OSM routing to handle changed server status code for a + successful route retrieval. + - [QTBUG-50519] Fixed map in mapviewer example when displaying the minimap. diff --git a/dist/changes-5.6.1 b/dist/changes-5.6.1 new file mode 100644 index 0000000..cd579b6 --- /dev/null +++ b/dist/changes-5.6.1 @@ -0,0 +1,38 @@ +Qt 5.6.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.6.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5.6/ + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtLocation +---------- + + - Improved the example and class documentation + - Consolidated various qmake project files across the module + - [QTBUG-51541] Fixed compile issue on linux/gcc-4.8 when using C++98 + - Improved compression rate of various screenshots throughout the documentation + +QtPositioning +------------- + + - [QTBUG-38802] Added default capability (location) for WinRT + - [QTBUG-53059] Fixed crash on iOS/OS X due to incorrectly initialized member + variable in the positioning backend + diff --git a/dist/changes-5.6.2 b/dist/changes-5.6.2 new file mode 100644 index 0000000..9f2a6f9 --- /dev/null +++ b/dist/changes-5.6.2 @@ -0,0 +1,55 @@ +Qt 5.6.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.6.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtLocation +---------- + + - Fixed autotests containing bugs not showing in the tests + - [QTBUG-31797][QTBUG-53455] Fixed the QtLocation autotest framework by + replacing waitForRendering() with waitForPolished() + - Disabled explicit example installation + - [QTBUG-52514] Fixed QML Map not working with repeaters + - [QTBUG-53128] Fixed QML Map items not updating on window resize + - [QTBUG-52075] Fixed QML Map items losing focus during fast dragging + - [QTBUG-52301] Prevented flickering upon MapItemView's model reset + - [QTBUG-54141] Fixed QML Map setVisibleRegion failing in some cases + - Fixed a potential memory leak in QGeoTiledMappingManagerEngine + - [QTBUG-19929] Prevented generating MapCircles with invalid radius + - [QTBUG-54599] Added support for fetching OSM provider information from + a remote repository + - [QTBUG-54337] Fixed bounding calculation for QGeoCircle + - Added a minimal QML Map usage example + - Added support for dynamically remove unavailable providers from the OSM + plugin + - [QTBUG-55081] Fixed accessing MapPolyline before it is added to a Map + - [QTBUG-54964] Fixed invisible copyright notice on Android using Holo theme + - Improved macOS documentation + - Fixed the geocoding in the MapViewer example + - [QTBUG-55371] Fixed OSM plugin geocoding feature + +QtPositioning +------------- + + - [QTBUG-54026] Reduced Android minimum update interval + - Improved Android 5.0+ compatibility + diff --git a/dist/changes-5.6.3 b/dist/changes-5.6.3 new file mode 100644 index 0000000..4709ff2 --- /dev/null +++ b/dist/changes-5.6.3 @@ -0,0 +1,38 @@ +Qt 5.6.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.6.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtLocation +---------- + + - [QTBUG-56099] Updated HERE plugin base address + - [QTBUG-56119] Added OSRMv5 support to the osm plugin + - [QTBUG-57027] Fixed fitViewportToGeoShape on rectangles crossing the date + line. + - Updated HERE plugin geocoding endpoints + + +QtPositioning +------------- + + - [QTBUG-54844] Fixed error status for QGeoPositionInfoSourceAndroid + - [QTBUG-56623] WinRT backend now uses backend-provided timestamps diff --git a/dist/changes-5.7.0 b/dist/changes-5.7.0 new file mode 100644 index 0000000..d1fdb43 --- /dev/null +++ b/dist/changes-5.7.0 @@ -0,0 +1,53 @@ +Qt 5.7 introduces many new features and improvements as well as bugfixes +over the 5.6.x series. Also, there is a change in the licensing terms. +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.7 series is binary compatible with the 5.6.x series. +Applications compiled for 5.6 will continue to run with 5.7. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important License Changes * +**************************************************************************** + + This module is no longer available under LGPLv2.1. The libraries are + now available under the following licenses: + * Commercial License + * GNU General Public License v2.0 (LICENSE.GPL2) and later + * GNU Lesser General Public License v3.0 (LICENSE.LGPL3) + + The tools are now available under the following licenses: + * Commercial License + * GNU General Public License 3.0 (LICENSE.GPL3) with exceptions + described in The Qt Company GPL Exception 1.0 (LICENSE.GPL3-EXCEPT) + +**************************************************************************** +* Library * +**************************************************************************** + +QtPositioning +------------- + + - Added support for tvOs to iOS/OS X positioning engine + - Added qHash() function for QGeoCoordinate + - Fixed negative QGeoCoordinate.azimuthTo results + - Added experimental support for GeoPosition API on Windows desktop + running Windows 8 or later + +QtLocation +---------- + + - [QTBUG-47025] Added option to hide map data copyright information + - Adjusted minimum map zoom level to prevent gray bounds. It prevents the map + from being smaller than the canvas size. + - Fixed several internal performance issues diff --git a/dist/changes-5.7.1 b/dist/changes-5.7.1 new file mode 100644 index 0000000..2d111d5 --- /dev/null +++ b/dist/changes-5.7.1 @@ -0,0 +1,45 @@ +Qt 5.7.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.7.0. + +Qt 5.7.1 contains a merge from Qt 5.6.2 and all changes in Qt 5.6.2 are +also in Qt 5.7.1. For more see changes-5.6.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.7 series is binary compatible with the 5.6.x series. +Applications compiled for 5.6 will continue to run with 5.7. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtLocation +---------- + +- [QTBUG-55535] Fixed map polygon not working correctly when zooming. +- [QTBUG-55964] Fixed rendering of polylines and polygons at the edge + of the map. +- [QTBUG-52610] Fixed incorrect map polyline drawing. +- [QTBUG-52076] Fixed crashes on tessellation of self-intersecting + GeoPolygons. +- [QTBUG-52030] Fixed that map's center and zoom were not initialized when + used in a layout. +- [QTBUG-52514] Fixed not working MapPolygon inside Repeater. +- [QTBUG-53128] Fixed map objects moving incorrectly on map resize. +- [QTBUG-52075] Fixed losing map item focus while dragging. + +QtPositioning +------------- + +- [QTBUG-54506] Fixed unneeded dependency on Activity for Android Platform. diff --git a/dist/changes-5.8.0 b/dist/changes-5.8.0 new file mode 100644 index 0000000..1c2a5b4 --- /dev/null +++ b/dist/changes-5.8.0 @@ -0,0 +1,70 @@ +Qt 5.8 introduces many new features and improvements as well as bugfixes +over the 5.7.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.8 series is binary compatible with the 5.7.x series. +Applications compiled for 5.7 will continue to run with 5.8. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtLocation +----------- + + - Added geoservices plugin to support ESRI mapping, geocoding and routing + services. + - Improved HERE geoservice plugin code base (improved warning) and converted + the HERE endpoints to newer versions (away from Nokia endpoints. At the same time + China specific URLs were removed. + - Improved Mapbox plugin to cater for better cache customization and + to support the standard box map modes. + - Renamed various internal C++ functions to improve code readability + - Added better high DPI support in the various geoservice provider plugins. + For more details see QTBUG-53318, QTBUG-48868 and QTBUG-36949. + - [QTBUG-45284] Added offline data support and improved cache handling in OSM + geoservice plugin + - Added routing support to Mapbox plugin + - Added server side provider support for QtLocation. This enables the quicker + selection of alternative providers by already deployed OSM applications in case + an OSM based default provider changes T&Cs. + - Removed QtSystemInfo dependency from QtLocation + - [QTBUG-56213] Adapted map related mouse/touch behavior following + changes to general mouse/touch handling in Qt QML + - Adapted QtLocation and QtPositioning to the Qt Lite related build system changes + - Marked QGeoMapPrivate as private export + - Added support for unitary tile caching. This enables use cases whereby the cache + size can be defined in number of tiles rather then bytes. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Android +------- + + - [QTBUG-55988] Added capability to ask for Location permissions at runtime. This is + required since Android 7.0. + +WinRT +----- + + - Fixed a name space related compile problem in the positioning plugin for WinRT + - Migrated the QtLocation rendering code to the new scenegraph changes enabling + Direct3D 12 + - [QTBUG-54474] Added GeolocationAccessStatus existence check + - [QTBUG-56340] Added direction information to position updates + - [QTBUG-56623] Changed positioning plugin to use the platforms positioning time + stamp rather than a programmatically acquired time stamp at the time of the callback. + Effectively, this forwards time stamps from the GPS satellite to the user application. + - [QTBUG-53925] Enabled WinRT positioning backend for MSVC2013/2015 diff --git a/dist/changes-5.9.0 b/dist/changes-5.9.0 new file mode 100644 index 0000000..46faf68 --- /dev/null +++ b/dist/changes-5.9.0 @@ -0,0 +1,131 @@ +Qt 5.9 introduces many new features and improvements as well as bugfixes +over the 5.8.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* General * +**************************************************************************** + +Third-Party Code +---------------- + + - Added Mapbox GL Native as a third-party component to + src/3rdparty/mapbox-gl-native. + +**************************************************************************** +* Library * +**************************************************************************** + +QtLocation +----------- + + - Added boundingGeoRectangle to QGeoShape to return a geographical bounding + box in form of a QGeoRectangle. + - Added QGeoPath as a new geo shape. + - Added a new QML type, MapParameter, to control plugin-specific map features + at runtime. + - Deprecated QGeoShape::extendShape. + - Renamed the QGeoProjection class into QWebMercator. + - Added new private API, QGeoProjection, for the coordinate <-> screen projection + conversion, removing it from QGeoTiledMapScene. + - Moved CacheAreas enum from QGeoFileTileCache into QAbstractGeoTileCache. + - Map.zoomLevel now always refers to a normalized tile size of 256x256 pixels. + Conversions to/from different tile sizes are performed internally by QGeoMap. + - Added clipping support to Clip2Tri 3rd party library through clipper, to protect Qt from + clipper invocations that throw. + - Updated clipper lib to version 6.4. + - QGeoProjectionWebMercator now uses a projection matrix to project to item position. + - [QTBUG-58124] Fixed a bug on destruction of the OSM plugin causing segfault. + - Added rotation, tilt and field of view properties to QDeclarativeGeoMap. + - Changed map items to be always positioned/wrapped based on their geo left bound. + - Changed the Map items opacity ramp values from 2.0 -> 3.0 to 1.5 -> 2.5. + - QDeclarativeGeoMap::setVisibleRegion now handles QGeoPath as well. + - Map Items geo data is now managed by a contained QGeoShape, which also handles geographical + transformations such as translations. + - Moved the declarative implementation from imports/ into location/declarativemaps and + location/declarativeplaces, privately exporting the classes. + - QQuickGeoMapGestureArea now correctly works with tilted/rotated maps. + - Added two new gestures to QQuickGeoMapGestureArea, two fingers rotation and two fingers tilting. + - Added the infrastructure to allow a QGeoMap to be responsible for drawing map items. + - Added a new QML type, MapCopyrightNotice, backed by the now exposed QDeclarativeGeoMapCopyrightNotice. + - MapCopyrightNotice can now be styled using CSS. + - Added a new plugin, MapboxGL, based on the mapbox-gl-native 3rd party library. + - The MapboxGL plugin now ships with a built-in development token. + - Added a new QML type, MapItemGroup, to group multiple map items in a new meta map item. + - Added the new mapItemOpacity method to QGeoMapItemBase, to account for the opacity of a MapItemGroup too. + - Added the new fitViewportToVisibleMapItems method to QDeclarativeGeoMap. + - Adapted mapviewer example to enable changing tilting/rotation/FoV. + - QGeoTiledMap now uses anisotropic filtering when available. + - Unblacklisted some previously blacklisted autotests now fixed in qtdeclarative. + - Blacklisted flick autotests on windows due to platform-induced flakiness. + - Added support to the MapboxGL plugin to natively renders map polylines, polygons and rectangles. + - Added support to the MapboxGL plugin to render both via FBO and via QSGRenderNode. + - QGeoCameraCapabilities are now specific to a QGeoMapType, and not any longer fixed to a plugin. + - DevicePixelRatio is now considered before enabling mipmapping so that mipmapping remains off if + tiles do not need to be minificated. + - Changed QGeoTiledMap default FoV from 90 to 45 degrees. + - [QTBUG-59417] Fixed QGeoTiledMapScene viewing frustum calculation. + - Added a new mapReady signal to QDeclarativeGeoMap to notify when the map becomes ready. + - Added ICU support to MapboxGL plugin, depending on its availability. + - [QTBUG-58821] Removed dependency on QtWidgets. + - Added a new plugin, itemsoverlay, to provide a transparent canvas to add only map items. + - MapQuickItem now correctly tilts and rotates when the zoomLevel property is set. + - [QTBUG-59259] Increased QGeoCoordinate debug operator precision. + - Improved the mapviewer example, also using QtQuick.Controls2 sliders. + - QtPositioning now also compiler-optimized when building in release. + - [QTBUG-59503] Flick autotests skipped on windows. + - [QTBUG-59479] Mercator-projected qgeocoordinates in map items are now cached. + - Removed pathPropertyChanged() from Polyline,Polygon. + - [QTBUG-23659] Enabled overzooming tiles in qgeotiledmapscene. + - [QTBUG-59416] keepTouchGrab now considered when handing mouse events in QDeclarativeGeoMap. + - Tile formats now proactively converted to ARGB32_Premultiplied. + - Added possibility to disable prefetching. + - Added parameter to control prefetching in tile-based geoservice plugins. + - Disabled warnings in third-party code. + - Improved flicking behavior of QQuickGeoMapGestureArea. + - [QTBUG-60021] Map update now triggered after initialization. + - QGeoMap pointers now protected with QPointer. + - QtLocation now marked as warning-free. + - [QTBUG-58801] Fixed copyright notice not showing before map type is changed. + - Added overzoomEnabled to QGeoCameraCapabilities. + - Various fixes for building with various QtLite configurations. + - QGeoTileFetcher::handleReply now virtual. + - [QTBUG-60266] declarative_ui autotests disabled for boot2qt. + + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +iOS +--- + + - [QTBUG-52014][QTBUG-59275] Allow background updates if such capability + is present in infoDict. + + +WinRT +----- + + - [QTBUG-57288] Remove support for WinRT 8.1 and Windows Phone 8.1. + - [QTBUG-60299] Added error handling for GeoPositionInfoSource creation. + + +Android +------- + + - [QTBUG-59010] Added guard against unprotected javaVM pointer usage. + - [QTBUG-59158] UTC flag for Android position timestamps now set. diff --git a/dist/changes-5.9.1 b/dist/changes-5.9.1 new file mode 100644 index 0000000..58b4ac7 --- /dev/null +++ b/dist/changes-5.9.1 @@ -0,0 +1,43 @@ +Qt 5.9.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + + - [QTBUG-60007] Fixed plugin resources not loading on static builds + - [QTBUG-60881] Fixed building on configurations without OpenGL + - Fixed an incorrect condition in QDeclarativeGeoMap::geometryChanged() + causing a crash in some scenarios + - MapItems can now be set to render under specific style layers with the + MapboxGL plugin + - [QTBUG-60821] Added detailed 3rd party attributions for the 3rd party + mapbox-gl-native library + - [QTBUG-61070] MapQuickItem's setCoordinate now checks for coordinate's + validity. + - [QTBUG-61087] OpenGL is now a requirement to build the MapboxGL plugin + - LocationSingleton now allows to create a qgeopath from a list of coordinates, + and not only empty qgeopaths + - Updated QtLocation qmltypes + - [QTBUG-61266] Updated QtPositioning qmltypes, adding 5.9 version + - [QTBUG-57690] Fixed Map.visibleRegion in the case that all the map is visible + - Various documentation fixes + - The MapboxGL plugin now uses the MapItem's objectName (if present) when creating + a mapbox layer name for it + diff --git a/dist/changes-5.9.2 b/dist/changes-5.9.2 new file mode 100644 index 0000000..ac6321d --- /dev/null +++ b/dist/changes-5.9.2 @@ -0,0 +1,56 @@ +Qt 5.9.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.9.2 Changes * +**************************************************************************** + +QtLocation +---------- + - [QTBUG-61070] mapQuickItems aren't drawn any longer if coordinate is invalid + - [QTBUG-61813] Fixed Map.toCoordinate always clamping y values to 0 + - [QTBUG-61727] Fixed dragging items out of map bounds + - [QTBUG-62098] Fixed plugins build dependency + - [QTBUG-62122] Fixed potential memleak on QDeclarativeGeoMap destruction + - [QTBUG-62154] Fixed MapCircle artifacts with small radiuses + - Restored usage of setProperty on Map.fitViewportToGeoShape + - [QTBUG-57690] Fixed visible region computation in QGeoProjectionWebMercator + - Fixed QDeclarativeGeoMap::populateMap duplicating items + - Fixed GeocodeModel not autoUpdating if plugin attaches late + - [QTBUG-62075] Fixed PluginParameter not working with script as property values + - Added a configure feature for each geoservice plugin + - Fixed file tile cache not honoring disk cache size of 0 + - [QTBUG-63124] Fixed wrong clipper dependency due to incorrect qmake syntax + - [QTBUG-63251] Fixed Map.fromCoordinate returning wrong values during tilting + + - OSM + * [QTBUG-61637] Fixed OSM plugin not working with providersrepository.disabled = true + * [QTBUG-63033] Fixed disabling redirection for providers that have no local fallback + + - MapboxGL: + * [QTBUG-61442] Fixed MapParameter dynamic usage + * [QTBUG-62454] Bumped Mapbox GL to v1.1.0 to prevent a crash + * [QTBUG-62861] Fixed broken native text rendering with Mapbox GL plugin + * [QTBUG-58869] Fixed Mapbox GL not rendering circles natively + * Fixed Mapbox GL plugin not respecting MapItem visibility and opacity + + +QtPositioning +------------- + - [QTBUG-62778] Fixed PositionSource never turning active on Android in some cases diff --git a/dist/changes-5.9.3 b/dist/changes-5.9.3 new file mode 100644 index 0000000..98a9b30 --- /dev/null +++ b/dist/changes-5.9.3 @@ -0,0 +1,41 @@ +Qt 5.9.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.9.3 Changes * +**************************************************************************** + +QtLocation +---------- + + - [QTBUG-63374] Fixed MapBoxGL crashing when no OpenGLContext can be created + - Updated all FDL and BSD license header throughout the module + - [QTBUG-62417] Forced MapBoxGL to only build on Windows when Qt is build + with Angle + - [QTBUG-63926] Added check to MapBoxGL handling corner cases of Polygon + placement + - [QTBUG-63928] Fixed missing consideration of alpha channel when + setting DeclarativeRectangleMapItem opacity. + +QtPositioning +------------- + + - Updated all FDL and BSD license header throughout the module + - Added missing null check to Android positioning plug-in + diff --git a/dist/changes-5.9.4 b/dist/changes-5.9.4 new file mode 100644 index 0000000..6393129 --- /dev/null +++ b/dist/changes-5.9.4 @@ -0,0 +1,31 @@ +Qt 5.9.4 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.9.4 Changes * +**************************************************************************** + +QtLocation +---------- + + - [QTBUG-63013] Upgraded Mapbox GL to fix SQLite query binding. + - [QTBUG-58589] Added plugin dependencies to the mapviewer example. + - [QTBUG-64632] Upgraded Mapbox GL to fix remove GLES limitations on Windows. + This upgrade also fixed building Mapbox GL with MinGW. + - [QTBUG-57147] Fixed license headers. diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..5fdb4b9 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,7 @@ +qt_examples_build_begin(EXTERNAL_BUILD) + +if(TARGET Qt::Positioning) + add_subdirectory(positioning) +endif() + +qt_examples_build_end() diff --git a/examples/examples.pro b/examples/examples.pro new file mode 100644 index 0000000..ba3715c --- /dev/null +++ b/examples/examples.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs + +qtHaveModule(positioning) { + SUBDIRS += positioning +} diff --git a/examples/positioning/CMakeLists.txt b/examples/positioning/CMakeLists.txt new file mode 100644 index 0000000..1c435b9 --- /dev/null +++ b/examples/positioning/CMakeLists.txt @@ -0,0 +1,12 @@ +if(TARGET Qt::Widgets) + qt_internal_add_example(logfilepositionsource) +endif() +if(TARGET Qt::Quick) + qt_internal_add_example(satelliteinfo) +endif() +if(TARGET Qt::Quick) + qt_internal_add_example(geoflickr) +endif() +if(TARGET Qt::Network AND TARGET Qt::Quick) + qt_internal_add_example(weatherinfo) +endif() diff --git a/examples/positioning/geoflickr/CMakeLists.txt b/examples/positioning/geoflickr/CMakeLists.txt new file mode 100644 index 0000000..e5c8960 --- /dev/null +++ b/examples/positioning/geoflickr/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.16) +project(geoflickr LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/positioning/geoflickr") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Positioning Qml Quick) + +qt_add_executable(geoflickr + qmllocationflickr.cpp +) + +set_target_properties(geoflickr PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(geoflickr PRIVATE + Qt::Core + Qt::Gui + Qt::Network + Qt::Positioning + Qt::Qml + Qt::Quick +) + +# Resources: +set(flickr_resource_files + "flickr-90.qml" + "flickr.qml" + "flickrcommon/Progress.qml" + "flickrcommon/RestModel.qml" + "flickrcommon/ScrollBar.qml" + "flickrcommon/Slider.qml" + "flickrmobile/Button.qml" + "flickrmobile/GeoTab.qml" + "flickrmobile/GridDelegate.qml" + "flickrmobile/ImageDetails.qml" + "flickrmobile/ListDelegate.qml" + "flickrmobile/TitleBar.qml" + "flickrmobile/ToolBar.qml" + "flickrmobile/images/gloss.png" + "flickrmobile/images/lineedit.png" + "flickrmobile/images/lineedit.sci" + "flickrmobile/images/moon.png" + "flickrmobile/images/quit.png" + "flickrmobile/images/star.png" + "flickrmobile/images/stripes.png" + "flickrmobile/images/sun.png" + "flickrmobile/images/titlebar.png" + "flickrmobile/images/titlebar.sci" + "flickrmobile/images/toolbutton.png" + "flickrmobile/images/toolbutton.sci" + "flickrmobile/nmealog.txt" +) + +qt6_add_resources(geoflickr "flickr" + PREFIX + "/" + FILES + ${flickr_resource_files} +) + +install(TARGETS geoflickr + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/positioning/geoflickr/doc/images/qml-flickr-1.jpg b/examples/positioning/geoflickr/doc/images/qml-flickr-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..42514ff06dc3549246d39e01719c202624419e58 GIT binary patch literal 66794 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 z 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 Eg5PjTRR910 literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/doc/src/geoflickr.qdoc b/examples/positioning/geoflickr/doc/src/geoflickr.qdoc new file mode 100644 index 0000000..37e05e3 --- /dev/null +++ b/examples/positioning/geoflickr/doc/src/geoflickr.qdoc @@ -0,0 +1,64 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example geoflickr + \title GeoFlickr (QML) + \ingroup qtpositioning-examples + + \brief The GeoFlickr example shows how to use the user's current + position to fetch local content from a web service. + + This is a small example, illustrating one of the very core parts + of the \l{Qt Positioning} API: the ability to retrieve and use the + user's current geographic position. + + Key QML types shown in this example: + \list + \li \l {QtPositioning::PositionSource} {PositionSource} + \li \l [QML] {XmlListModel} + \endlist + + \image qml-flickr-1.jpg + + \include examples-run.qdocinc + + \section1 Retrieving the Current Position + + Retrieving the user's current position is achieved using the + \l PositionSource type. In this example, we instantiate the + \l PositionSource as part of the \c GeoTab component (the floating "window" + describing current position and status). + + \snippet geoflickr/flickrmobile/GeoTab.qml possrc + + When the "Locate and update" button is pressed, we first interrogate + the \l PositionSource to check if it has an available backend for + positioning data. If it does not, we fall back to using a pre-recorded + NMEA log for demonstration. We then instruct the \l PositionSource to + request a location \l {QtPositioning::PositionSource::}{update}. + + \snippet geoflickr/flickrmobile/GeoTab.qml locatebutton-top + \snippet geoflickr/flickrmobile/GeoTab.qml locatebutton-clicked + + To share the new position data with the rest of the application, we + use properties that we have created on the \c GeoTab component: + + \snippet geoflickr/flickrmobile/GeoTab.qml props + + \section1 Using the Current Position + + The longitude and latitude values retrieved here are eventually set + in the properties on the \c RestModel component. The \c RestModel is an + \l [QML] {XmlListModel}, which retrieves XML data from a URL and creates a + data model by parsing it. + + In this case, it retrieves data from the Flickr REST API online, + based on our current position + + \snippet geoflickr/flickrcommon/RestModel.qml restmodel + + This model data is then shown in a variety of \l {Qt Quick} views to + produce the example application. + +*/ diff --git a/examples/positioning/geoflickr/flickr-90.qml b/examples/positioning/geoflickr/flickr-90.qml new file mode 100644 index 0000000..66fc65f --- /dev/null +++ b/examples/positioning/geoflickr/flickr-90.qml @@ -0,0 +1,14 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + width: 480; height: 320 + + Loader { + y: 320; rotation: -90 + transformOrigin: Item.TopLeft + source: "flickr.qml" + } +} diff --git a/examples/positioning/geoflickr/flickr.qml b/examples/positioning/geoflickr/flickr.qml new file mode 100644 index 0000000..865b449 --- /dev/null +++ b/examples/positioning/geoflickr/flickr.qml @@ -0,0 +1,100 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 +import QtQml.XmlListModel +import "flickrcommon" as Common +import "flickrmobile" as Mobile + +Item { + id: screen; width: 320; height: 480 + property bool inListView : false + + Rectangle { + id: background + anchors.fill: parent; color: "#343434"; + + Image { source: "flickrmobile/images/stripes.png"; fillMode: Image.Tile; anchors.fill: parent; opacity: 0.3 } + + Common.RestModel { + id: restModel + coordinate: geoTab.coordinate + } + + Item { + id: views + x: 2; width: parent.width - 4 + anchors.top: titleBar.bottom; anchors.bottom: toolBar.top + + Text { + text: qsTr("Network error") + font.pixelSize: 48 + fontSizeMode: Text.HorizontalFit + anchors.centerIn: parent + width: parent.width * 0.9 + visible: restModel.status === XmlListModel.Error + + } + + Mobile.GridDelegate { id: gridDelegate } + GridView { + x: (width/4-79)/2; y: x + id: photoGridView; model: restModel; delegate: gridDelegate; cacheBuffer: 100 + cellWidth: (parent.width-2)/4; cellHeight: cellWidth; width: parent.width; height: parent.height - 1; z: 6 + } + Mobile.ListDelegate { id: listDelegate } + ListView { + id: photoListView; model: restModel; delegate: listDelegate; z: 6 + width: parent.width; height: parent.height; x: -(parent.width * 1.5); cacheBuffer: 100; + } + states: State { + name: "ListView"; when: screen.inListView == true + PropertyChanges { target: photoListView; x: 0 } + PropertyChanges { target: photoGridView; x: -(parent.width * 1.5) } + } + + transitions: Transition { + NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad } + } + } + Mobile.ImageDetails { id: imageDetails; width: parent.width; anchors.left: views.right; height: parent.height; z:1 } + Mobile.TitleBar { id: titleBar; z: 5; width: parent.width; height: 40; opacity: 0.9 } + Mobile.GeoTab { + id: geoTab; + x: 15; y:50; + } + Mobile.ToolBar { + id: toolBar; z: 5 + height: 40; anchors.bottom: parent.bottom; width: parent.width; opacity: 0.9 + button1Label: "Update"; button2Label: "View mode" + onButton1Clicked: restModel.reload() + onButton2Clicked: if (screen.inListView == true) screen.inListView = false; else screen.inListView = true + } + Connections { + target: imageDetails + function onClosed() { + if (background.state == "DetailedView") { + background.state = ''; + imageDetails.photoUrl = ""; + } + } + } + + states: State { + name: "DetailedView" + PropertyChanges { target: views; x: -parent.width } + PropertyChanges { target: geoTab; x: -parent.width } + PropertyChanges { target: toolBar; button1Label: "More..." } + PropertyChanges { + target: toolBar + onButton1Clicked: if (imageDetails.state=='') imageDetails.state='Back'; else imageDetails.state='' + } + PropertyChanges { target: toolBar; button2Label: "Back" } + PropertyChanges { target: toolBar; onButton2Clicked: imageDetails.closed() } + } + + transitions: Transition { + NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad } + } + } +} diff --git a/examples/positioning/geoflickr/flickr.qrc b/examples/positioning/geoflickr/flickr.qrc new file mode 100644 index 0000000..1019f7d --- /dev/null +++ b/examples/positioning/geoflickr/flickr.qrc @@ -0,0 +1,30 @@ + + + flickr.qml + flickr-90.qml + flickrcommon/Progress.qml + flickrcommon/RestModel.qml + flickrcommon/ScrollBar.qml + flickrcommon/Slider.qml + flickrmobile/Button.qml + flickrmobile/GeoTab.qml + flickrmobile/GridDelegate.qml + flickrmobile/ImageDetails.qml + flickrmobile/ListDelegate.qml + flickrmobile/nmealog.txt + flickrmobile/TitleBar.qml + flickrmobile/ToolBar.qml + flickrmobile/images/gloss.png + flickrmobile/images/lineedit.png + flickrmobile/images/lineedit.sci + flickrmobile/images/moon.png + flickrmobile/images/quit.png + flickrmobile/images/star.png + flickrmobile/images/stripes.png + flickrmobile/images/sun.png + flickrmobile/images/titlebar.png + flickrmobile/images/titlebar.sci + flickrmobile/images/toolbutton.png + flickrmobile/images/toolbutton.sci + + diff --git a/examples/positioning/geoflickr/flickrcommon/Progress.qml b/examples/positioning/geoflickr/flickrcommon/Progress.qml new file mode 100644 index 0000000..aaa9969 --- /dev/null +++ b/examples/positioning/geoflickr/flickrcommon/Progress.qml @@ -0,0 +1,35 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + property real progress: 0 + + Rectangle { + anchors.fill: parent; smooth: true + border.color: "white"; border.width: 0; radius: height/2 - 2 + gradient: Gradient { + GradientStop { position: 0; color: "#66343434" } + GradientStop { position: 1.0; color: "#66000000" } + } + } + + Rectangle { + y: 2; height: parent.height-4; + x: 2; width: Math.max(parent.width * progress - 4, 0); + opacity: width < 1 ? 0 : 1; smooth: true + gradient: Gradient { + GradientStop { position: 0; color: "lightsteelblue" } + GradientStop { position: 1.0; color: "steelblue" } + } + radius: height/2 - 2 + } + + Text { + text: Math.round(progress * 100) + "%" + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + color: "white"; font.bold: true + } +} diff --git a/examples/positioning/geoflickr/flickrcommon/RestModel.qml b/examples/positioning/geoflickr/flickrcommon/RestModel.qml new file mode 100644 index 0000000..6e89903 --- /dev/null +++ b/examples/positioning/geoflickr/flickrcommon/RestModel.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQml.XmlListModel + +//! [restmodel] +XmlListModel { + property var coordinate + + source: "https://api.flickr.com/services/rest/?" + + "min_taken_date=2000-01-01+0:00:00&" + + "extras=date_taken&" + + "method=flickr.photos.search&" + + "per_page=30&" + + "sort=date-taken-desc&" + + "api_key=e36784df8a03fea04c22ed93318b291c&" + + "lat=" + coordinate.latitude + "&lon=" + coordinate.longitude; + query: "/rsp/photos/photo" + + XmlListModelRole { name: "title"; elementName: ""; attributeName: "title" } + XmlListModelRole { name: "datetaken"; elementName: ""; attributeName: "datetaken" } + XmlListModelRole { name: "farm"; elementName: ""; attributeName: "farm" } + XmlListModelRole { name: "server"; elementName: ""; attributeName: "server" } + XmlListModelRole { name: "id"; elementName: ""; attributeName: "id" } + XmlListModelRole { name: "secret"; elementName: ""; attributeName: "secret" } +} +//! [restmodel] diff --git a/examples/positioning/geoflickr/flickrcommon/ScrollBar.qml b/examples/positioning/geoflickr/flickrcommon/ScrollBar.qml new file mode 100644 index 0000000..fbcf1ca --- /dev/null +++ b/examples/positioning/geoflickr/flickrcommon/ScrollBar.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + id: container + + property var flickableArea + + Rectangle { + radius: 5 + color: "black" + opacity: 0.3 + border.color: "white" + border.width: 2 + x: 0 + y: flickableArea.visibleArea.yPosition * container.height + width: parent.width + height: flickableArea.visibleArea.heightRatio * container.height + } + states: [ + State { + name: "show" + when: flickableArea.movingVertically + PropertyChanges { + target: container + opacity: 1 + } + } + ] + transitions: [ + Transition { + from: "*" + to: "*" + NumberAnimation { + target: container + properties: "opacity" + duration: 400 + } + } + ] +} diff --git a/examples/positioning/geoflickr/flickrcommon/Slider.qml b/examples/positioning/geoflickr/flickrcommon/Slider.qml new file mode 100644 index 0000000..8526012 --- /dev/null +++ b/examples/positioning/geoflickr/flickrcommon/Slider.qml @@ -0,0 +1,39 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + id: slider; width: 400; height: 16 + + // value is read/write. + property real value + onValueChanged: { handle.x = 2 + (value - minimum) * slider.xMax / (maximum - minimum); } + property real maximum: 1 + property real minimum: 1 + property int xMax: slider.width - handle.width - 4 + + Rectangle { + anchors.fill: parent + border.color: "white"; border.width: 0; radius: 8 + gradient: Gradient { + GradientStop { position: 0.0; color: "#66343434" } + GradientStop { position: 1.0; color: "#66000000" } + } + } + + Rectangle { + id: handle; smooth: true + x: slider.width / 2 - handle.width / 2; y: 2; width: 30; height: slider.height-4; radius: 6 + gradient: Gradient { + GradientStop { position: 0.0; color: "lightgray" } + GradientStop { position: 1.0; color: "gray" } + } + + MouseArea { + anchors.fill: parent; drag.target: parent + drag.axis: Drag.XAxis; drag.minimumX: 2; drag.maximumX: slider.xMax+2 + onPositionChanged: { value = (maximum - minimum) * (handle.x-2) / slider.xMax + minimum; } + } + } +} diff --git a/examples/positioning/geoflickr/flickrmobile/Button.qml b/examples/positioning/geoflickr/flickrmobile/Button.qml new file mode 100644 index 0000000..ee61b60 --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/Button.qml @@ -0,0 +1,41 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + id: container + + signal clicked + + property string text + + BorderImage { + id: buttonImage + source: "images/toolbutton.sci" + width: container.width; height: container.height + } + BorderImage { + id: pressed + opacity: 0 + source: "images/toolbutton.sci" + width: container.width; height: container.height + } + MouseArea { + id: mouseRegion + anchors.fill: buttonImage + onClicked: { container.clicked(); } + } + Text { + color: "white" + anchors.centerIn: buttonImage; font.bold: true + text: container.text; style: Text.Raised; styleColor: "black" + } + states: [ + State { + name: "Pressed" + when: mouseRegion.pressed == true + PropertyChanges { target: pressed; opacity: 1 } + } + ] +} diff --git a/examples/positioning/geoflickr/flickrmobile/GeoTab.qml b/examples/positioning/geoflickr/flickrmobile/GeoTab.qml new file mode 100644 index 0000000..8c0dcd7 --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/GeoTab.qml @@ -0,0 +1,135 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 +import QtPositioning + +Rectangle { + id: container + property int maxX: parent.width; property int maxY: parent.height +//! [props] + property var coordinate +//! [props] + + Binding { + target: container + property: "coordinate" + value: positionSource.position.coordinate + } + + width: 300; height: 130 + color: "blue" + opacity: 0.7 + border.color: "black" + border.width: 1 + radius: 5 + gradient: Gradient { + GradientStop {position: 0.0; color: "grey"} + GradientStop {position: 1.0; color: "black"} + } + MouseArea { + anchors.fill: parent + drag.target: parent + drag.axis: Drag.XandYAxis + drag.minimumX: -(parent.width * (2/3)); drag.maximumX: parent.maxX - (parent.width/3) + drag.minimumY: -(parent.height/2); drag.maximumY: parent.maxY - (parent.height/2) + } +//! [locatebutton-top] + Button { + id: locateButton + text: "Locate & update" +//! [locatebutton-top] + anchors {left: parent.left; leftMargin: 5} + y: 3; height: 32; width: parent.width - 10 +//! [locatebutton-clicked] + onClicked: { + if (positionSource.supportedPositioningMethods === + PositionSource.NoPositioningMethods) { + positionSource.nmeaSource = "nmealog.txt"; + sourceText.text = "(filesource): " + printableMethod(positionSource.supportedPositioningMethods); + } + positionSource.update(); + } + } +//! [locatebutton-clicked] +//! [possrc] + PositionSource { + id: positionSource + onPositionChanged: { planet.source = "images/sun.png"; } + + onSourceErrorChanged: { + if (sourceError == PositionSource.UpdateTimeoutError) { + activityText.fadeOut = true + return + } + + if (sourceError == PositionSource.NoError) + return + + console.log("Source error: " + sourceError) + activityText.fadeOut = true + stop() + } + } +//! [possrc] + function printableMethod(method) { + if (method === PositionSource.SatellitePositioningMethods) + return "Satellite"; + else if (method === PositionSource.NoPositioningMethods) + return "Not available" + else if (method === PositionSource.NonSatellitePositioningMethods) + return "Non-satellite" + else if (method === PositionSource.AllPositioningMethods) + return "Multiple" + return "source error"; + } + + Grid { + id: locationGrid + columns: 2 + anchors {left: parent.left; leftMargin: 5; top: locateButton.bottom; topMargin: 5} + spacing: 5 + Text {color: "white"; font.bold: true + text: "Lat:"; style: Text.Raised; styleColor: "black" + } + Text {id: latitudeValue; color: "white"; font.bold: true + text: positionSource.position.coordinate.latitude; style: Text.Raised; styleColor: "black"; + } + Text {color: "white"; font.bold: true + text: "Lon:"; style: Text.Raised; styleColor: "black" + } + Text {id: longitudeValue; color: "white"; font.bold: true + text: positionSource.position.coordinate.longitude; style: Text.Raised; styleColor: "black" + } + } + Image { + id: planet + anchors {top: locationGrid.bottom; left: parent.left; leftMargin: locationGrid.anchors.leftMargin} + source: "images/moon.png" + width: 30; height: 30 + } + Text {id: sourceText; color: "white"; font.bold: true; + anchors {left: planet.right; leftMargin: 5; verticalCenter: planet.verticalCenter} + text: "Source: " + printableMethod(positionSource.supportedPositioningMethods); style: Text.Raised; styleColor: "black"; + } + + Text { + id: activityText; color: "white"; font.bold: true; + anchors { top: planet.bottom; horizontalCenter: parent.horizontalCenter } + property bool fadeOut: false + + text: { + if (fadeOut) + return qsTr("Timeout occurred!"); + else if (positionSource.active) + return qsTr("Retrieving update...") + else + return "" + } + + Timer { + id: fadeoutTimer; repeat: false; interval: 3000; running: activityText.fadeOut + onTriggered: { activityText.fadeOut = false; } + } + } +} diff --git a/examples/positioning/geoflickr/flickrmobile/GridDelegate.qml b/examples/positioning/geoflickr/flickrmobile/GridDelegate.qml new file mode 100644 index 0000000..0358f7a --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/GridDelegate.qml @@ -0,0 +1,77 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + + import QtQuick 2.0 + import QtQuick.Window 2.0 + + Component { + id: photoDelegate + Item { + id: wrapper; width: 79; height: 79 + + function photoClicked() { + imageDetails.photoTitle = title; + imageDetails.photoDate = datetaken; + imageDetails.photoUrl = "http://farm" + farm + ".static.flickr.com/" + server + "/" + id + "_" + secret + ".jpg"; + console.log(imageDetails.photoUrl); + scaleMe.state = "Details"; + } + + Item { + anchors.centerIn: parent + scale: 0.0 + Behavior on scale { NumberAnimation { easing.type: Easing.InOutQuad} } + id: scaleMe + + Rectangle { height: 79; width: 79; id: blackRect; anchors.centerIn: parent; color: "black"; smooth: true } + Rectangle { + id: whiteRect; width: 76; height: 76; anchors.centerIn: parent; color: "#dddddd"; smooth: true + Image { id: thumb; + // source: imagePath; + source: imageDetails.photoUrl = "http://farm" + farm + ".static.flickr.com/" + server + "/" + id + "_" + secret + "_t.jpg" + width: parent.width; height: parent.height + x: 1; y: 1; smooth: true} + Image { source: "images/gloss.png" } + } + + Connections { + target: toolBar + function onButton2Clicked() { + if (scaleMe.state == 'Details' ) scaleMe.state = 'Show' + } + } + + states: [ + State { + name: "Show"; when: thumb.status == Image.Ready + PropertyChanges { target: scaleMe; scale: Math.round(Screen.pixelDensity / 4) } + }, + State { + name: "Details" + PropertyChanges { target: scaleMe; scale: Math.round(Screen.pixelDensity / 4)} + ParentChange { target: wrapper; parent: imageDetails.frontContainer } + PropertyChanges { target: wrapper; x: 20; y: 60; z: 1000 } + PropertyChanges { target: background; state: "DetailedView" } + } + ] + transitions: [ + Transition { + from: "Show"; to: "Details" + ParentAnimation { + NumberAnimation { properties: "x,y"; duration: 500; easing.type: Easing.InOutQuad } + } + }, + Transition { + from: "Details"; to: "Show" + SequentialAnimation { + ParentAnimation { + NumberAnimation { properties: "x,y"; duration: 500; easing.type: Easing.InOutQuad } + } + PropertyAction { targets: wrapper; properties: "z" } + } + } + ] + } + MouseArea { anchors.fill: wrapper; onClicked: { photoClicked() } } + } + } diff --git a/examples/positioning/geoflickr/flickrmobile/ImageDetails.qml b/examples/positioning/geoflickr/flickrmobile/ImageDetails.qml new file mode 100644 index 0000000..5ad5f4a --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/ImageDetails.qml @@ -0,0 +1,119 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 +import "../flickrcommon" as Common + +Flipable { + id: container + + property var frontContainer: containerFront + property string photoTitle: "" + property string photoDate + property string photoUrl + property real prevScale: 1.0 + + signal closed + + transform: Rotation { + id: itemRotation + origin.x: container.width / 2; + axis.y: 1; axis.z: 0 + } + + front: Item { + id: containerFront; anchors.fill: container + + Rectangle { + anchors.fill: parent + color: "black"; opacity: 0.4 + } + + Column { + spacing: 10 + anchors { + left: parent.left; leftMargin: 20 + right: parent.right; rightMargin: 20 + top: parent.top; topMargin: 180 + } + Text { font.bold: true; color: "white"; elide: Text.ElideRight; text: container.photoTitle } + Text { color: "white"; elide: Text.ElideRight; text: "Published: " + container.photoDate } + } + } + + back: Item { + anchors.fill: container + + Rectangle { anchors.fill: parent; color: "black"; opacity: 0.4 } + + Common.Progress { + anchors.centerIn: parent; width: 200; height: 18 + progress: bigImage.progress; visible: bigImage.status != Image.Ready + } + + Flickable { + id: flickable; anchors.fill: parent; clip: true + contentWidth: imageContainer.width; contentHeight: imageContainer.height + + Item { + id: imageContainer + width: Math.max(bigImage.width * bigImage.scale, flickable.width); + height: Math.max(bigImage.height * bigImage.scale, flickable.height); + + Image { + id: bigImage; // source: container.photoUrl + source: container.photoUrl + scale: slider.value + anchors.centerIn: parent; smooth: !flickable.movingVertically + onStatusChanged : { + // Default scale shows the entire image. + if (status == Image.Ready && width != 0) { + slider.minimum = Math.min(flickable.width / width, flickable.height / height); + prevScale = Math.min(slider.minimum, 1); + slider.value = prevScale; + } + } + } + } + } + + Text { + text: "Image Unavailable" + visible: bigImage.status == Image.Error + anchors.centerIn: parent; color: "white"; font.bold: true + } + + Common.Slider { + id: slider; visible: { bigImage.status == Image.Ready && maximum > minimum } + anchors { + bottom: parent.bottom; bottomMargin: 65 + left: parent.left; leftMargin: 25 + right: parent.right; rightMargin: 25 + } + onValueChanged: { + if (bigImage.width * value > flickable.width) { + var xoff = (flickable.width/2 + flickable.contentX) * value / prevScale; + flickable.contentX = xoff - flickable.width/2; + } + if (bigImage.height * value > flickable.height) { + var yoff = (flickable.height/2 + flickable.contentY) * value / prevScale; + flickable.contentY = yoff - flickable.height/2; + } + prevScale = value; + } + } + } + + states: State { + name: "Back" + PropertyChanges { target: itemRotation; angle: 180 } + } + + transitions: Transition { + SequentialAnimation { + PropertyAction { target: bigImage; property: "smooth"; value: false } + NumberAnimation { easing.type: Easing.InOutQuad; properties: "angle"; duration: 500 } + PropertyAction { target: bigImage; property: "smooth"; value: !flickable.movingVertically } + } + } +} diff --git a/examples/positioning/geoflickr/flickrmobile/ListDelegate.qml b/examples/positioning/geoflickr/flickrmobile/ListDelegate.qml new file mode 100644 index 0000000..070d33f --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/ListDelegate.qml @@ -0,0 +1,29 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + Component { + Item { + id: wrapper; width: wrapper.ListView.view.width; height: 86 + Item { + id: moveMe + Rectangle { color: "black"; opacity: index % 2 ? 0.2 : 0.4; height: 84; width: wrapper.width; y: 1 } + Rectangle { + x: 6; y: 4; width: 76; height: 76; color: "white"; smooth: true + + Image { + //source: imagePath; + source: "http://farm" + farm + ".static.flickr.com/" + server + "/" + id + "_" + secret + "_t.jpg" + width: parent.width; height: parent.height + x: 0; y: 0 } + + Image { source: "images/gloss.png" } + } + Column { + x: 92; width: wrapper.ListView.view.width - 95; y: 15; spacing: 2 + Text { text: title; color: "white"; width: parent.width; font.bold: true; elide: Text.ElideRight; style: Text.Raised; styleColor: "black" } + Text { text: datetaken; width: parent.width; elide: Text.ElideRight; color: "#cccccc"; style: Text.Raised; styleColor: "black" } + } + } + } +} diff --git a/examples/positioning/geoflickr/flickrmobile/TitleBar.qml b/examples/positioning/geoflickr/flickrmobile/TitleBar.qml new file mode 100644 index 0000000..39c44e2 --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/TitleBar.qml @@ -0,0 +1,40 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + id: titleBar + BorderImage { source: "images/titlebar.sci"; width: parent.width; height: parent.height + 14; y: -7 } + + Item { + id: container + width: (parent.width * 2) - 55 ; height: parent.height + + Image { + id: quitButton + anchors.left: parent.left//; anchors.leftMargin: 0 + anchors.verticalCenter: parent.verticalCenter + source: "images/quit.png" + MouseArea { + anchors.fill: parent + onClicked: Qt.quit() + } + } + + Text { + id: categoryText + anchors { + left: quitButton.right; leftMargin: 10; rightMargin: 10 + verticalCenter: parent.verticalCenter + } + elide: Text.ElideLeft + text: "GeoFlickr (QML)" + font.bold: true; color: "White"; style: Text.Raised; styleColor: "Black" + } + } + + transitions: Transition { + NumberAnimation { properties: "x"; easing.type: Easing.InOutQuad } + } +} diff --git a/examples/positioning/geoflickr/flickrmobile/ToolBar.qml b/examples/positioning/geoflickr/flickrmobile/ToolBar.qml new file mode 100644 index 0000000..f2bf3c5 --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/ToolBar.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + id: toolbar + + property alias button1Label: button1.text + property alias button2Label: button2.text + signal button1Clicked + signal button2Clicked + + BorderImage { source: "images/titlebar.sci"; width: parent.width; height: parent.height + 14; y: -7 } + + Button { + id: button1 + anchors.left: parent.left; anchors.leftMargin: 5; y: 3; width: 140; height: 32 + onClicked: toolbar.button1Clicked() + } + + Button { + id: button2 + anchors.right: parent.right; anchors.rightMargin: 5; y: 3; width: 140; height: 32 + onClicked: toolbar.button2Clicked() + } +} diff --git a/examples/positioning/geoflickr/flickrmobile/images/gloss.png b/examples/positioning/geoflickr/flickrmobile/images/gloss.png new file mode 100644 index 0000000000000000000000000000000000000000..dff2bd34718bce770ed746136f8976332111c23e GIT binary patch literal 889 zcmV-<1BU#GP)eTd}%-tK1b1D4>ySGqo)GjrzLvFHj= z6ours|8KvB5bhFPA3bXSq1ii_tVuw48*3Puc;)XPLEvq@0M!gpbZ1Ll1^l47D7vdi z`@@I+JGf&8-y<7EA2J)e*Kb)8I7LzPu`*^hYk{LE`s7KS8b=@dIEp?8r?nWqwK9sn zvw-muUwc|}_Y@;|?*mciRyY+zi+%{KdB%EZQq!Uz4K>fTb9m*V=%?x|v0k%@aA_1p zKj-OF4Vi~amlplvwVgWKu@Y^RJ$PT8-rb$((ynscUqru!wW1zG=X7b&?-q^SwcDCX zOeTt=KP*L~4qA)W5dG;8mpbY8r*WQ=!^cYXXDcBDq71VmgpZVqh#$%{MJPO zoUKQgEa5i4%F2|6Jt^(AGe>l~A>&}BIQOxZF_i^aEo?ap`Ar(lJM8EZyCMZ+SB29pGh zSg@hzWe6M#$7mL#(BchidKseYIN$B98PBp5u9&iBm>7s)6M`~`R`WoGh%sv>M^Owx zc`ihUiK;@M6*JlaXsvR~ZX;=hHZd`MB)~DVaLr??uW-eXB~zlHa~2a>wgA~7W-9Km+0YRW8uA|UW4I5BTM4~?*i`v?*i`vud&yE=VmBv+|22M P00000NkvXXu0mjfaetp8 literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/flickrmobile/images/lineedit.png b/examples/positioning/geoflickr/flickrmobile/images/lineedit.png new file mode 100644 index 0000000000000000000000000000000000000000..a6afb5121a6f8f02491ce9fa220d9f8b6c0f31c0 GIT binary patch literal 1307 zcmV+$1?2jPP)^_M)OMqYwHdLJ>s}eN&%{;FDDU1^oxa7nPzf zf|n{76#7tuptM>qwY6%kY0}0t>Ez5g`}=&DOiXMwNlBU%`@!bG%sywZNPmU@yB5~XvhKv!26k>*eX&bbw5aXw&G#TbLCA|i}k z8f7#)N6$bH1z+HgV`usG{a=Q?E!s!7KC!vxy=C(31Wd&|ecvMJ3*;m7aD5HC*jIC@bW7P5Ig-Q0^y^q_fw-J0mj6kel zw5houE82_#qG*u0YpWrOL||gWgF7E!_uyWV$r+*^k1tf(Nzyug%&@zEC#Vp+-0V1` zzZa3St15$kvK(nl2r0Q-Ol?bzPe1yE_Wn-16qKwXbQZd~X=oG9`UMY4vl+b0EnCN` zx?~q=^<8j}D4GBshPtXa^+Ya*&qxsw>eJKYeXeO|nvjp$2uVtm%P$GQ)!16A-IodyiE^a&f9@g^NzD zgk`h4nq^mljWq?lp1@rd!^XPn3-G$v@IS#B>(;l1*FD3=7z6=p7QBqiqj*h#&EKk9 zS5?Jwoz)G%Hvs=H0AE)=yzUq_#^Q+=c-?wn*BH}0|MpiYT>j7{ndOr+G4IzOEFes*|GuptD@Dn(UGS#&L;j-B|1sH2&U z*y-tMthY=|O)&E12&puhdPbUwrL2)l&@_WansDUHBbW#pjRtn=iwR<%r@Xbo>xbXq z$gvR+AQ*y%t9FW(r2eak2q6SQ2y>BZ>oaQ{Si`}O4l?}XFokNK^g@Dj-o4kex%6Cl zbA{3AKREpPVMralr3&30T?m4~tjYp3#x%Xv+RLJ=pMU$6*WP`Vw?2HE(vDvGH&!`) z=oDr{dBY=Z1JVB4{)cKwd%}h9#u+~`PH(A~qAgOS0~=d(nRpiqz_Tp7ET(F)tO{e7 z&NJ@D=)I{#d25;Rqi31?qW*%Z4h)(!4G(v0E53Nwle=ndLj^P#M$e4Wn3_Q*QyOG= z?^iU63Yz`vea1jnUk`=u9Qi_#^Iu=!_@Se(6#5Gc0 zr98Q=HtI=(yw9^-MaUwHRW)2O7;H&o=HewTo|>XD7CtH6S$fJB{J3#O{sI^eqK)Qb RrHcRn002ovPDHLkV1hGOfVKbt literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/flickrmobile/images/lineedit.sci b/examples/positioning/geoflickr/flickrmobile/images/lineedit.sci new file mode 100644 index 0000000..054bff7 --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/images/lineedit.sci @@ -0,0 +1,5 @@ +border.left: 10 +border.top: 10 +border.bottom: 10 +border.right: 10 +source: lineedit.png diff --git a/examples/positioning/geoflickr/flickrmobile/images/moon.png b/examples/positioning/geoflickr/flickrmobile/images/moon.png new file mode 100644 index 0000000000000000000000000000000000000000..1583ac83f7cfbfdca3f9c0818a2ff00e7585bef3 GIT binary patch literal 2366 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 literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/flickrmobile/images/quit.png b/examples/positioning/geoflickr/flickrmobile/images/quit.png new file mode 100644 index 0000000000000000000000000000000000000000..aef73853e362dd6787ecffaa057f21adf7d1d456 GIT binary patch literal 1785 zcmV({j3*ryZagbwx(==k`U_8JXxI-RukX6@Fn9*<|uYPJ5Jmv`vw{d;O1w&?VP$K0pa zn8Sg&?gBgEu-kjfOUtykyGIJc)pu!kSJlzc5w7o&!|tFrt8ab^yRx#vkYD6%j^3TV zqXWEn1LHP^W8=KMyiD-fkzk)oX6a&SaY?`&1FBxFsjAheHc+?Iq1`&e+5x-zLs+lZ z8wKQLHk%a|q8v)Df_Cwgh2m{{tHg2FsZEuS_OGCxB$AN~tWyyH=TMxPE$iO8hc&b929q5(agq zg@t}PnSyUBR0U+IP^2PMC=^s-LzGG-YPZ|M!Zw?YeNBT61OhccUZqkg0m&~|#B(K0 zMNPvo7BDA!%E)14!D#HqVcFxOV=807ot+)Z=ko%Te-G7cHU$X4c=;5c&&QCIOeRUe zi}DJHm)jXCPrRw}c(&DSQ56=wE97^uNx&-bBeq07Cu@K?#6p%V%XD~nC}2${6B&(0 zipP_P5DFDxd0FOrvc$1d#`AIx&jYl{&tU0|2IIXTHCUs;(2qx>Vq>v2*q7MvZi=sQ z7(;v|o7G0`RtMHE;(8AMPeZ92_sSw37vVa{P-B6-hSeMT(MW`jx?N#K_Pv`*rvZ~n zQ)91zfWw}^&WVTx=G z#J|H){Ei~-R>Vd!=ndZx`pS<|n4-9lW@cutI0SX!vkdA7c+h{XfX@&4pn%xn>uc*Y zH#<)jN$NgY1&z8?nVp@bwY4>|u{Jk1X%kSsP2T{{Pk#LNd4046pYC>!$YQqA^z_W% zlP_ONj{<46SQMR3M``TlLcTzo-c13eS}-6K1T^YH;k-J&Yx-R>h##Q#PFi zWL0dIaA-?~1zb235`Xi~7uQ&!@5K>h29|Hk-@bEpm|NV66spbyBvBs%?>pI_-{F^7*;> zD`YTH9dY5EjH~w~w1l9J!Ksy#Mi9?nbKV^mR?GqNlG7chJXlrw#ro65_hmc%|4C=`rT0w<1i?VJXt+7_iVoa_}WjQZG z7XP1nFRbLnD4%*J(24dOcEA?OqFoqP^lTl544NNutN%f|(;oPIL+d zgsL_mOWfBJ?zvlUFG-f3)8P_54>w?Z<_{2~Kn{<^#l^10V!7gWMYSL|h8>JqA*a)I zXGjg!B3XO<35OdnZl8HW3>q=r9b$3;K!0*(Q#;ctxm<3tSghmu{)F_|bGzNbC+`ZW z#b%Q!Et$<=e)7Dx>i!T*9kOpGJtF)T9DSGdCYI3cx9J+}=Tw+(|20r_JVQ(&Ie~(WXHxMd(c4()0X~bUEaWAuh*L~4 z{Jfce-bDO+d^GY}tR)x`VN=nnt$k&zd-uES(1G4cbWwT_nKPGanNAY@YMZG|-MUiC zm%xRquF{FA2Xl`mD%*z3u6;v0PTiP$^Wx62D&cRSP^e5idG&1O$VfN2<_Nj5nS0m9 zvV_bJ*wJ_H!mfOUbpzg0+iJ0LBc(x$AGe{`ocpiW^NTY}$0xWvdVkRau+;zn002ov JPDHLkV1nwjbWZ>P literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/flickrmobile/images/stripes.png b/examples/positioning/geoflickr/flickrmobile/images/stripes.png new file mode 100644 index 0000000000000000000000000000000000000000..75d2bf6c66ea20238f29bc6a086a31a5eecc4add GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqX`U{QArhD8o;BoRRupM@X#YWC z&AhG~(G?Tk7NzVx{!C}(WsWwToQawCX>C!bqA#&neMnfkRqW1Q<;|IC>;n4?mzErn zP+wi?SU!JJ+@EuLGLzb7+U`79``e!BN>uf^N)M~+&)ps{&z2X9U-Do=3(!UePgg&e IbxsLQ0E~z{qyPW_ literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/flickrmobile/images/sun.png b/examples/positioning/geoflickr/flickrmobile/images/sun.png new file mode 100644 index 0000000000000000000000000000000000000000..c5fd36ed39d42ce1f365f27e9637b3a0e1f3e73f GIT binary patch literal 8110 zcmV;fA5q|mP)aOmd?w$=8?1P0M0FjhLQKDoaB+?QUreudd7;=Oo{HG5)^lkXh ze_q00{&Lu1hb`F>O;f=|3n@_&L4eo?7|gzPPw!n_%d59!=Dq%?>h9S90yLYBoW&!{I`gmNw^E;Dv=OurBT>Ys3J%1jwy$$+11&9bpWR`vnU`r9`{zEHiJfn$xt-`R#0etyMfL(}TTq>=$rhyzx^l`S3 zRRDch`6loqff<_^o3pV1fYS!GC^`77*)<}F5y7Gbpr#2@w$G0l*SOXk5ovAJ$4mK%=Z52G}eDg`_N?As`G} zF%U<1^leVxeA04lRP%(ObNGY%X1@u9%j#nRh{&YTBnp(6RSi5iOdyXP+*g_tM#0~I z#$chUR9O&N(?OiZG)!WaUL7mYc%^C)xJ}|4D4=lx3Y<4UKEe-XO$~O2>gyG2C8fqK z?sC;xoXb8QfZ(Mi;0I4k%)br~&jH7Fn>e*llRrN}G63N%D7*oJQw`u$jjMfPDcYgg zXvtpO^pthbLxs_50$B$pn^6T>-svV#=z=qY2r+8CHmNcWnaSn9g5*~LdGpsaGE{*> zi@EKA{qPxFePu@djR8WRx(VzkAHMs1r}z)g5^5N6y=P%|yHHEbwNLSJ|z1jQkGyxYaOlT2_!>E5ie zr4#d;CtFs92wZEx>?#TBlrZMWj60&Tqe8_3I4l#3=mbp>f6`+hF}2_yjI?cXGP`MAbcK10~%HdKuG@4drQ*Zx3r zH6IGTSr7m#0!IYMd8JU!3jXIG5Alo7&tl^gQL#Ie<-L+>+sCM!Ye5E=#U~vy17R|5hH>ef4ZztJ6^$W zm<+|v7MJbQYVY`Js9wo+W6PpndytEo(#loEQc!lU2I!NZahDWY0+&L#3tQQp{bR>{d4sy94mTSktNtvgxkimXNvWSC@z-2|BmEuM%=WS;eNWGjbX)Q4gQTl7RB2YAR1B69 z95NKc-BZIG7d-UVAZoioeJ*Sz4L5Hh5^$pf%ACYEK_nd|M~o;T%6tl@lcgl%J_juJ+aU{{be$pd4NiQ z96%1F!W5J{s7n+?6o?H(EWiz5+L$*F*%)Y0`JhsL9njDLoZF?&i#6^$TSW9LTs z!=C|QZvhv>ZLec+@vB+oNP4b&Jbpz{WgtlqBDz3(bF1KbKyYt`qi=1};;0rB8Wdxg z1@w1fg!}0Kfo1mdlr+V9V$hcRdM6ND#+D5Taa;1))2OU&K+LumKDl*e{77*{Ej6Ef zUfXU9P#b{pAWc&+)a{@U-St@Zfgloq1%N=nP{_eDf|;qKe&XjVgLl9FC{cm#DY{8Q z*JRXg3v;28)xQcyuaw;2;|6fV*fa)N)Bfm^!3WkM)hZYR^!$)Z>TaGyoF7r^U5zsC zNZEc$?9OQCO3}zJ<%{*>pVoH13+OG7VUSWFr2stvgOmc)6rg*!3@L%g1PmboVG?IV z7-Sfb3{kg(>XFm&@XE`N+6K7UY3?a15^1g7kZv{yYZs)Kte4x#R?HhYe(G*8M1V8} zg#a|001@P#a#sFXmE`ru>9#cf-+?fKl4}ThwYE;a+?DyYwlp>cDvJi2>T|<)^Cu!( zG12ldkl6v5F-Vnwa)5S|_+dO?97s=_y5*<3<$diBUSt2Yav)WLbODM6h!>X-Q5^5S zojs7JX4-$M*mX-)HXzXW0rEcPfXg9xJOik@$S{o#&$Vt8h~zVkS!)aC_M?Jnn6Z`Gy$Xz z;|8fiFlY(}9Wo6;03{GiUW)`k0>A;J0+bCfZ3D9h%GUW*x?!%=X9llO?E5Sdk)^~p zU}P57fD#JEtF`-$%9j~srH7Fo)91hDe{>A_R{)+nBlLwcBl+vkjFHxw!O)VD*$$AB znC$_S%u(6;q~~;@f3EjbtVQV-peh-la*&Du#URB~3*jlV>{|$?z|bU50!^^kuQ~}1 z;s_K^z|njFh;RT3*2i9Y8k# zG8w>qK(#>Hfb`@kPbRJonMJ7s9U@Z;kvlD9%K7`jbsu0+9;5;U1CUCg>VU2Tyc-@W zO8tzfMGJb|*p{ui97SUtqRxZ-8Q9e!bWHesY0B?@mS`>(Q*L-%dyDBy_W(rXSz3Ro ztGE@6>x+pw)3CA5GOk)@E2KjmCe6s?TY}I=Fh|GR;gnHAst%|MfpmcQRS+d0H35St zOu(4ZE~d0gx9Mg&l<-qfWFHU+NEjf7sEG@TFCcyu&dIE@=> zVkx2+;0Y*14&ZeF1CUlAqoJxECKimh%X&CE+A`MOB(7J2tDO+8btzO*iLg#3?|~&i zEK50Kc)kh!3)e`#0;c<~u(?Z>;;S-UBg~1A%R8Ulp}wmql{JM_k0dYbjvRDuZ@T7e8rKw$yNEI^eh7i~)X z6$3nQ%`(HBP7(*PRmE6k4oCf#@QwCX9j{!W$r|0jPl}21rk>gC^6R z#u3_glY=L-{|keNAt(VJ0Wt>QCIqD>{g5V*B~UEDkSpTt{Uk=f%7M@$6 q(yB& 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

;0zh{wA6OyP`PpX?5+&HR6pc9-BAki5H0 zByU68bx5^Jdi<^wtwng<5@1Cse;J?uPDbxFhe;A8w{D#I@c?=4DTV&>DUezUvh%hm z`=n~`%u#jwlJseZipKrWd4HA>n;rECYTSfh#=Aw(^ocbeuZ zc0TC&nh#|m^6IaUly+VMw2DWYuzr>sJ4Y1dd+4P%;g3~<8yV6e5|t@so1Yh(HYg46 zpgnku#z{chc?jA=g4Bdmlg#iEAS#H6QlS7R4X~}iqKl}wp+@yo*v6>%8j$^wRPhMy zEHw$^|AqQ!%k>gx%OfWc7dyE0_Bx*aY!mFNF3)zeNZUq^m=H4j+(Jt9`yb)f?km4d z@NpeVrTKVeEtI_&GbcuvXjzB(d1kaz&nXW^5ZAaw!7+`K~grnCozxONw* z6m~8YuVd8lQZ24@&wri4xP!vXJlXfhgdOckM^E*IncVU^_KH$mzMSj;fEa zqGSCC@yfQD>u=Komjs^%;N7`)QYu_e%=G!SkNUM~R`PZ*`bk63;%8zzyH;O$^Kl{g%Ws~}4r7B^Bua%B| z>-G(>@|QnDXs63a#yhg9&g--${P-11=N=u4qRWI@3CJ~sY6Zp(71hUq%Q2NkRK(0& z4-nZSK?PA5iml`#bd!9%$4Quzw3*nM)w8UkHp}9&dS-Z*0N~&JNg?0;DaJCa{C=aP zPk+bB*PkPN4xlGC0c?JBTf1+mxlZCvd*I*m%v;+xr8cgjGB~Hd*UR{qp*RBR!I7$P z@2ra3r$EC?B=rXbvL+-!k9ow_10!q5Mqo8gi7Ez4s-$Q@6*I=5!ra=tNcqe$tW;L9 z)O!`7`Yc}jm8YFO$j=eevZFeJ<}qpO={~oZYh{e&rL2lYX}_ z!y9^`H==(6U;!3I&5^=Lx7xV`J%l7fz>c7?D_k2RE&6JU2N*^vNs{aS?v`k^fmm`* ze1XEG&^4y$$~&gYb@)fD?)FEh_b;Klai9G4Zyt{C`OAU6HvF*jfFQPw zu>etUrahB$TqAB2dwMYP1<`p)q6t7!IL)PzpseMTJr% zV?j0?0!9ONh<0#@XySe^f{~snp|Tt^1d1dhLu1$2bYSry<8kJ=l=1dTh`A*Ih{lZS z-evBt%zhjXGHbN@Ls}dksKQDFV_jUryAet&kg7+$NP}hNt;;Zi6r2_NYs&bdXJ}Vo zb&a6%OiE-n1P#t|m^8y0P_%CDNHj)zZczh(R=atK`@Qn|smjOcAoFA+hvM53B?MH= zS~taLZ$!WP4WQ94(ANQ^pp7bEg2;Ho-?nS|Sm}|mfV`7Lr+Hl&EaoNt^Ll|t14R|_ z-01adQC$N7H37xhP&YO{K3|Tozj}Gwdt*>=Xvo{A50|U|?L--e*Zx6MUi(K{{`>4* zXZQ|QLcjMU$+e|f9!2fL&t{Ye(BFt-$>ZCEmh3`(s1xRY;~)*7WQgdVpS|_#6_FR- zH@Of2!gjryk5v5*OWfa}sP6$LeQW_K3g~-%9R>i%J6|#%@E+#Ijk`geTG3Br^6Dq$ zLaVFy)+-_auH_#{Mvun`mCD_Rl=ru&(chM@RJm77`P*{+UjTy4T^PfT-T(jq07*qo IM6N<$f(!}_`Tzg` literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/flickrmobile/images/titlebar.png b/examples/positioning/geoflickr/flickrmobile/images/titlebar.png new file mode 100644 index 0000000000000000000000000000000000000000..aa35c9e1b6583bbeb5b0b2ba070f236b36297eda GIT binary patch literal 1327 zcmV+~1000E`Nkl`f!%0rEEPTYqq|G_0m&4Ap+E=_4Pe8zLK6_*upKav37Z`-H{x7y3c#8H{EGoc5R3VI_Um%_ z{cq>z=Wuv<2-aF~j;AU6x)Gg{uVt*>)FaDuXZRLuJ%>YDeXWBeTsNj0yXWU;xV^oF zySuyJ%d)&N0l=RhKK$~>>FFti6Y%)>NNrIRG&F+n-jnGAJEqQ^-vaR(C*{06r?2Nx z+9=}=JN8=UtCWJv|W%Syrb)RaKA~+Y15*bPr6Em7}HGv0pYBVSnvU?<3M-!x;7~}0JfsSJ_GK74>&*pg^Q{TJf*L#xTlqQ|rgpLhP&7>7eVQo(;d}$q zva}p0Dc)ObN(wRt{^aBYa+J(^T?EH#n(!h%u-?4DbUJP5-pvM6?_(xB_2Wf)Dqm18 zm107J$XKR605P@qHJi>i^P|nP@Oj2cFeE<0s`sllP`*;n)_Rml#g*Y&89-oS zA`|t1T?ac;Ule&^M%osX@0|?v^cp|guX^)ErH3$lX(LC_Q#{-K<3ZY!Du1bix^B^h=)vUfe90@eZGAw8y&6-^pE#Wx_d zf@9sc+THHhc=&84V(?9r_bky!N@3v2gW5@-jdiU5c=^{ZlG^ehk)gTOAIV>gbun)NbT6A zcZ#G>CtrV=H@!<4>@#Lx&xW!Bz=F35{^zUB8qm<;RJ1>5_W2rzNWFMjh2qG_QhFcj z5lb*n6_KR&M|zO#rO@@E9X$wL;@`{BDa2S;WZl$v^SfkX?9OYc6A10_dx(6h2-?)L zLKnH@dg%*Ru>Yrwnw)qGa{Ya`uabZ5B;N}HU*E`*xB2qKfULEnkXHU0r06t)k;*P> zEBSIVbaL+nK`+o40IeR?s}sqcq2-k0`=%`GiDssyWk)$voY&W-pK2w|jQ lCTB{<{F8{3tU5o7_z#DajA}HOxLyDN002ovPDHLkV1k~ddi4MR literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/flickrmobile/images/titlebar.sci b/examples/positioning/geoflickr/flickrmobile/images/titlebar.sci new file mode 100644 index 0000000..0418d94 --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/images/titlebar.sci @@ -0,0 +1,5 @@ +border.left: 10 +border.top: 12 +border.bottom: 12 +border.right: 10 +source: titlebar.png diff --git a/examples/positioning/geoflickr/flickrmobile/images/toolbutton.png b/examples/positioning/geoflickr/flickrmobile/images/toolbutton.png new file mode 100644 index 0000000000000000000000000000000000000000..11310013eedc808ca278e3068d7779e708422726 GIT binary patch literal 2550 zcmVe zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00~}6L_t(&-kn;@Ze&RjJrQ}U z%I)@yx>vMhM)Vd??@(_*@_Yb7zz49M58wmf14gXj57@F~Rl)u9qI_Ld^LrWu%xs>-#eH7mxJ+t3r+Iu8>W-a$yaW&t9&L`W+wBlS zfLl#pt~TpGtyZfqA$po-jn!)P$DjWACx19QJHykbPjPf~R4mp`GJ`_tnt(B$NSb8* zzQ_XH0$@3QS~Nt>JtdI!X60wP2}Fdu54Tva*SNgA#6MqugMWPW6^@UOzjlnD5dfT= zoc#X9ix;2&_Se6`#l;1#uCB2Ehi68#3$>GQ&EiUM!f+9^cl;4}c5EU-m|w1^6+#F& zK0e0jCqKliSFiB*FTTLXA3grv1OS`O=JT_&Gn}8F-8ETgyHgg=*R!L*lAJU z{d}G_7_K?rx!~xVyW<`}gnh^5si>^ZGTuyS(`M1OQK- zJi%tO!GCt&#n|)yL5pugLm^OmbDx@NlF)fEk><<7FboZW0t6@k(*1ymcxVtz(*#lg z>~M2)joaHB{OI{7`1arb`fLJ#^?IFS*aF2~Q>LCE71Q5IL$F-wUE-g~UqYuw-8W91xn+bx`P@ZMvZCNMK50N8G~P*pH9 zL^DqZ&ENt)LYaKi!;NQmGju%+0H$cKFZvjcX1 z3lfFb0OuH6e~;a63r9c*Ap$T>6TJ5j5$txmIfa;AP=S|S+yPBAj$oxZdvWW^Iga8uDf^wmPB@BB2s9<3e0NHtnC{zg|fO9SapsENVl)F#7d{_lx z-pvfaKzx?e2qF=uH4{adCkVLNp4_%?~t) zssKzS1E{~dcBd==y(}PTb9-<6EPnMkiUV1u74Wpq1j3YavSEM~xjDL{X3rBWDBq-> z<#R!#$?=6sL)*oQ4jItoebN65fQA9dSR|Tcb;siL5&)1=rR%hnCY8XlW7Txs2S9yq z0>A>#1BT^|;r6*U%nJZ|3@{&s&I^ZKU`=15OjQd~&kxk8G&4!G%Nngd3jkWw5uHpE zTE8-6K)Mh@i0G<9c`0x*wPo3Hi)5_megz#P>d zGxL=RL<$L!9Z94{MURcu-u1mZwpfV5?^^&0uOC9kjvofVUN1CY7d*fO<_XGa!O?dX zf~O3E191T9VoOx!Qh2aqDbFv(5YJLB(Cq5i_6u~3_ zwbCyDnC{Q~z#ImH9Be7Nq`|V2l%*Shs$cX-%JG%P28av*JeS*c9o7gn09Yqz84w3| zb2gJQ?adRETCugS_ytATwLZdBc$unVohIe{UT2{?1jH|FOJI8M;l1ytLGS$x0D06;<&KZf=^ zKY%!<#cH>~WXj~R2rdiYS@o08_Vcb{k)!l zS%IomIEvfYl$2q$^oEvSqYJt8Ub;xAvQZ7f=$f^{T^~S1nApJ)gE(4Rs=Ri5z0j3J zn$D49XHcjugx68ww7}X05jM&teE*hOT_2dK$1M0UOh0GN9i%v`kmmx6Dg0nD7!gpI3_$P_2Y zXj^4Hpb~@jABRyBv#xkv7@Q)ZX^GWhn9R`BTRahgC%42QakQgUs;|?9;zFSmM@zL% zV}$49@j^}607?MEnUtDLmgEhg>NvdsL1X{l?miLb6QL>F?fCeFO zsI4~A0h=mq2wEVgUjNPZ_SA?HcRhSr0ghPFZG_VDS?VlMl^)zw?WNM5^V=(e&bbVP zRz3Tk4%(EbBtv=*8={Q8u2YKVQik-7Z#x$-NEQ+htR;Wx&Yp9`fu<B652VFZWs1RLPz+Io`c{_x1PR z|MypJ{*KUJFE1~D@&5Yy`QyirvDs{LOy>%5{%%hECFmYHFNM)una#u=iB$nYl{xCd z>`+x%o@f%LY03<`ySu}iH*fIv?OUwZ>tEj9e)yIE;PmwL*>=1AaDTV`n{)0{=Nx!) z-Lt<3#d3W%kV<5&zUl_us};i&=sgCA%~?Pyr_&~;w%^s&Ri4EE09*nYhh&1)L;wH) M07*qoM6N<$g3{N*E&u=k literal 0 HcmV?d00001 diff --git a/examples/positioning/geoflickr/flickrmobile/images/toolbutton.sci b/examples/positioning/geoflickr/flickrmobile/images/toolbutton.sci new file mode 100644 index 0000000..9e4f965 --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/images/toolbutton.sci @@ -0,0 +1,5 @@ +border.left: 15 +border.top: 4 +border.bottom: 4 +border.right: 15 +source: toolbutton.png diff --git a/examples/positioning/geoflickr/flickrmobile/nmealog.txt b/examples/positioning/geoflickr/flickrmobile/nmealog.txt new file mode 100644 index 0000000..8c8286d --- /dev/null +++ b/examples/positioning/geoflickr/flickrmobile/nmealog.txt @@ -0,0 +1,1403 @@ +$GPGGA,222437.000,2734.33926,S,15305.44310,E,1,07,1.3,50.6,M,39.2,M,,*72 +$GPGLL,2734.33926,S,15305.44310,E,222437.000,A,A*49 +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222437.000,13.3,7.4,6.6,85.1,6.0,6.8,13.7*56 +$GPGSV,3,1,10,16,49,115,42,25,39,269,36,23,58,176,29,20,72,335,35*75 +$GPGSV,3,2,10,19,02,028,,04,06,241,22,13,30,223,30,27,19,284,35*78 +$GPGSV,3,3,10,11,06,337,30,03,13,055,25*7C +$GPRMC,222437.000,A,2734.33926,S,15305.44310,E,33.9,157.8,030308,11.2,W,A*0F +$GPVTG,157.8,T,169.0,M,33.9,N,62.9,K,A*22 +$GPGGA,222438.000,2734.34821,S,15305.44697,E,1,07,1.2,50.8,M,39.2,M,,*79 +$GPGLL,2734.34821,S,15305.44697,E,222438.000,A,A*4D +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222438.000,12.4,6.4,9.3,16.2,6.1,8.3,16.4*5F +$GPGSV,3,1,10,16,49,115,41,25,39,269,36,23,58,176,28,20,72,335,36*74 +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,28,27,19,284,35*73 +$GPGSV,3,3,10,11,06,337,28,03,13,055,25*75 +$GPRMC,222438.000,A,2734.34821,S,15305.44697,E,33.8,158.3,030308,11.2,W,A*0E +$GPVTG,158.3,T,169.5,M,33.8,N,62.5,K,A*2E +$GPGGA,222439.000,2734.35696,S,15305.45072,E,1,06,1.7,51.2,M,39.2,M,,*78 +$GPGLL,2734.35696,S,15305.45072,E,222439.000,A,A*43 +$GPGSA,A,3,16,25,23,20,13,27,,,,,,,3.3,1.7,2.8*3A +$GPGST,222439.000,10.3,9.1,12.2,44.6,9.8,9.9,25.2*62 +$GPGSV,3,1,10,16,49,115,34,25,39,269,36,23,58,175,29,20,72,335,35*77 +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,27,27,19,284,32*7B +$GPGSV,3,3,10,11,06,337,28,03,14,055,25*72 +$GPRMC,222439.000,A,2734.35696,S,15305.45072,E,33.2,158.7,030308,11.2,W,A*0E +$GPVTG,158.7,T,169.9,M,33.2,N,61.5,K,A*2F +$GPGGA,222440.000,2734.36580,S,15305.45446,E,1,07,1.3,52.0,M,39.2,M,,*76 +$GPGLL,2734.36580,S,15305.45446,E,222440.000,A,A*49 +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222440.000,13.0,8.0,13.4,6.2,7.4,12.2,20.9*64 +$GPGSV,3,1,10,16,49,115,40,25,39,269,38,23,58,175,31,20,72,335,34*72 +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,26,27,19,284,30*78 +$GPGSV,3,3,10,11,06,337,26,03,14,055,25*7C +$GPRMC,222440.000,A,2734.36580,S,15305.45446,E,33.7,159.1,030308,11.2,W,A*06 +$GPVTG,159.1,T,170.3,M,33.7,N,62.4,K,A*2D +$GPGGA,222441.000,2734.37483,S,15305.45825,E,1,07,1.3,52.7,M,39.2,M,,*7A +$GPGLL,2734.37483,S,15305.45825,E,222441.000,A,A*42 +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222441.000,14.0,7.6,14.1,17.6,7.7,12.5,21.0*51 +$GPGSV,3,1,10,16,49,115,41,25,39,269,39,23,58,175,29,20,72,335,35*7A +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,24,27,19,284,30*7A +$GPGSV,3,3,10,11,06,337,28,03,14,055,25*72 +$GPRMC,222441.000,A,2734.37483,S,15305.45825,E,34.6,159.4,030308,11.2,W,A*0E +$GPVTG,159.4,T,170.6,M,34.6,N,64.1,K,A*28 +$GPGGA,222442.000,2734.38407,S,15305.46216,E,1,06,1.3,53.3,M,39.2,M,,*77 +$GPGLL,2734.38407,S,15305.46216,E,222442.000,A,A*4B +$GPGSA,A,3,16,25,20,13,27,11,,,,,,,2.3,1.3,1.9*3C +$GPGST,222442.000,16.6,7.0,14.4,14.6,7.0,12.8,21.6*5A +$GPGSV,3,1,10,16,49,115,40,25,39,269,38,23,58,175,22,20,72,335,35*71 +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,25,27,19,284,29*73 +$GPGSV,3,3,10,11,06,337,27,03,14,055,25*7D +$GPRMC,222442.000,A,2734.38407,S,15305.46216,E,35.5,159.3,030308,11.2,W,A*02 +$GPVTG,159.3,T,170.5,M,35.5,N,65.8,K,A*26 +$GPGGA,222443.000,2734.39347,S,15305.46609,E,1,05,1.8,53.8,M,39.2,M,,*7D +$GPGLL,2734.39347,S,15305.46609,E,222443.000,A,A*42 +$GPGSA,A,3,16,25,20,27,11,,,,,,,,2.8,1.8,2.1*35 +$GPGST,222443.000,11.3,6.5,14.6,14.5,6.6,13.0,18.4*5A +$GPGSV,3,1,10,16,49,115,40,25,39,269,38,23,58,175,22,20,72,335,36*72 +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,26,27,19,284,31*79 +$GPGSV,3,3,10,11,06,337,28,03,14,055,25*72 +$GPRMC,222443.000,A,2734.39347,S,15305.46609,E,36.2,159.4,030308,11.2,W,A*08 +$GPVTG,159.4,T,170.6,M,36.2,N,67.0,K,A*2C +$GPGGA,222444.000,2734.40297,S,15305.47000,E,1,06,1.3,54.1,M,39.2,M,,*70 +$GPGLL,2734.40297,S,15305.47000,E,222444.000,A,A*49 +$GPGSA,A,3,16,25,20,13,27,11,,,,,,,2.3,1.3,1.9*3C +$GPGST,222444.000,17.6,6.3,12.7,14.4,6.3,11.4,16.2*55 +$GPGSV,3,1,10,16,49,115,38,25,39,269,38,23,58,175,22,20,72,335,35*7E +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,25,27,19,284,29*73 +$GPGSV,3,3,10,11,06,337,25,03,14,055,23*79 +$GPRMC,222444.000,A,2734.40297,S,15305.47000,E,36.5,159.5,030308,11.2,W,A*05 +$GPVTG,159.5,T,170.8,M,36.5,N,67.5,K,A*21 +$GPGGA,222445.000,2734.41247,S,15305.47390,E,1,07,1.3,54.2,M,39.2,M,,*75 +$GPGLL,2734.41247,S,15305.47390,E,222445.000,A,A*4E +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222445.000,16.0,7.0,14.4,10.4,6.7,13.0,20.7*52 +$GPGSV,3,1,10,16,49,115,36,25,39,269,36,23,58,175,22,20,72,335,34*7F +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,26,27,19,284,31*79 +$GPGSV,3,3,10,11,06,337,26,03,14,055,23*7A +$GPRMC,222445.000,A,2734.41247,S,15305.47390,E,36.6,159.7,030308,11.2,W,A*03 +$GPVTG,159.7,T,170.9,M,36.6,N,67.8,K,A*2C +$GPGGA,222446.000,2734.42201,S,15305.47790,E,1,07,1.3,54.4,M,39.2,M,,*75 +$GPGLL,2734.42201,S,15305.47790,E,222446.000,A,A*48 +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222446.000,13.0,7.4,12.3,6.6,6.9,11.2,17.9*60 +$GPGSV,3,1,10,16,49,115,36,25,39,269,37,23,58,175,27,20,72,335,35*7A +$GPGSV,3,2,10,19,02,028,,04,06,241,23,13,30,223,30,27,19,284,32*7E +$GPGSV,3,3,10,11,06,337,27,03,14,055,23*7B +$GPRMC,222446.000,A,2734.42201,S,15305.47790,E,36.6,159.3,030308,11.2,W,A*01 +$GPVTG,159.3,T,170.5,M,36.6,N,67.7,K,A*2B +$GPGGA,222447.000,2734.43157,S,15305.48195,E,1,07,1.3,54.3,M,39.2,M,,*7E +$GPGLL,2734.43157,S,15305.48195,E,222447.000,A,A*44 +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222447.000,10.7,6.7,10.5,6.6,6.2,9.6,15.5*5B +$GPGSV,3,1,11,16,49,115,32,25,39,269,37,23,58,175,28,20,72,335,33*76 +$GPGSV,3,2,11,19,02,028,,04,06,241,23,13,30,223,30,27,19,284,32*7F +$GPGSV,3,3,11,11,06,337,29,01,,,19,03,14,055,23*7D +$GPRMC,222447.000,A,2734.43157,S,15305.48195,E,36.7,159.1,030308,11.2,W,A*0E +$GPVTG,159.1,T,170.3,M,36.7,N,67.9,K,A*20 +$GPGGA,222448.000,2734.44111,S,15305.48610,E,1,08,1.1,54.1,M,39.2,M,,*71 +$GPGLL,2734.44111,S,15305.48610,E,222448.000,A,A*44 +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222448.000,20.4,10.5,8.8,52.5,8.7,9.1,15.2*6C +$GPGSV,3,1,11,16,49,115,27,25,39,269,38,23,58,175,26,20,72,335,31*71 +$GPGSV,3,2,11,19,02,028,,04,06,241,23,13,30,223,37,27,19,284,27*7C +$GPGSV,3,3,11,11,06,337,27,01,,,19,03,14,055,23*73 +$GPRMC,222448.000,A,2734.44111,S,15305.48610,E,36.8,158.7,030308,11.2,W,A*06 +$GPVTG,158.7,T,169.9,M,36.8,N,68.2,K,A*2E +$GPGGA,222449.000,2734.45068,S,15305.49044,E,1,08,1.1,53.6,M,39.2,M,,*78 +$GPGLL,2734.45068,S,15305.49044,E,222449.000,A,A*4D +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222449.000,17.1,8.8,10.2,14.2,8.2,9.3,17.4*6D +$GPGSV,3,1,11,16,49,115,28,25,39,269,37,23,58,175,25,20,72,335,28*7A +$GPGSV,3,2,11,19,02,028,,04,06,241,23,13,30,223,37,27,19,284,32*78 +$GPGSV,3,3,11,11,06,337,27,01,,,19,03,14,055,24*74 +$GPRMC,222449.000,A,2734.45068,S,15305.49044,E,37.2,157.8,030308,11.2,W,A*04 +$GPVTG,157.8,T,169.0,M,37.2,N,68.9,K,A*27 +$GPGGA,222450.000,2734.46041,S,15305.49485,E,1,08,1.1,53.3,M,39.2,M,,*74 +$GPGLL,2734.46041,S,15305.49485,E,222450.000,A,A*44 +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222450.000,17.4,8.9,12.7,10.1,11.5,8.2,16.5*5E +$GPGSV,3,1,11,16,49,115,25,25,39,269,36,23,58,175,30,20,72,336,28*71 +$GPGSV,3,2,11,19,02,028,,04,06,241,21,13,30,223,38,27,19,284,34*73 +$GPGSV,3,3,11,11,06,337,27,01,,,19,03,14,055,22*72 +$GPRMC,222450.000,A,2734.46041,S,15305.49485,E,37.7,157.9,030308,11.2,W,A*09 +$GPVTG,157.9,T,169.1,M,37.7,N,69.8,K,A*22 +$GPGGA,222451.000,2734.47033,S,15305.49924,E,1,08,1.1,53.1,M,39.2,M,,*75 +$GPGLL,2734.47033,S,15305.49924,E,222451.000,A,A*47 +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222451.000,14.1,8.0,10.5,14.3,9.5,7.5,15.0*61 +$GPGSV,3,1,11,16,49,115,27,25,39,269,38,23,58,175,28,20,72,336,25*79 +$GPGSV,3,2,11,19,02,028,,04,06,241,21,13,30,223,38,27,19,284,34*73 +$GPGSV,3,3,11,11,06,337,24,01,,,19,03,14,055,25*76 +$GPRMC,222451.000,A,2734.47033,S,15305.49924,E,38.1,158.1,030308,11.2,W,A*04 +$GPVTG,158.1,T,169.3,M,38.1,N,70.5,K,A*2B +$GPGGA,222452.000,2734.48022,S,15305.50375,E,1,08,1.1,52.5,M,39.2,M,,*7A +$GPGLL,2734.48022,S,15305.50375,E,222452.000,A,A*4D +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222452.000,24.1,13.9,9.7,80.6,12.7,9.0,21.0*54 +$GPGSV,3,1,11,16,49,115,29,25,39,269,38,23,58,175,27,20,72,336,30*7C +$GPGSV,3,2,11,19,02,028,,04,06,241,21,13,30,223,35,27,19,284,34*7E +$GPGSV,3,3,11,11,06,337,22,01,,,19,03,14,055,24*71 +$GPRMC,222452.000,A,2734.48022,S,15305.50375,E,38.3,157.9,030308,11.2,W,A*0B +$GPVTG,157.9,T,169.1,M,38.3,N,70.9,K,A*20 +$GPGGA,222453.000,2734.49019,S,15305.50802,E,1,06,1.7,52.1,M,39.2,M,,*75 +$GPGLL,2734.49019,S,15305.50802,E,222453.000,A,A*4E +$GPGSA,A,3,16,25,23,20,13,27,,,,,,,3.3,1.7,2.8*3A +$GPGST,222453.000,10.4,15.4,9.3,66.3,13.4,9.6,24.6*52 +$GPGSV,3,1,11,16,49,115,31,25,39,269,36,23,58,175,28,20,71,336,25*73 +$GPGSV,3,2,11,19,02,028,,04,06,241,21,13,30,223,33,27,19,284,31*7D +$GPGSV,3,3,11,11,06,337,22,01,,,19,03,14,055,24*71 +$GPRMC,222453.000,A,2734.49019,S,15305.50802,E,38.3,159.1,030308,11.2,W,A*0E +$GPVTG,159.1,T,170.3,M,38.3,N,70.9,K,A*2C +$GPGGA,222454.000,2734.50008,S,15305.51221,E,1,07,1.3,52.1,M,39.2,M,,*75 +$GPGLL,2734.50008,S,15305.51221,E,222454.000,A,A*4B +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222454.000,12.5,11.7,8.3,70.6,10.4,8.0,19.0*5E +$GPGSV,3,1,11,16,49,115,30,25,39,269,36,23,58,175,26,20,71,336,28*71 +$GPGSV,3,2,11,19,02,028,,04,06,241,21,13,30,223,32,27,19,284,30*7D +$GPGSV,3,3,11,11,06,337,24,01,,,18,03,14,055,24*76 +$GPRMC,222454.000,A,2734.50008,S,15305.51221,E,38.1,159.4,030308,11.2,W,A*0C +$GPVTG,159.4,T,170.6,M,38.1,N,70.5,K,A*22 +$GPGGA,222455.000,2734.50992,S,15305.51642,E,1,07,1.3,52.2,M,39.2,M,,*7C +$GPGLL,2734.50992,S,15305.51642,E,222455.000,A,A*41 +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222455.000,11.5,10.8,9.3,83.5,9.9,8.6,23.3*65 +$GPGSV,3,1,11,16,49,115,33,25,39,269,36,23,58,175,32,20,71,336,31*7F +$GPGSV,3,2,11,19,02,028,,04,06,241,21,13,30,223,29,27,19,284,29*7F +$GPGSV,3,3,11,11,06,337,28,01,,,18,03,14,055,24*7A +$GPRMC,222455.000,A,2734.50992,S,15305.51642,E,37.8,159.0,030308,11.2,W,A*04 +$GPVTG,159.0,T,170.2,M,37.8,N,70.0,K,A*21 +$GPGGA,222456.000,2734.51963,S,15305.52059,E,1,07,1.3,52.5,M,39.2,M,,*78 +$GPGLL,2734.51963,S,15305.52059,E,222456.000,A,A*42 +$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D +$GPGST,222456.000,11.3,9.0,13.1,11.0,8.4,11.9,20.9*55 +$GPGSV,3,1,11,16,49,115,31,25,39,269,37,23,58,175,27,20,71,336,33*7A +$GPGSV,3,2,11,19,02,028,,04,06,241,19,13,30,223,29,27,19,284,32*7E +$GPGSV,3,3,11,11,06,337,30,01,,,18,03,14,055,24*73 +$GPRMC,222456.000,A,2734.51963,S,15305.52059,E,37.3,158.8,030308,11.2,W,A*05 +$GPVTG,158.8,T,170.0,M,37.3,N,69.1,K,A*28 +$GPGGA,222457.000,2734.52908,S,15305.52467,E,1,06,1.3,53.2,M,39.2,M,,*79 +$GPGLL,2734.52908,S,15305.52467,E,222457.000,A,A*44 +$GPGSA,A,3,16,25,20,13,27,11,,,,,,,2.3,1.3,1.9*3C +$GPGST,222457.000,20.4,7.8,12.0,8.1,7.3,10.9,17.9*63 +$GPGSV,3,1,11,16,49,115,37,25,39,269,37,23,58,175,24,20,71,336,35*79 +$GPGSV,3,2,11,19,02,028,,04,06,241,19,13,30,223,29,27,19,284,32*7E +$GPGSV,3,3,11,11,06,337,28,01,,,18,03,14,055,23*7D +$GPRMC,222457.000,A,2734.52908,S,15305.52467,E,36.2,158.7,030308,11.2,W,A*0C +$GPVTG,158.7,T,169.9,M,36.2,N,67.1,K,A*28 +$GPGGA,222458.000,2734.53845,S,15305.52866,E,1,06,1.6,54.2,M,39.2,M,,*70 +$GPGLL,2734.53845,S,15305.52866,E,222458.000,A,A*4F +$GPGSA,A,3,16,25,23,20,27,11,,,,,,,2.6,1.6,2.1*34 +$GPGST,222458.000,16.7,7.3,13.9,11.0,7.0,12.5,17.9*5D +$GPGSV,3,1,11,16,49,115,36,25,39,269,37,23,58,175,24,20,71,336,35*78 +$GPGSV,3,2,11,19,02,028,19,04,06,241,19,13,30,223,26,27,19,284,31*7A +$GPGSV,3,3,11,11,06,337,23,01,,,18,03,14,055,23*76 +$GPRMC,222458.000,A,2734.53845,S,15305.52866,E,35.9,159.1,030308,11.2,W,A*08 +$GPVTG,159.1,T,170.3,M,35.9,N,66.5,K,A*20 +$GPGGA,222459.000,2734.54772,S,15305.53309,E,1,08,1.1,55.6,M,39.2,M,,*72 +$GPGLL,2734.54772,S,15305.53309,E,222459.000,A,A*41 +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222459.000,17.5,6.5,9.3,15.5,6.1,8.3,15.2*5C +$GPGSV,3,1,11,16,49,115,38,25,39,268,36,23,58,175,35,20,71,336,35*76 +$GPGSV,3,2,11,19,02,028,19,04,06,241,19,13,30,223,33,27,19,284,34*7B +$GPGSV,3,3,11,11,06,337,29,01,,,18,03,14,055,22*7D +$GPRMC,222459.000,A,2734.54772,S,15305.53309,E,35.9,156.8,030308,11.2,W,A*00 +$GPVTG,156.8,T,168.0,M,35.9,N,66.4,K,A*2D +$GPGGA,222500.000,2734.55655,S,15305.53845,E,1,08,1.1,56.1,M,39.2,M,,*7D +$GPGLL,2734.55655,S,15305.53845,E,222500.000,A,A*4A +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222500.000,14.5,9.8,7.9,83.3,7.3,9.0,14.3*5C +$GPGSV,3,1,11,16,49,115,36,25,39,268,31,23,58,175,39,20,71,336,33*75 +$GPGSV,3,2,11,19,02,028,21,04,06,241,19,13,30,223,30,27,19,284,29*7F +$GPGSV,3,3,11,11,06,337,25,01,,,18,03,14,055,28*7B +$GPRMC,222500.000,A,2734.55655,S,15305.53845,E,35.9,151.6,030308,11.2,W,A*02 +$GPVTG,151.6,T,162.8,M,35.9,N,66.5,K,A*27 +$GPGGA,222501.000,2734.56495,S,15305.54489,E,1,08,1.1,57.0,M,39.2,M,,*7A +$GPGLL,2734.56495,S,15305.54489,E,222501.000,A,A*4D +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222501.000,14.3,8.0,10.9,27.0,8.0,9.5,15.6*64 +$GPGSV,3,1,11,16,49,115,41,25,39,268,31,23,58,175,36,20,71,336,31*78 +$GPGSV,3,2,11,19,02,028,21,04,06,241,19,13,30,223,27,27,19,284,29*79 +$GPGSV,3,3,11,11,06,337,22,01,,,18,03,14,055,31*74 +$GPRMC,222501.000,A,2734.56495,S,15305.54489,E,36.5,145.7,030308,11.2,W,A*0E +$GPVTG,145.7,T,156.9,M,36.5,N,67.5,K,A*2B +$GPGGA,222502.000,2734.57337,S,15305.55181,E,1,06,1.5,57.9,M,39.2,M,,*78 +$GPGLL,2734.57337,S,15305.55181,E,222502.000,A,A*4C +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222502.000,14.5,7.0,11.9,20.7,7.1,10.5,15.0*5F +$GPGSV,3,1,11,16,49,115,43,25,39,268,35,23,58,175,37,20,71,336,34*7A +$GPGSV,3,2,11,19,02,028,21,04,06,241,19,13,30,223,23,27,19,284,33*76 +$GPGSV,3,3,11,11,06,337,22,01,,,18,03,14,055,34*71 +$GPRMC,222502.000,A,2734.57337,S,15305.55181,E,37.4,143.8,030308,11.2,W,A*06 +$GPVTG,143.8,T,155.0,M,37.4,N,69.3,K,A*20 +$GPGGA,222503.000,2734.58184,S,15305.55887,E,1,08,1.1,58.5,M,39.2,M,,*7A +$GPGLL,2734.58184,S,15305.55887,E,222503.000,A,A*47 +$GPGSA,A,3,16,25,23,20,13,27,11,03,,,,,2.0,1.1,1.6*30 +$GPGST,222503.000,13.4,6.4,14.1,0.3,5.9,12.9,21.5*60 +$GPGSV,3,1,11,16,49,115,43,25,39,268,35,23,58,175,38,20,71,336,35*74 +$GPGSV,3,2,11,19,02,028,19,04,06,241,19,13,30,223,23,27,19,284,32*7C +$GPGSV,3,3,11,11,06,337,26,01,,,17,03,14,055,34*7A +$GPRMC,222503.000,A,2734.58184,S,15305.55887,E,37.8,143.4,030308,11.2,W,A*0D +$GPVTG,143.4,T,154.6,M,37.8,N,70.0,K,A*2C +$GPGGA,222504.000,2734.59032,S,15305.56580,E,1,07,1.2,58.9,M,39.2,M,,*79 +$GPGLL,2734.59032,S,15305.56580,E,222504.000,A,A*44 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222504.000,24.6,6.2,13.3,3.6,5.7,12.2,20.2*67 +$GPGSV,3,1,11,16,49,115,43,25,39,268,35,23,58,175,39,20,71,336,35*75 +$GPGSV,3,2,11,19,02,028,19,04,06,241,19,13,30,223,22,27,19,284,31*7E +$GPGSV,3,3,11,11,06,337,25,01,,,17,03,14,055,30*7D +$GPRMC,222504.000,A,2734.59032,S,15305.56580,E,37.6,143.6,030308,11.2,W,A*02 +$GPVTG,143.6,T,154.8,M,37.6,N,69.7,K,A*21 +$GPGGA,222505.000,2734.59874,S,15305.57271,E,1,06,1.5,59.4,M,39.2,M,,*70 +$GPGLL,2734.59874,S,15305.57271,E,222505.000,A,A*47 +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222505.000,17.4,5.5,11.8,3.4,5.0,10.8,17.3*61 +$GPGSV,3,1,11,16,49,115,44,25,39,268,35,23,58,175,39,20,71,336,36*71 +$GPGSV,3,2,11,19,02,028,21,04,06,241,19,13,30,223,24,27,19,284,31*73 +$GPGSV,3,3,11,11,06,337,,01,,,17,03,14,055,29*72 +$GPRMC,222505.000,A,2734.59874,S,15305.57271,E,37.3,143.7,030308,11.2,W,A*05 +$GPVTG,143.7,T,154.9,M,37.3,N,69.1,K,A*22 +$GPGGA,222506.000,2734.60703,S,15305.57943,E,1,07,1.2,60.1,M,39.2,M,,*75 +$GPGLL,2734.60703,S,15305.57943,E,222506.000,A,A*4B +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222506.000,16.1,6.2,11.7,15.3,6.1,10.4,17.4*54 +$GPGSV,3,1,11,16,49,115,43,25,39,268,34,23,58,175,37,20,71,336,36*79 +$GPGSV,3,2,11,19,02,028,21,04,06,241,,13,30,223,24,27,19,284,31*7B +$GPGSV,3,3,11,11,06,337,,01,,,17,03,14,055,28*73 +$GPRMC,222506.000,A,2734.60703,S,15305.57943,E,36.5,143.9,030308,11.2,W,A*00 +$GPVTG,143.9,T,155.1,M,36.5,N,67.6,K,A*2B +$GPGGA,222507.000,2734.61507,S,15305.58593,E,1,07,1.2,60.9,M,39.2,M,,*75 +$GPGLL,2734.61507,S,15305.58593,E,222507.000,A,A*43 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222507.000,14.0,6.8,11.8,10.9,6.4,10.7,18.5*54 +$GPGSV,3,1,11,16,49,115,43,25,39,268,34,23,58,175,37,20,71,336,34*7B +$GPGSV,3,2,11,19,02,028,21,04,06,241,,13,30,223,29,27,19,284,34*73 +$GPGSV,3,3,11,11,06,337,,01,,,17,03,14,055,29*72 +$GPRMC,222507.000,A,2734.61507,S,15305.58593,E,35.4,143.9,030308,11.2,W,A*0A +$GPVTG,143.9,T,155.1,M,35.4,N,65.5,K,A*28 +$GPGGA,222508.000,2734.62275,S,15305.59221,E,1,06,1.7,61.8,M,39.2,M,,*70 +$GPGLL,2734.62275,S,15305.59221,E,222508.000,A,A*42 +$GPGSA,A,3,16,25,23,20,13,27,,,,,,,3.3,1.7,2.8*3A +$GPGST,222508.000,12.5,9.3,16.3,19.5,9.4,14.4,27.5*51 +$GPGSV,3,1,11,16,49,115,43,25,39,268,33,23,58,175,38,20,71,336,31*76 +$GPGSV,3,2,11,19,02,028,21,04,06,241,,13,30,223,30,27,19,284,35*7A +$GPGSV,3,3,11,11,06,337,,01,,,17,03,14,055,28*73 +$GPRMC,222508.000,A,2734.62275,S,15305.59221,E,33.9,143.9,030308,11.2,W,A*00 +$GPVTG,143.9,T,155.1,M,33.9,N,62.9,K,A*28 +$GPGGA,222509.000,2734.63006,S,15305.59817,E,1,06,1.7,62.7,M,39.2,M,,*75 +$GPGLL,2734.63006,S,15305.59817,E,222509.000,A,A*4B +$GPGSA,A,3,16,25,23,20,13,27,,,,,,,3.3,1.7,2.8*3A +$GPGST,222509.000,10.4,8.1,14.2,21.9,8.4,12.3,23.7*52 +$GPGSV,3,1,11,16,49,115,44,25,39,268,32,23,58,175,37,20,71,336,29*76 +$GPGSV,3,2,11,19,02,028,21,04,06,241,,13,30,223,28,27,19,284,35*73 +$GPGSV,3,3,11,11,06,337,,01,,,17,03,14,055,30*7A +$GPRMC,222509.000,A,2734.63006,S,15305.59817,E,32.2,143.9,030308,11.2,W,A*03 +$GPVTG,143.9,T,155.1,M,32.2,N,59.7,K,A*24 +$GPGGA,222510.000,2734.63706,S,15305.60376,E,1,06,1.7,63.5,M,39.2,M,,*7F +$GPGLL,2734.63706,S,15305.60376,E,222510.000,A,A*42 +$GPGSA,A,3,16,25,23,20,13,27,,,,,,,3.3,1.7,2.8*3A +$GPGST,222510.000,12.4,8.3,12.9,28.0,8.7,11.0,21.6*57 +$GPGSV,3,1,11,16,48,115,43,25,39,268,32,23,58,175,37,20,71,336,29*70 +$GPGSV,3,2,11,19,02,028,20,04,06,241,,13,30,223,31,27,19,284,35*7A +$GPGSV,3,3,11,11,06,337,,01,,,17,03,14,055,25*7E +$GPRMC,222510.000,A,2734.63706,S,15305.60376,E,30.6,144.3,030308,11.2,W,A*01 +$GPVTG,144.3,T,155.5,M,30.6,N,56.7,K,A*24 +$GPGGA,222511.000,2734.64376,S,15305.60904,E,1,07,1.2,64.4,M,39.2,M,,*77 +$GPGLL,2734.64376,S,15305.60904,E,222511.000,A,A*48 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222511.000,14.6,5.7,10.5,2.7,5.2,9.6,15.0*5C +$GPGSV,3,1,11,16,48,115,44,25,39,268,32,23,58,175,37,20,71,336,28*76 +$GPGSV,3,2,11,19,02,028,20,04,06,241,23,13,30,223,29,27,19,284,36*71 +$GPGSV,3,3,11,11,06,337,,01,,,17,03,14,055,29*72 +$GPRMC,222511.000,A,2734.64376,S,15305.60904,E,29.1,144.2,030308,11.2,W,A*05 +$GPVTG,144.2,T,155.4,M,29.1,N,53.9,K,A*20 +$GPGGA,222512.000,2734.64992,S,15305.61405,E,1,07,1.2,65.4,M,39.2,M,,*78 +$GPGLL,2734.64992,S,15305.61405,E,222512.000,A,A*46 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222512.000,13.4,17.0,5.7,85.6,5.3,15.5,23.6*5A +$GPGSV,3,1,11,16,48,115,45,25,39,268,33,23,58,175,38,20,71,336,28*79 +$GPGSV,3,2,11,19,02,028,20,04,06,241,23,13,30,223,26,27,19,284,33*7B +$GPGSV,3,3,11,11,06,337,24,01,,,17,03,14,055,27*7A +$GPRMC,222512.000,A,2734.64992,S,15305.61405,E,27.2,143.6,030308,11.2,W,A*05 +$GPVTG,143.6,T,154.8,M,27.2,N,50.5,K,A*2C +$GPGGA,222513.000,2734.65572,S,15305.61884,E,1,07,1.2,66.2,M,39.2,M,,*7A +$GPGLL,2734.65572,S,15305.61884,E,222513.000,A,A*41 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222513.000,12.3,7.0,14.8,2.4,6.5,13.5,21.4*6D +$GPGSV,3,1,10,16,48,115,44,25,39,268,35,23,58,175,38,20,71,336,28*7F +$GPGSV,3,2,10,19,02,028,20,04,06,241,23,13,30,223,23,27,19,284,33*7F +$GPGSV,3,3,10,11,06,337,24,03,14,055,28*73 +$GPRMC,222513.000,A,2734.65572,S,15305.61884,E,25.8,143.6,030308,11.2,W,A*0A +$GPVTG,143.6,T,154.8,M,25.8,N,47.9,K,A*2E +$GPGGA,222514.000,2734.66155,S,15305.62364,E,1,06,1.5,67.0,M,39.2,M,,*7C +$GPGLL,2734.66155,S,15305.62364,E,222514.000,A,A*42 +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222514.000,25.5,6.1,14.4,3.1,5.6,13.2,19.2*6A +$GPGSV,3,1,10,16,48,115,44,25,39,268,33,23,58,175,38,20,71,336,26*77 +$GPGSV,3,2,10,19,02,028,18,04,06,241,23,13,30,223,23,27,19,284,34*73 +$GPGSV,3,3,10,11,06,337,28,03,14,055,29*7E +$GPRMC,222514.000,A,2734.66155,S,15305.62364,E,25.9,143.6,030308,11.2,W,A*08 +$GPVTG,143.6,T,154.8,M,25.9,N,48.0,K,A*29 +$GPGGA,222515.000,2734.66761,S,15305.62860,E,1,06,1.5,67.5,M,39.2,M,,*76 +$GPGLL,2734.66761,S,15305.62860,E,222515.000,A,A*4D +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222515.000,20.1,5.5,13.0,3.0,5.1,11.8,17.4*68 +$GPGSV,3,1,10,16,48,115,44,25,39,268,32,23,58,175,38,20,71,336,26*76 +$GPGSV,3,2,10,19,02,028,18,04,06,241,23,13,30,223,24,27,19,284,34*74 +$GPGSV,3,3,10,11,06,337,28,03,14,055,24*73 +$GPRMC,222515.000,A,2734.66761,S,15305.62860,E,26.9,143.7,030308,11.2,W,A*05 +$GPVTG,143.7,T,154.9,M,26.9,N,49.8,K,A*23 +$GPGGA,222516.000,2734.67384,S,15305.63376,E,1,06,1.5,68.2,M,39.2,M,,*7E +$GPGLL,2734.67384,S,15305.63376,E,222516.000,A,A*4D +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222516.000,16.4,5.8,11.5,4.5,5.3,10.5,17.3*6A +$GPGSV,3,1,10,16,48,115,44,25,39,268,32,23,58,175,38,20,71,336,30*71 +$GPGSV,3,2,10,19,02,028,18,04,06,241,23,13,30,223,24,27,19,284,33*73 +$GPGSV,3,3,10,11,06,337,28,03,14,055,28*7F +$GPRMC,222516.000,A,2734.67384,S,15305.63376,E,27.7,143.8,030308,11.2,W,A*05 +$GPVTG,143.8,T,155.0,M,27.7,N,51.4,K,A*2E +$GPGGA,222517.000,2734.68035,S,15305.63901,E,1,06,1.5,68.8,M,39.2,M,,*79 +$GPGLL,2734.68035,S,15305.63901,E,222517.000,A,A*40 +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222517.000,19.1,6.2,12.1,7.2,5.8,11.0,15.3*66 +$GPGSV,3,1,10,16,48,115,44,25,39,268,34,23,58,175,38,20,71,336,32*75 +$GPGSV,3,2,10,19,02,028,20,04,06,241,23,13,30,223,24,27,19,284,34*7F +$GPGSV,3,3,10,11,06,337,24,03,14,055,29*72 +$GPRMC,222517.000,A,2734.68035,S,15305.63901,E,28.6,144.1,030308,11.2,W,A*08 +$GPVTG,144.1,T,155.3,M,28.6,N,53.0,K,A*2B +$GPGGA,222518.000,2734.68718,S,15305.64446,E,1,07,1.4,69.1,M,39.2,M,,*7F +$GPGLL,2734.68718,S,15305.64446,E,222518.000,A,A*4E +$GPGSA,A,3,16,25,23,20,27,11,03,,,,,,2.4,1.4,1.9*3C +$GPGST,222518.000,13.8,5.5,10.6,5.8,5.1,9.6,13.4*54 +$GPGSV,3,1,10,16,48,115,43,25,39,268,33,23,58,175,37,20,71,336,35*7D +$GPGSV,3,2,10,19,02,028,20,04,06,241,18,13,30,223,24,27,19,284,33*70 +$GPGSV,3,3,10,11,06,337,22,03,14,055,33*7F +$GPRMC,222518.000,A,2734.68718,S,15305.64446,E,29.9,144.4,030308,11.2,W,A*0D +$GPVTG,144.4,T,155.6,M,29.9,N,55.3,K,A*20 +$GPGGA,222519.000,2734.69424,S,15305.65010,E,1,07,1.4,69.5,M,39.2,M,,*71 +$GPGLL,2734.69424,S,15305.65010,E,222519.000,A,A*44 +$GPGSA,A,3,16,25,23,20,27,11,03,,,,,,2.4,1.4,1.9*3C +$GPGST,222519.000,14.0,13.4,5.0,89.4,4.6,12.3,18.8*58 +$GPGSV,3,1,10,16,48,115,44,25,39,268,34,23,58,175,37,20,71,336,37*7F +$GPGSV,3,2,10,19,02,028,20,04,06,241,18,13,30,223,23,27,19,284,31*75 +$GPGSV,3,3,10,11,06,337,26,03,14,055,35*7D +$GPRMC,222519.000,A,2734.69424,S,15305.65010,E,31.0,144.4,030308,11.2,W,A*07 +$GPVTG,144.4,T,155.6,M,31.0,N,57.5,K,A*24 +$GPGGA,222520.000,2734.70163,S,15305.65604,E,1,07,1.4,69.6,M,39.2,M,,*75 +$GPGLL,2734.70163,S,15305.65604,E,222520.000,A,A*43 +$GPGSA,A,3,16,25,23,20,27,11,03,,,,,,2.4,1.4,1.9*3C +$GPGST,222520.000,9.8,11.6,4.7,89.0,4.3,10.6,15.9*6A +$GPGSV,3,1,10,16,48,115,44,25,39,268,35,23,58,175,39,20,71,336,36*71 +$GPGSV,3,2,10,19,02,028,20,04,06,241,19,13,30,223,23,27,19,284,31*74 +$GPGSV,3,3,10,11,06,337,31,03,14,055,37*79 +$GPRMC,222520.000,A,2734.70163,S,15305.65604,E,32.5,144.1,030308,11.2,W,A*03 +$GPVTG,144.1,T,155.3,M,32.5,N,60.2,K,A*21 +$GPGGA,222521.000,2734.70923,S,15305.66218,E,1,07,1.4,69.5,M,39.2,M,,*71 +$GPGLL,2734.70923,S,15305.66218,E,222521.000,A,A*44 +$GPGSA,A,3,16,25,23,20,27,11,03,,,,,,2.4,1.4,1.9*3C +$GPGST,222521.000,11.1,6.2,10.8,9.6,5.8,9.8,16.8*53 +$GPGSV,3,1,10,16,48,115,44,25,39,268,36,23,58,175,40,20,71,336,38*72 +$GPGSV,3,2,10,19,02,028,20,04,06,241,19,13,30,223,23,27,19,284,26*72 +$GPGSV,3,3,10,11,06,338,31,03,14,055,37*76 +$GPRMC,222521.000,A,2734.70923,S,15305.66218,E,33.5,144.0,030308,11.2,W,A*04 +$GPVTG,144.0,T,155.3,M,33.5,N,62.0,K,A*21 +$GPGGA,222522.000,2734.71700,S,15305.66845,E,1,06,1.5,69.1,M,39.2,M,,*7A +$GPGLL,2734.71700,S,15305.66845,E,222522.000,A,A*4B +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222522.000,15.0,5.7,9.9,5.5,5.2,9.0,15.4*68 +$GPGSV,3,1,10,16,48,115,43,25,39,268,36,23,58,175,40,20,71,336,37*7A +$GPGSV,3,2,10,19,02,028,20,04,06,241,24,13,30,223,23,27,19,284,26*7C +$GPGSV,3,3,10,11,06,338,25,03,14,055,37*73 +$GPRMC,222522.000,A,2734.71700,S,15305.66845,E,34.2,144.1,030308,11.2,W,A*0A +$GPVTG,144.1,T,155.3,M,34.2,N,63.4,K,A*25 +$GPGGA,222523.000,2734.72487,S,15305.67483,E,1,07,1.4,68.6,M,39.2,M,,*75 +$GPGLL,2734.72487,S,15305.67483,E,222523.000,A,A*42 +$GPGSA,A,3,16,25,23,20,27,11,03,,,,,,2.4,1.4,1.9*3C +$GPGST,222523.000,13.8,5.2,10.1,3.9,4.8,9.2,13.8*5B +$GPGSV,3,1,10,16,48,115,44,25,39,268,37,23,58,175,41,20,71,336,35*7F +$GPGSV,3,2,10,19,02,028,20,04,06,241,24,13,30,223,23,27,19,284,26*7C +$GPGSV,3,3,10,11,06,338,23,03,14,055,31*73 +$GPRMC,222523.000,A,2734.72487,S,15305.67483,E,34.7,144.2,030308,11.2,W,A*05 +$GPVTG,144.2,T,155.4,M,34.7,N,64.3,K,A*24 +$GPGGA,222524.000,2734.73280,S,15305.68126,E,1,07,1.4,68.1,M,39.2,M,,*70 +$GPGLL,2734.73280,S,15305.68126,E,222524.000,A,A*40 +$GPGSA,A,3,16,25,23,20,27,11,03,,,,,,2.4,1.4,1.9*3C +$GPGST,222524.000,10.5,4.9,9.4,3.5,4.5,8.6,12.8*60 +$GPGSV,3,1,10,16,48,115,44,25,39,268,37,23,58,175,41,20,71,336,35*7F +$GPGSV,3,2,10,19,02,028,20,04,06,241,22,13,30,223,23,27,19,284,26*7A +$GPGSV,3,3,10,11,06,338,25,03,14,055,29*7C +$GPRMC,222524.000,A,2734.73280,S,15305.68126,E,35.0,144.2,030308,11.2,W,A*01 +$GPVTG,144.2,T,155.4,M,35.0,N,64.9,K,A*28 +$GPGGA,222525.000,2734.74083,S,15305.68778,E,1,07,1.4,67.7,M,39.2,M,,*73 +$GPGLL,2734.74083,S,15305.68778,E,222525.000,A,A*4A +$GPGSA,A,3,16,25,23,20,27,11,03,,,,,,2.4,1.4,1.9*3C +$GPGST,222525.000,10.3,5.2,13.4,3.6,4.8,12.3,20.4*6B +$GPGSV,3,1,10,16,48,115,43,25,39,268,38,23,58,175,40,20,71,336,36*75 +$GPGSV,3,2,10,19,02,028,20,04,06,241,22,13,30,223,23,27,19,284,23*7F +$GPGSV,3,3,10,11,06,338,27,03,14,055,36*70 +$GPRMC,222525.000,A,2734.74083,S,15305.68778,E,35.6,144.2,030308,11.2,W,A*0D +$GPVTG,144.2,T,155.4,M,35.6,N,65.9,K,A*2F +$GPGGA,222526.000,2734.74894,S,15305.69428,E,1,06,1.5,67.2,M,39.2,M,,*7C +$GPGLL,2734.74894,S,15305.69428,E,222526.000,A,A*40 +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222526.000,8.0,5.7,12.0,2.6,5.2,10.9,17.4*54 +$GPGSV,3,1,10,16,48,115,43,25,39,268,37,23,58,175,40,20,71,336,35*79 +$GPGSV,3,2,10,19,02,028,20,04,06,241,22,13,30,223,23,27,19,284,24*78 +$GPGSV,3,3,10,11,06,338,27,03,14,055,39*7F +$GPRMC,222526.000,A,2734.74894,S,15305.69428,E,35.8,144.5,030308,11.2,W,A*0E +$GPVTG,144.5,T,155.7,M,35.8,N,66.3,K,A*2C +$GPGGA,222527.000,2734.75707,S,15305.70075,E,1,05,1.7,66.8,M,39.2,M,,*77 +$GPGLL,2734.75707,S,15305.70075,E,222527.000,A,A*41 +$GPGSA,A,3,16,25,23,20,03,,,,,,,,2.9,1.7,2.4*39 +$GPGST,222527.000,13.9,6.3,10.9,6.3,5.9,10.0,18.2*60 +$GPGSV,3,1,10,16,48,115,44,25,39,268,38,23,58,175,40,20,71,336,33*77 +$GPGSV,3,2,10,19,02,028,,04,06,241,25,13,30,223,23,27,19,284,26*7F +$GPGSV,3,3,10,11,06,338,,03,14,055,36*75 +$GPRMC,222527.000,A,2734.75707,S,15305.70075,E,35.8,144.6,030308,11.2,W,A*0C +$GPVTG,144.6,T,155.8,M,35.8,N,66.2,K,A*21 +$GPGGA,222528.000,2734.76518,S,15305.70724,E,1,06,1.5,66.1,M,39.2,M,,*7C +$GPGLL,2734.76518,S,15305.70724,E,222528.000,A,A*42 +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222528.000,11.3,5.6,10.1,4.5,5.2,9.2,16.1*51 +$GPGSV,3,1,10,16,48,115,43,25,39,268,39,23,58,175,39,20,71,336,28*75 +$GPGSV,3,2,10,19,02,028,,04,06,241,25,13,30,223,23,27,19,284,26*7F +$GPGSV,3,3,10,11,06,338,,03,14,055,36*75 +$GPRMC,222528.000,A,2734.76518,S,15305.70724,E,35.7,144.4,030308,11.2,W,A*02 +$GPVTG,144.4,T,155.6,M,35.7,N,66.2,K,A*22 +$GPGGA,222529.000,2734.77313,S,15305.71385,E,1,06,1.5,66.1,M,39.2,M,,*7F +$GPGLL,2734.77313,S,15305.71385,E,222529.000,A,A*41 +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222529.000,10.9,5.6,12.5,5.4,5.2,11.4,20.9*6F +$GPGSV,3,1,10,16,48,115,41,25,39,268,40,23,58,175,36,20,71,336,28*76 +$GPGSV,3,2,10,19,02,028,,04,06,241,25,13,30,223,23,27,19,284,24*7D +$GPGSV,3,3,10,11,06,338,27,03,14,055,30*76 +$GPRMC,222529.000,A,2734.77313,S,15305.71385,E,35.6,143.5,030308,11.2,W,A*06 +$GPVTG,143.5,T,154.7,M,35.6,N,65.8,K,A*2C +$GPGGA,222530.000,2734.78106,S,15305.72042,E,1,06,1.5,66.0,M,39.2,M,,*74 +$GPGLL,2734.78106,S,15305.72042,E,222530.000,A,A*4B +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222530.000,9.4,5.4,18.9,2.4,4.9,17.3,30.6*54 +$GPGSV,3,1,10,16,48,115,40,25,39,268,40,23,58,175,36,20,71,336,28*77 +$GPGSV,3,2,10,19,02,028,,04,06,241,25,13,30,223,23,27,19,284,26*7F +$GPGSV,3,3,10,11,06,338,27,03,14,055,29*7E +$GPRMC,222530.000,A,2734.78106,S,15305.72042,E,35.5,143.7,030308,11.2,W,A*0D +$GPVTG,143.7,T,155.0,M,35.5,N,65.8,K,A*2B +$GPGGA,222531.000,2734.78918,S,15305.72691,E,1,05,4.4,66.0,M,39.2,M,,*7D +$GPGLL,2734.78918,S,15305.72691,E,222531.000,A,A*45 +$GPGSA,A,3,16,25,23,27,11,,,,,,,,9.3,4.4,8.2*36 +$GPGST,222531.000,9.1,8.5,53.9,3.2,8.2,49.2,81.3*56 +$GPGSV,3,1,10,16,48,115,40,25,39,268,39,23,58,175,37,20,71,336,28*78 +$GPGSV,3,2,10,19,02,028,,04,06,241,25,13,31,223,23,27,19,284,25*7D +$GPGSV,3,3,10,11,06,338,24,03,14,055,22*76 +$GPRMC,222531.000,A,2734.78918,S,15305.72691,E,35.9,144.5,030308,11.2,W,A*0A +$GPVTG,144.5,T,155.7,M,35.9,N,66.4,K,A*2A +$GPGGA,222532.000,2734.79737,S,15305.73347,E,1,06,1.5,66.0,M,39.2,M,,*74 +$GPGLL,2734.79737,S,15305.73347,E,222532.000,A,A*4B +$GPGSA,A,3,16,25,23,20,27,03,,,,,,,2.5,1.5,2.0*36 +$GPGST,222532.000,11.0,6.8,38.7,1.2,6.3,35.3,58.4*69 +$GPGSV,3,1,10,16,48,115,40,25,39,268,39,23,58,175,36,20,71,336,28*79 +$GPGSV,3,2,10,19,02,028,,04,06,241,25,13,31,223,24,27,19,284,23*7C +$GPGSV,3,3,10,11,06,338,24,03,14,055,30*75 +$GPRMC,222532.000,A,2734.79737,S,15305.73347,E,36.1,144.5,030308,11.2,W,A*0F +$GPVTG,144.5,T,155.7,M,36.1,N,66.9,K,A*2C +$GPGGA,222533.000,2734.80571,S,15305.74004,E,1,06,4.1,66.1,M,39.2,M,,*70 +$GPGLL,2734.80571,S,15305.74004,E,222533.000,A,A*4F +$GPGSA,A,3,16,25,23,27,11,03,,,,,,,8.3,4.1,7.3*3F +$GPGST,222533.000,9.4,6.1,45.5,0.4,5.6,41.6,69.5*50 +$GPGSV,3,1,10,16,48,115,40,25,39,268,39,23,58,175,37,20,71,336,28*78 +$GPGSV,3,2,10,19,02,028,,04,06,241,23,13,31,223,24,27,19,284,25*7C +$GPGSV,3,3,10,11,06,338,22,03,14,055,25*77 +$GPRMC,222533.000,A,2734.80571,S,15305.74004,E,36.6,145.0,030308,11.2,W,A*08 +$GPVTG,145.0,T,156.2,M,36.6,N,67.7,K,A*26 +$GPGGA,222534.000,2734.81441,S,15305.74656,E,1,06,1.8,65.2,M,39.2,M,,*79 +$GPGLL,2734.81441,S,15305.74656,E,222534.000,A,A*4A +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.5,1.8,3.1*3A +$GPGST,222534.000,20.2,5.8,45.7,1.7,5.4,41.7,71.3*6C +$GPGSV,3,1,10,16,48,115,40,25,39,268,38,23,58,175,37,20,71,336,28*79 +$GPGSV,3,2,10,19,02,028,,04,06,241,23,13,31,223,25,27,19,284,25*7D +$GPGSV,3,3,10,11,06,338,22,03,14,055,31*72 +$GPRMC,222534.000,A,2734.81441,S,15305.74656,E,37.6,146.2,030308,11.2,W,A*0D +$GPVTG,146.2,T,157.5,M,37.6,N,69.7,K,A*2E +$GPGGA,222535.000,2734.82349,S,15305.75307,E,1,05,1.9,63.5,M,39.2,M,,*77 +$GPGLL,2734.82349,S,15305.75307,E,222535.000,A,A*47 +$GPGSA,A,3,16,25,23,13,03,,,,,,,,3.6,1.9,3.1*3D +$GPGST,222535.000,27.6,7.0,40.6,3.1,6.7,37.1,68.4*6C +$GPGSV,3,1,10,16,48,115,40,25,39,268,36,23,58,175,37,20,71,336,28*77 +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,31,223,25,27,19,284,23*78 +$GPGSV,3,3,10,11,06,338,22,03,14,055,26*74 +$GPRMC,222535.000,A,2734.82349,S,15305.75307,E,38.7,147.3,030308,11.2,W,A*0E +$GPVTG,147.3,T,158.6,M,38.7,N,71.7,K,A*25 +$GPGGA,222536.000,2734.83215,S,15305.75969,E,1,05,1.7,63.5,M,39.2,M,,*71 +$GPGLL,2734.83215,S,15305.75969,E,222536.000,A,A*4F +$GPGSA,A,3,16,25,23,20,03,,,,,,,,2.9,1.7,2.4*39 +$GPGST,222536.000,7.9,6.3,97.2,3.9,8.3,88.7,161.0*62 +$GPGSV,3,1,10,16,48,115,40,25,39,268,37,23,58,175,36,20,71,336,28*77 +$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,31,223,25,27,19,284,23*78 +$GPGSV,3,3,10,11,06,338,22,03,14,055,26*74 +$GPRMC,222536.000,A,2734.83215,S,15305.75969,E,37.6,145.6,030308,11.2,W,A*0F +$GPVTG,145.6,T,156.8,M,37.6,N,69.7,K,A*25 +$GPGGA,222537.000,2734.84076,S,15305.76655,E,1,05,1.7,63.5,M,39.2,M,,*73 +$GPGLL,2734.84076,S,15305.76655,E,222537.000,A,A*4D +$GPGSA,A,3,16,25,23,20,03,,,,,,,,2.9,1.7,2.4*39 +$GPGST,222537.000,16.0,7.8,110.8,2.1,8.0,101.2,209.1*57 +$GPGSV,3,1,10,16,48,115,39,25,39,268,36,23,58,175,34,20,71,336,28*7A +$GPGSV,3,2,10,19,02,028,,04,06,241,22,13,31,223,25,27,19,284,23*7A +$GPGSV,3,3,10,11,06,338,22,03,14,055,25*77 +$GPRMC,222537.000,A,2734.84076,S,15305.76655,E,37.9,144.6,030308,11.2,W,A*03 +$GPVTG,144.6,T,155.8,M,37.9,N,70.3,K,A*24 +$GPGGA,222538.000,2734.84945,S,15305.77356,E,1,05,1.9,63.5,M,39.2,M,,*7C +$GPGLL,2734.84945,S,15305.77356,E,222538.000,A,A*4C +$GPGSA,A,3,16,25,23,13,03,,,,,,,,3.6,1.9,3.1*3D +$GPGST,222538.000,13.1,8.0,61.7,1.6,7.5,56.4,113.0*51 +$GPGSV,3,1,10,16,48,115,40,25,39,268,37,23,58,175,32,20,71,336,*79 +$GPGSV,3,2,10,19,02,028,,04,06,241,22,13,31,223,25,27,19,284,23*7A +$GPGSV,3,3,10,11,06,338,22,03,14,055,28*7A +$GPRMC,222538.000,A,2734.84945,S,15305.77356,E,38.4,144.2,030308,11.2,W,A*04 +$GPVTG,144.2,T,155.4,M,38.4,N,71.1,K,A*2D +$GPGGA,222539.000,2734.85792,S,15305.78022,E,1,05,1.9,63.5,M,39.2,M,,*77 +$GPGLL,2734.85792,S,15305.78022,E,222539.000,A,A*47 +$GPGSA,A,3,16,25,23,13,03,,,,,,,,3.6,1.9,3.1*3D +$GPGST,222539.000,6.4,7.5,72.7,1.5,7.1,66.5,137.2*68 +$GPGSV,3,1,10,16,48,115,40,25,39,268,38,23,58,175,32,20,71,336,*76 +$GPGSV,3,2,10,19,02,028,,04,06,241,22,13,31,223,25,27,19,284,23*7A +$GPGSV,3,3,10,11,06,338,22,03,14,055,28*7A +$GPRMC,222539.000,A,2734.85792,S,15305.78022,E,37.1,144.9,030308,11.2,W,A*0E +$GPVTG,144.9,T,156.1,M,37.1,N,68.7,K,A*24 +$GPGGA,222540.000,2734.86604,S,15305.78646,E,1,05,4.4,63.5,M,39.2,M,,*78 +$GPGLL,2734.86604,S,15305.78646,E,222540.000,A,A*40 +$GPGSA,A,3,16,25,23,27,11,,,,,,,,9.3,4.4,8.2*36 +$GPGST,222540.000,13.6,8.3,67.7,1.8,7.8,61.9,111.1*55 +$GPGSV,3,1,10,16,48,115,40,25,39,268,38,23,58,175,32,20,71,336,*76 +$GPGSV,3,2,10,19,02,028,,04,06,241,26,13,31,223,22,27,19,284,22*78 +$GPGSV,3,3,10,11,06,338,20,03,14,055,28*78 +$GPRMC,222540.000,A,2734.86604,S,15305.78646,E,35.3,145.6,030308,11.2,W,A*07 +$GPVTG,145.6,T,156.8,M,35.3,N,65.4,K,A*2D +$GPGGA,222541.000,2734.87421,S,15305.79222,E,1,06,1.8,63.5,M,39.2,M,,*70 +$GPGLL,2734.87421,S,15305.79222,E,222541.000,A,A*42 +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.5,1.8,3.1*3A +$GPGST,222541.000,11.7,33.3,8.1,87.4,7.5,30.4,54.6*51 +$GPGSV,3,1,10,16,48,115,39,25,39,268,33,23,58,175,36,20,71,336,*77 +$GPGSV,3,2,10,19,02,028,,04,06,241,26,13,31,223,22,27,19,284,22*78 +$GPGSV,3,3,10,11,06,338,20,03,14,055,26*76 +$GPRMC,222541.000,A,2734.87421,S,15305.79222,E,34.6,147.7,030308,11.2,W,A*02 +$GPVTG,147.7,T,158.9,M,34.6,N,64.1,K,A*21 +$GPGGA,222542.000,2734.88135,S,15305.79765,E,1,06,1.8,63.5,M,39.2,M,,*7A +$GPGLL,2734.88135,S,15305.79765,E,222542.000,A,A*48 +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.5,1.8,3.1*3A +$GPGST,222542.000,23.5,7.9,53.0,0.2,7.2,48.5,78.4*6F +$GPGSV,3,1,10,16,48,115,40,25,39,268,36,23,58,175,35,20,71,336,*7F +$GPGSV,3,2,10,19,02,028,,04,06,241,27,13,31,223,23,27,19,284,25*7F +$GPGSV,3,3,10,11,06,338,20,03,14,055,26*76 +$GPRMC,222542.000,A,2734.88135,S,15305.79765,E,31.0,145.8,030308,11.2,W,A*06 +$GPVTG,145.8,T,157.0,M,31.0,N,57.4,K,A*2C +$GPGGA,222543.000,2734.88798,S,15305.80287,E,1,07,1.2,63.0,M,39.2,M,,*7B +$GPGLL,2734.88798,S,15305.80287,E,222543.000,A,A*47 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222543.000,18.8,6.7,28.4,0.5,6.1,26.0,41.8*62 +$GPGSV,3,1,10,16,48,115,40,25,39,268,39,23,58,175,35,20,71,336,21*73 +$GPGSV,3,2,10,19,02,028,,04,06,241,37,13,31,223,22,27,19,284,24*7E +$GPGSV,3,3,10,11,06,338,20,03,14,055,32*73 +$GPRMC,222543.000,A,2734.88798,S,15305.80287,E,29.0,144.8,030308,11.2,W,A*01 +$GPVTG,144.8,T,156.0,M,29.0,N,53.8,K,A*2D +$GPGGA,222544.000,2734.89328,S,15305.80767,E,1,06,1.8,62.9,M,39.2,M,,*7A +$GPGLL,2734.89328,S,15305.80767,E,222544.000,A,A*45 +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.5,1.8,3.1*3A +$GPGST,222544.000,14.9,35.2,5.8,89.5,5.4,32.2,52.6*52 +$GPGSV,3,1,10,16,48,115,43,25,39,268,40,23,58,175,25,20,71,336,21*7F +$GPGSV,3,2,10,19,02,028,,04,06,241,28,13,31,223,30,27,19,284,29*7E +$GPGSV,3,3,10,11,06,338,20,03,14,055,33*72 +$GPRMC,222544.000,A,2734.89328,S,15305.80767,E,24.5,140.9,030308,11.2,W,A*0E +$GPVTG,140.9,T,152.1,M,24.5,N,45.3,K,A*29 +$GPGGA,222545.000,2734.89633,S,15305.81084,E,1,05,1.9,62.9,M,39.2,M,,*7D +$GPGLL,2734.89633,S,15305.81084,E,222545.000,A,A*40 +$GPGSA,A,3,16,25,23,13,03,,,,,,,,3.6,1.9,3.1*3D +$GPGST,222545.000,19.5,6.0,33.0,1.0,5.5,30.2,52.4*69 +$GPGSV,3,1,10,16,48,115,41,25,39,268,34,23,58,175,29,20,71,336,30*72 +$GPGSV,3,2,10,19,02,028,,04,06,241,25,13,31,223,29,27,19,284,30*73 +$GPGSV,3,3,10,11,06,338,20,03,14,055,30*71 +$GPRMC,222545.000,A,2734.89633,S,15305.81084,E,14.6,136.6,030308,11.2,W,A*05 +$GPVTG,136.6,T,147.8,M,14.6,N,27.0,K,A*2D +$GPGGA,222546.000,2734.89236,S,15305.81130,E,1,06,1.3,62.6,M,39.2,M,,*77 +$GPGLL,2734.89236,S,15305.81130,E,222546.000,A,A*4C +$GPGSA,A,3,16,25,23,20,13,03,,,,,,,2.3,1.3,1.9*3B +$GPGST,222546.000,11.5,5.6,15.6,0.9,5.2,14.3,26.4*6E +$GPGSV,3,1,10,16,48,115,35,25,39,268,40,23,58,175,41,20,71,336,38*74 +$GPGSV,3,2,10,19,02,028,,04,06,241,26,13,31,223,33,27,19,284,26*7C +$GPGSV,3,3,10,11,06,338,20,03,14,055,28*78 +$GPRMC,222546.000,A,2734.89236,S,15305.81130,E,16.9,2.1,030308,11.2,W,A*05 +$GPVTG,2.1,T,13.3,M,16.9,N,31.2,K,A*1F +$GPGGA,222547.000,2734.89429,S,15305.81239,E,1,05,2.3,62.5,M,39.2,M,,*77 +$GPGLL,2734.89429,S,15305.81239,E,222547.000,A,A*4F +$GPGSA,A,3,16,23,13,27,03,,,,,,,,4.6,2.3,3.9*39 +$GPGST,222547.000,11.4,38.3,9.7,69.8,14.7,33.0,49.2*6B +$GPGSV,3,1,10,16,48,115,32,25,39,268,37,23,58,175,42,20,71,336,37*7F +$GPGSV,3,2,10,19,02,028,,04,06,241,26,13,31,223,36,27,19,284,29*76 +$GPGSV,3,3,10,11,06,338,20,03,14,055,34*75 +$GPRMC,222547.000,A,2734.89429,S,15305.81239,E,8.4,154.5,030308,11.2,W,A*32 +$GPVTG,154.5,T,165.7,M,8.4,N,15.6,K,A*1D +$GPGGA,222548.000,2734.89474,S,15305.81253,E,1,07,1.2,62.0,M,39.2,M,,*79 +$GPGLL,2734.89474,S,15305.81253,E,222548.000,A,A*44 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222548.000,11.0,12.3,7.9,86.0,7.3,11.3,20.6*5F +$GPGSV,3,1,10,16,48,115,34,25,39,268,36,23,58,175,42,20,71,336,38*77 +$GPGSV,3,2,10,19,02,028,,04,06,241,25,13,31,223,36,27,19,284,29*75 +$GPGSV,3,3,10,11,06,338,20,03,14,055,33*72 +$GPRMC,222548.000,A,2734.89474,S,15305.81253,E,0.3,353.0,030308,11.2,W,A*36 +$GPVTG,353.0,T,4.3,M,0.3,N,0.5,K,A*27 +$GPGGA,222549.000,2734.89490,S,15305.81265,E,1,04,2.0,61.8,M,39.2,M,,*7E +$GPGLL,2734.89490,S,15305.81265,E,222549.000,A,A*4A +$GPGSA,A,3,25,23,13,03,,,,,,,,,3.9,2.0,3.3*3D +$GPGST,222549.000,17.0,16.1,8.8,81.3,8.3,14.6,29.3*57 +$GPGSV,3,1,11,16,48,115,33,25,39,268,37,23,58,175,42,20,71,336,36*7E +$GPGSV,3,2,11,19,02,028,,04,06,241,25,13,31,223,35,27,19,284,30*7F +$GPGSV,3,3,11,11,06,338,20,01,,,21,03,14,055,33*71 +$GPRMC,222549.000,A,2734.89490,S,15305.81265,E,0.2,330.7,030308,11.2,W,A*3B +$GPVTG,330.7,T,341.9,M,0.2,N,0.3,K,A*2A +$GPGGA,222550.000,2734.89526,S,15305.81278,E,1,04,2.6,61.7,M,39.2,M,,*7F +$GPGLL,2734.89526,S,15305.81278,E,222550.000,A,A*42 +$GPGSA,A,3,16,25,23,13,,,,,,,,,6.1,2.6,5.6*31 +$GPGST,222550.000,13.4,12.4,27.3,43.1,18.9,19.8,52.9*5A +$GPGSV,3,1,11,16,48,115,30,25,39,268,38,23,58,175,42,20,71,336,37*73 +$GPGSV,3,2,11,19,02,028,,04,06,241,25,13,31,223,36,27,19,284,31*7D +$GPGSV,3,3,11,11,06,338,,01,,,21,03,14,055,32*72 +$GPRMC,222550.000,A,2734.89526,S,15305.81278,E,0.1,350.7,030308,11.2,W,A*36 +$GPVTG,350.7,T,1.9,M,0.1,N,0.2,K,A*29 +$GPGGA,222551.000,2734.89528,S,15305.81279,E,1,05,2.3,61.7,M,39.2,M,,*75 +$GPGLL,2734.89528,S,15305.81279,E,222551.000,A,A*4C +$GPGSA,A,3,16,23,13,27,03,,,,,,,,4.6,2.3,3.9*39 +$GPGST,222551.000,13.7,31.0,11.1,60.5,16.5,25.2,39.3*5F +$GPGSV,3,1,11,16,48,115,30,25,39,268,39,23,58,175,41,20,71,336,35*73 +$GPGSV,3,2,11,19,02,028,,04,06,241,23,13,31,223,36,27,19,284,31*7B +$GPGSV,3,3,11,11,06,338,,01,,,20,03,14,055,30*71 +$GPRMC,222551.000,A,2734.89528,S,15305.81279,E,0.1,345.0,030308,11.2,W,A*3B +$GPVTG,345.0,T,356.2,M,0.1,N,0.2,K,A*20 +$GPGGA,222552.000,2734.89550,S,15305.81288,E,1,05,2.1,61.7,M,39.2,M,,*75 +$GPGLL,2734.89550,S,15305.81288,E,222552.000,A,A*4E +$GPGSA,A,3,16,25,23,13,27,,,,,,,,4.7,2.1,4.2*32 +$GPGST,222552.000,11.7,11.5,20.8,20.0,11.8,18.2,39.1*55 +$GPGSV,3,1,11,16,48,115,31,25,39,268,40,23,58,175,42,20,71,336,35*7F +$GPGSV,3,2,11,19,02,028,,04,06,241,23,13,31,223,38,27,19,284,31*75 +$GPGSV,3,3,11,11,06,338,,01,,,20,03,14,055,30*71 +$GPRMC,222552.000,A,2734.89550,S,15305.81288,E,0.1,11.2,030308,11.2,W,A*09 +$GPVTG,11.2,T,22.5,M,0.1,N,0.2,K,A*27 +$GPGGA,222553.000,2734.89573,S,15305.81294,E,1,05,2.1,61.5,M,39.2,M,,*7A +$GPGLL,2734.89573,S,15305.81294,E,222553.000,A,A*43 +$GPGSA,A,3,16,25,23,13,27,,,,,,,,4.7,2.1,4.2*32 +$GPGST,222553.000,9.8,10.3,17.6,19.1,10.4,15.6,33.7*6C +$GPGSV,3,1,10,16,48,115,29,25,39,268,38,23,58,175,41,20,71,336,37*79 +$GPGSV,3,2,10,19,02,028,,04,06,241,23,13,31,223,39,27,19,284,30*74 +$GPGSV,3,3,10,11,06,338,,03,14,055,29*7B +$GPRMC,222553.000,A,2734.89573,S,15305.81294,E,0.1,351.8,030308,11.2,W,A*39 +$GPVTG,351.8,T,3.0,M,0.1,N,0.2,K,A*2C +$GPGGA,222554.000,2734.89591,S,15305.81298,E,1,04,2.6,61.4,M,39.2,M,,*7A +$GPGLL,2734.89591,S,15305.81298,E,222554.000,A,A*44 +$GPGSA,A,3,16,25,23,13,,,,,,,,,6.1,2.6,5.6*31 +$GPGST,222554.000,16.9,10.4,17.8,12.8,10.0,16.1,37.3*5F +$GPGSV,3,1,10,16,48,115,32,25,39,268,38,23,58,175,41,20,71,336,36*72 +$GPGSV,3,2,10,19,02,028,,04,06,241,23,13,31,223,38,27,19,284,31*74 +$GPGSV,3,3,10,11,06,338,,03,14,055,26*74 +$GPRMC,222554.000,A,2734.89591,S,15305.81298,E,0.1,334.9,030308,11.2,W,A*3C +$GPVTG,334.9,T,346.1,M,0.1,N,0.2,K,A*2D +$GPGGA,222555.000,2734.89607,S,15305.81301,E,1,04,2.6,61.2,M,39.2,M,,*70 +$GPGLL,2734.89607,S,15305.81301,E,222555.000,A,A*48 +$GPGSA,A,3,16,25,23,13,,,,,,,,,6.1,2.6,5.6*31 +$GPGST,222555.000,14.4,11.9,23.3,40.8,16.2,17.6,44.5*56 +$GPGSV,3,1,11,16,48,115,32,25,39,268,37,23,58,175,40,20,71,336,38*73 +$GPGSV,3,2,11,19,02,028,,04,06,241,23,13,31,223,37,27,19,284,30*7B +$GPGSV,3,3,11,11,06,338,,01,,,20,03,14,055,25*75 +$GPRMC,222555.000,A,2734.89607,S,15305.81301,E,0.1,6.2,030308,11.2,W,A*39 +$GPVTG,6.2,T,17.4,M,0.1,N,0.2,K,A*16 +$GPGGA,222556.000,2734.89612,S,15305.81301,E,1,04,2.6,61.1,M,39.2,M,,*74 +$GPGLL,2734.89612,S,15305.81301,E,222556.000,A,A*4F +$GPGSA,A,3,16,25,23,13,,,,,,,,,6.1,2.6,5.6*31 +$GPGST,222556.000,12.4,15.8,24.1,4.1,14.5,22.0,39.9*69 +$GPGSV,3,1,11,16,48,115,33,25,39,268,38,23,58,174,41,20,71,336,38*7D +$GPGSV,3,2,11,19,02,028,,04,06,242,23,13,31,223,38,27,19,284,32*75 +$GPGSV,3,3,11,11,06,338,,01,,,20,03,14,055,28*78 +$GPRMC,222556.000,A,2734.89612,S,15305.81301,E,0.1,21.8,030308,11.2,W,A*01 +$GPVTG,21.8,T,33.0,M,0.1,N,0.2,K,A*2B +$GPGGA,222557.000,2734.89635,S,15305.81337,E,1,05,2.1,61.0,M,39.2,M,,*72 +$GPGLL,2734.89635,S,15305.81337,E,222557.000,A,A*4E +$GPGSA,A,3,16,25,23,13,27,,,,,,,,4.7,2.1,4.2*32 +$GPGST,222557.000,10.3,13.0,15.0,5.2,11.9,13.7,32.7*6B +$GPGSV,3,1,10,16,48,115,33,25,39,268,38,23,58,174,41,20,71,336,36*72 +$GPGSV,3,2,10,19,02,028,,04,06,242,23,13,31,223,39,27,19,284,28*7E +$GPGSV,3,3,10,11,06,338,,03,14,055,31*72 +$GPRMC,222557.000,A,2734.89635,S,15305.81337,E,1.2,96.1,030308,11.2,W,A*07 +$GPVTG,96.1,T,107.3,M,1.2,N,2.2,K,A*1B +$GPGGA,222558.000,2734.89638,S,15305.81517,E,1,06,1.8,60.6,M,39.2,M,,*7A +$GPGLL,2734.89638,S,15305.81517,E,222558.000,A,A*48 +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.5,1.8,3.1*3A +$GPGST,222558.000,18.6,12.9,7.5,72.4,7.5,11.4,21.9*57 +$GPGSV,3,1,10,16,48,115,39,25,39,268,38,23,58,174,37,20,71,336,26*78 +$GPGSV,3,2,10,19,02,028,,04,06,242,23,13,31,223,34,27,19,284,29*72 +$GPGSV,3,3,10,11,06,338,,03,14,055,30*73 +$GPRMC,222558.000,A,2734.89638,S,15305.81517,E,5.6,82.0,030308,11.2,W,A*05 +$GPVTG,82.0,T,93.2,M,5.6,N,10.3,K,A*10 +$GPGGA,222559.000,2734.89631,S,15305.81911,E,1,05,2.2,60.5,M,39.2,M,,*71 +$GPGLL,2734.89631,S,15305.81911,E,222559.000,A,A*4A +$GPGSA,A,3,16,25,23,20,27,,,,,,,,3.6,2.2,2.9*3A +$GPGST,222559.000,17.0,15.1,33.1,15.1,15.5,29.4,59.0*59 +$GPGSV,3,1,10,16,48,115,34,25,39,268,35,23,58,174,30,20,71,336,29*70 +$GPGSV,3,2,10,19,02,028,,04,06,242,23,13,31,223,35,27,19,284,28*72 +$GPGSV,3,3,10,11,06,338,,03,14,055,27*75 +$GPRMC,222559.000,A,2734.89631,S,15305.81911,E,12.5,87.6,030308,11.2,W,A*31 +$GPVTG,87.6,T,98.8,M,12.5,N,23.2,K,A*26 +$GPGGA,222600.000,2734.89436,S,15305.82359,E,1,06,1.8,61.2,M,39.2,M,,*72 +$GPGLL,2734.89436,S,15305.82359,E,222600.000,A,A*45 +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.5,1.8,3.1*3A +$GPGST,222600.000,14.4,14.9,6.9,79.1,6.7,13.4,28.4*57 +$GPGSV,3,1,10,16,48,115,37,25,39,268,36,23,58,174,29,20,71,336,33*73 +$GPGSV,3,2,10,19,02,028,,04,06,242,23,13,31,223,39,27,19,284,28*7E +$GPGSV,3,3,10,11,06,338,,03,14,055,28*7A +$GPRMC,222600.000,A,2734.89436,S,15305.82359,E,15.9,62.5,030308,11.2,W,A*3D +$GPVTG,62.5,T,73.7,M,15.9,N,29.5,K,A*22 +$GPGGA,222601.000,2734.89190,S,15305.82850,E,1,06,1.8,60.5,M,39.2,M,,*7E +$GPGLL,2734.89190,S,15305.82850,E,222601.000,A,A*4F +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.6,1.8,3.1*39 +$GPGST,222601.000,11.5,13.4,6.1,78.5,6.0,12.0,24.9*56 +$GPGSV,3,1,10,16,48,115,40,25,39,268,27,23,58,174,35,20,71,336,28*74 +$GPGSV,3,2,10,19,02,028,,04,06,242,,13,31,223,39,27,19,284,27*70 +$GPGSV,3,3,10,11,06,338,,03,14,055,23*71 +$GPRMC,222601.000,A,2734.89190,S,15305.82850,E,18.0,58.9,030308,11.2,W,A*36 +$GPVTG,58.9,T,70.1,M,18.0,N,33.4,K,A*2C +$GPGGA,222602.000,2734.88904,S,15305.83361,E,1,05,1.6,60.0,M,39.2,M,,*79 +$GPGLL,2734.88904,S,15305.83361,E,222602.000,A,A*40 +$GPGSA,A,3,16,23,20,13,03,,,,,,,,2.5,1.6,1.9*3F +$GPGST,222602.000,11.3,17.1,6.5,54.9,10.2,13.2,18.6*62 +$GPGSV,3,1,10,16,48,115,27,25,39,268,29,23,58,174,33,20,71,336,33*77 +$GPGSV,3,2,10,19,02,028,,04,06,242,,13,31,223,35,27,19,284,32*78 +$GPGSV,3,3,10,11,06,338,,03,14,055,24*76 +$GPRMC,222602.000,A,2734.88904,S,15305.83361,E,19.8,55.1,030308,11.2,W,A*35 +$GPVTG,55.1,T,66.3,M,19.8,N,36.7,K,A*23 +$GPGGA,222603.000,2734.88556,S,15305.83944,E,1,04,3.8,58.8,M,39.2,M,,*70 +$GPGLL,2734.88556,S,15305.83944,E,222603.000,A,A*47 +$GPGSA,A,3,25,23,20,27,,,,,,,,,6.5,3.8,5.2*3C +$GPGST,222603.000,12.6,48.6,15.6,66.9,41.3,21.9,62.5*59 +$GPGSV,3,1,10,16,48,115,23,25,39,268,29,23,58,174,31,20,71,337,37*74 +$GPGSV,3,2,10,19,02,028,,04,06,242,,13,31,223,34,27,19,284,26*7C +$GPGSV,3,3,10,11,06,338,,03,14,055,28*7A +$GPRMC,222603.000,A,2734.88556,S,15305.83944,E,22.7,54.4,030308,11.2,W,A*31 +$GPVTG,54.4,T,65.6,M,22.7,N,42.1,K,A*23 +$GPGGA,222604.000,2734.88238,S,15305.84546,E,1,04,4.4,57.8,M,39.2,M,,*75 +$GPGLL,2734.88238,S,15305.84546,E,222604.000,A,A*46 +$GPGSA,A,3,25,20,13,27,,,,,,,,,7.2,4.4,5.7*37 +$GPGST,222604.000,10.4,46.8,10.9,81.3,42.4,11.8,57.5*57 +$GPGSV,3,1,10,16,48,115,27,25,39,268,32,23,58,174,32,20,71,337,37*79 +$GPGSV,3,2,10,19,02,028,,04,06,242,,13,31,223,34,27,19,284,34*7F +$GPGSV,3,3,10,11,06,338,,03,14,055,29*7B +$GPRMC,222604.000,A,2734.88238,S,15305.84546,E,23.3,54.5,030308,11.2,W,A*34 +$GPVTG,54.5,T,65.7,M,23.3,N,43.2,K,A*24 +$GPGGA,222605.000,2734.87917,S,15305.85182,E,1,04,4.4,56.6,M,39.2,M,,*7F +$GPGLL,2734.87917,S,15305.85182,E,222605.000,A,A*43 +$GPGSA,A,3,25,20,13,27,,,,,,,,,7.2,4.4,5.7*37 +$GPGST,222605.000,14.3,40.3,10.1,81.5,36.5,10.7,49.8*58 +$GPGSV,3,1,10,16,48,115,24,25,39,268,32,23,58,174,33,20,71,337,37*7B +$GPGSV,3,2,10,19,02,028,,04,06,242,20,13,31,223,35,27,19,284,32*7A +$GPGSV,3,3,10,11,06,338,,03,14,055,26*74 +$GPRMC,222605.000,A,2734.87917,S,15305.85182,E,24.5,55.0,030308,11.2,W,A*34 +$GPVTG,55.0,T,66.2,M,24.5,N,45.3,K,A*20 +$GPGGA,222606.000,2734.87588,S,15305.85846,E,1,05,3.6,55.8,M,39.2,M,,*7E +$GPGLL,2734.87588,S,15305.85846,E,222606.000,A,A*4B +$GPGSA,A,3,25,23,20,13,27,,,,,,,,6.3,3.6,5.2*36 +$GPGST,222606.000,11.7,30.4,8.7,77.7,27.2,9.8,40.6*59 +$GPGSV,3,1,10,16,48,115,24,25,39,268,31,23,58,174,32,20,71,337,34*7A +$GPGSV,3,2,10,19,02,029,,04,06,242,20,13,31,223,35,27,19,284,34*7D +$GPGSV,3,3,10,11,06,338,,03,14,055,24*76 +$GPRMC,222606.000,A,2734.87588,S,15305.85846,E,25.3,55.9,030308,11.2,W,A*32 +$GPVTG,55.9,T,67.1,M,25.3,N,46.9,K,A*25 +$GPGGA,222607.000,2734.87218,S,15305.86543,E,1,06,1.8,55.5,M,39.2,M,,*78 +$GPGLL,2734.87218,S,15305.86543,E,222607.000,A,A*4F +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.6,1.8,3.1*39 +$GPGST,222607.000,11.2,13.8,8.5,86.1,7.8,12.6,27.3*52 +$GPGSV,3,1,10,16,48,115,29,25,39,268,26,23,58,174,34,20,71,337,32*71 +$GPGSV,3,2,10,19,02,029,,04,06,242,27,13,31,223,36,27,19,284,30*7D +$GPGSV,3,3,10,11,06,338,,03,14,055,24*76 +$GPRMC,222607.000,A,2734.87218,S,15305.86543,E,26.0,57.6,030308,11.2,W,A*3B +$GPVTG,57.6,T,68.8,M,26.0,N,48.1,K,A*28 +$GPGGA,222608.000,2734.86867,S,15305.87251,E,1,06,1.8,55.1,M,39.2,M,,*75 +$GPGLL,2734.86867,S,15305.87251,E,222608.000,A,A*46 +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.6,1.8,3.1*39 +$GPGST,222608.000,15.1,15.8,7.1,68.8,8.0,13.6,36.7*5C +$GPGSV,3,1,10,16,48,115,39,25,39,268,28,23,58,174,35,20,71,337,30*7D +$GPGSV,3,2,10,19,02,029,,04,06,242,27,13,31,223,40,27,19,284,28*75 +$GPGSV,3,3,10,11,06,338,,03,14,055,28*7A +$GPRMC,222608.000,A,2734.86867,S,15305.87251,E,25.9,60.7,030308,11.2,W,A*3D +$GPVTG,60.7,T,71.9,M,25.9,N,47.9,K,A*29 +$GPGGA,222609.000,2734.86555,S,15305.87973,E,1,06,1.8,54.7,M,39.2,M,,*74 +$GPGLL,2734.86555,S,15305.87973,E,222609.000,A,A*40 +$GPGSA,A,3,16,25,23,13,27,03,,,,,,,3.6,1.8,3.1*39 +$GPGST,222609.000,10.9,10.9,5.1,85.4,4.7,10.0,22.0*55 +$GPGSV,3,1,10,16,48,116,34,25,39,268,39,23,58,174,29,20,71,337,33*7D +$GPGSV,3,2,10,19,02,029,,04,06,242,24,13,31,223,42,27,19,284,23*7F +$GPGSV,3,3,10,11,06,338,,03,14,055,26*74 +$GPRMC,222609.000,A,2734.86555,S,15305.87973,E,25.7,64.3,030308,11.2,W,A*35 +$GPVTG,64.3,T,75.6,M,25.7,N,47.5,K,A*20 +$GPGGA,222610.000,2734.86253,S,15305.88695,E,1,05,1.9,54.1,M,39.2,M,,*71 +$GPGLL,2734.86253,S,15305.88695,E,222610.000,A,A*41 +$GPGSA,A,3,16,25,23,13,03,,,,,,,,3.7,1.9,3.1*3C +$GPGST,222610.000,11.1,14.6,7.4,64.7,8.3,12.4,28.7*57 +$GPGSV,3,1,10,16,48,116,29,25,39,268,42,23,58,174,28,20,71,337,32*7D +$GPGSV,3,2,10,19,02,029,,04,06,242,24,13,31,223,42,27,19,284,23*7F +$GPGSV,3,3,10,11,06,338,,03,14,055,24*76 +$GPRMC,222610.000,A,2734.86253,S,15305.88695,E,25.3,65.0,030308,11.2,W,A*32 +$GPVTG,65.0,T,76.3,M,25.3,N,46.8,K,A*2C +$GPGGA,222611.000,2734.85924,S,15305.89387,E,1,05,2.2,53.4,M,39.2,M,,*75 +$GPGLL,2734.85924,S,15305.89387,E,222611.000,A,A*4F +$GPGSA,A,3,16,25,23,20,13,,,,,,,,5.3,2.2,4.8*39 +$GPGST,222611.000,17.7,8.4,21.7,17.4,9.4,19.0,57.8*57 +$GPGSV,3,1,10,16,48,116,39,25,39,268,32,23,58,174,35,20,71,337,26*72 +$GPGSV,3,2,10,19,02,029,,04,06,242,31,13,31,223,39,27,19,284,24*70 +$GPGSV,3,3,10,11,06,338,,03,14,055,26*74 +$GPRMC,222611.000,A,2734.85924,S,15305.89387,E,24.9,61.4,030308,11.2,W,A*37 +$GPVTG,61.4,T,72.6,M,24.9,N,46.1,K,A*2F +$GPGGA,222612.000,2734.85516,S,15305.90007,E,1,07,1.2,53.3,M,39.2,M,,*7E +$GPGLL,2734.85516,S,15305.90007,E,222612.000,A,A*42 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222612.000,15.5,16.3,8.2,77.8,8.0,14.7,27.8*50 +$GPGSV,3,1,10,16,48,116,29,25,39,268,29,23,58,174,30,20,71,337,34*7F +$GPGSV,3,2,10,19,02,029,,04,06,242,27,13,31,223,35,27,19,284,28*77 +$GPGSV,3,3,10,11,06,338,,03,14,055,25*77 +$GPRMC,222612.000,A,2734.85516,S,15305.90007,E,24.5,53.1,030308,11.2,W,A*32 +$GPVTG,53.1,T,64.3,M,24.5,N,45.4,K,A*23 +$GPGGA,222613.000,2734.85043,S,15305.90565,E,1,05,1.9,53.2,M,39.2,M,,*73 +$GPGLL,2734.85043,S,15305.90565,E,222613.000,A,A*47 +$GPGSA,A,3,16,25,20,13,27,,,,,,,,3.7,1.9,3.2*3A +$GPGST,222613.000,21.1,11.0,20.9,21.8,11.7,18.1,48.5*55 +$GPGSV,3,1,10,16,48,116,30,25,39,268,32,23,58,174,24,20,71,337,36*7A +$GPGSV,3,2,10,19,02,029,,04,06,242,22,13,31,223,35,27,19,284,29*73 +$GPGSV,3,3,10,11,06,338,,03,14,055,29*7B +$GPRMC,222613.000,A,2734.85043,S,15305.90565,E,24.9,45.4,030308,11.2,W,A*39 +$GPVTG,45.4,T,56.6,M,24.9,N,46.1,K,A*2F +$GPGGA,222614.000,2734.84523,S,15305.91064,E,1,05,1.9,53.2,M,39.2,M,,*73 +$GPGLL,2734.84523,S,15305.91064,E,222614.000,A,A*47 +$GPGSA,A,3,16,25,20,13,27,,,,,,,,3.7,1.9,3.2*3A +$GPGST,222614.000,18.8,16.8,28.3,28.1,18.2,24.0,43.4*54 +$GPGSV,3,1,10,16,48,116,27,25,39,268,30,23,58,174,32,20,71,337,35*7A +$GPGSV,3,2,10,19,02,029,,04,06,242,28,13,31,223,26,27,19,284,32*71 +$GPGSV,3,3,10,11,06,338,,03,14,055,30*73 +$GPRMC,222614.000,A,2734.84523,S,15305.91064,E,24.7,40.2,030308,11.2,W,A*34 +$GPVTG,40.2,T,51.4,M,24.7,N,45.7,K,A*22 +$GPGGA,222615.000,2734.84002,S,15305.91547,E,1,07,1.2,53.0,M,39.2,M,,*7B +$GPGLL,2734.84002,S,15305.91547,E,222615.000,A,A*44 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222615.000,19.7,18.9,7.9,71.0,8.8,16.5,18.9*52 +$GPGSV,3,1,10,16,48,116,25,25,39,268,26,23,58,174,35,20,71,337,34*79 +$GPGSV,3,2,10,19,02,029,,04,06,242,24,13,31,223,25,27,19,284,30*7C +$GPGSV,3,3,10,11,06,338,,03,14,055,29*7B +$GPRMC,222615.000,A,2734.84002,S,15305.91547,E,24.1,38.7,030308,11.2,W,A*3B +$GPVTG,38.7,T,49.9,M,24.1,N,44.7,K,A*2B +$GPGGA,222616.000,2734.83488,S,15305.92024,E,1,07,1.2,53.1,M,39.2,M,,*7B +$GPGLL,2734.83488,S,15305.92024,E,222616.000,A,A*45 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222616.000,18.1,15.8,11.2,70.8,10.8,14.1,19.9*51 +$GPGSV,3,1,10,16,48,116,27,25,39,268,29,23,58,174,34,20,71,337,30*71 +$GPGSV,3,2,10,19,02,029,,04,06,242,27,13,31,223,24,27,19,284,28*77 +$GPGSV,3,3,10,11,06,338,,03,14,055,32*71 +$GPRMC,222616.000,A,2734.83488,S,15305.92024,E,24.0,39.3,030308,11.2,W,A*3E +$GPVTG,39.3,T,50.5,M,24.0,N,44.5,K,A*29 +$GPGGA,222617.000,2734.82955,S,15305.92505,E,1,07,1.2,53.2,M,39.2,M,,*73 +$GPGLL,2734.82955,S,15305.92505,E,222617.000,A,A*4E +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222617.000,14.7,13.3,9.2,70.7,8.9,11.8,16.8*5B +$GPGSV,3,1,10,16,48,116,23,25,39,268,30,23,58,174,35,20,71,337,33*7F +$GPGSV,3,2,10,19,02,029,,04,06,242,25,13,31,223,25,27,19,284,26*7A +$GPGSV,3,3,10,11,06,338,,03,14,055,32*71 +$GPRMC,222617.000,A,2734.82955,S,15305.92505,E,24.7,38.8,030308,11.2,W,A*38 +$GPVTG,38.8,T,50.0,M,24.7,N,45.7,K,A*22 +$GPGGA,222618.000,2734.82405,S,15305.92991,E,1,07,1.2,53.5,M,39.2,M,,*72 +$GPGLL,2734.82405,S,15305.92991,E,222618.000,A,A*48 +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222618.000,13.7,14.7,7.8,77.2,7.6,13.2,24.3*54 +$GPGSV,3,1,10,16,48,116,27,25,39,268,30,23,58,174,36,20,71,337,32*79 +$GPGSV,3,2,10,19,02,029,,04,06,242,31,13,31,223,25,27,19,283,23*7D +$GPGSV,3,3,10,11,06,338,,03,14,056,32*72 +$GPRMC,222618.000,A,2734.82405,S,15305.92991,E,25.3,38.3,030308,11.2,W,A*30 +$GPVTG,38.3,T,49.5,M,25.3,N,46.8,K,A*2D +$GPGGA,222619.000,2734.81867,S,15305.93485,E,1,07,1.2,53.8,M,39.2,M,,*7C +$GPGLL,2734.81867,S,15305.93485,E,222619.000,A,A*4B +$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 +$GPGST,222619.000,20.5,18.3,9.9,85.5,9.1,16.7,27.9*5A +$GPGSV,3,1,10,16,48,116,27,25,39,268,30,23,58,174,35,20,71,337,33*7B +$GPGSV,3,2,10,19,02,029,,04,06,242,29,13,31,223,23,27,19,283,23*72 +$GPGSV,3,3,10,11,06,338,,03,14,056,32*72 +$GPRMC,222619.000,A,2734.81867,S,15305.93485,E,25.3,39.2,030308,11.2,W,A*33 +$GPVTG,39.2,T,50.4,M,25.3,N,46.8,K,A*24 +$GPGGA,222620.000,2734.81344,S,15305.93979,E,1,05,1.6,53.8,M,39.2,M,,*74 +$GPGLL,2734.81344,S,15305.93979,E,222620.000,A,A*45 +$GPGSA,A,3,16,23,20,13,03,,,,,,,,2.5,1.6,1.9*3F +$GPGST,222620.000,18.2,14.7,21.1,9.8,19.1,13.7,29.8*64 +$GPGSV,3,1,10,16,48,116,26,25,39,268,30,23,58,174,33,20,71,337,34*7B +$GPGSV,3,2,10,19,02,029,,04,06,242,24,13,31,223,25,27,19,283,29*73 +$GPGSV,3,3,10,11,06,338,,03,14,056,33*73 +$GPRMC,222620.000,A,2734.81344,S,15305.93979,E,24.7,39.5,030308,11.2,W,A*3F +$GPVTG,39.5,T,50.7,M,24.7,N,45.8,K,A*26 +$GPGGA,222621.000,2734.80838,S,15305.94469,E,1,06,1.3,53.5,M,39.2,M,,*74 +$GPGLL,2734.80838,S,15305.94469,E,222621.000,A,A*4E +$GPGSA,A,3,16,25,23,20,13,03,,,,,,,2.3,1.3,1.9*3B +$GPGST,222621.000,14.6,11.8,13.4,39.2,11.7,11.4,21.8*5D +$GPGSV,3,1,10,16,48,116,25,25,39,268,31,23,58,174,33,20,71,337,37*7A +$GPGSV,3,2,10,19,03,029,,04,06,242,24,13,31,223,24,27,19,283,36*7D +$GPGSV,3,3,10,11,06,338,,03,14,056,32*72 +$GPRMC,222621.000,A,2734.80838,S,15305.94469,E,24.1,40.1,030308,11.2,W,A*38 +$GPVTG,40.1,T,51.3,M,24.1,N,44.7,K,A*21 +$GPGGA,222622.000,2734.80354,S,15305.94956,E,1,06,1.7,53.3,M,39.2,M,,*75 +$GPGLL,2734.80354,S,15305.94956,E,222622.000,A,A*4D +$GPGSA,A,3,16,25,23,20,13,27,,,,,,,3.3,1.7,2.9*3B +$GPGST,222622.000,13.2,10.2,17.1,41.6,12.5,13.2,30.8*59 +$GPGSV,3,1,10,16,48,116,26,25,39,268,31,23,58,174,26,20,71,337,39*73 +$GPGSV,3,2,10,19,03,029,,04,06,242,24,13,31,223,28,27,19,283,36*71 +$GPGSV,3,3,10,11,06,338,,03,14,056,35*75 +$GPRMC,222622.000,A,2734.80354,S,15305.94956,E,23.6,41.3,030308,11.2,W,A*38 +$GPVTG,41.3,T,52.5,M,23.6,N,43.7,K,A*20 +$GPGGA,222623.000,2734.79878,S,15305.95470,E,1,05,1.9,52.8,M,39.2,M,,*78 +$GPGLL,2734.79878,S,15305.95470,E,222623.000,A,A*47 +$GPGSA,A,3,16,25,20,13,27,,,,,,,,3.7,1.9,3.2*3A +$GPGST,222623.000,14.7,24.8,16.6,50.3,19.9,18.6,39.3*5E +$GPGSV,3,1,11,16,48,116,24,25,39,268,32,23,58,174,24,20,71,337,38*70 +$GPGSV,3,2,11,19,03,029,,04,06,242,24,13,31,223,32,27,19,283,34*79 +$GPGSV,3,3,11,11,06,338,,01,,,18,03,14,056,34*7D +$GPRMC,222623.000,A,2734.79878,S,15305.95470,E,24.0,43.4,030308,11.2,W,A*36 +$GPVTG,43.4,T,54.6,M,24.0,N,44.4,K,A*25 +$GPGGA,222624.000,2734.79400,S,15305.96019,E,1,05,1.9,52.3,M,39.2,M,,*7F +$GPGLL,2734.79400,S,15305.96019,E,222624.000,A,A*4B +$GPGSA,A,3,16,25,20,27,03,,,,,,,,2.7,1.9,2.0*39 +$GPGST,222624.000,12.3,24.0,7.9,80.2,8.0,21.7,15.3*5C +$GPGSV,3,1,11,16,48,116,23,25,39,268,32,23,58,174,26,20,71,337,37*7A +$GPGSV,3,2,11,19,03,029,,04,06,242,24,13,31,223,35,27,19,283,25*7E +$GPGSV,3,3,11,11,06,338,,01,,,18,03,14,056,31*78 +$GPRMC,222624.000,A,2734.79400,S,15305.96019,E,24.7,45.3,030308,11.2,W,A*3C +$GPVTG,45.3,T,56.6,M,24.7,N,45.7,K,A*23 +$GPGGA,222625.000,2734.78953,S,15305.96595,E,1,05,1.9,51.8,M,39.2,M,,*7D +$GPGLL,2734.78953,S,15305.96595,E,222625.000,A,A*41 +$GPGSA,A,3,16,25,20,13,27,,,,,,,,3.7,1.9,3.2*3A +$GPGST,222625.000,24.0,12.2,19.9,37.5,14.2,16.0,36.1*57 +$GPGSV,3,1,11,16,48,116,30,25,39,268,32,23,58,174,23,20,71,337,37*7D +$GPGSV,3,2,11,19,03,029,,04,06,242,25,13,31,223,36,27,19,283,25*7C +$GPGSV,3,3,11,11,06,338,,01,,,18,03,14,056,24*7C +$GPRMC,222625.000,A,2734.78953,S,15305.96595,E,24.8,47.9,030308,11.2,W,A*31 +$GPVTG,47.9,T,59.1,M,24.8,N,46.0,K,A*28 +$GPGGA,222626.000,2734.78516,S,15305.97172,E,1,05,2.5,51.1,M,39.2,M,,*79 +$GPGLL,2734.78516,S,15305.97172,E,222626.000,A,A*43 +$GPGSA,A,3,16,25,20,04,13,,,,,,,,4.2,2.5,3.3*37 +$GPGST,222626.000,20.2,12.6,23.1,19.8,13.0,20.2,38.4*5F +$GPGSV,3,1,11,16,48,116,31,25,39,268,32,23,58,174,25,20,71,337,38*75 +$GPGSV,3,2,11,19,03,029,,04,06,242,25,13,31,223,36,27,19,283,23*7A +$GPGSV,3,3,11,11,06,338,,01,,,18,03,14,056,24*7C +$GPRMC,222626.000,A,2734.78516,S,15305.97172,E,24.7,48.3,030308,11.2,W,A*39 +$GPVTG,48.3,T,59.5,M,24.7,N,45.7,K,A*22 +$GPGGA,222627.000,2734.78079,S,15305.97737,E,1,04,2.5,50.5,M,39.2,M,,*77 +$GPGLL,2734.78079,S,15305.97737,E,222627.000,A,A*49 +$GPGSA,A,3,16,23,20,13,,,,,,,,,5.8,2.5,5.2*39 +$GPGST,222627.000,16.3,12.4,42.2,11.3,13.5,37.9,90.0*51 +$GPGSV,3,1,11,16,48,116,28,25,39,268,32,23,58,174,25,20,71,337,37*72 +$GPGSV,3,2,11,19,03,029,,04,06,242,29,13,31,223,37,27,19,283,30*75 +$GPGSV,3,3,11,11,06,338,,01,,,18,03,14,056,24*7C +$GPRMC,222627.000,A,2734.78079,S,15305.97737,E,24.3,48.1,030308,11.2,W,A*35 +$GPVTG,48.1,T,59.3,M,24.3,N,45.1,K,A*24 +$GPGGA,222628.000,2734.77637,S,15305.98293,E,1,07,1.3,50.2,M,39.2,M,,*7E +$GPGLL,2734.77637,S,15305.98293,E,222628.000,A,A*41 +$GPGSA,A,3,16,25,23,04,13,27,03,,,,,,2.2,1.3,1.8*38 +$GPGST,222628.000,13.2,14.5,8.8,76.9,8.4,13.0,22.0*5F +$GPGSV,3,1,11,16,48,116,30,25,39,268,32,23,58,174,27,20,71,337,37*79 +$GPGSV,3,2,11,19,03,029,,04,06,242,32,13,31,223,37,27,19,283,28*76 +$GPGSV,3,3,11,11,06,338,,01,,,18,03,14,056,25*7D +$GPRMC,222628.000,A,2734.77637,S,15305.98293,E,23.9,48.5,030308,11.2,W,A*34 +$GPVTG,48.5,T,59.7,M,23.9,N,44.3,K,A*2A +$GPGGA,222629.000,2734.77226,S,15305.98850,E,1,08,1.1,49.5,M,39.2,M,,*7C +$GPGLL,2734.77226,S,15305.98850,E,222629.000,A,A*41 +$GPGSA,A,3,16,25,23,20,04,13,27,03,,,,,1.7,1.1,1.3*35 +$GPGST,222629.000,11.0,9.5,7.3,89.6,6.7,8.6,14.3*5E +$GPGSV,3,1,11,16,48,116,31,25,39,268,32,23,58,174,25,20,71,337,36*7B +$GPGSV,3,2,11,19,03,029,,04,06,242,30,13,31,223,37,27,19,283,28*74 +$GPGSV,3,3,11,11,06,338,,01,,,18,03,14,056,27*7F +$GPRMC,222629.000,A,2734.77226,S,15305.98850,E,23.5,49.4,030308,11.2,W,A*38 +$GPVTG,49.4,T,60.6,M,23.5,N,43.5,K,A*2C +$GPGGA,222630.000,2734.76859,S,15305.99361,E,1,04,3.5,49.4,M,39.2,M,,*74 +$GPGLL,2734.76859,S,15305.99361,E,222630.000,A,A*42 +$GPGSA,A,3,16,25,20,27,,,,,,,,,4.9,3.5,3.4*39 +$GPGST,222630.000,13.4,7.9,50.0,19.9,17.0,43.1,69.5*66 +$GPGSV,3,1,11,16,48,116,31,25,39,268,30,23,58,174,22,20,71,337,36*7E +$GPGSV,3,2,11,19,03,029,,04,06,242,32,13,31,223,35,27,19,283,24*78 +$GPGSV,3,3,11,11,06,338,18,01,,,18,03,14,056,29*78 +$GPRMC,222630.000,A,2734.76859,S,15305.99361,E,21.1,50.3,030308,11.2,W,A*32 +$GPVTG,50.3,T,61.5,M,21.1,N,39.1,K,A*2E +$GPGGA,222631.000,2734.76498,S,15305.99809,E,1,08,1.1,48.2,M,39.2,M,,*7C +$GPGLL,2734.76498,S,15305.99809,E,222631.000,A,A*47 +$GPGSA,A,3,16,25,23,20,04,13,27,03,,,,,1.7,1.1,1.3*35 +$GPGST,222631.000,18.4,10.8,5.8,77.6,5.6,9.7,13.2*63 +$GPGSV,3,1,11,16,48,116,32,25,39,268,31,23,58,174,22,20,71,337,35*7F +$GPGSV,3,2,11,19,03,029,,04,06,242,30,13,31,223,36,27,19,283,25*78 +$GPGSV,3,3,11,11,06,338,18,01,,,18,03,14,056,33*73 +$GPRMC,222631.000,A,2734.76498,S,15305.99809,E,19.4,47.4,030308,11.2,W,A*38 +$GPVTG,47.4,T,58.6,M,19.4,N,35.9,K,A*2C +$GPGGA,222632.000,2734.76359,S,15306.00162,E,1,08,1.1,49.6,M,39.2,M,,*77 +$GPGLL,2734.76359,S,15306.00162,E,222632.000,A,A*49 +$GPGSA,A,3,16,25,23,20,04,13,27,03,,,,,1.7,1.1,1.3*35 +$GPGST,222632.000,18.1,14.9,6.7,53.4,9.5,11.5,16.1*5A +$GPGSV,3,1,11,16,48,116,30,25,39,268,31,23,58,174,31,20,71,337,31*7B +$GPGSV,3,2,11,19,03,029,,04,06,242,22,13,31,223,37,27,19,283,29*76 +$GPGSV,3,3,11,11,06,338,24,01,,,18,03,14,056,25*7B +$GPRMC,222632.000,A,2734.76359,S,15306.00162,E,12.4,65.5,030308,11.2,W,A*3C +$GPVTG,65.5,T,76.7,M,12.4,N,22.9,K,A*2D +$GPGGA,222633.000,2734.76254,S,15306.00553,E,1,08,1.1,49.0,M,39.2,M,,*7A +$GPGLL,2734.76254,S,15306.00553,E,222633.000,A,A*42 +$GPGSA,A,3,16,25,23,20,04,13,27,03,,,,,1.7,1.1,1.3*35 +$GPGST,222633.000,13.9,12.3,5.8,55.3,7.8,9.7,13.7*62 +$GPGSV,3,1,10,16,48,116,35,25,39,268,35,23,58,174,30,20,71,337,35*7E +$GPGSV,3,2,10,19,03,029,,04,06,242,26,13,31,223,39,27,19,283,26*72 +$GPGSV,3,3,10,11,06,338,24,03,14,056,30*76 +$GPRMC,222633.000,A,2734.76254,S,15306.00553,E,12.9,72.5,030308,11.2,W,A*3C +$GPVTG,72.5,T,83.7,M,12.9,N,23.9,K,A*2D +$GPGGA,222634.000,2734.76305,S,15306.00850,E,1,08,1.1,48.4,M,39.2,M,,*73 +$GPGLL,2734.76305,S,15306.00850,E,222634.000,A,A*4E +$GPGSA,A,3,16,25,23,20,04,13,27,03,,,,,1.7,1.1,1.3*35 +$GPGST,222634.000,11.3,10.3,5.3,58.0,6.5,8.4,12.0*62 +$GPGSV,3,1,10,16,48,116,33,25,39,268,38,23,58,174,30,20,71,337,30*70 +$GPGSV,3,2,10,19,03,029,,04,06,242,29,13,31,223,34,27,19,283,30*77 +$GPGSV,3,3,10,11,06,338,23,03,14,056,25*75 +$GPRMC,222634.000,A,2734.76305,S,15306.00850,E,9.4,99.3,030308,11.2,W,A*04 +$GPVTG,99.3,T,110.5,M,9.4,N,17.3,K,A*2D +$GPGGA,222635.000,2734.76418,S,15306.01089,E,1,08,1.1,47.9,M,39.2,M,,*76 +$GPGLL,2734.76418,S,15306.01089,E,222635.000,A,A*49 +$GPGSA,A,3,16,25,23,20,04,13,27,03,,,,,1.7,1.1,1.3*35 +$GPGST,222635.000,13.4,9.3,7.7,66.3,7.3,8.3,14.0*50 +$GPGSV,3,1,10,16,48,116,36,25,39,268,31,23,58,174,37,20,71,337,36*7D +$GPGSV,3,2,10,19,03,029,,04,06,242,31,13,31,223,34,27,19,283,31*7F +$GPGSV,3,3,10,11,06,338,23,03,14,056,23*73 +$GPRMC,222635.000,A,2734.76418,S,15306.01089,E,8.3,116.7,030308,11.2,W,A*37 +$GPVTG,116.7,T,127.9,M,8.3,N,15.4,K,A*14 +$GPGGA,222636.000,2734.76577,S,15306.01258,E,1,07,1.7,47.9,M,39.2,M,,*7A +$GPGLL,2734.76577,S,15306.01258,E,222636.000,A,A*4C +$GPGSA,A,3,16,25,23,20,04,13,27,,,,,,2.8,1.7,2.3*3F +$GPGST,222636.000,10.6,11.9,8.1,45.4,9.3,9.3,18.8*65 +$GPGSV,3,1,10,16,48,116,41,25,39,268,35,23,58,174,40,20,71,337,33*7C +$GPGSV,3,2,10,19,03,029,,04,06,242,32,13,31,223,28,27,19,283,34*74 +$GPGSV,3,3,10,11,06,338,25,03,14,056,23*75 +$GPRMC,222636.000,A,2734.76577,S,15306.01258,E,7.6,135.7,030308,11.2,W,A*39 +$GPVTG,135.7,T,146.9,M,7.6,N,14.1,K,A*1C +$GPGGA,222637.000,2734.76759,S,15306.01422,E,1,07,1.7,47.8,M,39.2,M,,*7F +$GPGLL,2734.76759,S,15306.01422,E,222637.000,A,A*48 +$GPGSA,A,3,16,25,23,20,04,13,27,,,,,,2.8,1.7,2.3*3F +$GPGST,222637.000,8.9,7.2,10.9,44.4,8.4,8.5,17.1*59 +$GPGSV,3,1,10,16,48,116,44,25,39,268,36,23,58,174,33,20,71,337,33*7E +$GPGSV,3,2,10,19,03,029,,04,06,242,24,13,31,223,29,27,19,283,36*70 +$GPGSV,3,3,10,11,06,338,25,03,14,056,23*75 +$GPRMC,222637.000,A,2734.76759,S,15306.01422,E,8.0,140.6,030308,11.2,W,A*37 +$GPVTG,140.6,T,151.8,M,8.0,N,14.8,K,A*18 +$GPGGA,222638.000,2734.76957,S,15306.01592,E,1,06,2.0,47.6,M,39.2,M,,*71 +$GPGLL,2734.76957,S,15306.01592,E,222638.000,A,A*4D +$GPGSA,A,3,16,25,23,20,04,13,,,,,,,3.2,2.0,2.6*30 +$GPGST,222638.000,10.4,8.9,16.3,14.1,8.7,14.6,19.9*51 +$GPGSV,3,1,10,16,48,116,38,25,39,268,30,23,58,174,29,20,71,337,29*73 +$GPGSV,3,2,10,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,29*7B +$GPGSV,3,3,10,11,06,338,21,03,14,056,23*71 +$GPRMC,222638.000,A,2734.76957,S,15306.01592,E,8.8,142.8,030308,11.2,W,A*36 +$GPVTG,142.8,T,154.0,M,8.8,N,16.2,K,A*19 +$GPGGA,222639.000,2734.77109,S,15306.01748,E,1,07,1.7,47.8,M,39.2,M,,*7C +$GPGLL,2734.77109,S,15306.01748,E,222639.000,A,A*4B +$GPGSA,A,3,16,25,23,20,04,13,27,,,,,,2.8,1.7,2.3*3F +$GPGST,222639.000,9.5,9.6,14.7,43.8,11.3,11.5,19.8*51 +$GPGSV,3,1,10,16,48,116,37,25,39,268,32,23,58,174,37,20,71,337,29*71 +$GPGSV,3,2,10,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,27*75 +$GPGSV,3,3,10,11,06,338,21,03,14,056,23*71 +$GPRMC,222639.000,A,2734.77109,S,15306.01748,E,7.1,137.2,030308,11.2,W,A*3E +$GPVTG,137.2,T,148.4,M,7.1,N,13.1,K,A*18 +$GPGGA,222640.000,2734.77216,S,15306.02018,E,1,04,2.6,47.8,M,39.2,M,,*7F +$GPGLL,2734.77216,S,15306.02018,E,222640.000,A,A*49 +$GPGSA,A,3,16,25,23,13,,,,,,,,,6.2,2.6,5.6*32 +$GPGST,222640.000,20.0,11.7,22.3,7.0,10.9,20.3,46.8*65 +$GPGSV,3,1,10,16,48,116,32,25,39,268,29,23,58,174,24,20,71,337,25*70 +$GPGSV,3,2,10,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,25*77 +$GPGSV,3,3,10,11,06,338,21,03,14,056,23*71 +$GPRMC,222640.000,A,2734.77216,S,15306.02018,E,9.4,114.2,030308,11.2,W,A*36 +$GPVTG,114.2,T,125.4,M,9.4,N,17.4,K,A*18 +$GPGGA,222641.000,2734.77543,S,15306.02149,E,1,04,2.6,47.7,M,39.2,M,,*73 +$GPGLL,2734.77543,S,15306.02149,E,222641.000,A,A*4A +$GPGSA,A,3,16,25,23,13,,,,,,,,,6.2,2.6,5.6*32 +$GPGST,222641.000,18.3,40.3,13.2,79.5,13.7,36.3,59.1*5E +$GPGSV,3,1,10,16,48,116,34,25,39,268,23,23,58,174,26,20,71,337,27*7C +$GPGSV,3,2,10,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,23*71 +$GPGSV,3,3,10,11,06,338,21,03,14,056,23*71 +$GPRMC,222641.000,A,2734.77543,S,15306.02149,E,12.5,160.9,030308,11.2,W,A*06 +$GPVTG,160.9,T,172.1,M,12.5,N,23.1,K,A*2E +$GPGGA,222642.000,2734.77709,S,15306.02300,E,1,04,2.6,47.7,M,39.2,M,,*73 +$GPGLL,2734.77709,S,15306.02300,E,222642.000,A,A*4A +$GPGSA,A,3,16,20,04,13,,,,,,,,,4.3,2.6,3.4*35 +$GPGST,222642.000,15.8,14.5,71.8,20.7,26.3,61.6,97.2*58 +$GPGSV,3,1,10,16,48,116,41,25,40,268,23,23,58,174,27,20,71,337,34*73 +$GPGSV,3,2,10,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,23*71 +$GPGSV,3,3,10,11,06,338,21,03,14,056,23*71 +$GPRMC,222642.000,A,2734.77709,S,15306.02300,E,7.5,140.7,030308,11.2,W,A*3E +$GPVTG,140.7,T,151.9,M,7.5,N,13.9,K,A*14 +$GPGGA,222643.000,2734.77831,S,15306.02427,E,1,04,2.6,47.5,M,39.2,M,,*76 +$GPGLL,2734.77831,S,15306.02427,E,222643.000,A,A*4D +$GPGSA,A,3,16,20,04,13,,,,,,,,,4.3,2.6,3.4*35 +$GPGST,222643.000,12.9,15.5,112.8,21.4,39.9,96.1,154.3*5C +$GPGSV,3,1,10,16,48,116,41,25,40,268,23,23,58,174,26,20,71,337,35*73 +$GPGSV,3,2,10,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,23*71 +$GPGSV,3,3,10,11,06,338,21,03,14,056,23*71 +$GPRMC,222643.000,A,2734.77831,S,15306.02427,E,5.6,136.2,030308,11.2,W,A*3C +$GPVTG,136.2,T,147.4,M,5.6,N,10.4,K,A*15 +$GPGGA,222644.000,2734.77900,S,15306.02522,E,1,04,2.5,47.4,M,39.2,M,,*74 +$GPGLL,2734.77900,S,15306.02522,E,222644.000,A,A*4D +$GPGSA,A,3,16,23,20,13,,,,,,,,,5.8,2.5,5.2*39 +$GPGST,222644.000,11.9,32.3,39.9,23.1,35.5,30.7,165.7*69 +$GPGSV,3,1,10,16,48,116,38,25,40,268,23,23,58,174,25,20,71,337,37*7C +$GPGSV,3,2,10,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,23*71 +$GPGSV,3,3,10,11,06,338,21,03,14,056,26*74 +$GPRMC,222644.000,A,2734.77900,S,15306.02522,E,3.7,127.8,030308,11.2,W,A*31 +$GPVTG,127.8,T,139.0,M,3.7,N,6.9,K,A*2F +$GPGGA,222645.000,2734.77991,S,15306.02594,E,1,04,3.4,47.4,M,39.2,M,,*70 +$GPGLL,2734.77991,S,15306.02594,E,222645.000,A,A*49 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.4,5.0*30 +$GPGST,222645.000,15.3,40.1,15.0,66.6,34.1,19.2,69.1*50 +$GPGSV,3,1,10,16,48,116,33,25,40,268,23,23,58,174,23,20,71,337,35*73 +$GPGSV,3,2,10,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,23*71 +$GPGSV,3,3,10,11,06,338,21,03,14,056,30*73 +$GPRMC,222645.000,A,2734.77991,S,15306.02594,E,3.9,145.4,030308,11.2,W,A*33 +$GPVTG,145.4,T,156.6,M,3.9,N,7.2,K,A*2C +$GPGGA,222646.000,2734.78074,S,15306.02652,E,1,04,3.4,47.4,M,39.2,M,,*77 +$GPGLL,2734.78074,S,15306.02652,E,222646.000,A,A*4E +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.4,5.0*30 +$GPGST,222646.000,14.8,53.5,15.6,78.9,48.1,16.9,76.9*50 +$GPGSV,3,1,11,16,48,116,32,25,40,268,23,23,58,174,26,20,71,337,32*71 +$GPGSV,3,2,11,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,23*70 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,34*4D +$GPRMC,222646.000,A,2734.78074,S,15306.02652,E,3.5,149.5,030308,11.2,W,A*35 +$GPVTG,149.5,T,160.7,M,3.5,N,6.6,K,A*2C +$GPGGA,222647.000,2734.78140,S,15306.02704,E,1,04,3.4,47.3,M,39.2,M,,*75 +$GPGLL,2734.78140,S,15306.02704,E,222647.000,A,A*4B +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.4,5.0*30 +$GPGST,222647.000,11.7,42.4,13.1,77.7,38.0,14.3,60.9*53 +$GPGSV,3,1,11,16,48,116,37,25,40,268,23,23,58,174,31,20,71,337,36*76 +$GPGSV,3,2,11,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,23*70 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,34*4D +$GPRMC,222647.000,A,2734.78140,S,15306.02704,E,2.8,145.4,030308,11.2,W,A*31 +$GPVTG,145.4,T,156.6,M,2.8,N,5.1,K,A*2D +$GPGGA,222648.000,2734.78183,S,15306.02753,E,1,04,3.5,47.2,M,39.2,M,,*77 +$GPGLL,2734.78183,S,15306.02753,E,222648.000,A,A*49 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222648.000,11.3,35.2,16.9,76.3,31.5,16.9,53.8*53 +$GPGSV,3,1,11,16,48,116,35,25,40,267,23,23,58,174,37,20,71,337,35*7E +$GPGSV,3,2,11,19,03,029,,04,06,242,28,13,31,223,31,27,19,283,23*70 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,35*4C +$GPRMC,222648.000,A,2734.78183,S,15306.02753,E,2.1,135.8,030308,11.2,W,A*31 +$GPVTG,135.8,T,147.1,M,2.1,N,3.9,K,A*26 +$GPGGA,222649.000,2734.78197,S,15306.02773,E,1,04,3.5,46.8,M,39.2,M,,*7A +$GPGLL,2734.78197,S,15306.02773,E,222649.000,A,A*4F +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222649.000,13.9,60.8,14.8,84.0,55.3,14.7,79.7*52 +$GPGSV,3,1,11,16,48,116,31,25,40,267,23,23,58,174,36,20,71,337,31*7F +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,19,283,23*78 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,29*41 +$GPRMC,222649.000,A,2734.78197,S,15306.02773,E,0.6,148.6,030308,11.2,W,A*36 +$GPVTG,148.6,T,159.8,M,0.6,N,1.2,K,A*28 +$GPGGA,222650.000,2734.78195,S,15306.02785,E,1,04,3.5,46.4,M,39.2,M,,*75 +$GPGLL,2734.78195,S,15306.02785,E,222650.000,A,A*4C +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222650.000,11.4,48.0,12.9,83.3,43.6,12.8,63.8*5B +$GPGSV,3,1,11,16,48,116,30,25,40,267,23,23,58,174,33,20,71,337,30*7A +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,19,283,23*78 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,26*4E +$GPRMC,222650.000,A,2734.78195,S,15306.02785,E,0.2,6.4,030308,11.2,W,A*38 +$GPVTG,6.4,T,17.6,M,0.2,N,0.3,K,A*10 +$GPGGA,222651.000,2734.78191,S,15306.02798,E,1,04,3.5,45.9,M,39.2,M,,*72 +$GPGLL,2734.78191,S,15306.02798,E,222651.000,A,A*45 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222651.000,9.8,40.0,12.0,82.4,36.3,11.9,53.8*6E +$GPGSV,3,1,11,16,48,116,28,25,40,267,,23,58,174,35,20,71,337,26*73 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,19,283,*79 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,28*40 +$GPRMC,222651.000,A,2734.78191,S,15306.02798,E,0.1,352.6,030308,11.2,W,A*32 +$GPVTG,352.6,T,3.8,M,0.1,N,0.3,K,A*28 +$GPGGA,222652.000,2734.78198,S,15306.02797,E,1,04,3.5,45.9,M,39.2,M,,*77 +$GPGLL,2734.78198,S,15306.02797,E,222652.000,A,A*40 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222652.000,21.7,41.2,15.0,83.8,37.5,14.2,91.6*58 +$GPGSV,3,1,11,16,48,116,24,25,40,267,,23,58,174,23,20,71,337,26*78 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,19,283,*79 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,24*4C +$GPRMC,222652.000,A,2734.78198,S,15306.02797,E,0.2,263.5,030308,11.2,W,A*34 +$GPVTG,263.5,T,274.7,M,0.2,N,0.3,K,A*26 +$GPGGA,222653.000,2734.78226,S,15306.02793,E,1,04,3.5,45.9,M,39.2,M,,*74 +$GPGLL,2734.78226,S,15306.02793,E,222653.000,A,A*43 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222653.000,18.8,36.4,20.7,81.4,33.0,19.3,78.6*5F +$GPGSV,3,1,11,16,48,116,24,25,40,267,,23,58,174,25,20,71,337,25*7D +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,24*4C +$GPRMC,222653.000,A,2734.78226,S,15306.02793,E,0.8,188.1,030308,11.2,W,A*3F +$GPVTG,188.1,T,199.3,M,0.8,N,1.5,K,A*2D +$GPGGA,222654.000,2734.78231,S,15306.02789,E,1,04,3.5,45.9,M,39.2,M,,*7E +$GPGLL,2734.78231,S,15306.02789,E,222654.000,A,A*49 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222654.000,14.4,23.3,16.5,69.8,20.7,16.0,57.9*5D +$GPGSV,3,1,11,16,48,116,34,25,40,267,,23,58,174,34,20,71,337,31*79 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,31*48 +$GPRMC,222654.000,A,2734.78231,S,15306.02789,E,0.1,145.6,030308,11.2,W,A*3A +$GPVTG,145.6,T,156.8,M,0.1,N,0.2,K,A*2C +$GPGGA,222655.000,2734.78251,S,15306.02806,E,1,04,3.5,45.8,M,39.2,M,,*70 +$GPGLL,2734.78251,S,15306.02806,E,222655.000,A,A*46 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222655.000,12.0,28.1,14.0,78.7,25.3,13.6,52.5*54 +$GPGSV,3,1,11,16,48,116,40,25,40,267,,23,58,174,38,20,71,337,35*72 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,36*4F +$GPRMC,222655.000,A,2734.78251,S,15306.02806,E,0.7,135.5,030308,11.2,W,A*37 +$GPVTG,135.5,T,146.8,M,0.7,N,1.2,K,A*2E +$GPGGA,222656.000,2734.78273,S,15306.02823,E,1,04,3.5,45.7,M,39.2,M,,*7B +$GPGLL,2734.78273,S,15306.02823,E,222656.000,A,A*42 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222656.000,9.9,24.8,12.2,76.6,22.2,12.0,44.0*69 +$GPGSV,3,1,11,16,48,116,38,25,40,267,,23,58,174,36,20,71,337,30*76 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,35*4C +$GPRMC,222656.000,A,2734.78273,S,15306.02823,E,0.5,135.5,030308,11.2,W,A*31 +$GPVTG,135.5,T,146.7,M,0.5,N,1.0,K,A*21 +$GPGGA,222657.000,2734.78312,S,15306.02858,E,1,04,3.5,45.5,M,39.2,M,,*72 +$GPGLL,2734.78312,S,15306.02858,E,222657.000,A,A*49 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222657.000,8.4,22.4,10.9,74.9,19.9,11.0,38.1*60 +$GPGSV,3,1,11,16,48,116,37,25,40,267,,23,58,174,36,20,71,337,30*79 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,21,08,00,298,,03,14,056,34*4D +$GPRMC,222657.000,A,2734.78312,S,15306.02858,E,1.3,137.6,030308,11.2,W,A*3C +$GPVTG,137.6,T,148.8,M,1.3,N,2.4,K,A*21 +$GPGGA,222658.000,2734.78370,S,15306.02910,E,1,04,3.5,45.4,M,39.2,M,,*75 +$GPGLL,2734.78370,S,15306.02910,E,222658.000,A,A*4F +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222658.000,11.5,25.4,19.7,45.8,20.9,20.7,46.1*53 +$GPGSV,3,1,11,16,48,116,34,25,40,267,18,23,58,174,36,20,71,337,32*71 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,32*48 +$GPRMC,222658.000,A,2734.78370,S,15306.02910,E,2.7,141.8,030308,11.2,W,A*32 +$GPVTG,141.8,T,153.0,M,2.7,N,5.0,K,A*28 +$GPGGA,222659.000,2734.78463,S,15306.02956,E,1,04,3.5,45.4,M,39.2,M,,*73 +$GPGLL,2734.78463,S,15306.02956,E,222659.000,A,A*49 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222659.000,10.9,34.8,17.8,79.2,31.4,17.1,52.2*5E +$GPGSV,3,1,11,16,48,116,32,25,40,267,18,23,58,174,37,20,71,337,32*76 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,26*4D +$GPRMC,222659.000,A,2734.78463,S,15306.02956,E,3.6,157.2,030308,11.2,W,A*39 +$GPVTG,157.2,T,168.4,M,3.6,N,6.7,K,A*2D +$GPGGA,222700.000,2734.78553,S,15306.02974,E,1,04,3.5,45.3,M,39.2,M,,*7B +$GPGLL,2734.78553,S,15306.02974,E,222700.000,A,A*46 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222700.000,13.4,30.5,15.4,80.9,27.6,14.6,58.2*5C +$GPGSV,3,1,11,16,48,116,38,25,40,267,18,23,58,174,42,20,71,337,34*78 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,30*4A +$GPRMC,222700.000,A,2734.78553,S,15306.02974,E,3.1,171.1,030308,11.2,W,A*36 +$GPVTG,171.1,T,182.3,M,3.1,N,5.7,K,A*2D +$GPGGA,222701.000,2734.78678,S,15306.02887,E,1,05,1.6,45.4,M,39.2,M,,*7A +$GPGLL,2734.78678,S,15306.02887,E,222701.000,A,A*40 +$GPGSA,A,3,16,23,20,13,03,,,,,,,,2.5,1.6,1.9*3F +$GPGST,222701.000,18.6,22.3,33.4,25.2,29.0,22.6,46.2*53 +$GPGSV,3,1,11,16,48,116,30,25,40,267,18,23,58,174,33,20,71,337,27*74 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,20,27,20,283,*71 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,27*4C +$GPRMC,222701.000,A,2734.78678,S,15306.02887,E,5.1,212.6,030308,11.2,W,A*37 +$GPVTG,212.6,T,223.8,M,5.1,N,9.5,K,A*27 +$GPGGA,222702.000,2734.78726,S,15306.02769,E,1,04,3.5,45.3,M,39.2,M,,*7B +$GPGLL,2734.78726,S,15306.02769,E,222702.000,A,A*46 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.0*31 +$GPGST,222702.000,14.7,49.5,20.8,84.3,45.1,19.5,72.8*5F +$GPGSV,3,1,11,16,48,116,36,25,40,267,18,23,58,174,40,20,71,337,31*71 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,20,27,20,283,*71 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,28*43 +$GPRMC,222702.000,A,2734.78726,S,15306.02769,E,4.2,246.4,030308,11.2,W,A*30 +$GPVTG,246.4,T,257.6,M,4.2,N,7.7,K,A*27 +$GPGGA,222703.000,2734.78745,S,15306.02617,E,1,05,1.6,45.3,M,39.2,M,,*77 +$GPGLL,2734.78745,S,15306.02617,E,222703.000,A,A*4A +$GPGSA,A,3,16,23,20,13,03,,,,,,,,2.5,1.6,1.9*3F +$GPGST,222703.000,12.3,16.0,23.0,21.5,20.3,15.6,33.1*53 +$GPGSV,3,1,11,16,48,116,31,25,40,267,18,23,58,174,29,20,70,337,23*7B +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,22,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,27*4C +$GPRMC,222703.000,A,2734.78745,S,15306.02617,E,4.9,265.5,030308,11.2,W,A*37 +$GPVTG,265.5,T,276.7,M,4.9,N,9.1,K,A*26 +$GPGGA,222704.000,2734.78730,S,15306.02555,E,1,04,3.5,45.3,M,39.2,M,,*77 +$GPGLL,2734.78730,S,15306.02555,E,222704.000,A,A*4A +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.1*30 +$GPGST,222704.000,9.5,34.0,22.1,80.5,30.8,20.6,55.7*69 +$GPGSV,3,1,11,16,48,116,31,25,40,267,18,23,58,174,29,20,70,337,23*7B +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,22,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,31*4B +$GPRMC,222704.000,A,2734.78730,S,15306.02555,E,2.1,286.5,030308,11.2,W,A*34 +$GPVTG,286.5,T,297.7,M,2.1,N,3.9,K,A*28 +$GPGGA,222705.000,2734.78698,S,15306.02452,E,1,04,3.5,45.3,M,39.2,M,,*73 +$GPGLL,2734.78698,S,15306.02452,E,222705.000,A,A*4E +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.1*30 +$GPGST,222705.000,93.8,65.1,31.9,84.0,59.3,29.7,94.1*5F +$GPGSV,3,1,11,16,48,116,29,25,40,267,18,23,58,174,29,20,70,337,23*72 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,22,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,30*4A +$GPRMC,222705.000,A,2734.78698,S,15306.02452,E,3.6,290.3,030308,11.2,W,A*37 +$GPVTG,290.3,T,301.5,M,3.6,N,6.8,K,A*27 +$GPGGA,222706.000,2734.78686,S,15306.02339,E,1,04,3.5,45.3,M,39.2,M,,*75 +$GPGLL,2734.78686,S,15306.02339,E,222706.000,A,A*48 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.1*30 +$GPGST,222706.000,114.3,62.0,48.3,70.3,55.4,45.7,116.3*5B +$GPGSV,3,1,11,16,48,116,24,25,40,267,18,23,58,174,29,20,70,337,23*7F +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,22,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,24*4F +$GPRMC,222706.000,A,2734.78686,S,15306.02339,E,3.4,277.7,030308,11.2,W,A*3E +$GPVTG,277.7,T,288.9,M,3.4,N,6.3,K,A*2F +$GPGGA,222707.000,2734.78679,S,15306.02251,E,1,04,3.5,45.3,M,39.2,M,,*7B +$GPGLL,2734.78679,S,15306.02251,E,222707.000,A,A*46 +$GPGSA,A,3,16,23,20,03,,,,,,,,,6.1,3.5,5.1*30 +$GPGST,222707.000,128.0,90.0,67.0,53.0,75.4,69.6,158.6*55 +$GPGSV,3,1,11,16,48,116,24,25,40,267,18,23,58,174,29,20,70,337,23*7F +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,223,22,27,20,283,*73 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,24*4F +$GPRMC,222707.000,A,2734.78679,S,15306.02251,E,,,030308,,,A*79 +$GPVTG,,T,,M,,N,,K,N*2C +$GPGGA,222708.000,2734.78673,S,15306.02181,E,1,05,1.6,45.3,M,39.2,M,,*70 +$GPGLL,2734.78673,S,15306.02181,E,222708.000,A,A*4D +$GPGSA,A,3,16,23,20,13,03,,,,,,,,2.5,1.6,1.9*3F +$GPGST,222708.000,66.8,93.0,70.5,62.6,69.3,81.1,141.7*6F +$GPGSV,3,1,11,16,48,116,24,25,40,267,,23,58,174,29,20,70,337,23*76 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,222,22,27,20,283,*72 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,24*4F +$GPRMC,222708.000,A,2734.78673,S,15306.02181,E,,,030308,,,A*72 +$GPVTG,,T,,M,,N,,K,N*2C +$GPGGA,222709.000,2734.78668,S,15306.02124,E,1,05,1.6,45.3,M,39.2,M,,*74 +$GPGLL,2734.78668,S,15306.02124,E,222709.000,A,A*49 +$GPGSA,A,2,16,23,20,13,03,,,,,,,,1.8,1.6,0.9*31 +$GPGST,222709.000,89.5,61.2,117.7,37.9,91.7,79.5,4.3*54 +$GPGSV,3,1,11,16,48,116,24,25,40,267,,23,58,174,29,20,70,337,23*76 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,222,22,27,20,283,*72 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,24*4F +$GPRMC,222709.000,A,2734.78668,S,15306.02124,E,,,030308,,,A*76 +$GPVTG,,T,,M,,N,,K,N*2C +$GPGGA,222710.000,2734.78664,S,15306.02080,E,1,05,1.6,45.3,M,39.2,M,,*7F +$GPGLL,2734.78664,S,15306.02080,E,222710.000,A,A*42 +$GPGSA,A,2,16,23,20,13,03,,,,,,,,1.8,1.6,0.9*31 +$GPGST,222710.000,117.0,82.3,157.6,39.0,121.7,107.9,3.9*62 +$GPGSV,3,1,11,16,48,116,24,25,40,267,,23,58,174,29,20,70,337,23*76 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,222,22,27,20,283,*72 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,24*4F +$GPRMC,222710.000,A,2734.78664,S,15306.02080,E,,,030308,,,A*7D +$GPVTG,,T,,M,,N,,K,N*2C +$GPGGA,222711.000,2734.78660,S,15306.02044,E,1,05,1.6,45.3,M,39.2,M,,*72 +$GPGLL,2734.78660,S,15306.02044,E,222711.000,A,A*4F +$GPGSA,A,2,16,23,20,13,03,,,,,,,,1.8,1.6,0.9*31 +$GPGST,222711.000,128.0,107.6,205.2,40.2,156.7,142.6,3.5*58 +$GPGSV,3,1,11,16,48,116,24,25,40,267,,23,58,174,29,20,70,337,23*76 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,222,22,27,20,283,*72 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,24*4F +$GPRMC,222711.000,A,2734.78660,S,15306.02044,E,,,030308,,,A*70 +$GPVTG,,T,,M,,N,,K,N*2C +$GPGGA,222712.000,2734.78658,S,15306.02015,E,1,05,1.6,45.3,M,39.2,M,,*7E +$GPGLL,2734.78658,S,15306.02015,E,222712.000,A,A*43 +$GPGSA,A,2,16,23,20,13,03,,,,,,,,1.8,1.6,0.9*31 +$GPGST,222712.000,128.0,137.2,261.1,41.4,197.4,183.9,3.2*51 +$GPGSV,3,1,11,16,48,116,24,25,40,267,,23,58,173,29,20,70,337,23*71 +$GPGSV,3,2,11,19,03,029,,04,06,242,,13,31,222,22,27,20,283,*72 +$GPGSV,3,3,11,11,06,338,,08,00,298,,03,14,056,24*4F +$GPRMC,222712.000,A,2734.78658,S,15306.02015,E,,,030308,,,A*7C \ No newline at end of file diff --git a/examples/positioning/geoflickr/geoflickr.pro b/examples/positioning/geoflickr/geoflickr.pro new file mode 100644 index 0000000..4bbb795 --- /dev/null +++ b/examples/positioning/geoflickr/geoflickr.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +TARGET = geoflickr + +QT += qml quick network positioning +SOURCES += qmllocationflickr.cpp + +RESOURCES += \ + flickr.qrc + +OTHER_FILES += flickr.qml \ + flickrcommon/* \ + flickrmobile/* + +target.path = $$[QT_INSTALL_EXAMPLES]/positioning/geoflickr +INSTALLS += target diff --git a/examples/positioning/geoflickr/geoflickr.qmlproject b/examples/positioning/geoflickr/geoflickr.qmlproject new file mode 100644 index 0000000..d4909f8 --- /dev/null +++ b/examples/positioning/geoflickr/geoflickr.qmlproject @@ -0,0 +1,16 @@ +import QmlProject 1.0 + +Project { + /* Include .qml, .js, and image files from current directory and subdirectories */ + QmlFiles { + directory: "." + } + JavaScriptFiles { + directory: "." + } + ImageFiles { + directory: "." + } + /* List of plugin directories passed to QML runtime */ + // importPaths: [ " ../exampleplugin " ] +} diff --git a/examples/positioning/geoflickr/qmllocationflickr.cpp b/examples/positioning/geoflickr/qmllocationflickr.cpp new file mode 100644 index 0000000..a32084c --- /dev/null +++ b/examples/positioning/geoflickr/qmllocationflickr.cpp @@ -0,0 +1,21 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication application(argc, argv); + const QString mainQmlApp = QStringLiteral("qrc:///flickr.qml"); + QQuickView view; + view.setSource(QUrl(mainQmlApp)); + view.setResizeMode(QQuickView::SizeRootObjectToView); + // Qt.quit() called in embedded .qml by default only emits + // quit() signal, so do this (optionally use Qt.exit()). + QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit())); + view.setGeometry(QRect(100, 100, 360, 640)); + view.show(); + return application.exec(); +} diff --git a/examples/positioning/logfilepositionsource/CMakeLists.txt b/examples/positioning/logfilepositionsource/CMakeLists.txt new file mode 100644 index 0000000..277a609 --- /dev/null +++ b/examples/positioning/logfilepositionsource/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.16) +project(logfilepositionsource LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/positioning/logfilepositionsource") + +find_package(Qt6 REQUIRED COMPONENTS Core Positioning Widgets) + +qt_add_executable(logfilepositionsource + clientapplication.cpp clientapplication.h + logfilepositionsource.cpp logfilepositionsource.h + main.cpp +) + +set_target_properties(logfilepositionsource PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(logfilepositionsource PRIVATE + Qt::Core + Qt::Positioning + Qt::Widgets +) + +# Resources: +set(logfile_resource_files + "simplelog.txt" +) + +qt6_add_resources(logfilepositionsource "logfile" + PREFIX + "/" + FILES + ${logfile_resource_files} +) + +install(TARGETS logfilepositionsource + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/positioning/logfilepositionsource/clientapplication.cpp b/examples/positioning/logfilepositionsource/clientapplication.cpp new file mode 100644 index 0000000..5296011 --- /dev/null +++ b/examples/positioning/logfilepositionsource/clientapplication.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#include +#include + +#include "logfilepositionsource.h" +#include "clientapplication.h" + +ClientApplication::ClientApplication(QWidget *parent) + : QMainWindow(parent) +{ + textEdit = new QTextEdit; + setCentralWidget(textEdit); + + LogFilePositionSource *source = new LogFilePositionSource(this); + connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), + this, SLOT(positionUpdated(QGeoPositionInfo))); + + source->startUpdates(); +} + +void ClientApplication::positionUpdated(const QGeoPositionInfo &info) +{ + textEdit->append(QString("Position updated: Date/time = %1, Coordinate = %2").arg(info.timestamp().toString()).arg(info.coordinate().toString())); +} diff --git a/examples/positioning/logfilepositionsource/clientapplication.h b/examples/positioning/logfilepositionsource/clientapplication.h new file mode 100644 index 0000000..6bf0b4f --- /dev/null +++ b/examples/positioning/logfilepositionsource/clientapplication.h @@ -0,0 +1,27 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#ifndef CLIENTAPPLICATION_H +#define CLIENTAPPLICATION_H + +#include + +QT_BEGIN_NAMESPACE +class QGeoPositionInfo; +class QTextEdit; +QT_END_NAMESPACE + +class ClientApplication : public QMainWindow +{ + Q_OBJECT +public: + ClientApplication(QWidget *parent = 0); + +private slots: + void positionUpdated(const QGeoPositionInfo &info); + +private: + QTextEdit *textEdit; +}; + + +#endif diff --git a/examples/positioning/logfilepositionsource/doc/src/logfilepositionsource.qdoc b/examples/positioning/logfilepositionsource/doc/src/logfilepositionsource.qdoc new file mode 100644 index 0000000..4decaa5 --- /dev/null +++ b/examples/positioning/logfilepositionsource/doc/src/logfilepositionsource.qdoc @@ -0,0 +1,70 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\example logfilepositionsource +\title Log File Position Source (C++) +\ingroup qtpositioning-examples + +\brief Logfile Position Source shows how to create and work with a custom + position source. It can be useful for simulating GPS data, or when the + data is received in some custom format. + +\include examples-run.qdocinc + +\section1 Creating custom Position Source + +In this example, the data is read from a text file, \e simplelog.txt. The file +specifies position data using a simple text format: it contains one position +update per line, where each line contains a date/time, a latitude and a +longitude, separated by spaces. The date/time is in ISO 8601 format and the +latitude and longitude are in degrees decimal format. +Here is an excerpt from \e simplelog.txt: + +\code +2009-08-24T22:25:01 -27.576082 153.092415 +2009-08-24T22:25:02 -27.576223 153.092530 +2009-08-24T22:25:03 -27.576364 153.092648 +\endcode + +We create a custom \c LogFilePositionSource class, which derives from +\l QGeoPositionInfoSource. It reads position data from the file and distributes +it via the \l {QGeoPositionInfoSource::}{positionUpdated()} signal. + +The resulting time and position information is then displayed on the screen as +simple text in date/time and latitude/longitude format. + +Here is the definition of the \c LogFilePositionSource class: + +\quotefromfile logfilepositionsource/logfilepositionsource.h +\skipto class LogFilePositionSource +\printuntil }; + +The main methods overrided by the subclass are: + +\list + \li \l{QGeoPositionInfoSource::startUpdates()}{startUpdates()}: called by client applications + to start regular position updates. + \li \l{QGeoPositionInfoSource::stopUpdates()}{stopUpdates()}: called by client applications to + stop regular position updates. + \li \l{QGeoPositionInfoSource::requestUpdate()}{requestUpdate()}: called by client applications + to request a single update, with a specified timeout. +\endlist + +When a position update is available, the subclass emits the +\l{QGeoPositionInfoSource::positionUpdated()}{positionUpdated()} signal. + +Here are the key methods in the class implementation: + +\quotefromfile logfilepositionsource/logfilepositionsource.cpp +\skipto LogFilePositionSource::LogFilePositionSource +\printuntil /^\}/ +\skipto LogFilePositionSource::startUpdates +\printuntil /^\}/ +\skipto LogFilePositionSource::stopUpdates +\printuntil /^\}/ +\skipto LogFilePositionSource::requestUpdate +\printuntil /^\}/ +\printuntil LogFilePositionSource::readNextPosition +\printuntil /^\}/ +*/ diff --git a/examples/positioning/logfilepositionsource/logfile.qrc b/examples/positioning/logfilepositionsource/logfile.qrc new file mode 100644 index 0000000..6121394 --- /dev/null +++ b/examples/positioning/logfilepositionsource/logfile.qrc @@ -0,0 +1,5 @@ + + + simplelog.txt + + diff --git a/examples/positioning/logfilepositionsource/logfilepositionsource.cpp b/examples/positioning/logfilepositionsource/logfilepositionsource.cpp new file mode 100644 index 0000000..c84a639 --- /dev/null +++ b/examples/positioning/logfilepositionsource/logfilepositionsource.cpp @@ -0,0 +1,89 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#include + +#include "logfilepositionsource.h" + +LogFilePositionSource::LogFilePositionSource(QObject *parent) + : QGeoPositionInfoSource(parent), + logFile(new QFile(this)), + timer(new QTimer(this)) +{ + connect(timer, SIGNAL(timeout()), this, SLOT(readNextPosition())); + + logFile->setFileName(":/simplelog.txt"); + if (!logFile->open(QIODevice::ReadOnly)) + qWarning() << "Error: cannot open source file" << logFile->fileName(); +} + +QGeoPositionInfo LogFilePositionSource::lastKnownPosition(bool /*fromSatellitePositioningMethodsOnly*/) const +{ + return lastPosition; +} + +LogFilePositionSource::PositioningMethods LogFilePositionSource::supportedPositioningMethods() const +{ + return AllPositioningMethods; +} + +int LogFilePositionSource::minimumUpdateInterval() const +{ + return 500; +} + +void LogFilePositionSource::startUpdates() +{ + lastError = QGeoPositionInfoSource::NoError; + int interval = updateInterval(); + if (interval < minimumUpdateInterval()) + interval = minimumUpdateInterval(); + + timer->start(interval); +} + +void LogFilePositionSource::stopUpdates() +{ + timer->stop(); +} + +void LogFilePositionSource::requestUpdate(int /*timeout*/) +{ + // For simplicity, ignore timeout - assume that if data is not available + // now, no data will be added to the file later + lastError = QGeoPositionInfoSource::NoError; + if (logFile->canReadLine()) { + readNextPosition(); + } else { + lastError = QGeoPositionInfoSource::UpdateTimeoutError; + emit QGeoPositionInfoSource::errorOccurred(lastError); + } +} + +void LogFilePositionSource::readNextPosition() +{ + QByteArray line = logFile->readLine().trimmed(); + if (!line.isEmpty()) { + QList data = line.split(' '); + double latitude; + double longitude; + bool hasLatitude = false; + bool hasLongitude = false; + QDateTime timestamp = QDateTime::fromString(QString(data.value(0)), Qt::ISODate); + latitude = data.value(1).toDouble(&hasLatitude); + longitude = data.value(2).toDouble(&hasLongitude); + + if (hasLatitude && hasLongitude && timestamp.isValid()) { + QGeoCoordinate coordinate(latitude, longitude); + QGeoPositionInfo info(coordinate, timestamp); + if (info.isValid()) { + lastPosition = info; + emit positionUpdated(info); + } + } + } +} + +QGeoPositionInfoSource::Error LogFilePositionSource::error() const +{ + return lastError; +} diff --git a/examples/positioning/logfilepositionsource/logfilepositionsource.h b/examples/positioning/logfilepositionsource/logfilepositionsource.h new file mode 100644 index 0000000..e3db1e2 --- /dev/null +++ b/examples/positioning/logfilepositionsource/logfilepositionsource.h @@ -0,0 +1,41 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#ifndef LOGFILEPOSITIONSOURCE_H +#define LOGFILEPOSITIONSOURCE_H + +#include + +QT_BEGIN_NAMESPACE +class QFile; +class QTimer; +QT_END_NAMESPACE + +class LogFilePositionSource : public QGeoPositionInfoSource +{ + Q_OBJECT +public: + LogFilePositionSource(QObject *parent = 0); + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override; + + PositioningMethods supportedPositioningMethods() const override; + int minimumUpdateInterval() const override; + Error error() const override; + +public slots: + virtual void startUpdates() override; + virtual void stopUpdates() override; + + virtual void requestUpdate(int timeout = 5000) override; + +private slots: + void readNextPosition(); + +private: + QFile *logFile; + QTimer *timer; + QGeoPositionInfo lastPosition; + Error lastError = QGeoPositionInfoSource::NoError; +}; + +#endif diff --git a/examples/positioning/logfilepositionsource/logfilepositionsource.pro b/examples/positioning/logfilepositionsource/logfilepositionsource.pro new file mode 100644 index 0000000..cb9e30a --- /dev/null +++ b/examples/positioning/logfilepositionsource/logfilepositionsource.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = logfilepositionsource +QT = positioning core widgets + + +HEADERS = logfilepositionsource.h \ + clientapplication.h +SOURCES = logfilepositionsource.cpp \ + clientapplication.cpp \ + main.cpp + +RESOURCES += \ + logfile.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/positioning/logfilepositionsource +INSTALLS += target diff --git a/examples/positioning/logfilepositionsource/main.cpp b/examples/positioning/logfilepositionsource/main.cpp new file mode 100644 index 0000000..17e08cb --- /dev/null +++ b/examples/positioning/logfilepositionsource/main.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#include + +#include "clientapplication.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + ClientApplication client; + client.show(); + + return app.exec(); +} diff --git a/examples/positioning/logfilepositionsource/simplelog.txt b/examples/positioning/logfilepositionsource/simplelog.txt new file mode 100644 index 0000000..d016b2a --- /dev/null +++ b/examples/positioning/logfilepositionsource/simplelog.txt @@ -0,0 +1,156 @@ +2009-08-24T22:24:37 -27.572321 153.090718 +2009-08-24T22:24:38 -27.572470 153.090783 +2009-08-24T22:24:39 -27.572616 153.090845 +2009-08-24T22:24:40 -27.572763 153.090908 +2009-08-24T22:24:41 -27.572914 153.090971 +2009-08-24T22:24:42 -27.573068 153.091036 +2009-08-24T22:24:43 -27.573224 153.091102 +2009-08-24T22:24:44 -27.573383 153.091167 +2009-08-24T22:24:45 -27.573541 153.091232 +2009-08-24T22:24:46 -27.573700 153.091298 +2009-08-24T22:24:47 -27.573860 153.091366 +2009-08-24T22:24:48 -27.574019 153.091435 +2009-08-24T22:24:49 -27.574178 153.091507 +2009-08-24T22:24:50 -27.574340 153.091581 +2009-08-24T22:24:51 -27.574506 153.091654 +2009-08-24T22:24:52 -27.574670 153.091729 +2009-08-24T22:24:53 -27.574836 153.091800 +2009-08-24T22:24:54 -27.575001 153.091870 +2009-08-24T22:24:55 -27.575165 153.091940 +2009-08-24T22:24:56 -27.575327 153.092010 +2009-08-24T22:24:57 -27.575485 153.092078 +2009-08-24T22:24:58 -27.575641 153.092144 +2009-08-24T22:24:59 -27.575795 153.092218 +2009-08-24T22:25:00 -27.575942 153.092308 +2009-08-24T22:25:01 -27.576082 153.092415 +2009-08-24T22:25:02 -27.576223 153.092530 +2009-08-24T22:25:03 -27.576364 153.092648 +2009-08-24T22:25:04 -27.576505 153.092763 +2009-08-24T22:25:05 -27.576646 153.092879 +2009-08-24T22:25:06 -27.576784 153.092990 +2009-08-24T22:25:07 -27.576918 153.093099 +2009-08-24T22:25:08 -27.577046 153.093204 +2009-08-24T22:25:09 -27.577168 153.093303 +2009-08-24T22:25:10 -27.577284 153.093396 +2009-08-24T22:25:11 -27.577396 153.093484 +2009-08-24T22:25:12 -27.577499 153.093568 +2009-08-24T22:25:13 -27.577595 153.093647 +2009-08-24T22:25:14 -27.577692 153.093727 +2009-08-24T22:25:15 -27.577793 153.093810 +2009-08-24T22:25:16 -27.577897 153.093896 +2009-08-24T22:25:17 -27.578006 153.093984 +2009-08-24T22:25:18 -27.578120 153.094074 +2009-08-24T22:25:19 -27.578237 153.094168 +2009-08-24T22:25:20 -27.578360 153.094267 +2009-08-24T22:25:21 -27.578487 153.094370 +2009-08-24T22:25:22 -27.578617 153.094474 +2009-08-24T22:25:23 -27.578748 153.094581 +2009-08-24T22:25:24 -27.578880 153.094688 +2009-08-24T22:25:25 -27.579014 153.094796 +2009-08-24T22:25:26 -27.579149 153.094905 +2009-08-24T22:25:27 -27.579285 153.095012 +2009-08-24T22:25:28 -27.579420 153.095121 +2009-08-24T22:25:29 -27.579552 153.095231 +2009-08-24T22:25:30 -27.579684 153.095340 +2009-08-24T22:25:31 -27.579820 153.095449 +2009-08-24T22:25:32 -27.579956 153.095558 +2009-08-24T22:25:33 -27.580095 153.095667 +2009-08-24T22:25:34 -27.580240 153.095776 +2009-08-24T22:25:35 -27.580392 153.095885 +2009-08-24T22:25:36 -27.580536 153.095995 +2009-08-24T22:25:37 -27.580679 153.096109 +2009-08-24T22:25:38 -27.580824 153.096226 +2009-08-24T22:25:39 -27.580965 153.096337 +2009-08-24T22:25:40 -27.581101 153.096441 +2009-08-24T22:25:41 -27.581237 153.096537 +2009-08-24T22:25:42 -27.581356 153.096628 +2009-08-24T22:25:43 -27.581466 153.096714 +2009-08-24T22:25:44 -27.581555 153.096795 +2009-08-24T22:25:45 -27.581606 153.096847 +2009-08-24T22:25:46 -27.581539 153.096855 +2009-08-24T22:25:47 -27.581572 153.096873 +2009-08-24T22:25:48 -27.581579 153.096875 +2009-08-24T22:25:49 -27.581582 153.096878 +2009-08-24T22:25:50 -27.581588 153.096880 +2009-08-24T22:25:51 -27.581588 153.096880 +2009-08-24T22:25:52 -27.581592 153.096881 +2009-08-24T22:25:53 -27.581596 153.096882 +2009-08-24T22:25:54 -27.581599 153.096883 +2009-08-24T22:25:55 -27.581601 153.096883 +2009-08-24T22:25:56 -27.581602 153.096883 +2009-08-24T22:25:57 -27.581606 153.096890 +2009-08-24T22:25:58 -27.581606 153.096919 +2009-08-24T22:25:59 -27.581605 153.096985 +2009-08-24T22:26:00 -27.581573 153.097060 +2009-08-24T22:26:01 -27.581532 153.097142 +2009-08-24T22:26:02 -27.581484 153.097227 +2009-08-24T22:26:03 -27.581426 153.097324 +2009-08-24T22:26:04 -27.581373 153.097424 +2009-08-24T22:26:05 -27.581320 153.097530 +2009-08-24T22:26:06 -27.581265 153.097641 +2009-08-24T22:26:07 -27.581203 153.097757 +2009-08-24T22:26:08 -27.581144 153.097875 +2009-08-24T22:26:09 -27.581093 153.097995 +2009-08-24T22:26:10 -27.581042 153.098116 +2009-08-24T22:26:11 -27.580987 153.098231 +2009-08-24T22:26:12 -27.580919 153.098334 +2009-08-24T22:26:13 -27.580841 153.098428 +2009-08-24T22:26:14 -27.580754 153.098511 +2009-08-24T22:26:15 -27.580667 153.098591 +2009-08-24T22:26:16 -27.580581 153.098671 +2009-08-24T22:26:17 -27.580492 153.098751 +2009-08-24T22:26:18 -27.580401 153.098832 +2009-08-24T22:26:19 -27.580311 153.098914 +2009-08-24T22:26:20 -27.580224 153.098996 +2009-08-24T22:26:21 -27.580140 153.099078 +2009-08-24T22:26:22 -27.580059 153.099159 +2009-08-24T22:26:23 -27.579980 153.099245 +2009-08-24T22:26:24 -27.579900 153.099336 +2009-08-24T22:26:25 -27.579826 153.099433 +2009-08-24T22:26:26 -27.579753 153.099529 +2009-08-24T22:26:27 -27.579680 153.099623 +2009-08-24T22:26:28 -27.579606 153.099716 +2009-08-24T22:26:29 -27.579538 153.099808 +2009-08-24T22:26:30 -27.579477 153.099893 +2009-08-24T22:26:31 -27.579416 153.099968 +2009-08-24T22:26:32 -27.579393 153.100027 +2009-08-24T22:26:33 -27.579376 153.100092 +2009-08-24T22:26:34 -27.579384 153.100142 +2009-08-24T22:26:35 -27.579403 153.100181 +2009-08-24T22:26:36 -27.579429 153.100210 +2009-08-24T22:26:37 -27.579460 153.100237 +2009-08-24T22:26:38 -27.579493 153.100265 +2009-08-24T22:26:39 -27.579518 153.100291 +2009-08-24T22:26:40 -27.579536 153.100336 +2009-08-24T22:26:41 -27.579591 153.100358 +2009-08-24T22:26:42 -27.579618 153.100383 +2009-08-24T22:26:43 -27.579639 153.100404 +2009-08-24T22:26:44 -27.579650 153.100420 +2009-08-24T22:26:45 -27.579665 153.100432 +2009-08-24T22:26:46 -27.579679 153.100442 +2009-08-24T22:26:47 -27.579690 153.100451 +2009-08-24T22:26:48 -27.579697 153.100459 +2009-08-24T22:26:49 -27.579700 153.100462 +2009-08-24T22:26:50 -27.579699 153.100464 +2009-08-24T22:26:51 -27.579699 153.100466 +2009-08-24T22:26:52 -27.579700 153.100466 +2009-08-24T22:26:53 -27.579704 153.100466 +2009-08-24T22:26:54 -27.579705 153.100465 +2009-08-24T22:26:55 -27.579708 153.100468 +2009-08-24T22:26:56 -27.579712 153.100471 +2009-08-24T22:26:57 -27.579719 153.100476 +2009-08-24T22:26:58 -27.579728 153.100485 +2009-08-24T22:26:59 -27.579744 153.100493 +2009-08-24T22:27:00 -27.579759 153.100496 +2009-08-24T22:27:01 -27.579780 153.100481 +2009-08-24T22:27:02 -27.579788 153.100462 +2009-08-24T22:27:03 -27.579791 153.100436 +2009-08-24T22:27:04 -27.579788 153.100426 +2009-08-24T22:27:05 -27.579783 153.100409 +2009-08-24T22:27:06 -27.579781 153.100390 +2009-08-24T22:27:07 -27.579780 153.100375 +2009-08-24T22:27:08 -27.579779 153.100364 +2009-08-24T22:27:09 -27.579778 153.100354 +2009-08-24T22:27:10 -27.579777 153.100347 +2009-08-24T22:27:11 -27.579777 153.100341 +2009-08-24T22:27:12 -27.579776 153.100336 diff --git a/examples/positioning/positioning.pro b/examples/positioning/positioning.pro new file mode 100644 index 0000000..50c328b --- /dev/null +++ b/examples/positioning/positioning.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs + +qtHaveModule(widgets): SUBDIRS += logfilepositionsource +qtHaveModule(quick) { + SUBDIRS += satelliteinfo + + qtHaveModule(xmlpatterns): SUBDIRS += geoflickr + qtHaveModule(network): SUBDIRS += weatherinfo +} diff --git a/examples/positioning/satelliteinfo/CMakeLists.txt b/examples/positioning/satelliteinfo/CMakeLists.txt new file mode 100644 index 0000000..68acad0 --- /dev/null +++ b/examples/positioning/satelliteinfo/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.16) +project(satelliteinfo LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/positioning/satelliteinfo") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Positioning Quick) + +qt_add_executable(satelliteinfo + main.cpp + satellitemodel.cpp satellitemodel.h +) + +set_target_properties(satelliteinfo PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(satelliteinfo PRIVATE + Qt::Core + Qt::Gui + Qt::Positioning + Qt::Quick +) + +qt_add_qml_module(satelliteinfo + URI Local + VERSION 1.0 + QML_FILES satelliteinfo.qml + NO_RESOURCE_TARGET_PATH +) + +install(TARGETS satelliteinfo + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/positioning/satelliteinfo/doc/images/example-satelliteinfo.png b/examples/positioning/satelliteinfo/doc/images/example-satelliteinfo.png new file mode 100644 index 0000000000000000000000000000000000000000..aa9a217c232773407fe0bcec4665723d3ed4565d GIT binary patch literal 27371 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 k63DQRexEtLIU8q)dJ~KYEcqim+ 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 KWlN>sef&T0c$BCB literal 0 HcmV?d00001 diff --git a/examples/positioning/satelliteinfo/doc/src/satelliteinfo.qdoc b/examples/positioning/satelliteinfo/doc/src/satelliteinfo.qdoc new file mode 100644 index 0000000..1257e9a --- /dev/null +++ b/examples/positioning/satelliteinfo/doc/src/satelliteinfo.qdoc @@ -0,0 +1,110 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example satelliteinfo + \title SatelliteInfo (C++/QML) + + \brief The SatelliteInfo example shows the available satellites + at the user's current position and marks the satellites + currently contributing to the GPS fix as pink. + + \ingroup qtpositioning-examples + + Key \l{Qt Positioning} classes used in this example: + + \list + \li \l{QGeoSatelliteInfo} + \li \l{QGeoSatelliteInfoSource} + \endlist + + \image ../images/example-satelliteinfo.png + + The example displays the signal strength of all satellites in view. Any + satellite that is currently used to calculate the GPS fix is marked pink. + The number at the bottom of each signal bar is the individual satellite + identifier. + + The application operates in three different modes: + + \table + \header + \li Application mode + \li Description + \row + \li running + \li The application continuously queries the system for satellite updates. When new data + is available it will be displayed. + \row + \li stopped + \li The application stops updating the satellite information. + \row + \li single + \li The application makes a single update request with a timeout of 10s. The display + remains empty until the request was answered by the system. + \endtable + + If the platform does not provide satellite information, the application + automatically switches into a demo mode, whereby it continuously switches + between predefined sets of satellite data. + + \include examples-run.qdocinc + + \section1 Satellite Info Model + + The key part of this example is the \c SatelliteModel data model. It + represents the information about the satellites. + It uses the \l Q_PROPERTY and \l QML_ELEMENT macros, so that it can be + available from QML. + + \snippet satelliteinfo/satellitemodel.h 0 + \snippet satelliteinfo/satellitemodel.h 1 + \snippet satelliteinfo/satellitemodel.h 2 + + The \c SatelliteModel object creates an instance of + \l QGeoSatelliteInfoSource using the \l {QGeoSatelliteInfoSource::} + {createDefaultSource()} method. Once the source is created, the + \l {QGeoSatelliteInfoSource::}{satellitesInViewUpdated()} and + \l {QGeoSatelliteInfoSource::}{satellitesInUseUpdated()} signals are used + to notify about the changes in satellite information. + + \snippet satelliteinfo/satellitemodel.cpp 0 + + The aforementioned signals provide the lists of \l QGeoSatelliteInfo + objects that represent satellites in view and satellites in use, + respectively. This data is used to update the model. + + \snippet satelliteinfo/satellitemodel.cpp 1 + + If the satellite info source is not available, demo data is used to simulate + satellite information updates. + + \snippet satelliteinfo/satellitemodel.cpp 2 + + The model is later used in QML to visualize the data. + + \section1 Exposing the Model to QML + + To expose \c SatelliteModel to QML, we use the \l QML_ELEMENT macro. + See the \l QQmlEngine class documentation for more details on it. + + To make the type available in QML, we need to update our build accordingly. + + \section2 CMake Build + + For a CMake-based build, we need to add the following to the + \c {CMakeLists.txt}: + + \quotefromfile satelliteinfo/CMakeLists.txt + \skipto qt_add_qml_module(satelliteinfo + \printuntil ) + + \section2 qmake Build + + For a qmake build, we need to modify the \c {satelliteinfo.pro} file in the + following way: + + \quotefromfile satelliteinfo/satelliteinfo.pro + \skipto CONFIG + \printuntil QML_IMPORT_MAJOR_VERSION +*/ diff --git a/examples/positioning/satelliteinfo/main.cpp b/examples/positioning/satelliteinfo/main.cpp new file mode 100644 index 0000000..fac124a --- /dev/null +++ b/examples/positioning/satelliteinfo/main.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include +#include +#include +#include +#include "satellitemodel.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQuickView view; + view.setSource(QStringLiteral("qrc:///satelliteinfo.qml")); + view.setResizeMode(QQuickView::SizeRootObjectToView); + + QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit())); + view.show(); + + return app.exec(); +} + + diff --git a/examples/positioning/satelliteinfo/satelliteinfo.pro b/examples/positioning/satelliteinfo/satelliteinfo.pro new file mode 100644 index 0000000..ebee094 --- /dev/null +++ b/examples/positioning/satelliteinfo/satelliteinfo.pro @@ -0,0 +1,26 @@ +TEMPLATE = app +TARGET = satelliteinfo + +QT += quick positioning + +CONFIG += qmltypes +QML_IMPORT_NAME = Local +QML_IMPORT_MAJOR_VERSION = 1 + +SOURCES += main.cpp \ + satellitemodel.cpp + +HEADERS += \ + satellitemodel.h + +OTHER_FILES += \ + satelliteinfo.qml + +RESOURCES += \ + satelliteinfo.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/positioning/satelliteinfo +INSTALLS += target + + + diff --git a/examples/positioning/satelliteinfo/satelliteinfo.qml b/examples/positioning/satelliteinfo/satelliteinfo.qml new file mode 100644 index 0000000..d77e53d --- /dev/null +++ b/examples/positioning/satelliteinfo/satelliteinfo.qml @@ -0,0 +1,269 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 +import Local 1.0 + +Rectangle { + id: page + width: 360 + height: 360 + + SatelliteModel { + id: satelliteModel + running: true + onErrorFound: function(code) { + errorLabel.text = qsTr("Last Error: %1", "%1=error number").arg(code) + } + } + + Item { + id: header + height: column.height + 30 + width: parent.width + state: "running" + + anchors.top: parent.top + + function toggle() + { + switch (header.state) { + case "single": header.state = "running"; break; + default: + case "running": header.state = "stopped"; break; + case "stopped": header.state = "single"; break; + } + } + + function enterSingle() + { + satelliteModel.singleRequestMode = true; + satelliteModel.running = true; + } + + function enterRunning() + { + satelliteModel.running = false; + satelliteModel.singleRequestMode = false; + satelliteModel.running = true; + } + + states: [ + State { + name: "stopped" + PropertyChanges { target: startStop; bText: qsTr("Single") } + PropertyChanges { + target: modeLabel; text: qsTr("Current Mode: stopped") + } + PropertyChanges { target: satelliteModel; running: false; } + }, + State { + name: "single" + PropertyChanges { target: startStop; bText: qsTr("Start") } + PropertyChanges { + target: modeLabel; text: qsTr("Current Mode: single") + } + StateChangeScript { script: header.enterSingle(); } + }, + State { + name: "running" + PropertyChanges { target: startStop; bText: qsTr("Stop") } + PropertyChanges { + target: modeLabel; text: qsTr("Current Mode: running") + } + StateChangeScript { script: header.enterRunning(); } + } + ] + + Column { + id: column + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.margins: 7 + Text { + id: overview + text: satelliteModel.satelliteInfoAvailable + ? qsTr("Known Satellites") + : qsTr("Known Satellites (Demo Mode)") + font.pointSize: 12 + } + + Text { + id: modeLabel + font.pointSize: 12 + } + + Text { + id: errorLabel + text: qsTr("Last Error: None") + font.pointSize: 12 + } + } + Rectangle { + id: startStop + border.color: "black" + border.width: 3 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: 7 + radius: 10 + height: maxField.height*1.4 + width: maxField.width*1.4 + + property string bText: qsTr("Stop"); + + Text { //need this for sizing + id: maxField + text: qsTr("Single") + font.pointSize: 13 + opacity: 0 + } + + Text { + id: buttonText + anchors.centerIn: parent + text: startStop.bText + font.pointSize: 13 + } + + MouseArea { + anchors.fill: parent + onPressed: { startStop.color = "lightGray" } + onClicked: { header.toggle() } + onReleased: { startStop.color = "white" } + } + } + } + + Rectangle { + anchors.top: header.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: rect.myMargin + border.width: 3 + radius: 10 + border.color: "black" + + Item { + id: rect + anchors.fill: parent + anchors.margins: myMargin + property int myMargin: 7 + + Row { + id: view + property int rows: repeater.model.entryCount + property int singleWidth: ((rect.width - scale.width)/rows )-rect.myMargin + spacing: rect.myMargin + + Rectangle { + id: scale + width: strengthLabel.width+10 + height: rect.height + color: "#32cd32" + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: lawngreenRect.top + font.pointSize: 11 + text: "50" + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + font.pointSize: 11 + text: "100" + } + + Rectangle { + id: redRect + width: parent.width + color: "red" + height: parent.height*10/100 + anchors.bottom: parent.bottom + Text { + id: strengthLabel + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + font.pointSize: 11 + text: "00" + } + } + Rectangle { + id: orangeRect + height: parent.height*10/100 + anchors.bottom: redRect.top + width: parent.width + color: "#ffa500" + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + font.pointSize: 11 + text: "10" + } + } + Rectangle { + id: goldRect + height: parent.height*10/100 + anchors.bottom: orangeRect.top + width: parent.width + color: "#ffd700" + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + font.pointSize: 11 + text: "20" + } + } + Rectangle { + id: yellowRect + height: parent.height*10/100 + anchors.bottom: goldRect.top + width: parent.width + color: "yellow" + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + font.pointSize: 11 + text: "30" + } + } + Rectangle { + id: lawngreenRect + height: parent.height*10/100 + anchors.bottom: yellowRect.top + width: parent.width + color: "#7cFc00" + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + font.pointSize: 11 + text: "40" + } + } + } + + Repeater { + id: repeater + model: satelliteModel + delegate: Rectangle { + height: rect.height + width: view.singleWidth + Rectangle { + anchors.bottom: parent.bottom + width: parent.width + height: parent.height*signalStrength/100 + color: isInUse ? "#7FFF0000" : "#7F0000FF" + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + text: satelliteIdentifier + } + } + } + } + } + } +} + diff --git a/examples/positioning/satelliteinfo/satelliteinfo.qrc b/examples/positioning/satelliteinfo/satelliteinfo.qrc new file mode 100644 index 0000000..8745f87 --- /dev/null +++ b/examples/positioning/satelliteinfo/satelliteinfo.qrc @@ -0,0 +1,5 @@ + + + satelliteinfo.qml + + diff --git a/examples/positioning/satelliteinfo/satellitemodel.cpp b/examples/positioning/satelliteinfo/satellitemodel.cpp new file mode 100644 index 0000000..70960b7 --- /dev/null +++ b/examples/positioning/satelliteinfo/satellitemodel.cpp @@ -0,0 +1,277 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "satellitemodel.h" +#include +#include + +//! [0] +SatelliteModel::SatelliteModel(QObject *parent) : + QAbstractListModel(parent), source(0), m_componentCompleted(false), m_running(false), + m_runningRequested(false), demo(false), isSingle(false), singleRequestServed(false) +{ + source = QGeoSatelliteInfoSource::createDefaultSource(this); + if (!demo && !source) { + qWarning() << "No satellite data source found. Changing to demo mode."; + demo = true; + } + if (!demo) { + source->setUpdateInterval(3000); + connect(source, SIGNAL(satellitesInViewUpdated(QList)), + this, SLOT(satellitesInViewUpdated(QList))); + connect(source, SIGNAL(satellitesInUseUpdated(QList)), + this, SLOT(satellitesInUseUpdated(QList))); + connect(source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error)), + this, SLOT(error(QGeoSatelliteInfoSource::Error))); + } + + if (demo) { + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(updateDemoData())); + timer->start(3000); + } +} +//! [0] + +int SatelliteModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + if (!source && !demo) + return 0; + + return knownSatellites.count(); +} + +QVariant SatelliteModel::data(const QModelIndex &index, int role) const +{ + if (!demo && !source) + return QVariant(); + + if (!index.isValid() || index.row() < 0) + return QVariant(); + + if (index.row() >= knownSatellites.count()) { + qWarning() << "SatelliteModel: Index out of bound"; + return QVariant(); + } + + const QGeoSatelliteInfo &info = knownSatellites.at(index.row()); + switch (role) { + case IdentifierRole: + return info.satelliteIdentifier(); + case InUseRole: + return satellitesInUse.contains(info.satelliteIdentifier()); + case SignalStrengthRole: + return info.signalStrength(); + case ElevationRole: + if (!info.hasAttribute(QGeoSatelliteInfo::Elevation)) + return QVariant(); + return info.attribute(QGeoSatelliteInfo::Elevation); + case AzimuthRole: + if (!info.hasAttribute(QGeoSatelliteInfo::Azimuth)) + return QVariant(); + return info.attribute(QGeoSatelliteInfo::Azimuth); + default: + break; + + } + + return QVariant(); +} + +QHash SatelliteModel::roleNames() const +{ + QHash roleNames; + roleNames.insert(IdentifierRole, "satelliteIdentifier"); + roleNames.insert(InUseRole, "isInUse"); + roleNames.insert(SignalStrengthRole, "signalStrength"); + roleNames.insert(ElevationRole, "elevation"); + roleNames.insert(AzimuthRole, "azimuth"); + return roleNames; +} + +void SatelliteModel::componentComplete() +{ + m_componentCompleted = true; + if (m_runningRequested) + setRunning(true); +} + +bool SatelliteModel::running() const +{ + return m_running; +} + +bool SatelliteModel::isSingleRequest() const +{ + return isSingle; +} + +void SatelliteModel::setSingleRequest(bool single) +{ + if (running()) { + qWarning() << "Cannot change single request mode while running"; + return; + } + + if (single != isSingle) { //flag changed + isSingle = single; + emit singleRequestChanged(); + } +} + +void SatelliteModel::setRunning(bool isActive) +{ + if (!source && !demo) + return; + + if (!m_componentCompleted) { + m_runningRequested = isActive; + return; + } + + if (m_running == isActive) + return; + + m_running = isActive; + + if (m_running) { + clearModel(); + if (demo) + timer->start(2000); + else if (isSingleRequest()) + source->requestUpdate(10000); + else + source->startUpdates(); + + if (demo) + singleRequestServed = false; + } else { + if (demo) + timer->stop(); + else if (!isSingleRequest()) + source->stopUpdates(); + } + + + Q_EMIT runningChanged(); +} + +int SatelliteModel::entryCount() const +{ + return knownSatellites.count(); +} + +bool SatelliteModel::canProvideSatelliteInfo() const +{ + return !demo; +} + +void SatelliteModel::clearModel() +{ + beginResetModel(); + knownSatelliteIds.clear(); + knownSatellites.clear(); + satellitesInUse.clear(); + endResetModel(); +} + +//! [2] +void SatelliteModel::updateDemoData() +{ + static bool flag = true; + QList satellites; + if (flag) { + for (int i = 0; i<5; i++) { + QGeoSatelliteInfo info; + info.setSatelliteIdentifier(i); + info.setSignalStrength(20 + 20*i); + satellites.append(info); + } + } else { + for (int i = 0; i<9; i++) { + QGeoSatelliteInfo info; + info.setSatelliteIdentifier(i*2); + info.setSignalStrength(20 + 10*i); + satellites.append(info); + } + } + + + satellitesInViewUpdated(satellites); + flag ? satellitesInUseUpdated(QList() << satellites.at(2)) + : satellitesInUseUpdated(QList() << satellites.at(3)); + flag = !flag; + + emit errorFound(flag); + + if (isSingleRequest() && !singleRequestServed) { + singleRequestServed = true; + setRunning(false); + } +} +//! [2] + +void SatelliteModel::error(QGeoSatelliteInfoSource::Error error) +{ + emit errorFound((int)error); +} + +QT_BEGIN_NAMESPACE +inline bool operator<(const QGeoSatelliteInfo& a, const QGeoSatelliteInfo& b) +{ + return a.satelliteIdentifier() < b.satelliteIdentifier(); +} +QT_END_NAMESPACE + +//! [1] +void SatelliteModel::satellitesInViewUpdated(const QList &infos) +{ + if (!running()) + return; + + int oldEntryCount = knownSatellites.count(); + + + QSet satelliteIdsInUpdate; + foreach (const QGeoSatelliteInfo &info, infos) + satelliteIdsInUpdate.insert(info.satelliteIdentifier()); + + QSet toBeRemoved = knownSatelliteIds - satelliteIdsInUpdate; + + //We reset the model as in reality just about all entry values change + //and there are generally a lot of inserts and removals each time + //Hence we don't bother with complex model update logic beyond resetModel() + beginResetModel(); + + knownSatellites = infos; + + //sort them for presentation purposes + std::sort(knownSatellites.begin(), knownSatellites.end()); + + //remove old "InUse" data + //new satellites are by default not in "InUse" + //existing satellites keep their "inUse" state + satellitesInUse -= toBeRemoved; + + knownSatelliteIds = satelliteIdsInUpdate; + endResetModel(); + + if (oldEntryCount != knownSatellites.count()) + emit entryCountChanged(); +} + +void SatelliteModel::satellitesInUseUpdated(const QList &infos) +{ + if (!running()) + return; + + beginResetModel(); + + satellitesInUse.clear(); + foreach (const QGeoSatelliteInfo &info, infos) + satellitesInUse.insert(info.satelliteIdentifier()); + + endResetModel(); +} +//! [1] diff --git a/examples/positioning/satelliteinfo/satellitemodel.h b/examples/positioning/satelliteinfo/satellitemodel.h new file mode 100644 index 0000000..d4ec22f --- /dev/null +++ b/examples/positioning/satelliteinfo/satellitemodel.h @@ -0,0 +1,93 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SATELLITEMODEL_H +#define SATELLITEMODEL_H + +#include +#include +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QTimer) +QT_FORWARD_DECLARE_CLASS(QGeoSatelliteInfoSource) + +//! [0] +class SatelliteModel : public QAbstractListModel, public QQmlParserStatus +{ + Q_OBJECT + Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged) + Q_PROPERTY(bool satelliteInfoAvailable READ canProvideSatelliteInfo NOTIFY canProvideSatelliteInfoChanged) + Q_PROPERTY(int entryCount READ entryCount NOTIFY entryCountChanged) + Q_PROPERTY(bool singleRequestMode READ isSingleRequest WRITE setSingleRequest NOTIFY singleRequestChanged) + Q_INTERFACES(QQmlParserStatus) + QML_ELEMENT +public: + explicit SatelliteModel(QObject *parent = 0); + + enum { + IdentifierRole = Qt::UserRole + 1, + InUseRole, + SignalStrengthRole, + ElevationRole, + AzimuthRole + }; + + //From QAbstractListModel + int rowCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + + //From QQmlParserStatus + void classBegin() override {} + void componentComplete() override; +//! [0] + + bool running() const; + void setRunning(bool isActive); + + bool isSingleRequest() const; + void setSingleRequest(bool single); + + int entryCount() const; + + bool canProvideSatelliteInfo() const; + +//! [1] +signals: + void runningChanged(); + void entryCountChanged(); + void errorFound(int code); + void canProvideSatelliteInfoChanged(); + void singleRequestChanged(); + +public slots: + void clearModel(); + void updateDemoData(); +//! [1] + +private slots: + void error(QGeoSatelliteInfoSource::Error); + void satellitesInViewUpdated(const QList &infos); + void satellitesInUseUpdated(const QList &infos); + +private: + QGeoSatelliteInfoSource *source; + bool m_componentCompleted; + bool m_running; + bool m_runningRequested; + QList knownSatellites; + QSet knownSatelliteIds; + QSet satellitesInUse; + bool demo; + QTimer *timer; + bool isSingle; + bool singleRequestServed; +//! [2] +}; +//! [2] + +QML_DECLARE_TYPE(SatelliteModel) + +#endif // SATELLITEMODEL_H diff --git a/examples/positioning/weatherinfo/CMakeLists.txt b/examples/positioning/weatherinfo/CMakeLists.txt new file mode 100644 index 0000000..53424d0 --- /dev/null +++ b/examples/positioning/weatherinfo/CMakeLists.txt @@ -0,0 +1,71 @@ +cmake_minimum_required(VERSION 3.16) +project(weatherinfo LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/positioning/weatherinfo") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Positioning Qml Quick) + +qt_add_executable(weatherinfo + appmodel.cpp appmodel.h + providerbackend.cpp providerbackend.h + openweathermapbackend.cpp openweathermapbackend.h + weatherapibackend.cpp weatherapibackend.h + main.cpp +) + +set_target_properties(weatherinfo PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(weatherinfo PRIVATE + Qt::Core + Qt::Gui + Qt::Network + Qt::Positioning + Qt::Qml + Qt::Quick +) + +qt_add_qml_module(weatherinfo + URI WeatherInfo + VERSION 1.0 + QML_FILES + components/BigForecastIcon.qml + components/ForecastIcon.qml + components/WeatherIcon.qml + weatherinfo.qml + RESOURCES + icons/weather-few-clouds.png + icons/weather-fog.png + icons/weather-haze.png + icons/weather-icy.png + icons/weather-overcast.png + icons/weather-showers.png + icons/weather-sleet.png + icons/weather-snow.png + icons/weather-storm.png + icons/weather-sunny-very-few-clouds.png + icons/weather-sunny.png + icons/weather-thundershower.png + icons/weather-showers-scattered.png + NO_RESOURCE_TARGET_PATH +) + +if(IOS) + set_target_properties(weatherinfo PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/ios/Info.plist" + ) +endif() + +install(TARGETS weatherinfo + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/positioning/weatherinfo/appmodel.cpp b/examples/positioning/weatherinfo/appmodel.cpp new file mode 100644 index 0000000..ff45523 --- /dev/null +++ b/examples/positioning/weatherinfo/appmodel.cpp @@ -0,0 +1,467 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "appmodel.h" +#include "openweathermapbackend.h" +#include "weatherapibackend.h" + +#include +#include +#include +#include + +Q_LOGGING_CATEGORY(requestsLog, "wapp.requests") + +WeatherData::WeatherData(QObject *parent) : + QObject(parent) +{ +} + +WeatherData::WeatherData(const WeatherData &other) : + QObject(nullptr), + m_dayOfWeek(other.m_dayOfWeek), + m_weather(other.m_weather), + m_weatherDescription(other.m_weatherDescription), + m_temperature(other.m_temperature) +{ +} + +WeatherData::WeatherData(const WeatherInfo &other) + : QObject(nullptr), + m_dayOfWeek(other.m_dayOfWeek), + m_weather(other.m_weatherIconId), + m_weatherDescription(other.m_weatherDescription), + m_temperature(other.m_temperature) +{ +} + +QString WeatherData::dayOfWeek() const +{ + return m_dayOfWeek; +} + +/*! + * The icon value is based on OpenWeatherMap.org icon set. For details + * see http://bugs.openweathermap.org/projects/api/wiki/Weather_Condition_Codes + * + * e.g. 01d ->sunny day + * + * The icon string will be translated to + * http://openweathermap.org/img/w/01d.png + */ +QString WeatherData::weatherIcon() const +{ + return m_weather; +} + +QString WeatherData::weatherDescription() const +{ + return m_weatherDescription; +} + +QString WeatherData::temperature() const +{ + return m_temperature; +} + +void WeatherData::setDayOfWeek(const QString &value) +{ + m_dayOfWeek = value; + emit dataChanged(); +} + +void WeatherData::setWeatherIcon(const QString &value) +{ + m_weather = value; + emit dataChanged(); +} + +void WeatherData::setWeatherDescription(const QString &value) +{ + m_weatherDescription = value; + emit dataChanged(); +} + +void WeatherData::setTemperature(const QString &value) +{ + m_temperature = value; + emit dataChanged(); +} + +/* + The class is used as a cache for the weather information. + It contains a map to cache weather for cities. + The gps location is cached separately. + + For the coordiante search we do not compare the coordinate directly, but + check if it's within a circle of 3 km radius (we assume that the weather + does not really change within that radius). + + The cache returns a pair with empty location and weather data if no data + is found, or if the data is outdated. +*/ +class WeatherDataCache +{ +public: + WeatherDataCache() = default; + + using WeatherDataPair = QPair>; + + WeatherDataPair getWeatherData(const QString &name) const; + WeatherDataPair getWeatherData(const QGeoCoordinate &coordinate) const; + + void addCacheElement(const LocationInfo &location, const QList &info); + + static bool isCacheResultValid(const WeatherDataPair &result); + +private: + struct CacheItem + { + qint64 m_cacheTime; + QList m_weatherData; + }; + + QMap m_cityCache; + + QGeoCoordinate m_gpsLocation; + QString m_gpsName; + CacheItem m_gpsData; + + static const qint64 kCacheTimeoutInterval = 3600; // 1 hour + static const int kCircleRadius = 3000; // 3 km +}; + +WeatherDataCache::WeatherDataPair WeatherDataCache::getWeatherData(const QString &name) const +{ + if (m_cityCache.contains(name)) { + const qint64 currentTime = QDateTime::currentSecsSinceEpoch(); + const auto &item = m_cityCache.value(name); + if (currentTime - item.m_cacheTime < kCacheTimeoutInterval) + return qMakePair(name, item.m_weatherData); + } + return qMakePair(QString(), QList()); +} + +WeatherDataCache::WeatherDataPair WeatherDataCache::getWeatherData(const QGeoCoordinate &coordinate) const +{ + if (m_gpsLocation.isValid() && !m_gpsName.isEmpty()) { + const QGeoCircle area(m_gpsLocation, kCircleRadius); + if (area.contains(coordinate)) { + const qint64 currentTime = QDateTime::currentSecsSinceEpoch(); + if (currentTime - m_gpsData.m_cacheTime < kCacheTimeoutInterval) + return qMakePair(m_gpsName, m_gpsData.m_weatherData); + } + } + return qMakePair(QString(), QList()); +} + +void WeatherDataCache::addCacheElement(const LocationInfo &location, const QList &info) +{ + // It it expected that we have valid QGeoCoordinate only when the weather + // is received based on coordinates. + const qint64 currentTime = QDateTime::currentSecsSinceEpoch(); + if (location.m_coordinate.isValid()) { + m_gpsLocation = location.m_coordinate; + m_gpsName = location.m_name; + m_gpsData = { currentTime, info }; + } else { + m_cityCache[location.m_name] = { currentTime, info }; + } +} + +bool WeatherDataCache::isCacheResultValid(const WeatherDataCache::WeatherDataPair &result) +{ + return !result.first.isEmpty() && !result.second.isEmpty(); +} + +class AppModelPrivate +{ +public: + QGeoPositionInfoSource *src = nullptr; + QGeoCoordinate coord; + QString city; + WeatherData now; + QList forecast; + QQmlListProperty *fcProp = nullptr; + bool ready = false; + bool useGps = true; + WeatherDataCache m_dataCache; + ProviderBackend *m_currentBackend = nullptr; + QList m_supportedBackends; + qsizetype m_currentBackendIndex = 0; +}; + +static void forecastAppend(QQmlListProperty *prop, WeatherData *val) +{ + Q_UNUSED(val); + Q_UNUSED(prop); +} + +static WeatherData *forecastAt(QQmlListProperty *prop, qsizetype index) +{ + AppModelPrivate *d = static_cast(prop->data); + return d->forecast.at(index); +} + +static qsizetype forecastCount(QQmlListProperty *prop) +{ + AppModelPrivate *d = static_cast(prop->data); + return d->forecast.size(); +} + +static void forecastClear(QQmlListProperty *prop) +{ + static_cast(prop->data)->forecast.clear(); +} + +//! [0] +AppModel::AppModel(QObject *parent) : + QObject(parent), + d(new AppModelPrivate) +{ +//! [0] + d->fcProp = new QQmlListProperty(this, d, forecastAppend, + forecastCount, + forecastAt, + forecastClear); + + d->m_supportedBackends.push_back(new OpenWeatherMapBackend(this)); + d->m_supportedBackends.push_back(new WeatherApiBackend(this)); + registerBackend(0); + +//! [1] + d->src = QGeoPositionInfoSource::createDefaultSource(this); + + if (d->src) { + d->useGps = true; + connect(d->src, SIGNAL(positionUpdated(QGeoPositionInfo)), + this, SLOT(positionUpdated(QGeoPositionInfo))); + connect(d->src, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error)), + this, SLOT(positionError(QGeoPositionInfoSource::Error))); + d->src->startUpdates(); + } else { + d->useGps = false; + d->city = "Brisbane"; + emit cityChanged(); + requestWeatherByCity(); + } +} +//! [1] + +AppModel::~AppModel() +{ + if (d->src) + d->src->stopUpdates(); + if (d->fcProp) + delete d->fcProp; + foreach (WeatherData *inf, d->forecast) + delete inf; + d->forecast.clear(); + delete d; +} + +//! [2] +void AppModel::positionUpdated(QGeoPositionInfo gpsPos) +{ + d->coord = gpsPos.coordinate(); + + if (!d->useGps) + return; + + requestWeatherByCoordinates(); +} +//! [2] + +void AppModel::positionError(QGeoPositionInfoSource::Error e) +{ + Q_UNUSED(e); + qWarning() << "Position source error. Falling back to simulation mode."; + + // activate simulation mode + if (d->useGps) { + d->useGps = false; + d->city = "Brisbane"; + emit cityChanged(); + requestWeatherByCity(); + } +} + +void AppModel::refreshWeather() +{ + if (d->city.isEmpty()) { + qCDebug(requestsLog) << "refreshing weather skipped (no city)"; + return; + } + qCDebug(requestsLog) << "refreshing weather"; + requestWeatherByCity(); +} + +void AppModel::handleWeatherData(const LocationInfo &location, + const QList &weatherDetails) +{ + if (applyWeatherData(location.m_name, weatherDetails)) + d->m_dataCache.addCacheElement(location, weatherDetails); +} + +void AppModel::switchToNextBackend() +{ + deregisterCurrentBackend(); + registerBackend(d->m_currentBackendIndex + 1); + if (d->m_currentBackend) { + // repeat the query + if (d->useGps) + requestWeatherByCoordinates(); + else + requestWeatherByCity(); + } else { + qWarning("The application has iterated through all of the weather backends, " + "and none of them seems to respond now. Please wait until any of the " + "backends becomes available again."); + } +} + +bool AppModel::applyWeatherData(const QString &city, const QList &weatherDetails) +{ + // Check that we didn't get outdated weather data. The city should match, + // if only we do not use GPS. + if (city != d->city && !d->useGps) + return false; + + if (city != d->city && d->useGps) { + d->city = city; + emit cityChanged(); + } + + // delete previous forecast + foreach (WeatherData *inf, d->forecast) + delete inf; + d->forecast.clear(); + + // The first item in the list represents current weather. + if (!weatherDetails.isEmpty()) { + d->now.setTemperature(weatherDetails.first().m_temperature); + d->now.setWeatherIcon(weatherDetails.first().m_weatherIconId); + d->now.setWeatherDescription(weatherDetails.first().m_weatherDescription); + } + + // The other items represent weather forecast. The amount of items depends + // on the provider backend. + for (qsizetype i = 1; i < weatherDetails.size(); ++i) { + WeatherData *forecastEntry = new WeatherData(weatherDetails.at(i)); + d->forecast.append(forecastEntry); + } + + if (!d->ready) { + d->ready = true; + emit readyChanged(); + } + + emit weatherChanged(); + + return true; +} + +void AppModel::requestWeatherByCoordinates() +{ + const auto cacheResult = d->m_dataCache.getWeatherData(d->coord); + if (WeatherDataCache::isCacheResultValid(cacheResult)) + applyWeatherData(cacheResult.first, cacheResult.second); + else if (d->m_currentBackend) + d->m_currentBackend->requestWeatherInfo(d->coord); +} + +void AppModel::requestWeatherByCity() +{ + const auto cacheResult = d->m_dataCache.getWeatherData(d->city); + if (WeatherDataCache::isCacheResultValid(cacheResult)) + applyWeatherData(cacheResult.first, cacheResult.second); + else if (d->m_currentBackend) + d->m_currentBackend->requestWeatherInfo(d->city); +} + +void AppModel::registerBackend(qsizetype index) +{ + if (index >= 0 && index < d->m_supportedBackends.size()) { + d->m_currentBackend = d->m_supportedBackends.at(index); + d->m_currentBackendIndex = index; + connect(d->m_currentBackend, &ProviderBackend::weatherInformation, + this, &AppModel::handleWeatherData); + connect(d->m_currentBackend, &ProviderBackend::errorOccurred, + this, &AppModel::switchToNextBackend); + } +} + +void AppModel::deregisterCurrentBackend() +{ + if (d->m_currentBackend) { + disconnect(d->m_currentBackend, &ProviderBackend::weatherInformation, + this, &AppModel::handleWeatherData); + disconnect(d->m_currentBackend, &ProviderBackend::errorOccurred, + this, &AppModel::switchToNextBackend); + d->m_currentBackend = nullptr; + } +} + +bool AppModel::hasValidCity() const +{ + return (!(d->city.isEmpty()) && d->city.size() > 1 && d->city != ""); +} + +bool AppModel::hasValidWeather() const +{ + return hasValidCity() && (!(d->now.weatherIcon().isEmpty()) && + (d->now.weatherIcon().size() > 1) && + d->now.weatherIcon() != ""); +} + +WeatherData *AppModel::weather() const +{ + return &(d->now); +} + +QQmlListProperty AppModel::forecast() const +{ + return *(d->fcProp); +} + +bool AppModel::ready() const +{ + return d->ready; +} + +bool AppModel::hasSource() const +{ + return (d->src != NULL); +} + +bool AppModel::useGps() const +{ + return d->useGps; +} + +void AppModel::setUseGps(bool value) +{ + d->useGps = value; + if (value) { + d->city = ""; + emit cityChanged(); + emit weatherChanged(); + // if we already have a valid GPS position, do not wait until it + // updates, but query the city immediately + if (d->coord.isValid()) + requestWeatherByCoordinates(); + } + emit useGpsChanged(); +} + +QString AppModel::city() const +{ + return d->city; +} + +void AppModel::setCity(const QString &value) +{ + d->city = value; + emit cityChanged(); + requestWeatherByCity(); +} diff --git a/examples/positioning/weatherinfo/appmodel.h b/examples/positioning/weatherinfo/appmodel.h new file mode 100644 index 0000000..548172c --- /dev/null +++ b/examples/positioning/weatherinfo/appmodel.h @@ -0,0 +1,143 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef APPMODEL_H +#define APPMODEL_H + +#include +#include +#include +#include +#include + +#include + +#include "providerbackend.h" + +//! [0] +class WeatherData : public QObject { + Q_OBJECT + Q_PROPERTY(QString dayOfWeek + READ dayOfWeek WRITE setDayOfWeek + NOTIFY dataChanged) + Q_PROPERTY(QString weatherIcon + READ weatherIcon WRITE setWeatherIcon + NOTIFY dataChanged) + Q_PROPERTY(QString weatherDescription + READ weatherDescription WRITE setWeatherDescription + NOTIFY dataChanged) + Q_PROPERTY(QString temperature + READ temperature WRITE setTemperature + NOTIFY dataChanged) + QML_ANONYMOUS + +public: + explicit WeatherData(QObject *parent = 0); + WeatherData(const WeatherData &other); + WeatherData(const WeatherInfo &other); + + QString dayOfWeek() const; + QString weatherIcon() const; + QString weatherDescription() const; + QString temperature() const; + + void setDayOfWeek(const QString &value); + void setWeatherIcon(const QString &value); + void setWeatherDescription(const QString &value); + void setTemperature(const QString &value); + +signals: + void dataChanged(); +//! [0] +private: + QString m_dayOfWeek; + QString m_weather; + QString m_weatherDescription; + QString m_temperature; +//! [1] +}; +//! [1] + +Q_DECLARE_METATYPE(WeatherData) + +class AppModelPrivate; +//! [2] +class AppModel : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool ready + READ ready + NOTIFY readyChanged) + Q_PROPERTY(bool hasSource + READ hasSource + NOTIFY readyChanged) + Q_PROPERTY(bool hasValidCity + READ hasValidCity + NOTIFY cityChanged) + Q_PROPERTY(bool hasValidWeather + READ hasValidWeather + NOTIFY weatherChanged) + Q_PROPERTY(bool useGps + READ useGps WRITE setUseGps + NOTIFY useGpsChanged) + Q_PROPERTY(QString city + READ city WRITE setCity + NOTIFY cityChanged) + Q_PROPERTY(WeatherData *weather + READ weather + NOTIFY weatherChanged) + Q_PROPERTY(QQmlListProperty forecast + READ forecast + NOTIFY weatherChanged) + QML_ELEMENT + +public: + explicit AppModel(QObject *parent = 0); + ~AppModel(); + + bool ready() const; + bool hasSource() const; + bool useGps() const; + bool hasValidCity() const; + bool hasValidWeather() const; + void setUseGps(bool value); + + QString city() const; + void setCity(const QString &value); + + WeatherData *weather() const; + QQmlListProperty forecast() const; + +public slots: + Q_INVOKABLE void refreshWeather(); + +//! [2] +private slots: + void positionUpdated(QGeoPositionInfo gpsPos); + void positionError(QGeoPositionInfoSource::Error e); + void handleWeatherData(const LocationInfo &location, const QList &weatherDetails); + void switchToNextBackend(); + +//! [3] +signals: + void readyChanged(); + void useGpsChanged(); + void cityChanged(); + void weatherChanged(); +//! [3] + +private: + bool applyWeatherData(const QString &city, const QList &weatherDetails); + void requestWeatherByCoordinates(); + void requestWeatherByCity(); + void registerBackend(qsizetype index); + void deregisterCurrentBackend(); + + + AppModelPrivate *d; + +//! [4] +}; +//! [4] + +#endif // APPMODEL_H diff --git a/examples/positioning/weatherinfo/components/BigForecastIcon.qml b/examples/positioning/weatherinfo/components/BigForecastIcon.qml new file mode 100644 index 0000000..74912a3 --- /dev/null +++ b/examples/positioning/weatherinfo/components/BigForecastIcon.qml @@ -0,0 +1,45 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + id: current + + property string topText: "20*" + property string bottomText: "Mostly cloudy" + property string weatherIcon: "sunny" + property real smallSide: (current.width < current.height ? current.width : current.height) + + Text { + text: current.topText + font.pointSize: 28 + anchors { + top: current.top + left: current.left + topMargin: 5 + leftMargin: 5 + } + } + + WeatherIcon { + weatherIcon: current.weatherIcon + anchors.centerIn: parent + anchors.verticalCenterOffset: -15 + width: current.smallSide + height: current.smallSide + } + + Text { + text: current.bottomText + font.pointSize: 23 + wrapMode: Text.WordWrap + width: parent.width + horizontalAlignment: Text.AlignRight + anchors { + bottom: current.bottom + right: current.right + rightMargin: 5 + } + } +} diff --git a/examples/positioning/weatherinfo/components/ForecastIcon.qml b/examples/positioning/weatherinfo/components/ForecastIcon.qml new file mode 100644 index 0000000..a47766a --- /dev/null +++ b/examples/positioning/weatherinfo/components/ForecastIcon.qml @@ -0,0 +1,52 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + id: top + + property string topText: "Mon" + property string weatherIcon: "sunny" + property string bottomText: "22*/23*" + + Text { + id: dayText + horizontalAlignment: Text.AlignHCenter + width: top.width + text: top.topText + + anchors.top: parent.top + anchors.topMargin: top.height / 5 - dayText.paintedHeight + anchors.horizontalCenter: parent.horizontalCenter + } + + WeatherIcon { + id: icon + weatherIcon: top.weatherIcon + + property real side: { + var h = 3 * top.height / 5 + if (top.width < h) + top.width; + else + h; + } + + width: icon.side + height: icon.side + + anchors.centerIn: parent + } + + Text { + id: tempText + horizontalAlignment: Text.AlignHCenter + width: top.width + text: top.bottomText + + anchors.bottom: parent.bottom + anchors.bottomMargin: top.height / 5 - tempText.paintedHeight + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/positioning/weatherinfo/components/WeatherIcon.qml b/examples/positioning/weatherinfo/components/WeatherIcon.qml new file mode 100644 index 0000000..4737163 --- /dev/null +++ b/examples/positioning/weatherinfo/components/WeatherIcon.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 + +Item { + id: container + + property string weatherIcon: "sunny" + + Image { + id: img + source: "../icons/weather-" + container.weatherIcon + ".png" + smooth: true + anchors.fill: parent + } +} diff --git a/examples/positioning/weatherinfo/doc/images/example-weatherinfo.png b/examples/positioning/weatherinfo/doc/images/example-weatherinfo.png new file mode 100644 index 0000000000000000000000000000000000000000..3a1c6c24b87c8ac40eda60bc0900513555c4fcba GIT binary patch literal 70264 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%0A3t&vL;l}uv4i`LE#+kTkb4n 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 literal 0 HcmV?d00001 diff --git a/examples/positioning/weatherinfo/doc/src/weatherinfo.qdoc b/examples/positioning/weatherinfo/doc/src/weatherinfo.qdoc new file mode 100644 index 0000000..662c3b6 --- /dev/null +++ b/examples/positioning/weatherinfo/doc/src/weatherinfo.qdoc @@ -0,0 +1,140 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example weatherinfo + \title Weather Info (C++/QML) + + \brief The Weather Info example shows how to use the user's current position + to retrieve local content from a web service in a C++ plugin for QML. + + \ingroup qtpositioning-examples + + Key \l{Qt Positioning} classes used in this example: + + \list + \li \l{QGeoPositionInfo} + \li \l{QGeoPositionInfoSource} + \endlist + + \image ../images/example-weatherinfo.png + + \include examples-run.qdocinc + + \section1 Weather Data Providers + + The example uses two unrelated weather data providers: + + \list + \li \l {http://www.openweathermap.org}{OpenWeather} + \li \l {https://www.weatherapi.com/}{WeatherAPI.com} + \endlist + + The provider to be used is selected automatically at runtime and can be + changed if the selected provider is not available. However, it can't be + specified manually. + + \note Free plans are used for both providers, which implies certain + limitations on the amount of weather requests. If the limits are exceeded, + the providers become temporary unavailable. When both providers are + unavailable, the application would not be able to show any weather + information. In this case it is required to wait until at least one of the + providers becomes available again. + + \section1 Application Data Models + + The key part of this example is the application's data model, contained + in the \c WeatherData and \c AppModel classes. \c WeatherData represents + the weather information taken from the HTTP service. It is a simple data + class, but we use \l Q_PROPERTY to expose it nicely to QML later. + It also uses \l QML_ANONYMOUS macro, which makes it recognized in QML. + + \snippet weatherinfo/appmodel.h 0 + \snippet weatherinfo/appmodel.h 1 + + \c AppModel models the state of the entire application. At startup, we + get the platform's default position source using + \l QGeoPositionInfoSource::createDefaultSource(). + + \snippet weatherinfo/appmodel.cpp 0 + \snippet weatherinfo/appmodel.cpp 1 + + If no default source is available, we take a static position and fetch + weather for that. If, however, we do have a position source, we connect + its \l {QGeoPositionInfoSource::}{positionUpdated()} signal to a slot on the + \c AppModel and call \l {QGeoPositionInfoSource::}{startUpdates()}, which + begins regular updates of device position. + + When a position update is received, we use the longitude and latitude + of the returned coordinate to retrieve weather data for the specified + location. + + \snippet weatherinfo/appmodel.cpp 2 + + To inform the UI about this process, the \c cityChanged() signal is emitted + when a new city is used, and the \c weatherChanged() signal whenever a + weather update occurs. + + The model also uses \l QML_ELEMENT macro, which makes it available in QML. + + \snippet weatherinfo/appmodel.h 2 + \snippet weatherinfo/appmodel.h 3 + \snippet weatherinfo/appmodel.h 4 + + We use a \l QQmlListProperty for the weather forecast information, + which contains the weather forecast for the next days (the number of days + is provider-specific). This makes it easy to access the forecast from QML. + + \section1 Expose Custom Models to QML + + To expose the models to the QML UI layer, we use the \l QML_ELEMENT and + \l QML_ANONYMOUS macros. See the \l QQmlEngine class description for more + details on these macros. + + To make the types available in QML, we need to update our build accordingly. + + \section2 CMake Build + + For a CMake-based build, we need to add the following to the + \c {CMakeLists.txt}: + + \quotefromfile weatherinfo/CMakeLists.txt + \skipto qt_add_qml_module(weatherinfo + \printuntil ) + + \section2 qmake Build + + For a qmake build, we need to modify the \c {weatherinfo.pro} file in the + following way: + + \quotefromfile weatherinfo/weatherinfo.pro + \skipto CONFIG + \printuntil QML_IMPORT_MAJOR_VERSION + + \section1 Instantiate the Models in QML + + Finally, in the actual QML, we instantiate the \c {AppModel}: + + \snippet weatherinfo/weatherinfo.qml 0 + \snippet weatherinfo/weatherinfo.qml 1 + \snippet weatherinfo/weatherinfo.qml 2 + + Once the model is instantiated like this, we can use its properties + elsewhere in the QML document: + + \snippet weatherinfo/weatherinfo.qml 3 + \snippet weatherinfo/weatherinfo.qml 4 + + \section1 Files and Attributions + + The example bundles the following images from Third-Party sources: + + \table + \row + \li \l{weatherinfo-tango-icons}{Tango Icons} + \li Public Domain + \row + \li \l{weatherinfo-tango-weather-pack}{Tango Weather Icon Pack by Darkobra} + \li Public Domain + \endtable +*/ diff --git a/examples/positioning/weatherinfo/icons/README.txt b/examples/positioning/weatherinfo/icons/README.txt new file mode 100644 index 0000000..d384153 --- /dev/null +++ b/examples/positioning/weatherinfo/icons/README.txt @@ -0,0 +1,5 @@ +The scalable icons are from: + +http://tango.freedesktop.org/Tango_Icon_Library +http://darkobra.deviantart.com/art/Tango-Weather-Icon-Pack-98024429 + diff --git a/examples/positioning/weatherinfo/icons/qt_attribution.json b/examples/positioning/weatherinfo/icons/qt_attribution.json new file mode 100644 index 0000000..23bbe38 --- /dev/null +++ b/examples/positioning/weatherinfo/icons/qt_attribution.json @@ -0,0 +1,28 @@ +[ + { + "Id": "weatherinfo-tango-weather-pack", + "Name": "Tango Weather Icon Pack by Darkobra", + "QDocModule": "qtpositioning", + "QtUsage": "Used in the \"Weather Info (C++/QML)\" example", + "QtParts": [ "examples" ], + "Description": "74 brand spankin' new Tango icons for your viewing pleasure.", + "Homepage": "https://www.deviantart.com/darkobra/art/Tango-Weather-Icon-Pack-98024429", + + "License": "Public Domain", + "Copyright": "Copyright DarKobra (C Stark)", + "Files": "weather-fog.png weather-haze.png weather-icy.png weather-sleet.png weather-sunny.png weather-sunny-very-few-clouds.png weather-sunny-few-clouds.png weather-thunder-shower.png" + }, + { + "Id": "weatherinfo-tango-icons", + "Name": "Tango Icons", + "QDocModule": "qtpositioning", + "QtUsage": "Used in the \"Weather Info (C++/QML)\" example", + "QtParts": [ "examples" ], + "Description": "The Tango Desktop Project exists to help create a consistent graphical user interface experience for free and Open Source software. ", + "Homepage": "http://tango.freedesktop.org/Tango_Desktop_Project", + + "License": "Public Domain", + "Copyright": "Copyright Tango Project contributors", + "Files": "weather-few-clouds.png weather-overcast.png weather-showers.png weather-storm.png weather-snow.png weather-showers-scattered.png" + } +] diff --git a/examples/positioning/weatherinfo/icons/weather-few-clouds.png b/examples/positioning/weatherinfo/icons/weather-few-clouds.png new file mode 100644 index 0000000000000000000000000000000000000000..a8000ef0a2ffbc852baf7c969fa4b2ef31ea2547 GIT binary patch literal 79488 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

l;#XiE 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

q~)d8s!8}{10j9MX@ELWZG*C&ZZL! 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

g`s}QO5ynaZ!c)D4y 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 literal 0 HcmV?d00001 diff --git a/examples/positioning/weatherinfo/icons/weather-fog.png b/examples/positioning/weatherinfo/icons/weather-fog.png new file mode 100644 index 0000000000000000000000000000000000000000..9ffe9c4afcde071ce38d6846f7b2e2bee233cbaf GIT binary patch literal 43896 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�J}hmz``kpmts#GklXq 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 W$Cxu22_JOG2`p6Z{w#w{Rv)qrRC%Yn70e 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 z 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 T&UI|Szei3=S+YjlB<%kIn6v!l literal 0 HcmV?d00001 diff --git a/examples/positioning/weatherinfo/icons/weather-icy.png b/examples/positioning/weatherinfo/icons/weather-icy.png new file mode 100644 index 0000000000000000000000000000000000000000..18d203840b84401e6d7fefdb0846d09e0401c2f0 GIT binary patch literal 49362 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

K35|IsY+(I%c&*uc^9w5Vce(+&K_Koe(3XqglO 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

  • NnU*6Kv5~Hyu;EjK`hl33$K_I}E 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 literal 0 HcmV?d00001 diff --git a/examples/positioning/weatherinfo/icons/weather-snow.png b/examples/positioning/weatherinfo/icons/weather-snow.png new file mode 100644 index 0000000000000000000000000000000000000000..e7426e3cddc7d6352a6a2483eb3bcc060d860c8a GIT binary patch literal 70939 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 VyzTpd{lCsvMr6R@QFW__#k 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%0DYr^=+;A+oR!^FXBhMu4`BG6 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 literal 0 HcmV?d00001 diff --git a/examples/positioning/weatherinfo/icons/weather-sunny-very-few-clouds.png b/examples/positioning/weatherinfo/icons/weather-sunny-very-few-clouds.png new file mode 100644 index 0000000000000000000000000000000000000000..133bcb29f734312d7a3e686acc0ec90fd1274210 GIT binary patch literal 65731 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 literal 0 HcmV?d00001 diff --git a/examples/positioning/weatherinfo/icons/weather-sunny.png b/examples/positioning/weatherinfo/icons/weather-sunny.png new file mode 100644 index 0000000000000000000000000000000000000000..0fac921d7bd2d314d127bba8ea93e8aa01de0845 GIT binary patch literal 59084 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 gvT@w*0M|;(`oV}RQWLRkszv!Y`Z3zP` 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 + + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleIdentifier + Anonymous.weatherinfo + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleVersion + 0.0.1 + CFBundleShortVersionString + 0.0.1 + CFBundleGetInfoString + + NSHumanReadableCopyright + + CFBundleIconFile + + CFBundleDevelopmentRegion + English + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + NSLocationWhenInUseUsageDescription + Location services needed to give local weather forecast + + diff --git a/examples/positioning/weatherinfo/main.cpp b/examples/positioning/weatherinfo/main.cpp new file mode 100644 index 0000000..ac0e7bd --- /dev/null +++ b/examples/positioning/weatherinfo/main.cpp @@ -0,0 +1,27 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include +#include +#include +#include +#include +#include + +#include "appmodel.h" + +int main(int argc, char *argv[]) +{ + QLoggingCategory::setFilterRules("wapp.*.debug=false"); + QGuiApplication application(argc, argv); + + const QString mainQmlApp = QStringLiteral("qrc:///weatherinfo.qml"); + QQuickView view; + view.setSource(QUrl(mainQmlApp)); + view.setResizeMode(QQuickView::SizeRootObjectToView); + + QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit())); + view.setGeometry(QRect(100, 100, 360, 640)); + view.show(); + return application.exec(); +} diff --git a/examples/positioning/weatherinfo/openweathermapbackend.cpp b/examples/positioning/weatherinfo/openweathermapbackend.cpp new file mode 100644 index 0000000..0943d0d --- /dev/null +++ b/examples/positioning/weatherinfo/openweathermapbackend.cpp @@ -0,0 +1,218 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "openweathermapbackend.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(requestsLog) + +static constexpr auto kZeroKelvin = 273.15; + +static QString niceTemperatureString(double t) +{ + return QString::number(qRound(t - kZeroKelvin)) + QChar(0xB0); +} + +/* + Converts weather code to a string that will be used to show the icon. + The possible strings are based on the icon names. The icon name is built up + as follows: + weather-[mystring].png + where [mystring] is the value returned by this method. + Check resources for the full list of available icons. +*/ +static QString weatherCodeToString(const QString &code) +{ + if (code == u"01d" || code == u"01n") + return "sunny"; + else if (code == u"02d" || code == u"02n") + return "sunny-very-few-clouds"; + else if (code == u"03d" || code == u"03n") + return "few-clouds"; + else if (code == u"04d" || code == u"04n") + return "overcast"; + else if (code == u"09d" || code == u"09n" || code == u"10d" || code == u"10n") + return "showers"; + else if (code == u"11d" || code == u"11n") + return "thundershower"; + else if (code == u"13d" || code == u"13n") + return "snow"; + else if (code == u"50d" || code == u"50n") + return "fog"; + + return "sunny"; // default choice +} + +static void parseWeatherDescription(const QJsonObject &object, WeatherInfo &info) +{ + const QJsonArray weatherArray = object.value(u"weather").toArray(); + if (!weatherArray.isEmpty()) { + const QJsonObject obj = weatherArray.first().toObject(); + info.m_weatherDescription = obj.value(u"description").toString(); + info.m_weatherIconId = weatherCodeToString(obj.value(u"icon").toString()); + } else { + qCDebug(requestsLog, "An empty weather array is returned."); + } +} + +OpenWeatherMapBackend::OpenWeatherMapBackend(QObject *parent) + : ProviderBackend(parent), + m_networkManager(new QNetworkAccessManager(this)), + m_appId(QStringLiteral("36496bad1955bf3365448965a42b9eac")) +{ +} + +void OpenWeatherMapBackend::requestWeatherInfo(const QString &city) +{ + QUrlQuery query; + query.addQueryItem(QStringLiteral("q"), city); + + requestCurrentWeather(query, QGeoCoordinate()); +} + +void OpenWeatherMapBackend::requestWeatherInfo(const QGeoCoordinate &coordinate) +{ + QUrlQuery query; + query.addQueryItem(QStringLiteral("lat"), QString::number(coordinate.latitude())); + query.addQueryItem(QStringLiteral("lon"), QString::number(coordinate.longitude())); + + requestCurrentWeather(query, coordinate); +} + +void OpenWeatherMapBackend::handleCurrentWeatherReply(QNetworkReply *reply, + const QGeoCoordinate &coordinate) +{ + if (!reply) { + emit errorOccurred(); + return; + } + bool parsed = false; + if (!reply->error()) { + // extract info about current weather + const QJsonDocument document = QJsonDocument::fromJson(reply->readAll()); + const QJsonObject documentObject = document.object(); + + LocationInfo currentLocation; + currentLocation.m_name = documentObject.value(u"name").toString(); + if (coordinate.isValid()) + currentLocation.m_coordinate = coordinate; + qCDebug(requestsLog) << "Got current weather for" << currentLocation.m_name; + + WeatherInfo currentWeather; + + parseWeatherDescription(documentObject, currentWeather); + + const QJsonObject mainObject = documentObject.value(u"main").toObject(); + const QJsonValue tempValue = mainObject.value(u"temp"); + if (tempValue.isDouble()) + currentWeather.m_temperature = niceTemperatureString(tempValue.toDouble()); + else + qCDebug(requestsLog, "Failed to parse current temperature."); + + parsed = !currentLocation.m_name.isEmpty() && !currentWeather.m_temperature.isEmpty(); + + if (parsed) { + // request forecast + requestWeatherForecast(currentLocation, currentWeather); + } + } + if (!parsed) { + emit errorOccurred(); + if (reply->error()) + qCDebug(requestsLog) << reply->errorString(); + else + qCDebug(requestsLog, "Failed to parse current weather JSON."); + } + + reply->deleteLater(); +} + +void OpenWeatherMapBackend::handleWeatherForecastReply(QNetworkReply *reply, + const LocationInfo &location, + const WeatherInfo ¤tWeather) +{ + if (!reply) { + emit errorOccurred(); + return; + } + if (!reply->error()) { + QJsonDocument document = QJsonDocument::fromJson(reply->readAll()); + const QJsonObject documentObject = document.object(); + + QList weatherDetails; + // current weather will be the first in the list + weatherDetails << currentWeather; + + QJsonArray daysList = documentObject.value(u"list").toArray(); + // include current day as well + for (qsizetype i = 0; i < daysList.size(); ++i) { + QJsonObject dayObject = daysList.at(i).toObject(); + WeatherInfo info; + + const QDateTime dt = QDateTime::fromSecsSinceEpoch(dayObject.value(u"dt").toInteger()); + info.m_dayOfWeek = dt.toString(u"ddd"); + + const QJsonObject tempObject = dayObject.value(u"temp").toObject(); + + const QJsonValue minTemp = tempObject.value(u"min"); + const QJsonValue maxTemp = tempObject.value(u"max"); + if (minTemp.isDouble() && maxTemp.isDouble()) { + info.m_temperature = niceTemperatureString(minTemp.toDouble()) + QChar('/') + + niceTemperatureString(maxTemp.toDouble()); + } else { + qCDebug(requestsLog, "Failed to parse min or max temperature."); + } + + parseWeatherDescription(dayObject, info); + + if (!info.m_temperature.isEmpty() && !info.m_weatherIconId.isEmpty()) + weatherDetails.push_back(info); + } + + emit weatherInformation(location, weatherDetails); + } else { + emit errorOccurred(); + qCDebug(requestsLog) << reply->errorString(); + } + + reply->deleteLater(); +} + +void OpenWeatherMapBackend::requestCurrentWeather(QUrlQuery &query, + const QGeoCoordinate &coordinate) +{ + QUrl url("http://api.openweathermap.org/data/2.5/weather"); + query.addQueryItem(QStringLiteral("mode"), QStringLiteral("json")); + query.addQueryItem(QStringLiteral("APPID"), m_appId); + url.setQuery(query); + + QNetworkReply *reply = m_networkManager->get(QNetworkRequest(url)); + connect(reply, &QNetworkReply::finished, this, + [this, reply, coordinate]() { handleCurrentWeatherReply(reply, coordinate); }); +} + +void OpenWeatherMapBackend::requestWeatherForecast(const LocationInfo &location, + const WeatherInfo ¤tWeather) +{ + QUrl url("http://api.openweathermap.org/data/2.5/forecast/daily"); + QUrlQuery query; + query.addQueryItem(QStringLiteral("q"), location.m_name); + query.addQueryItem(QStringLiteral("mode"), QStringLiteral("json")); + query.addQueryItem(QStringLiteral("cnt"), QStringLiteral("4")); + query.addQueryItem(QStringLiteral("APPID"), m_appId); + url.setQuery(query); + + QNetworkReply *reply = m_networkManager->get(QNetworkRequest(url)); + connect(reply, &QNetworkReply::finished, this, [this, reply, location, currentWeather]() { + handleWeatherForecastReply(reply, location, currentWeather); + }); +} diff --git a/examples/positioning/weatherinfo/openweathermapbackend.h b/examples/positioning/weatherinfo/openweathermapbackend.h new file mode 100644 index 0000000..eb25962 --- /dev/null +++ b/examples/positioning/weatherinfo/openweathermapbackend.h @@ -0,0 +1,38 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef OPENWEATHERMAPBACKEND_H +#define OPENWEATHERMAPBACKEND_H + +#include "providerbackend.h" + +QT_BEGIN_NAMESPACE +class QNetworkAccessManager; +class QNetworkReply; +class QUrlQuery; +QT_END_NAMESPACE + +class OpenWeatherMapBackend : public ProviderBackend +{ + Q_OBJECT +public: + explicit OpenWeatherMapBackend(QObject *parent = nullptr); + ~OpenWeatherMapBackend() = default; + + void requestWeatherInfo(const QString &city) override; + void requestWeatherInfo(const QGeoCoordinate &coordinate) override; + +private slots: + void handleCurrentWeatherReply(QNetworkReply *reply, const QGeoCoordinate &coordinate); + void handleWeatherForecastReply(QNetworkReply *reply, const LocationInfo &location, + const WeatherInfo ¤tWeather); + +private: + void requestCurrentWeather(QUrlQuery &query, const QGeoCoordinate &coordinate); + void requestWeatherForecast(const LocationInfo &location, const WeatherInfo ¤tWeather); + + QNetworkAccessManager *m_networkManager; + const QString m_appId; +}; + +#endif // OPENWEATHERMAPBACKEND_H diff --git a/examples/positioning/weatherinfo/providerbackend.cpp b/examples/positioning/weatherinfo/providerbackend.cpp new file mode 100644 index 0000000..0a2a8df --- /dev/null +++ b/examples/positioning/weatherinfo/providerbackend.cpp @@ -0,0 +1,6 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "providerbackend.h" + +ProviderBackend::ProviderBackend(QObject *parent) : QObject(parent) { } diff --git a/examples/positioning/weatherinfo/providerbackend.h b/examples/positioning/weatherinfo/providerbackend.h new file mode 100644 index 0000000..e8e93ff --- /dev/null +++ b/examples/positioning/weatherinfo/providerbackend.h @@ -0,0 +1,43 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef PROVIDERBACKEND_H +#define PROVIDERBACKEND_H + +#include +#include + +struct WeatherInfo +{ + QString m_dayOfWeek; + QString m_weatherIconId; + QString m_weatherDescription; + QString m_temperature; +}; + +struct LocationInfo +{ + QString m_name; + QGeoCoordinate m_coordinate; +}; + +class ProviderBackend : public QObject +{ + Q_OBJECT +public: + explicit ProviderBackend(QObject *parent = nullptr); + + virtual void requestWeatherInfo(const QString &city) = 0; + virtual void requestWeatherInfo(const QGeoCoordinate &coordinate) = 0; + +signals: + // The first element in weatherDetails represents current weather. + // Next are the weather forecast, including the current day. + // The LocationInfo object should contain valid coordinate only when it was + // initially used to request the weather. If the city name was used, an + // empty coordinate is expected to be transferred. + void weatherInformation(const LocationInfo &location, const QList &weatherDetails); + void errorOccurred(); +}; + +#endif // PROVIDERBACKEND_H diff --git a/examples/positioning/weatherinfo/weatherapibackend.cpp b/examples/positioning/weatherinfo/weatherapibackend.cpp new file mode 100644 index 0000000..ee49dad --- /dev/null +++ b/examples/positioning/weatherinfo/weatherapibackend.cpp @@ -0,0 +1,219 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "weatherapibackend.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(requestsLog) + +static QString niceTemperatureString(double t) +{ + return QString::number(qRound(t)) + QChar(0xB0); +} + +/* + Converts weather code to a string that will be used to show the icon. + The possible strings are based on the icon names. The icon name is built up + as follows: + weather-[mystring].png + where [mystring] is the value returned by this method. + Check resources for the full list of available icons. +*/ +static QString weatherCodeToString(int code) +{ + switch (code) { + case 1000: + return "sunny"; + case 1003: + return "sunny-very-few-clouds"; + case 1006: + return "few-clouds"; + case 1009: + return "overcast"; + case 1030: + case 1135: + case 1147: + return "fog"; + case 1063: + case 1072: + case 1150: + case 1153: + case 1168: + case 1171: + case 1180: + case 1183: + case 1186: + case 1189: + case 1198: + return "showers-scattered"; + case 1066: + case 1069: + case 1114: + case 1117: + case 1210: + case 1213: + case 1216: + case 1219: + case 1222: + case 1225: + case 1237: + case 1255: + case 1258: + case 1261: + case 1264: + case 1279: + case 1282: + return "snow"; + case 1087: + return "storm"; + case 1192: + case 1195: + case 1201: + case 1240: + case 1243: + case 1246: + return "showers"; + case 1204: + case 1207: + case 1249: + case 1252: + return "sleet"; + case 1273: + case 1276: + return "thundershower"; + default: + return "sunny"; + } + + return "sunny"; // default choice +} + +static void parseWeatherDescription(const QJsonObject &object, WeatherInfo &info) +{ + const QJsonObject conditionObject = object.value(u"condition").toObject(); + info.m_weatherDescription = conditionObject.value(u"text").toString(); + info.m_weatherIconId = weatherCodeToString(conditionObject.value(u"code").toInt()); +} + +WeatherApiBackend::WeatherApiBackend(QObject *parent) + : ProviderBackend(parent), + m_networkManager(new QNetworkAccessManager(this)), + m_apiKey(QStringLiteral("8edde160c63c4be6b77101828211208")) +{ +} + +void WeatherApiBackend::requestWeatherInfo(const QString &city) +{ + generateWeatherRequest(city, QGeoCoordinate()); +} + +void WeatherApiBackend::requestWeatherInfo(const QGeoCoordinate &coordinate) +{ + const QString coordinateStr = + QString("%1,%2").arg(coordinate.latitude()).arg(coordinate.longitude()); + generateWeatherRequest(coordinateStr, coordinate); +} + +void WeatherApiBackend::handleWeatherForecastReply(QNetworkReply *reply, + const QGeoCoordinate &coordinate) +{ + if (!reply) { + emit errorOccurred(); + return; + } + bool parsed = false; + if (!reply->error()) { + QJsonDocument document = QJsonDocument::fromJson(reply->readAll()); + const QJsonObject documentObject = document.object(); + const QJsonObject locationObject = documentObject.value(u"location").toObject(); + + // extract location name + LocationInfo location; + location.m_name = locationObject.value(u"name").toString(); + if (coordinate.isValid()) + location.m_coordinate = coordinate; + qCDebug(requestsLog) << "Got weather for" << location.m_name; + + // extract current weather + WeatherInfo currentWeather; + + const QJsonObject currentWeatherObject = documentObject.value(u"current").toObject(); + const QJsonValue temperature = currentWeatherObject.value(u"temp_c"); + if (temperature.isDouble()) + currentWeather.m_temperature = niceTemperatureString(temperature.toDouble()); + + parseWeatherDescription(currentWeatherObject, currentWeather); + + parsed = !location.m_name.isEmpty() && !currentWeather.m_temperature.isEmpty(); + + if (parsed) { + QList weatherDetails; + weatherDetails << currentWeather; + + // extract forecast details + const QJsonObject forecastObject = documentObject.value(u"forecast").toObject(); + const QJsonArray forecastDays = forecastObject.value(u"forecastday").toArray(); + for (qsizetype i = 0; i < forecastDays.size(); ++i) { + const QJsonObject dayInfo = forecastDays.at(i).toObject(); + WeatherInfo info; + + const QDateTime dt = + QDateTime::fromSecsSinceEpoch(dayInfo.value(u"date_epoch").toInteger()); + info.m_dayOfWeek = dt.toString(u"ddd"); + + const QJsonObject dayObject = dayInfo.value(u"day").toObject(); + const QJsonValue minTemp = dayObject.value(u"mintemp_c"); + const QJsonValue maxTemp = dayObject.value(u"maxtemp_c"); + if (minTemp.isDouble() && maxTemp.isDouble()) { + info.m_temperature = niceTemperatureString(minTemp.toDouble()) + QChar('/') + + niceTemperatureString(maxTemp.toDouble()); + } else { + qCDebug(requestsLog, "Failed to parse min or max temperature."); + } + + parseWeatherDescription(dayObject, info); + + if (!info.m_temperature.isEmpty() && !info.m_weatherIconId.isEmpty()) + weatherDetails.push_back(info); + } + + emit weatherInformation(location, weatherDetails); + } + } + if (!parsed) { + emit errorOccurred(); + if (reply->error()) + qCDebug(requestsLog) << reply->errorString(); + else + qCDebug(requestsLog, "Failed to parse weather JSON."); + } + + reply->deleteLater(); +} + +void WeatherApiBackend::generateWeatherRequest(const QString &locationString, + const QGeoCoordinate &coordinate) +{ + QUrl url("https://api.weatherapi.com/v1/forecast.json"); + + QUrlQuery query; + query.addQueryItem(QStringLiteral("key"), m_apiKey); + query.addQueryItem(QStringLiteral("q"), locationString); + query.addQueryItem(QStringLiteral("days"), QStringLiteral("4")); + query.addQueryItem(QStringLiteral("aqi"), QStringLiteral("no")); + query.addQueryItem(QStringLiteral("alerts"), QStringLiteral("no")); + + url.setQuery(query); + + QNetworkReply *reply = m_networkManager->get(QNetworkRequest(url)); + connect(reply, &QNetworkReply::finished, this, + [this, reply, coordinate]() { handleWeatherForecastReply(reply, coordinate); }); +} diff --git a/examples/positioning/weatherinfo/weatherapibackend.h b/examples/positioning/weatherinfo/weatherapibackend.h new file mode 100644 index 0000000..b0d2a58 --- /dev/null +++ b/examples/positioning/weatherinfo/weatherapibackend.h @@ -0,0 +1,33 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef WEATHERAPIBACKEND_H +#define WEATHERAPIBACKEND_H + +#include "providerbackend.h" + +QT_BEGIN_NAMESPACE +class QNetworkAccessManager; +class QNetworkReply; +QT_END_NAMESPACE + +class WeatherApiBackend : public ProviderBackend +{ + Q_OBJECT +public: + explicit WeatherApiBackend(QObject *parent = nullptr); + + void requestWeatherInfo(const QString &city) override; + void requestWeatherInfo(const QGeoCoordinate &coordinate) override; + +private slots: + void handleWeatherForecastReply(QNetworkReply *reply, const QGeoCoordinate &coordinate); + +private: + void generateWeatherRequest(const QString &locationString, const QGeoCoordinate &coordinate); + + QNetworkAccessManager *m_networkManager; + const QString m_apiKey; +}; + +#endif // WEATHERAPIBACKEND_H diff --git a/examples/positioning/weatherinfo/weatherinfo.pro b/examples/positioning/weatherinfo/weatherinfo.pro new file mode 100644 index 0000000..35f137e --- /dev/null +++ b/examples/positioning/weatherinfo/weatherinfo.pro @@ -0,0 +1,34 @@ +TEMPLATE = app +TARGET = weatherinfo + +QT += core network positioning qml quick + +CONFIG += qmltypes +QML_IMPORT_NAME = WeatherInfo +QML_IMPORT_MAJOR_VERSION = 1 + +SOURCES += main.cpp \ + appmodel.cpp \ + openweathermapbackend.cpp \ + providerbackend.cpp \ + weatherapibackend.cpp + +OTHER_FILES += weatherinfo.qml \ + components/WeatherIcon.qml \ + components/ForecastIcon.qml \ + components/BigForecastIcon.qml \ + icons/* + +ios { + QMAKE_INFO_PLIST = ios/Info.plist +} + +RESOURCES += weatherinfo.qrc + +HEADERS += appmodel.h \ + openweathermapbackend.h \ + providerbackend.h \ + weatherapibackend.h + +target.path = $$[QT_INSTALL_EXAMPLES]/positioning/weatherinfo +INSTALLS += target diff --git a/examples/positioning/weatherinfo/weatherinfo.qml b/examples/positioning/weatherinfo/weatherinfo.qml new file mode 100644 index 0000000..c0795ce --- /dev/null +++ b/examples/positioning/weatherinfo/weatherinfo.qml @@ -0,0 +1,161 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.0 +import "components" +//! [0] +import WeatherInfo 1.0 + +Item { + id: window +//! [0] + width: 360 + height: 640 + + state: "loading" + + states: [ + State { + name: "loading" + PropertyChanges { target: main; opacity: 0 } + PropertyChanges { target: wait; opacity: 1 } + }, + State { + name: "ready" + PropertyChanges { target: main; opacity: 1 } + PropertyChanges { target: wait; opacity: 0 } + } + ] +//! [1] + AppModel { + id: appModel + onReadyChanged: { + if (appModel.ready) + window.state = "ready" + else + window.state = "loading" + } + } +//! [1] + Item { + id: wait + anchors.fill: parent + + Text { + text: "Loading weather data..." + anchors.centerIn: parent + font.pointSize: 18 + } + } + + Item { + id: main + anchors.fill: parent + + Column { + spacing: 6 + + anchors { + fill: parent + topMargin: 6; bottomMargin: 6; leftMargin: 6; rightMargin: 6 + } + + Rectangle { + width: parent.width + height: 25 + color: "lightgrey" + + Text { + text: (appModel.hasValidCity ? appModel.city : "Unknown location") + (appModel.useGps ? " (GPS)" : "") + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (appModel.useGps) { + appModel.useGps = false + appModel.city = "Brisbane" + } else { + switch (appModel.city) { + case "Brisbane": + appModel.city = "Oslo" + break + case "Oslo": + appModel.city = "Helsinki" + break + case "Helsinki": + appModel.city = "New York" + break + case "New York": + appModel.useGps = true + break + } + } + } + } + } + +//! [3] + BigForecastIcon { + id: current + + width: main.width -12 + height: 2 * (main.height - 25 - 12) / 3 + + weatherIcon: (appModel.hasValidWeather + ? appModel.weather.weatherIcon + : "sunny") +//! [3] + topText: (appModel.hasValidWeather + ? appModel.weather.temperature + : "??") + bottomText: (appModel.hasValidWeather + ? appModel.weather.weatherDescription + : "No weather data") + + MouseArea { + anchors.fill: parent + onClicked: { + appModel.refreshWeather() + } + } +//! [4] + } +//! [4] + + Row { + id: iconRow + spacing: 6 + + width: main.width - 12 + height: (main.height - 25 - 24) / 3 + + property int daysCount: appModel.forecast.length + property real iconWidth: (daysCount > 0) ? (iconRow.width / daysCount) - 10 + : iconRow.width + property real iconHeight: iconRow.height + + Repeater { + model: appModel.forecast + ForecastIcon { + id: forecast1 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (appModel.hasValidWeather ? + modelData.dayOfWeek : "??") + bottomText: (appModel.hasValidWeather ? + modelData.temperature : "??/??") + weatherIcon: (appModel.hasValidWeather ? + modelData.weatherIcon : "sunny") + } + } + } + } + } +//! [2] +} +//! [2] diff --git a/examples/positioning/weatherinfo/weatherinfo.qrc b/examples/positioning/weatherinfo/weatherinfo.qrc new file mode 100644 index 0000000..1578fa9 --- /dev/null +++ b/examples/positioning/weatherinfo/weatherinfo.qrc @@ -0,0 +1,21 @@ + + + weatherinfo.qml + components/BigForecastIcon.qml + components/ForecastIcon.qml + components/WeatherIcon.qml + icons/weather-few-clouds.png + icons/weather-fog.png + icons/weather-haze.png + icons/weather-icy.png + icons/weather-overcast.png + icons/weather-showers.png + icons/weather-sleet.png + icons/weather-snow.png + icons/weather-storm.png + icons/weather-sunny-very-few-clouds.png + icons/weather-sunny.png + icons/weather-thundershower.png + icons/weather-showers-scattered.png + + diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qclipperutils_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qclipperutils_p.h new file mode 100644 index 0000000..876b17c --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qclipperutils_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qclipperutils_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qdoublematrix4x4_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qdoublematrix4x4_p.h new file mode 100644 index 0000000..9f9622b --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qdoublematrix4x4_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qdoublematrix4x4_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qdoublevector2d_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qdoublevector2d_p.h new file mode 100644 index 0000000..a679f2f --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qdoublevector2d_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qdoublevector2d_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qdoublevector3d_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qdoublevector3d_p.h new file mode 100644 index 0000000..6b1a13c --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qdoublevector3d_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qdoublevector3d_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeoaddress_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeoaddress_p.h new file mode 100644 index 0000000..b494007 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeoaddress_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeoaddress_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeocircle_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeocircle_p.h new file mode 100644 index 0000000..80a2f05 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeocircle_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeocircle_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeocoordinate_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeocoordinate_p.h new file mode 100644 index 0000000..53b5c3b --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeocoordinate_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeocoordinate_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeocoordinateobject_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeocoordinateobject_p.h new file mode 100644 index 0000000..11739db --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeocoordinateobject_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeocoordinateobject_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeolocation_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeolocation_p.h new file mode 100644 index 0000000..15bd5a1 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeolocation_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeolocation_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeopath_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeopath_p.h new file mode 100644 index 0000000..a41c689 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeopath_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeopath_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeopolygon_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeopolygon_p.h new file mode 100644 index 0000000..6394c8b --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeopolygon_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeopolygon_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeopositioninfo_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeopositioninfo_p.h new file mode 100644 index 0000000..d85beda --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeopositioninfo_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeopositioninfo_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeopositioninfosource_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeopositioninfosource_p.h new file mode 100644 index 0000000..a43d355 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeopositioninfosource_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeopositioninfosource_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeorectangle_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeorectangle_p.h new file mode 100644 index 0000000..e4d2ac1 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeorectangle_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeorectangle_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeosatelliteinfo_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeosatelliteinfo_p.h new file mode 100644 index 0000000..2d475b8 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeosatelliteinfo_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeosatelliteinfo_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeosatelliteinfosource_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeosatelliteinfosource_p.h new file mode 100644 index 0000000..b13fd08 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeosatelliteinfosource_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeosatelliteinfosource_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qgeoshape_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qgeoshape_p.h new file mode 100644 index 0000000..ef4a35e --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qgeoshape_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qgeoshape_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qlocationutils_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qlocationutils_p.h new file mode 100644 index 0000000..0c3d9cd --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qlocationutils_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qlocationutils_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qnmeapositioninfosource_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qnmeapositioninfosource_p.h new file mode 100644 index 0000000..2fd5904 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qnmeapositioninfosource_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qnmeapositioninfosource_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qnmeasatelliteinfosource_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qnmeasatelliteinfosource_p.h new file mode 100644 index 0000000..9ebe5f8 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qnmeasatelliteinfosource_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qnmeasatelliteinfosource_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qpositioningglobal_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qpositioningglobal_p.h new file mode 100644 index 0000000..657c470 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qpositioningglobal_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qpositioningglobal_p.h" diff --git a/include/QtPositioning/6.4.2/QtPositioning/private/qwebmercator_p.h b/include/QtPositioning/6.4.2/QtPositioning/private/qwebmercator_p.h new file mode 100644 index 0000000..f2abab1 --- /dev/null +++ b/include/QtPositioning/6.4.2/QtPositioning/private/qwebmercator_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioning/qwebmercator_p.h" diff --git a/include/QtPositioning/QGeoAddress b/include/QtPositioning/QGeoAddress new file mode 100644 index 0000000..708bcab --- /dev/null +++ b/include/QtPositioning/QGeoAddress @@ -0,0 +1 @@ +#include "qgeoaddress.h" diff --git a/include/QtPositioning/QGeoAreaMonitorInfo b/include/QtPositioning/QGeoAreaMonitorInfo new file mode 100644 index 0000000..7e137e6 --- /dev/null +++ b/include/QtPositioning/QGeoAreaMonitorInfo @@ -0,0 +1 @@ +#include "qgeoareamonitorinfo.h" diff --git a/include/QtPositioning/QGeoAreaMonitorSource b/include/QtPositioning/QGeoAreaMonitorSource new file mode 100644 index 0000000..942ccf6 --- /dev/null +++ b/include/QtPositioning/QGeoAreaMonitorSource @@ -0,0 +1 @@ +#include "qgeoareamonitorsource.h" diff --git a/include/QtPositioning/QGeoCircle b/include/QtPositioning/QGeoCircle new file mode 100644 index 0000000..b77d827 --- /dev/null +++ b/include/QtPositioning/QGeoCircle @@ -0,0 +1 @@ +#include "qgeocircle.h" diff --git a/include/QtPositioning/QGeoCoordinate b/include/QtPositioning/QGeoCoordinate new file mode 100644 index 0000000..812fb2a --- /dev/null +++ b/include/QtPositioning/QGeoCoordinate @@ -0,0 +1 @@ +#include "qgeocoordinate.h" diff --git a/include/QtPositioning/QGeoLocation b/include/QtPositioning/QGeoLocation new file mode 100644 index 0000000..bd38c75 --- /dev/null +++ b/include/QtPositioning/QGeoLocation @@ -0,0 +1 @@ +#include "qgeolocation.h" diff --git a/include/QtPositioning/QGeoPath b/include/QtPositioning/QGeoPath new file mode 100644 index 0000000..bde3300 --- /dev/null +++ b/include/QtPositioning/QGeoPath @@ -0,0 +1 @@ +#include "qgeopath.h" diff --git a/include/QtPositioning/QGeoPolygon b/include/QtPositioning/QGeoPolygon new file mode 100644 index 0000000..e02b134 --- /dev/null +++ b/include/QtPositioning/QGeoPolygon @@ -0,0 +1 @@ +#include "qgeopolygon.h" diff --git a/include/QtPositioning/QGeoPositionInfo b/include/QtPositioning/QGeoPositionInfo new file mode 100644 index 0000000..d6feec9 --- /dev/null +++ b/include/QtPositioning/QGeoPositionInfo @@ -0,0 +1 @@ +#include "qgeopositioninfo.h" diff --git a/include/QtPositioning/QGeoPositionInfoSource b/include/QtPositioning/QGeoPositionInfoSource new file mode 100644 index 0000000..b7cc338 --- /dev/null +++ b/include/QtPositioning/QGeoPositionInfoSource @@ -0,0 +1 @@ +#include "qgeopositioninfosource.h" diff --git a/include/QtPositioning/QGeoPositionInfoSourceFactory b/include/QtPositioning/QGeoPositionInfoSourceFactory new file mode 100644 index 0000000..7448436 --- /dev/null +++ b/include/QtPositioning/QGeoPositionInfoSourceFactory @@ -0,0 +1 @@ +#include "qgeopositioninfosourcefactory.h" diff --git a/include/QtPositioning/QGeoRectangle b/include/QtPositioning/QGeoRectangle new file mode 100644 index 0000000..9a7d48f --- /dev/null +++ b/include/QtPositioning/QGeoRectangle @@ -0,0 +1 @@ +#include "qgeorectangle.h" diff --git a/include/QtPositioning/QGeoSatelliteInfo b/include/QtPositioning/QGeoSatelliteInfo new file mode 100644 index 0000000..a3fd47d --- /dev/null +++ b/include/QtPositioning/QGeoSatelliteInfo @@ -0,0 +1 @@ +#include "qgeosatelliteinfo.h" diff --git a/include/QtPositioning/QGeoSatelliteInfoSource b/include/QtPositioning/QGeoSatelliteInfoSource new file mode 100644 index 0000000..cc6ba9d --- /dev/null +++ b/include/QtPositioning/QGeoSatelliteInfoSource @@ -0,0 +1 @@ +#include "qgeosatelliteinfosource.h" diff --git a/include/QtPositioning/QGeoShape b/include/QtPositioning/QGeoShape new file mode 100644 index 0000000..d86ddc3 --- /dev/null +++ b/include/QtPositioning/QGeoShape @@ -0,0 +1 @@ +#include "qgeoshape.h" diff --git a/include/QtPositioning/QNmeaPositionInfoSource b/include/QtPositioning/QNmeaPositionInfoSource new file mode 100644 index 0000000..5c261c9 --- /dev/null +++ b/include/QtPositioning/QNmeaPositionInfoSource @@ -0,0 +1 @@ +#include "qnmeapositioninfosource.h" diff --git a/include/QtPositioning/QNmeaSatelliteInfoSource b/include/QtPositioning/QNmeaSatelliteInfoSource new file mode 100644 index 0000000..3734576 --- /dev/null +++ b/include/QtPositioning/QNmeaSatelliteInfoSource @@ -0,0 +1 @@ +#include "qnmeasatelliteinfosource.h" diff --git a/include/QtPositioning/QtPositioning b/include/QtPositioning/QtPositioning new file mode 100644 index 0000000..a93a2d1 --- /dev/null +++ b/include/QtPositioning/QtPositioning @@ -0,0 +1,23 @@ +#ifndef QT_QTPOSITIONING_MODULE_H +#define QT_QTPOSITIONING_MODULE_H +#include +#include "qpositioningglobal.h" +#include "qgeoaddress.h" +#include "qgeoareamonitorinfo.h" +#include "qgeoareamonitorsource.h" +#include "qgeocircle.h" +#include "qgeocoordinate.h" +#include "qgeolocation.h" +#include "qgeopath.h" +#include "qgeopolygon.h" +#include "qgeopositioninfo.h" +#include "qgeopositioninfosource.h" +#include "qgeopositioninfosourcefactory.h" +#include "qgeorectangle.h" +#include "qgeosatelliteinfo.h" +#include "qgeosatelliteinfosource.h" +#include "qgeoshape.h" +#include "qnmeapositioninfosource.h" +#include "qnmeasatelliteinfosource.h" +#include "qtpositioningversion.h" +#endif diff --git a/include/QtPositioning/QtPositioningVersion b/include/QtPositioning/QtPositioningVersion new file mode 100644 index 0000000..2f99398 --- /dev/null +++ b/include/QtPositioning/QtPositioningVersion @@ -0,0 +1 @@ +#include "qtpositioningversion.h" diff --git a/include/QtPositioning/headers.pri b/include/QtPositioning/headers.pri new file mode 100644 index 0000000..7e6d16a --- /dev/null +++ b/include/QtPositioning/headers.pri @@ -0,0 +1,6 @@ +SYNCQT.HEADER_FILES = qgeoaddress.h qgeoareamonitorinfo.h qgeoareamonitorsource.h qgeocircle.h qgeocoordinate.h qgeolocation.h qgeopath.h qgeopolygon.h qgeopositioninfo.h qgeopositioninfosource.h qgeopositioninfosourcefactory.h qgeorectangle.h qgeosatelliteinfo.h qgeosatelliteinfosource.h qgeoshape.h qnmeapositioninfosource.h qnmeasatelliteinfosource.h qpositioningglobal.h +SYNCQT.GENERATED_HEADER_FILES = QGeoAddress QGeoAreaMonitorInfo QGeoAreaMonitorSource QGeoCircle QGeoCoordinate QGeoLocation QGeoPath QGeoPolygon QGeoPositionInfo QGeoPositionInfoSource QGeoPositionInfoSourceFactory QGeoRectangle QGeoSatelliteInfo QGeoSatelliteInfoSource QGeoShape QNmeaPositionInfoSource QNmeaSatelliteInfoSource qtpositioningversion.h QtPositioningVersion QtPositioning +SYNCQT.PRIVATE_HEADER_FILES = qclipperutils_p.h qdoublematrix4x4_p.h qdoublevector2d_p.h qdoublevector3d_p.h qgeoaddress_p.h qgeocircle_p.h qgeocoordinate_p.h qgeocoordinateobject_p.h qgeolocation_p.h qgeopath_p.h qgeopolygon_p.h qgeopositioninfo_p.h qgeopositioninfosource_p.h qgeorectangle_p.h qgeosatelliteinfo_p.h qgeosatelliteinfosource_p.h qgeoshape_p.h qlocationutils_p.h qnmeapositioninfosource_p.h qnmeasatelliteinfosource_p.h qpositioningglobal_p.h qwebmercator_p.h +SYNCQT.QPA_HEADER_FILES = +SYNCQT.CLEAN_HEADER_FILES = qgeoaddress.h qgeoareamonitorinfo.h qgeoareamonitorsource.h qgeocircle.h qgeocoordinate.h qgeolocation.h qgeopath.h qgeopolygon.h qgeopositioninfo.h qgeopositioninfosource.h qgeopositioninfosourcefactory.h qgeorectangle.h qgeosatelliteinfo.h qgeosatelliteinfosource.h qgeoshape.h qnmeapositioninfosource.h qnmeasatelliteinfosource.h qpositioningglobal.h +SYNCQT.INJECTIONS = diff --git a/include/QtPositioning/qgeoaddress.h b/include/QtPositioning/qgeoaddress.h new file mode 100644 index 0000000..b8e0a99 --- /dev/null +++ b/include/QtPositioning/qgeoaddress.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeoaddress.h" diff --git a/include/QtPositioning/qgeoareamonitorinfo.h b/include/QtPositioning/qgeoareamonitorinfo.h new file mode 100644 index 0000000..f9a334c --- /dev/null +++ b/include/QtPositioning/qgeoareamonitorinfo.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeoareamonitorinfo.h" diff --git a/include/QtPositioning/qgeoareamonitorsource.h b/include/QtPositioning/qgeoareamonitorsource.h new file mode 100644 index 0000000..4555de8 --- /dev/null +++ b/include/QtPositioning/qgeoareamonitorsource.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeoareamonitorsource.h" diff --git a/include/QtPositioning/qgeocircle.h b/include/QtPositioning/qgeocircle.h new file mode 100644 index 0000000..f598c2c --- /dev/null +++ b/include/QtPositioning/qgeocircle.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeocircle.h" diff --git a/include/QtPositioning/qgeocoordinate.h b/include/QtPositioning/qgeocoordinate.h new file mode 100644 index 0000000..93b16d9 --- /dev/null +++ b/include/QtPositioning/qgeocoordinate.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeocoordinate.h" diff --git a/include/QtPositioning/qgeolocation.h b/include/QtPositioning/qgeolocation.h new file mode 100644 index 0000000..59429ea --- /dev/null +++ b/include/QtPositioning/qgeolocation.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeolocation.h" diff --git a/include/QtPositioning/qgeopath.h b/include/QtPositioning/qgeopath.h new file mode 100644 index 0000000..8e61b7e --- /dev/null +++ b/include/QtPositioning/qgeopath.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeopath.h" diff --git a/include/QtPositioning/qgeopolygon.h b/include/QtPositioning/qgeopolygon.h new file mode 100644 index 0000000..c9e8296 --- /dev/null +++ b/include/QtPositioning/qgeopolygon.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeopolygon.h" diff --git a/include/QtPositioning/qgeopositioninfo.h b/include/QtPositioning/qgeopositioninfo.h new file mode 100644 index 0000000..213fbb2 --- /dev/null +++ b/include/QtPositioning/qgeopositioninfo.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeopositioninfo.h" diff --git a/include/QtPositioning/qgeopositioninfosource.h b/include/QtPositioning/qgeopositioninfosource.h new file mode 100644 index 0000000..8f7082d --- /dev/null +++ b/include/QtPositioning/qgeopositioninfosource.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeopositioninfosource.h" diff --git a/include/QtPositioning/qgeopositioninfosourcefactory.h b/include/QtPositioning/qgeopositioninfosourcefactory.h new file mode 100644 index 0000000..e59bdd9 --- /dev/null +++ b/include/QtPositioning/qgeopositioninfosourcefactory.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeopositioninfosourcefactory.h" diff --git a/include/QtPositioning/qgeorectangle.h b/include/QtPositioning/qgeorectangle.h new file mode 100644 index 0000000..f4a6526 --- /dev/null +++ b/include/QtPositioning/qgeorectangle.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeorectangle.h" diff --git a/include/QtPositioning/qgeosatelliteinfo.h b/include/QtPositioning/qgeosatelliteinfo.h new file mode 100644 index 0000000..1c1d631 --- /dev/null +++ b/include/QtPositioning/qgeosatelliteinfo.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeosatelliteinfo.h" diff --git a/include/QtPositioning/qgeosatelliteinfosource.h b/include/QtPositioning/qgeosatelliteinfosource.h new file mode 100644 index 0000000..a3115b1 --- /dev/null +++ b/include/QtPositioning/qgeosatelliteinfosource.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeosatelliteinfosource.h" diff --git a/include/QtPositioning/qgeoshape.h b/include/QtPositioning/qgeoshape.h new file mode 100644 index 0000000..6e7d4db --- /dev/null +++ b/include/QtPositioning/qgeoshape.h @@ -0,0 +1 @@ +#include "../../src/positioning/qgeoshape.h" diff --git a/include/QtPositioning/qnmeapositioninfosource.h b/include/QtPositioning/qnmeapositioninfosource.h new file mode 100644 index 0000000..6f5d63d --- /dev/null +++ b/include/QtPositioning/qnmeapositioninfosource.h @@ -0,0 +1 @@ +#include "../../src/positioning/qnmeapositioninfosource.h" diff --git a/include/QtPositioning/qnmeasatelliteinfosource.h b/include/QtPositioning/qnmeasatelliteinfosource.h new file mode 100644 index 0000000..97e3390 --- /dev/null +++ b/include/QtPositioning/qnmeasatelliteinfosource.h @@ -0,0 +1 @@ +#include "../../src/positioning/qnmeasatelliteinfosource.h" diff --git a/include/QtPositioning/qpositioningglobal.h b/include/QtPositioning/qpositioningglobal.h new file mode 100644 index 0000000..a291214 --- /dev/null +++ b/include/QtPositioning/qpositioningglobal.h @@ -0,0 +1 @@ +#include "../../src/positioning/qpositioningglobal.h" diff --git a/include/QtPositioning/qtpositioningversion.h b/include/QtPositioning/qtpositioningversion.h new file mode 100644 index 0000000..1d3ed88 --- /dev/null +++ b/include/QtPositioning/qtpositioningversion.h @@ -0,0 +1,9 @@ +/* This file was generated by syncqt. */ +#ifndef QT_QTPOSITIONING_VERSION_H +#define QT_QTPOSITIONING_VERSION_H + +#define QTPOSITIONING_VERSION_STR "6.4.2" + +#define QTPOSITIONING_VERSION 0x060402 + +#endif // QT_QTPOSITIONING_VERSION_H diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/locationsingleton_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/locationsingleton_p.h new file mode 100644 index 0000000..6c10bb2 --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/locationsingleton_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/locationsingleton_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativegeoaddress_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativegeoaddress_p.h new file mode 100644 index 0000000..98e5c13 --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativegeoaddress_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qdeclarativegeoaddress_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativegeolocation_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativegeolocation_p.h new file mode 100644 index 0000000..b0c75f1 --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativegeolocation_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qdeclarativegeolocation_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativepluginparameter_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativepluginparameter_p.h new file mode 100644 index 0000000..bed66c7 --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativepluginparameter_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qdeclarativepluginparameter_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativeposition_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativeposition_p.h new file mode 100644 index 0000000..151ff26 --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativeposition_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qdeclarativeposition_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativepositionsource_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativepositionsource_p.h new file mode 100644 index 0000000..870a4fa --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qdeclarativepositionsource_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qdeclarativepositionsource_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qpositioningquickglobal_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qpositioningquickglobal_p.h new file mode 100644 index 0000000..532a737 --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qpositioningquickglobal_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qpositioningquickglobal_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qpositioningquickmodule_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qpositioningquickmodule_p.h new file mode 100644 index 0000000..5d00f31 --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qpositioningquickmodule_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qpositioningquickmodule_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qquickgeocoordinateanimation_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qquickgeocoordinateanimation_p.h new file mode 100644 index 0000000..08d8685 --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qquickgeocoordinateanimation_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qquickgeocoordinateanimation_p.h" diff --git a/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qquickgeocoordinateanimation_p_p.h b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qquickgeocoordinateanimation_p_p.h new file mode 100644 index 0000000..a50771e --- /dev/null +++ b/include/QtPositioningQuick/6.4.2/QtPositioningQuick/private/qquickgeocoordinateanimation_p_p.h @@ -0,0 +1 @@ +#include "../../../../../src/positioningquick/qquickgeocoordinateanimation_p_p.h" diff --git a/include/QtPositioningQuick/QtPositioningQuick b/include/QtPositioningQuick/QtPositioningQuick new file mode 100644 index 0000000..6b1a2f8 --- /dev/null +++ b/include/QtPositioningQuick/QtPositioningQuick @@ -0,0 +1,6 @@ +#ifndef QT_QTPOSITIONINGQUICK_MODULE_H +#define QT_QTPOSITIONINGQUICK_MODULE_H +#include +#include "qpositioningquickglobal.h" +#include "qtpositioningquickversion.h" +#endif diff --git a/include/QtPositioningQuick/QtPositioningQuickVersion b/include/QtPositioningQuick/QtPositioningQuickVersion new file mode 100644 index 0000000..2c697a7 --- /dev/null +++ b/include/QtPositioningQuick/QtPositioningQuickVersion @@ -0,0 +1 @@ +#include "qtpositioningquickversion.h" diff --git a/include/QtPositioningQuick/headers.pri b/include/QtPositioningQuick/headers.pri new file mode 100644 index 0000000..f70b1fd --- /dev/null +++ b/include/QtPositioningQuick/headers.pri @@ -0,0 +1,6 @@ +SYNCQT.HEADER_FILES = qpositioningquickglobal.h +SYNCQT.GENERATED_HEADER_FILES = qtpositioningquickversion.h QtPositioningQuickVersion QtPositioningQuick +SYNCQT.PRIVATE_HEADER_FILES = locationsingleton_p.h qdeclarativegeoaddress_p.h qdeclarativegeolocation_p.h qdeclarativepluginparameter_p.h qdeclarativeposition_p.h qdeclarativepositionsource_p.h qpositioningquickglobal_p.h qpositioningquickmodule_p.h qquickgeocoordinateanimation_p.h qquickgeocoordinateanimation_p_p.h +SYNCQT.QPA_HEADER_FILES = +SYNCQT.CLEAN_HEADER_FILES = qpositioningquickglobal.h +SYNCQT.INJECTIONS = diff --git a/include/QtPositioningQuick/qpositioningquickglobal.h b/include/QtPositioningQuick/qpositioningquickglobal.h new file mode 100644 index 0000000..4c34141 --- /dev/null +++ b/include/QtPositioningQuick/qpositioningquickglobal.h @@ -0,0 +1 @@ +#include "../../src/positioningquick/qpositioningquickglobal.h" diff --git a/include/QtPositioningQuick/qtpositioningquickversion.h b/include/QtPositioningQuick/qtpositioningquickversion.h new file mode 100644 index 0000000..680a360 --- /dev/null +++ b/include/QtPositioningQuick/qtpositioningquickversion.h @@ -0,0 +1,9 @@ +/* This file was generated by syncqt. */ +#ifndef QT_QTPOSITIONINGQUICK_VERSION_H +#define QT_QTPOSITIONINGQUICK_VERSION_H + +#define QTPOSITIONINGQUICK_VERSION_STR "6.4.2" + +#define QTPOSITIONINGQUICK_VERSION 0x060402 + +#endif // QT_QTPOSITIONINGQUICK_VERSION_H diff --git a/src/3rdparty/clip2tri/CMakeLists.txt b/src/3rdparty/clip2tri/CMakeLists.txt new file mode 100644 index 0000000..9b5a56b --- /dev/null +++ b/src/3rdparty/clip2tri/CMakeLists.txt @@ -0,0 +1,31 @@ +# Generated from clip2tri.pro. + +##################################################################### +## Bundled_Clip2Tri Generic Library: +##################################################################### + +qt_internal_add_3rdparty_library(Bundled_Clip2Tri + QMAKE_LIB_NAME _clip2tri + STATIC + SKIP_AUTOMOC # special case + EXCEPTIONS + SOURCES + clip2tri.cpp clip2tri.h + INCLUDE_DIRECTORIES + ../clipper + ../poly2tri + LIBRARIES + Qt::Bundled_Clipper # special case + Qt::Bundled_Poly2Tri # special case +) +qt_disable_warnings(Bundled_Clip2Tri) +qt_set_symbol_visibility_hidden(Bundled_Clip2Tri) + +## Scopes: +##################################################################### + +#### Keys ignored in scope 3:.:.:clip2tri.pro:GCC: +# QMAKE_CFLAGS_OPTIMIZE_FULL = "-ffast-math" + +#### Keys ignored in scope 4:.:.:clip2tri.pro:NOT CLANG AND NOT ICC AND NOT rim_qcc: +# QMAKE_CXXFLAGS_WARN_ON = "-Wno-error=return-type" diff --git a/src/3rdparty/clip2tri/LICENSE b/src/3rdparty/clip2tri/LICENSE new file mode 100644 index 0000000..9d99b88 --- /dev/null +++ b/src/3rdparty/clip2tri/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Bitfighter developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/3rdparty/clip2tri/clip2tri.cpp b/src/3rdparty/clip2tri/clip2tri.cpp new file mode 100644 index 0000000..db4911c --- /dev/null +++ b/src/3rdparty/clip2tri/clip2tri.cpp @@ -0,0 +1,406 @@ +/* + * Authors: kaen, raptor, sam686, watusimoto + * + * Originally from the bitfighter source code + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Bitfighter developers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "clip2tri.h" +#include + +#include + +static const double clipperScaleFactor = 1073741822.0; +static const double clipperScaleFactorInv = 1.0 / 1073741822.0; + +using namespace p2t; + +namespace c2t +{ + + +static const F32 CLIPPER_SCALE_FACT = 1000.0f; +static const F32 CLIPPER_SCALE_FACT_INVERSE = 0.001f; + +///////////////////////////////// + +Point::Point() +{ + x = 0; + y = 0; +} + +Point::Point(const Point& pt) +{ + x = pt.x; + y = pt.y; +} + + +///////////////////////////////// + +clip2tri::clip2tri() : openSubject(false) +{ + // Do nothing! +} + +clip2tri::~clip2tri() +{ + // Do nothing! +} + + +void clip2tri::triangulate(const vector > &inputPolygons, vector &outputTriangles, + const vector &boundingPolygon) +{ + // Use clipper to clean. This upscales the floating point input + PolyTree solution; + mergePolysToPolyTree(inputPolygons, solution); + + Path bounds = upscaleClipperPoints(boundingPolygon); + + // This will downscale the Clipper output and use poly2tri to triangulate + triangulateComplex(outputTriangles, bounds, solution); +} + +void clip2tri::addClipPolygon(const Path &path) +{ + try // prevent any exception to spill into Qt + { + clipper.AddPath(path, ptClip, true); + } + catch(QtClipperLib::clipperException &e) + { + printf("addClipPolygon: %s\n", e.what()); + } +} + +void clip2tri::addSubjectPath(const Path &path, bool closed) +{ + try // prevent any exception to spill into Qt + { + clipper.AddPath(path, ptSubject, closed); + } + catch(QtClipperLib::clipperException &e) + { + printf("addSubjectPath: %s\n", e.what()); + return; + } + if (!closed) + openSubject = true; +} + +void clip2tri::clearClipper() +{ + // clear doesn't throw + clipper.Clear(); + openSubject = false; +} + +static QtClipperLib::ClipType operation(const clip2tri::Operation &op) +{ + switch (op) { + case clip2tri::Intersection: + return QtClipperLib::ctIntersection; + case clip2tri::Union: + return QtClipperLib::ctUnion; + case clip2tri::Difference: + return QtClipperLib::ctDifference; + case clip2tri::Xor: + return QtClipperLib::ctXor; + } + return ctIntersection; +} + +static std::string operationName(const clip2tri::Operation &op) +{ + switch (op) { + case clip2tri::Intersection: + return std::string("Intersection"); + case clip2tri::Union: + return std::string("Union"); + case clip2tri::Difference: + return std::string("Difference"); + case clip2tri::Xor: + return std::string("Xor"); + } + return std::string("Intersection"); +} + +Paths clip2tri::execute(const clip2tri::Operation op, const PolyFillType subjFillType, const PolyFillType clipFillType) +{ + Paths solution; + try // prevent any exception from spilling into Qt + { + if (!openSubject) { + clipper.Execute(operation(op), solution, subjFillType, clipFillType); + } else { + PolyTree res; + clipper.Execute(operation(op), res, subjFillType, clipFillType); + PolyNode *n = res.GetFirst(); + if (n) { + solution.push_back(n->Contour); + while ((n = n->GetNext())) + solution.push_back(n->Contour); + } + } + } + catch(QtClipperLib::clipperException &e) + { + printf("executing %s: %s\n", operationName(op).c_str(), e.what()); + } + return solution; +} + +int clip2tri::pointInPolygon(const IntPoint &pt, const Path &path) +{ + return PointInPolygon(pt, path); +} + +Path clip2tri::upscaleClipperPoints(const vector &inputPolygon) +{ + Path outputPolygon; + outputPolygon.resize(inputPolygon.size()); + + for(S32 i = 0; i < inputPolygon.size(); i++) + outputPolygon[i] = IntPoint(S64(inputPolygon[i].x * CLIPPER_SCALE_FACT), S64(inputPolygon[i].y * CLIPPER_SCALE_FACT)); + + return outputPolygon; +} + + +Paths clip2tri::upscaleClipperPoints(const vector > &inputPolygons) +{ + Paths outputPolygons; + + outputPolygons.resize(inputPolygons.size()); + + for(S32 i = 0; i < inputPolygons.size(); i++) + { + outputPolygons[i].resize(inputPolygons[i].size()); + + for(S32 j = 0; j < inputPolygons[i].size(); j++) + outputPolygons[i][j] = IntPoint(S64(inputPolygons[i][j].x * CLIPPER_SCALE_FACT), S64(inputPolygons[i][j].y * CLIPPER_SCALE_FACT)); + } + + return outputPolygons; +} + + +vector > clip2tri::downscaleClipperPoints(const Paths &inputPolygons) +{ + vector > outputPolygons; + + outputPolygons.resize(inputPolygons.size()); + + for(U32 i = 0; i < inputPolygons.size(); i++) + { + outputPolygons[i].resize(inputPolygons[i].size()); + + for(U32 j = 0; j < inputPolygons[i].size(); j++) + outputPolygons[i][j] = Point(F32(inputPolygons[i][j].X) * CLIPPER_SCALE_FACT_INVERSE, F32(inputPolygons[i][j].Y) * CLIPPER_SCALE_FACT_INVERSE); + } + + return outputPolygons; +} + + +// Use Clipper to merge inputPolygons, placing the result in a Polytree +// NOTE: this does NOT downscale the Clipper points. You must do this afterwards +// +// Here you add all your non-navigatable objects (e.g. walls, barriers, etc.) +bool clip2tri::mergePolysToPolyTree(const vector > &inputPolygons, PolyTree &solution) +{ + Paths input = upscaleClipperPoints(inputPolygons); + + // Fire up clipper and union! + Clipper clipper; + clipper.StrictlySimple(true); + + try // there is a "throw" in AddPolygon + { + clipper.AddPaths(input, ptSubject, true); + } + catch(QtClipperLib::clipperException &e) + { + printf("mergePolysToPolyTree: %s\n", e.what()); + } + + return clipper.Execute(ctUnion, solution, pftNonZero, pftNonZero); +} + + +// Delete all poly2tri points from a vector and clear the vector +static void deleteAndClear(vector &vec) +{ + for(U32 i = 0; i < vec.size(); i++) + delete vec[i]; + + vec.clear(); +} + + +// Shrink large polygons by reducing each coordinate by 1 in the +// general direction of the last point as we wind around +// +// This normally wouldn't work in every case, but our upscaled-by-1000 polygons +// have little chance to create new duplicate points with this method. +// +// For information on why this was needed, see: +// +// https://code.google.com/p/poly2tri/issues/detail?id=90 +// +static void edgeShrink(Path &path) +{ + U32 prev = path.size() - 1; + for(U32 i = 0; i < path.size(); i++) + { + // Adjust coordinate by 1 depending on the direction + path[i].X - path[prev].X > 0 ? path[i].X-- : path[i].X++; + path[i].Y - path[prev].Y > 0 ? path[i].Y-- : path[i].Y++; + + prev = i; + } +} + + +// This uses poly2tri to triangulate. poly2tri isn't very robust so clipper needs to do +// the cleaning of points before getting here. +// +// A tree structure of polygons is required for doing complex polygons-within-polygons. +// For reference discussion on how this started to be developed, see here: +// +// https://code.google.com/p/poly2tri/issues/detail?id=74 +// +// For assistance with a special case crash, see this utility: +// http://javascript.poly2tri.googlecode.com/hg/index.html +// +// FIXME: what is ignoreFills and ignoreHoles for? kaen? +bool clip2tri::triangulateComplex(vector &outputTriangles, const Path &outline, + const PolyTree &polyTree, bool ignoreFills, bool ignoreHoles) +{ + // Keep track of memory for all the poly2tri objects we create + vector cdtRegistry; + vector > holesRegistry; + vector > polylinesRegistry; + + + // Let's be tricky and add our outline to the root node (it should have none), it'll be + // our first Clipper hole + PolyNode *rootNode = NULL; + + PolyNode tempNode; + if(polyTree.Total() == 0) // Polytree is empty with no root node, e.g. on an empty level + rootNode = &tempNode; + else + rootNode = polyTree.GetFirst()->Parent; + + rootNode->Contour = outline; + + // Now traverse our polyline nodes and triangulate them with only their children holes + PolyNode *currentNode = rootNode; + while(currentNode != NULL) + { + // A Clipper hole is actually what we want to build zones for; they become our bounding + // polylines. poly2tri holes are therefore the inverse + if((!ignoreHoles && currentNode->IsHole()) || + (!ignoreFills && !currentNode->IsHole())) + { + // Build up this polyline in poly2tri's format (downscale Clipper points) + vector polyline; + for(U32 j = 0; j < currentNode->Contour.size(); j++) + polyline.push_back(new p2t::Point(F64(currentNode->Contour[j].X), F64(currentNode->Contour[j].Y))); + + polylinesRegistry.push_back(polyline); // Memory + + // Set our polyline in poly2tri + p2t::CDT* cdt = new p2t::CDT(polyline); + cdtRegistry.push_back(cdt); + + for(U32 j = 0; j < currentNode->Childs.size(); j++) + { + PolyNode *childNode = currentNode->Childs[j]; + + // Slightly modify the polygon to guarantee no duplicate points + edgeShrink(childNode->Contour); + + vector hole; + for(U32 k = 0; k < childNode->Contour.size(); k++) + hole.push_back(new p2t::Point(F64(childNode->Contour[k].X), F64(childNode->Contour[k].Y))); + + holesRegistry.push_back(hole); // Memory + + // Add the holes for this polyline + cdt->AddHole(hole); + } + + cdt->Triangulate(); + + // Add current output triangles to our total + vector currentOutput = cdt->GetTriangles(); + + // Copy our data to TNL::Point and to our output Vector + p2t::Triangle *currentTriangle; + for(U32 j = 0; j < currentOutput.size(); j++) + { + currentTriangle = currentOutput[j]; + outputTriangles.push_back(Point(currentTriangle->GetPoint(0)->x * CLIPPER_SCALE_FACT_INVERSE, currentTriangle->GetPoint(0)->y * CLIPPER_SCALE_FACT_INVERSE)); + outputTriangles.push_back(Point(currentTriangle->GetPoint(1)->x * CLIPPER_SCALE_FACT_INVERSE, currentTriangle->GetPoint(1)->y * CLIPPER_SCALE_FACT_INVERSE)); + outputTriangles.push_back(Point(currentTriangle->GetPoint(2)->x * CLIPPER_SCALE_FACT_INVERSE, currentTriangle->GetPoint(2)->y * CLIPPER_SCALE_FACT_INVERSE)); + } + } + + currentNode = currentNode->GetNext(); + } + + + // Clean up memory used with poly2tri + // + // Clean-up workers + for(S32 i = 0; i < cdtRegistry.size(); i++) + delete cdtRegistry[i]; + + // Free the polylines + for(S32 i = 0; i < polylinesRegistry.size(); i++) + { + vector polyline = polylinesRegistry[i]; + deleteAndClear(polyline); + } + + // Free the holes + for(S32 i = 0; i < holesRegistry.size(); i++) + { + vector hole = holesRegistry[i]; + deleteAndClear(hole); + } + + // Make sure we have output data + if(outputTriangles.size() == 0) + return false; + + return true; +} + + +} /* namespace c2t */ diff --git a/src/3rdparty/clip2tri/clip2tri.h b/src/3rdparty/clip2tri/clip2tri.h new file mode 100644 index 0000000..3848d00 --- /dev/null +++ b/src/3rdparty/clip2tri/clip2tri.h @@ -0,0 +1,102 @@ +/* + * Authors: kaen, raptor, sam686, watusimoto + * + * Originally from the bitfighter source code + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Bitfighter developers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CLIP2TRI_H_ +#define CLIP2TRI_H_ + +#include +#include + +using namespace std; +using namespace QtClipperLib; + +namespace c2t +{ + +typedef signed int S32; +typedef signed long long S64; +typedef unsigned int U32; +typedef float F32; +typedef double F64; + + +struct Point +{ + F32 x; + F32 y; + + Point(); + Point(const Point &pt); + + template + Point(T in_x, U in_y) { x = static_cast(in_x); y = static_cast(in_y); } +}; + +class clip2tri +{ +private: + // + Path upscaleClipperPoints(const vector &inputPolygon); + + // These operate on a vector of polygons + Paths upscaleClipperPoints(const vector > &inputPolygons); + vector > downscaleClipperPoints(const Paths &inputPolygons); + + bool mergePolysToPolyTree(const vector > &inputPolygons, PolyTree &solution); + + bool triangulateComplex(vector &outputTriangles, const Path &outline, + const PolyTree &polyTree, bool ignoreFills = true, bool ignoreHoles = false); + +public: + enum Operation { Union, Intersection, Difference, Xor }; + clip2tri(); + virtual ~clip2tri(); + + void triangulate(const vector > &inputPolygons, vector &outputTriangles, + const vector &boundingPolygon); + + // Clip polygons are intended as closed, even if the first and last vertex aren't the same. + void addClipPolygon(const Path &path); + // Closed means the path has to be effectively closed. Meaning path[0] == path[path.size()-1] + void addSubjectPath(const Path &path, bool closed); + + void clearClipper(); + + Paths execute(const Operation op, + const PolyFillType subjFillType = pftNonZero, + const PolyFillType clipFillType = pftNonZero); + + static int pointInPolygon(const IntPoint &pt, const Path &path); + + Clipper clipper; + bool openSubject; +}; + +} /* namespace c2t */ + +#endif /* CLIP2TRI_H_ */ diff --git a/src/3rdparty/clip2tri/qt_attribution.json b/src/3rdparty/clip2tri/qt_attribution.json new file mode 100644 index 0000000..a4a1f18 --- /dev/null +++ b/src/3rdparty/clip2tri/qt_attribution.json @@ -0,0 +1,13 @@ +{ + "Id": "clip2tri", + "Name": "Clip2Tri Polygon Triangulation Library", + "QDocModule": "qtpositioning", + "QtUsage": "Used in the QML plugin of Qt Location and in Qt Positioning.", + + "Description": "Clip2Tri can be used together with Clipper for robust triangulation.", + "Homepage": "https://github.com/raptor/clip2tri", + "LicenseId": "MIT", + "License": "MIT License", + "LicenseFile": "LICENSE", + "Copyright": "Copyright (c) 2014 Bitfighter developers" +} diff --git a/src/3rdparty/clipper/CMakeLists.txt b/src/3rdparty/clipper/CMakeLists.txt new file mode 100644 index 0000000..08f2fad --- /dev/null +++ b/src/3rdparty/clipper/CMakeLists.txt @@ -0,0 +1,25 @@ +# Generated from clipper.pro. + +##################################################################### +## Bundled_Clipper Generic Library: +##################################################################### + +qt_internal_add_3rdparty_library(Bundled_Clipper + QMAKE_LIB_NAME _clipper + STATIC + SKIP_AUTOMOC # special case + EXCEPTIONS + SOURCES + clipper.cpp clipper.h +) +qt_disable_warnings(Bundled_Clipper) +qt_set_symbol_visibility_hidden(Bundled_Clipper) + +## Scopes: +##################################################################### + +#### Keys ignored in scope 3:.:.:clipper.pro:GCC: +# QMAKE_CFLAGS_OPTIMIZE_FULL = "-ffast-math" + +#### Keys ignored in scope 4:.:.:clipper.pro:NOT CLANG AND NOT ICC AND NOT rim_qcc: +# QMAKE_CXXFLAGS_WARN_ON = "-Wno-error=return-type" diff --git a/src/3rdparty/clipper/LICENSE b/src/3rdparty/clipper/LICENSE new file mode 100644 index 0000000..2213e37 --- /dev/null +++ b/src/3rdparty/clipper/LICENSE @@ -0,0 +1,48 @@ +Use, modification & distribution is subject to Boost Software License Ver 1. +http://www.boost.org/LICENSE_1_0.txt + +Attributions: +The code in this library is an extension of Bala Vatti's clipping algorithm: +"A generic solution to polygon clipping" +Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. +http://portal.acm.org/citation.cfm?id=129906 + +Computer graphics and geometric modeling: implementation and algorithms +By Max K. Agoston +Springer; 1 edition (January 4, 2005) +http://books.google.com/books?q=vatti+clipping+agoston + +See also: +"Polygon Offsetting by Computing Winding Numbers" +Paper no. DETC2005-85513 pp. 565-575 +ASME 2005 International Design Engineering Technical Conferences +and Computers and Information in Engineering Conference (IDETC/CIE2005) +September 24-28, 2005 , Long Beach, California, USA +http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf + + + +Boost Software License - Version 1.0 - August 17th, 2003 +http://www.boost.org/LICENSE_1_0.txt + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/3rdparty/clipper/clipper.cpp b/src/3rdparty/clipper/clipper.cpp new file mode 100644 index 0000000..d973564 --- /dev/null +++ b/src/3rdparty/clipper/clipper.cpp @@ -0,0 +1,4629 @@ +/******************************************************************************* +* * +* Author : Angus Johnson * +* Version : 6.4.2 * +* Date : 27 February 2017 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2017 * +* * +* License: * +* Use, modification & distribution is subject to Boost Software License Ver 1. * +* http://www.boost.org/LICENSE_1_0.txt * +* * +* Attributions: * +* The code in this library is an extension of Bala Vatti's clipping algorithm: * +* "A generic solution to polygon clipping" * +* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * +* http://portal.acm.org/citation.cfm?id=129906 * +* * +* Computer graphics and geometric modeling: implementation and algorithms * +* By Max K. Agoston * +* Springer; 1 edition (January 4, 2005) * +* http://books.google.com/books?q=vatti+clipping+agoston * +* * +* See also: * +* "Polygon Offsetting by Computing Winding Numbers" * +* Paper no. DETC2005-85513 pp. 565-575 * +* ASME 2005 International Design Engineering Technical Conferences * +* and Computers and Information in Engineering Conference (IDETC/CIE2005) * +* September 24-28, 2005 , Long Beach, California, USA * +* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * +* * +*******************************************************************************/ + +/******************************************************************************* +* * +* This is a translation of the Delphi Clipper library and the naming style * +* used has retained a Delphi flavour. * +* * +*******************************************************************************/ + +#include "clipper.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace QtClipperLib { + +static double const pi = 3.141592653589793238; +static double const two_pi = pi *2; +static double const def_arc_tolerance = 0.25; + +enum Direction { dRightToLeft, dLeftToRight }; + +static int const Unassigned = -1; //edge not currently 'owning' a solution +static int const Skip = -2; //edge that would otherwise close a path + +#define HORIZONTAL (-1.0E+40) +#define TOLERANCE (1.0e-20) +#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE)) + +struct TEdge { + IntPoint Bot; + IntPoint Curr; //current (updated for every new scanbeam) + IntPoint Top; + double Dx; + PolyType PolyTyp; + EdgeSide Side; //side only refers to current side of solution poly + int WindDelta; //1 or -1 depending on winding direction + int WindCnt; + int WindCnt2; //winding count of the opposite polytype + int OutIdx; + TEdge *Next; + TEdge *Prev; + TEdge *NextInLML; + TEdge *NextInAEL; + TEdge *PrevInAEL; + TEdge *NextInSEL; + TEdge *PrevInSEL; +}; + +struct IntersectNode { + TEdge *Edge1; + TEdge *Edge2; + IntPoint Pt; +}; + +struct LocalMinimum { + cInt Y; + TEdge *LeftBound; + TEdge *RightBound; +}; + +struct OutPt; + +//OutRec: contains a path in the clipping solution. Edges in the AEL will +//carry a pointer to an OutRec when they are part of the clipping solution. +struct OutRec { + int Idx; + bool IsHole; + bool IsOpen; + OutRec *FirstLeft; //see comments in clipper.pas + PolyNode *PolyNd; + OutPt *Pts; + OutPt *BottomPt; +}; + +struct OutPt { + int Idx; + IntPoint Pt; + OutPt *Next; + OutPt *Prev; +}; + +struct Join { + OutPt *OutPt1; + OutPt *OutPt2; + IntPoint OffPt; +}; + +struct LocMinSorter +{ + inline bool operator()(const LocalMinimum& locMin1, const LocalMinimum& locMin2) + { + return locMin2.Y < locMin1.Y; + } +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +inline cInt Round(double val) +{ + if ((val < 0)) return static_cast(val - 0.5); + else return static_cast(val + 0.5); +} +//------------------------------------------------------------------------------ + +inline cInt Abs(cInt val) +{ + return val < 0 ? -val : val; +} + +//------------------------------------------------------------------------------ +// PolyTree methods ... +//------------------------------------------------------------------------------ + +void PolyTree::Clear() +{ + for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i) + delete AllNodes[i]; + AllNodes.resize(0); + Childs.resize(0); +} +//------------------------------------------------------------------------------ + +PolyNode* PolyTree::GetFirst() const +{ + if (!Childs.empty()) + return Childs[0]; + else + return 0; +} +//------------------------------------------------------------------------------ + +int PolyTree::Total() const +{ + int result = (int)AllNodes.size(); + //with negative offsets, ignore the hidden outer polygon ... + if (result > 0 && Childs[0] != AllNodes[0]) result--; + return result; +} + +//------------------------------------------------------------------------------ +// PolyNode methods ... +//------------------------------------------------------------------------------ + +PolyNode::PolyNode(): Parent(0), Index(0), m_IsOpen(false) +{ +} +//------------------------------------------------------------------------------ + +int PolyNode::ChildCount() const +{ + return (int)Childs.size(); +} +//------------------------------------------------------------------------------ + +void PolyNode::AddChild(PolyNode& child) +{ + unsigned cnt = (unsigned)Childs.size(); + Childs.push_back(&child); + child.Parent = this; + child.Index = cnt; +} +//------------------------------------------------------------------------------ + +PolyNode* PolyNode::GetNext() const +{ + if (!Childs.empty()) + return Childs[0]; + else + return GetNextSiblingUp(); +} +//------------------------------------------------------------------------------ + +PolyNode* PolyNode::GetNextSiblingUp() const +{ + if (!Parent) //protects against PolyTree.GetNextSiblingUp() + return 0; + else if (Index == Parent->Childs.size() - 1) + return Parent->GetNextSiblingUp(); + else + return Parent->Childs[Index + 1]; +} +//------------------------------------------------------------------------------ + +bool PolyNode::IsHole() const +{ + bool result = true; + PolyNode* node = Parent; + while (node) + { + result = !result; + node = node->Parent; + } + return result; +} +//------------------------------------------------------------------------------ + +bool PolyNode::IsOpen() const +{ + return m_IsOpen; +} +//------------------------------------------------------------------------------ + +#ifndef use_int32 + +//------------------------------------------------------------------------------ +// Int128 class (enables safe math on signed 64bit integers) +// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1 +// Int128 val2((long64)9223372036854775807); +// Int128 val3 = val1 * val2; +// val3.AsString => "85070591730234615847396907784232501249" (8.5e+37) +//------------------------------------------------------------------------------ + +class Int128 +{ + public: + ulong64 lo; + long64 hi; + + Int128(long64 _lo = 0) + { + lo = (ulong64)_lo; + if (_lo < 0) hi = -1; else hi = 0; + } + + + Int128(const Int128 &val): lo(val.lo), hi(val.hi){} + + Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){} + + Int128& operator = (const long64 &val) + { + lo = (ulong64)val; + if (val < 0) hi = -1; else hi = 0; + return *this; + } + + bool operator == (const Int128 &val) const + {return (hi == val.hi && lo == val.lo);} + + bool operator != (const Int128 &val) const + { return !(*this == val);} + + bool operator > (const Int128 &val) const + { + if (hi != val.hi) + return hi > val.hi; + else + return lo > val.lo; + } + + bool operator < (const Int128 &val) const + { + if (hi != val.hi) + return hi < val.hi; + else + return lo < val.lo; + } + + bool operator >= (const Int128 &val) const + { return !(*this < val);} + + bool operator <= (const Int128 &val) const + { return !(*this > val);} + + Int128& operator += (const Int128 &rhs) + { + hi += rhs.hi; + lo += rhs.lo; + if (lo < rhs.lo) hi++; + return *this; + } + + Int128 operator + (const Int128 &rhs) const + { + Int128 result(*this); + result+= rhs; + return result; + } + + Int128& operator -= (const Int128 &rhs) + { + *this += -rhs; + return *this; + } + + Int128 operator - (const Int128 &rhs) const + { + Int128 result(*this); + result -= rhs; + return result; + } + + Int128 operator-() const //unary negation + { + if (lo == 0) + return Int128(-hi, 0); + else + return Int128(~hi, ~lo + 1); + } + + operator double() const + { + const double shift64 = 18446744073709551616.0; //2^64 + if (hi < 0) + { + if (lo == 0) return (double)hi * shift64; + else return -(double)(~lo + ~hi * shift64); + } + else + return (double)(lo + hi * shift64); + } + +}; +//------------------------------------------------------------------------------ + +Int128 Int128Mul (long64 lhs, long64 rhs) +{ + bool negate = (lhs < 0) != (rhs < 0); + + if (lhs < 0) lhs = -lhs; + ulong64 int1Hi = ulong64(lhs) >> 32; + ulong64 int1Lo = ulong64(lhs & 0xFFFFFFFF); + + if (rhs < 0) rhs = -rhs; + ulong64 int2Hi = ulong64(rhs) >> 32; + ulong64 int2Lo = ulong64(rhs & 0xFFFFFFFF); + + //nb: see comments in clipper.pas + ulong64 a = int1Hi * int2Hi; + ulong64 b = int1Lo * int2Lo; + ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi; + + Int128 tmp; + tmp.hi = long64(a + (c >> 32)); + tmp.lo = long64(c << 32); + tmp.lo += long64(b); + if (tmp.lo < b) tmp.hi++; + if (negate) tmp = -tmp; + return tmp; +}; +#endif + +//------------------------------------------------------------------------------ +// Miscellaneous global functions +//------------------------------------------------------------------------------ + +bool Orientation(const Path &poly) +{ + return Area(poly) >= 0; +} +//------------------------------------------------------------------------------ + +double Area(const Path &poly) +{ + int size = (int)poly.size(); + if (size < 3) return 0; + + double a = 0; + for (int i = 0, j = size -1; i < size; ++i) + { + a += ((double)poly[j].X + poly[i].X) * ((double)poly[j].Y - poly[i].Y); + j = i; + } + return -a * 0.5; +} +//------------------------------------------------------------------------------ + +double Area(const OutPt *op) +{ + const OutPt *startOp = op; + if (!op) return 0; + double a = 0; + do { + a += (double)(op->Prev->Pt.X + op->Pt.X) * (double)(op->Prev->Pt.Y - op->Pt.Y); + op = op->Next; + } while (op != startOp); + return a * 0.5; +} +//------------------------------------------------------------------------------ + +double Area(const OutRec &outRec) +{ + return Area(outRec.Pts); +} +//------------------------------------------------------------------------------ + +bool PointIsVertex(const IntPoint &Pt, OutPt *pp) +{ + OutPt *pp2 = pp; + do + { + if (pp2->Pt == Pt) return true; + pp2 = pp2->Next; + } + while (pp2 != pp); + return false; +} +//------------------------------------------------------------------------------ + +//See "The Point in Polygon Problem for Arbitrary Polygons" by Hormann & Agathos +//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf +int PointInPolygon(const IntPoint &pt, const Path &path) +{ + //returns 0 if false, +1 if true, -1 if pt ON polygon boundary + int result = 0; + size_t cnt = path.size(); + if (cnt < 3) return 0; + IntPoint ip = path[0]; + for(size_t i = 1; i <= cnt; ++i) + { + IntPoint ipNext = (i == cnt ? path[0] : path[i]); + if (ipNext.Y == pt.Y) + { + if ((ipNext.X == pt.X) || (ip.Y == pt.Y && + ((ipNext.X > pt.X) == (ip.X < pt.X)))) return -1; + } + if ((ip.Y < pt.Y) != (ipNext.Y < pt.Y)) + { + if (ip.X >= pt.X) + { + if (ipNext.X > pt.X) result = 1 - result; + else + { + double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) - + (double)(ipNext.X - pt.X) * (ip.Y - pt.Y); + if (!d) return -1; + if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result; + } + } else + { + if (ipNext.X > pt.X) + { + double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) - + (double)(ipNext.X - pt.X) * (ip.Y - pt.Y); + if (!d) return -1; + if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result; + } + } + } + ip = ipNext; + } + return result; +} +//------------------------------------------------------------------------------ + +int PointInPolygon (const IntPoint &pt, OutPt *op) +{ + //returns 0 if false, +1 if true, -1 if pt ON polygon boundary + int result = 0; + OutPt* startOp = op; + for(;;) + { + if (op->Next->Pt.Y == pt.Y) + { + if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y && + ((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1; + } + if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y)) + { + if (op->Pt.X >= pt.X) + { + if (op->Next->Pt.X > pt.X) result = 1 - result; + else + { + double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - + (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y); + if (!d) return -1; + if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result; + } + } else + { + if (op->Next->Pt.X > pt.X) + { + double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) - + (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y); + if (!d) return -1; + if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result; + } + } + } + op = op->Next; + if (startOp == op) break; + } + return result; +} +//------------------------------------------------------------------------------ + +bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2) +{ + OutPt* op = OutPt1; + do + { + //nb: PointInPolygon returns 0 if false, +1 if true, -1 if pt on polygon + int res = PointInPolygon(op->Pt, OutPt2); + if (res >= 0) return res > 0; + op = op->Next; + } + while (op != OutPt1); + return true; +} +//---------------------------------------------------------------------- + +bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range) +{ +#ifndef use_int32 + if (UseFullInt64Range) + return Int128Mul(e1.Top.Y - e1.Bot.Y, e2.Top.X - e2.Bot.X) == + Int128Mul(e1.Top.X - e1.Bot.X, e2.Top.Y - e2.Bot.Y); + else +#endif + return (e1.Top.Y - e1.Bot.Y) * (e2.Top.X - e2.Bot.X) == + (e1.Top.X - e1.Bot.X) * (e2.Top.Y - e2.Bot.Y); +} +//------------------------------------------------------------------------------ + +bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, + const IntPoint pt3, bool UseFullInt64Range) +{ +#ifndef use_int32 + if (UseFullInt64Range) + return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y); + else +#endif + return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); +} +//------------------------------------------------------------------------------ + +bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, + const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range) +{ +#ifndef use_int32 + if (UseFullInt64Range) + return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y); + else +#endif + return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); +} +//------------------------------------------------------------------------------ + +inline bool IsHorizontal(TEdge &e) +{ + return e.Dx == HORIZONTAL; +} +//------------------------------------------------------------------------------ + +inline double GetDx(const IntPoint pt1, const IntPoint pt2) +{ + return (pt1.Y == pt2.Y) ? + HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y); +} +//--------------------------------------------------------------------------- + +inline void SetDx(TEdge &e) +{ + cInt dy = (e.Top.Y - e.Bot.Y); + if (dy == 0) e.Dx = HORIZONTAL; + else e.Dx = (double)(e.Top.X - e.Bot.X) / dy; +} +//--------------------------------------------------------------------------- + +inline void SwapSides(TEdge &Edge1, TEdge &Edge2) +{ + EdgeSide Side = Edge1.Side; + Edge1.Side = Edge2.Side; + Edge2.Side = Side; +} +//------------------------------------------------------------------------------ + +inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2) +{ + int OutIdx = Edge1.OutIdx; + Edge1.OutIdx = Edge2.OutIdx; + Edge2.OutIdx = OutIdx; +} +//------------------------------------------------------------------------------ + +inline cInt TopX(TEdge &edge, const cInt currentY) +{ + return ( currentY == edge.Top.Y ) ? + edge.Top.X : edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y)); +} +//------------------------------------------------------------------------------ + +void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip) +{ +#ifdef use_xyz + ip.Z = 0; +#endif + + double b1, b2; + if (Edge1.Dx == Edge2.Dx) + { + ip.Y = Edge1.Curr.Y; + ip.X = TopX(Edge1, ip.Y); + return; + } + else if (Edge1.Dx == 0) + { + ip.X = Edge1.Bot.X; + if (IsHorizontal(Edge2)) + ip.Y = Edge2.Bot.Y; + else + { + b2 = Edge2.Bot.Y - (Edge2.Bot.X / Edge2.Dx); + ip.Y = Round(ip.X / Edge2.Dx + b2); + } + } + else if (Edge2.Dx == 0) + { + ip.X = Edge2.Bot.X; + if (IsHorizontal(Edge1)) + ip.Y = Edge1.Bot.Y; + else + { + b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx); + ip.Y = Round(ip.X / Edge1.Dx + b1); + } + } + else + { + b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx; + b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx; + double q = (b2-b1) / (Edge1.Dx - Edge2.Dx); + ip.Y = Round(q); + if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) + ip.X = Round(Edge1.Dx * q + b1); + else + ip.X = Round(Edge2.Dx * q + b2); + } + + if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y) + { + if (Edge1.Top.Y > Edge2.Top.Y) + ip.Y = Edge1.Top.Y; + else + ip.Y = Edge2.Top.Y; + if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) + ip.X = TopX(Edge1, ip.Y); + else + ip.X = TopX(Edge2, ip.Y); + } + //finally, don't allow 'ip' to be BELOW curr.Y (ie bottom of scanbeam) ... + if (ip.Y > Edge1.Curr.Y) + { + ip.Y = Edge1.Curr.Y; + //use the more vertical edge to derive X ... + if (std::fabs(Edge1.Dx) > std::fabs(Edge2.Dx)) + ip.X = TopX(Edge2, ip.Y); else + ip.X = TopX(Edge1, ip.Y); + } +} +//------------------------------------------------------------------------------ + +void ReversePolyPtLinks(OutPt *pp) +{ + if (!pp) return; + OutPt *pp1, *pp2; + pp1 = pp; + do { + pp2 = pp1->Next; + pp1->Next = pp1->Prev; + pp1->Prev = pp2; + pp1 = pp2; + } while( pp1 != pp ); +} +//------------------------------------------------------------------------------ + +void DisposeOutPts(OutPt*& pp) +{ + if (pp == 0) return; + pp->Prev->Next = 0; + while( pp ) + { + OutPt *tmpPp = pp; + pp = pp->Next; + delete tmpPp; + } +} +//------------------------------------------------------------------------------ + +inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt) +{ + std::memset(e, 0, sizeof(TEdge)); + e->Next = eNext; + e->Prev = ePrev; + e->Curr = Pt; + e->OutIdx = Unassigned; +} +//------------------------------------------------------------------------------ + +void InitEdge2(TEdge& e, PolyType Pt) +{ + if (e.Curr.Y >= e.Next->Curr.Y) + { + e.Bot = e.Curr; + e.Top = e.Next->Curr; + } else + { + e.Top = e.Curr; + e.Bot = e.Next->Curr; + } + SetDx(e); + e.PolyTyp = Pt; +} +//------------------------------------------------------------------------------ + +TEdge* RemoveEdge(TEdge* e) +{ + //removes e from double_linked_list (but without removing from memory) + e->Prev->Next = e->Next; + e->Next->Prev = e->Prev; + TEdge* result = e->Next; + e->Prev = 0; //flag as removed (see ClipperBase.Clear) + return result; +} +//------------------------------------------------------------------------------ + +inline void ReverseHorizontal(TEdge &e) +{ + //swap horizontal edges' Top and Bottom x's so they follow the natural + //progression of the bounds - ie so their xbots will align with the + //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] + std::swap(e.Top.X, e.Bot.X); +#ifdef use_xyz + std::swap(e.Top.Z, e.Bot.Z); +#endif +} +//------------------------------------------------------------------------------ + +void SwapPoints(IntPoint &pt1, IntPoint &pt2) +{ + IntPoint tmp = pt1; + pt1 = pt2; + pt2 = tmp; +} +//------------------------------------------------------------------------------ + +bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, + IntPoint pt2b, IntPoint &pt1, IntPoint &pt2) +{ + //precondition: segments are Collinear. + if (Abs(pt1a.X - pt1b.X) > Abs(pt1a.Y - pt1b.Y)) + { + if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b); + if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b); + if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a; + if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b; + return pt1.X < pt2.X; + } else + { + if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b); + if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b); + if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a; + if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b; + return pt1.Y > pt2.Y; + } +} +//------------------------------------------------------------------------------ + +bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) +{ + OutPt *p = btmPt1->Prev; + while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev; + double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt)); + p = btmPt1->Next; + while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next; + double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt)); + + p = btmPt2->Prev; + while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev; + double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt)); + p = btmPt2->Next; + while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next; + double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt)); + + if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) && + std::min(dx1p, dx1n) == std::min(dx2p, dx2n)) + return Area(btmPt1) > 0; //if otherwise identical use orientation + else + return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); +} +//------------------------------------------------------------------------------ + +OutPt* GetBottomPt(OutPt *pp) +{ + OutPt* dups = 0; + OutPt* p = pp->Next; + while (p != pp) + { + if (p->Pt.Y > pp->Pt.Y) + { + pp = p; + dups = 0; + } + else if (p->Pt.Y == pp->Pt.Y && p->Pt.X <= pp->Pt.X) + { + if (p->Pt.X < pp->Pt.X) + { + dups = 0; + pp = p; + } else + { + if (p->Next != pp && p->Prev != pp) dups = p; + } + } + p = p->Next; + } + if (dups) + { + //there appears to be at least 2 vertices at BottomPt so ... + while (dups != p) + { + if (!FirstIsBottomPt(p, dups)) pp = dups; + dups = dups->Next; + while (dups->Pt != pp->Pt) dups = dups->Next; + } + } + return pp; +} +//------------------------------------------------------------------------------ + +bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1, + const IntPoint pt2, const IntPoint pt3) +{ + if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2)) + return false; + else if (pt1.X != pt3.X) + return (pt2.X > pt1.X) == (pt2.X < pt3.X); + else + return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y); +} +//------------------------------------------------------------------------------ + +bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b) +{ + if (seg1a > seg1b) std::swap(seg1a, seg1b); + if (seg2a > seg2b) std::swap(seg2a, seg2b); + return (seg1a < seg2b) && (seg2a < seg1b); +} + +//------------------------------------------------------------------------------ +// ClipperBase class methods ... +//------------------------------------------------------------------------------ + +ClipperBase::ClipperBase() //constructor +{ + m_CurrentLM = m_MinimaList.begin(); //begin() == end() here + m_UseFullRange = false; +} +//------------------------------------------------------------------------------ + +ClipperBase::~ClipperBase() //destructor +{ + Clear(); +} +//------------------------------------------------------------------------------ + +void RangeTest(const IntPoint& Pt, bool& useFullRange) +{ + if (useFullRange) + { + if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) + throw clipperException("Coordinate outside allowed range"); + } + else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) + { + useFullRange = true; + RangeTest(Pt, useFullRange); + } +} +//------------------------------------------------------------------------------ + +TEdge* FindNextLocMin(TEdge* E) +{ + for (;;) + { + while (E->Bot != E->Prev->Bot || E->Curr == E->Top) E = E->Next; + if (!IsHorizontal(*E) && !IsHorizontal(*E->Prev)) break; + while (IsHorizontal(*E->Prev)) E = E->Prev; + TEdge* E2 = E; + while (IsHorizontal(*E)) E = E->Next; + if (E->Top.Y == E->Prev->Bot.Y) continue; //ie just an intermediate horz. + if (E2->Prev->Bot.X < E->Bot.X) E = E2; + break; + } + return E; +} +//------------------------------------------------------------------------------ + +TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward) +{ + TEdge *Result = E; + TEdge *Horz = 0; + + if (E->OutIdx == Skip) + { + //if edges still remain in the current bound beyond the skip edge then + //create another LocMin and call ProcessBound once more + if (NextIsForward) + { + while (E->Top.Y == E->Next->Bot.Y) E = E->Next; + //don't include top horizontals when parsing a bound a second time, + //they will be contained in the opposite bound ... + while (E != Result && IsHorizontal(*E)) E = E->Prev; + } + else + { + while (E->Top.Y == E->Prev->Bot.Y) E = E->Prev; + while (E != Result && IsHorizontal(*E)) E = E->Next; + } + + if (E == Result) + { + if (NextIsForward) Result = E->Next; + else Result = E->Prev; + } + else + { + //there are more edges in the bound beyond result starting with E + if (NextIsForward) + E = Result->Next; + else + E = Result->Prev; + MinimaList::value_type locMin; + locMin.Y = E->Bot.Y; + locMin.LeftBound = 0; + locMin.RightBound = E; + E->WindDelta = 0; + Result = ProcessBound(E, NextIsForward); + m_MinimaList.push_back(locMin); + } + return Result; + } + + TEdge *EStart; + + if (IsHorizontal(*E)) + { + //We need to be careful with open paths because this may not be a + //true local minima (ie E may be following a skip edge). + //Also, consecutive horz. edges may start heading left before going right. + if (NextIsForward) + EStart = E->Prev; + else + EStart = E->Next; + if (IsHorizontal(*EStart)) //ie an adjoining horizontal skip edge + { + if (EStart->Bot.X != E->Bot.X && EStart->Top.X != E->Bot.X) + ReverseHorizontal(*E); + } + else if (EStart->Bot.X != E->Bot.X) + ReverseHorizontal(*E); + } + + EStart = E; + if (NextIsForward) + { + while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip) + Result = Result->Next; + if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip) + { + //nb: at the top of a bound, horizontals are added to the bound + //only when the preceding edge attaches to the horizontal's left vertex + //unless a Skip edge is encountered when that becomes the top divide + Horz = Result; + while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev; + if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev; + } + while (E != Result) + { + E->NextInLML = E->Next; + if (IsHorizontal(*E) && E != EStart && + E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); + E = E->Next; + } + if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X) + ReverseHorizontal(*E); + Result = Result->Next; //move to the edge just beyond current bound + } else + { + while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip) + Result = Result->Prev; + if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip) + { + Horz = Result; + while (IsHorizontal(*Horz->Next)) Horz = Horz->Next; + if (Horz->Next->Top.X == Result->Prev->Top.X || + Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next; + } + + while (E != Result) + { + E->NextInLML = E->Prev; + if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) + ReverseHorizontal(*E); + E = E->Prev; + } + if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X) + ReverseHorizontal(*E); + Result = Result->Prev; //move to the edge just beyond current bound + } + + return Result; +} +//------------------------------------------------------------------------------ + +bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) +{ +#ifdef use_lines + if (!Closed && PolyTyp == ptClip) + throw clipperException("AddPath: Open paths must be subject."); +#else + if (!Closed) + throw clipperException("AddPath: Open paths have been disabled."); +#endif + + int highI = (int)pg.size() -1; + if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI; + while (highI > 0 && (pg[highI] == pg[highI -1])) --highI; + if ((Closed && highI < 2) || (!Closed && highI < 1)) return false; + + //create a new edge array ... + TEdge *edges = new TEdge [highI +1]; + + bool IsFlat = true; + //1. Basic (first) edge initialization ... + try + { + edges[1].Curr = pg[1]; + RangeTest(pg[0], m_UseFullRange); + RangeTest(pg[highI], m_UseFullRange); + InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]); + InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]); + for (int i = highI - 1; i >= 1; --i) + { + RangeTest(pg[i], m_UseFullRange); + InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]); + } + } + catch(...) + { + delete [] edges; + throw; //range test fails + } + TEdge *eStart = &edges[0]; + + //2. Remove duplicate vertices, and (when closed) collinear edges ... + TEdge *E = eStart, *eLoopStop = eStart; + for (;;) + { + //nb: allows matching start and end points when not Closed ... + if (E->Curr == E->Next->Curr && (Closed || E->Next != eStart)) + { + if (E == E->Next) break; + if (E == eStart) eStart = E->Next; + E = RemoveEdge(E); + eLoopStop = E; + continue; + } + if (E->Prev == E->Next) + break; //only two vertices + else if (Closed && + SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) && + (!m_PreserveCollinear || + !Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr))) + { + //Collinear edges are allowed for open paths but in closed paths + //the default is to merge adjacent collinear edges into a single edge. + //However, if the PreserveCollinear property is enabled, only overlapping + //collinear edges (ie spikes) will be removed from closed paths. + if (E == eStart) eStart = E->Next; + E = RemoveEdge(E); + E = E->Prev; + eLoopStop = E; + continue; + } + E = E->Next; + if ((E == eLoopStop) || (!Closed && E->Next == eStart)) break; + } + + if ((!Closed && (E == E->Next)) || (Closed && (E->Prev == E->Next))) + { + delete [] edges; + return false; + } + + if (!Closed) + { + m_HasOpenPaths = true; + eStart->Prev->OutIdx = Skip; + } + + //3. Do second stage of edge initialization ... + E = eStart; + do + { + InitEdge2(*E, PolyTyp); + E = E->Next; + if (IsFlat && E->Curr.Y != eStart->Curr.Y) IsFlat = false; + } + while (E != eStart); + + //4. Finally, add edge bounds to LocalMinima list ... + + //Totally flat paths must be handled differently when adding them + //to LocalMinima list to avoid endless loops etc ... + if (IsFlat) + { + if (Closed) + { + delete [] edges; + return false; + } + E->Prev->OutIdx = Skip; + MinimaList::value_type locMin; + locMin.Y = E->Bot.Y; + locMin.LeftBound = 0; + locMin.RightBound = E; + locMin.RightBound->Side = esRight; + locMin.RightBound->WindDelta = 0; + for (;;) + { + if (E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); + if (E->Next->OutIdx == Skip) break; + E->NextInLML = E->Next; + E = E->Next; + } + m_MinimaList.push_back(locMin); + m_edges.push_back(edges); + return true; + } + + m_edges.push_back(edges); + bool leftBoundIsForward; + TEdge* EMin = 0; + + //workaround to avoid an endless loop in the while loop below when + //open paths have matching start and end points ... + if (E->Prev->Bot == E->Prev->Top) E = E->Next; + + for (;;) + { + E = FindNextLocMin(E); + if (E == EMin) break; + else if (!EMin) EMin = E; + + //E and E.Prev now share a local minima (left aligned if horizontal). + //Compare their slopes to find which starts which bound ... + MinimaList::value_type locMin; + locMin.Y = E->Bot.Y; + if (E->Dx < E->Prev->Dx) + { + locMin.LeftBound = E->Prev; + locMin.RightBound = E; + leftBoundIsForward = false; //Q.nextInLML = Q.prev + } else + { + locMin.LeftBound = E; + locMin.RightBound = E->Prev; + leftBoundIsForward = true; //Q.nextInLML = Q.next + } + + if (!Closed) locMin.LeftBound->WindDelta = 0; + else if (locMin.LeftBound->Next == locMin.RightBound) + locMin.LeftBound->WindDelta = -1; + else locMin.LeftBound->WindDelta = 1; + locMin.RightBound->WindDelta = -locMin.LeftBound->WindDelta; + + E = ProcessBound(locMin.LeftBound, leftBoundIsForward); + if (E->OutIdx == Skip) E = ProcessBound(E, leftBoundIsForward); + + TEdge* E2 = ProcessBound(locMin.RightBound, !leftBoundIsForward); + if (E2->OutIdx == Skip) E2 = ProcessBound(E2, !leftBoundIsForward); + + if (locMin.LeftBound->OutIdx == Skip) + locMin.LeftBound = 0; + else if (locMin.RightBound->OutIdx == Skip) + locMin.RightBound = 0; + m_MinimaList.push_back(locMin); + if (!leftBoundIsForward) E = E2; + } + return true; +} +//------------------------------------------------------------------------------ + +bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed) +{ + bool result = false; + for (Paths::size_type i = 0; i < ppg.size(); ++i) + if (AddPath(ppg[i], PolyTyp, Closed)) result = true; + return result; +} +//------------------------------------------------------------------------------ + +void ClipperBase::Clear() +{ + DisposeLocalMinimaList(); + for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) + { + TEdge* edges = m_edges[i]; + delete [] edges; + } + m_edges.clear(); + m_UseFullRange = false; + m_HasOpenPaths = false; +} +//------------------------------------------------------------------------------ + +void ClipperBase::Reset() +{ + m_CurrentLM = m_MinimaList.begin(); + if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process + std::sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter()); + + m_Scanbeam = ScanbeamList(); //clears/resets priority_queue + //reset all edges ... + for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm) + { + InsertScanbeam(lm->Y); + TEdge* e = lm->LeftBound; + if (e) + { + e->Curr = e->Bot; + e->Side = esLeft; + e->OutIdx = Unassigned; + } + + e = lm->RightBound; + if (e) + { + e->Curr = e->Bot; + e->Side = esRight; + e->OutIdx = Unassigned; + } + } + m_ActiveEdges = 0; + m_CurrentLM = m_MinimaList.begin(); +} +//------------------------------------------------------------------------------ + +void ClipperBase::DisposeLocalMinimaList() +{ + m_MinimaList.clear(); + m_CurrentLM = m_MinimaList.begin(); +} +//------------------------------------------------------------------------------ + +bool ClipperBase::PopLocalMinima(cInt Y, const LocalMinimum *&locMin) +{ + if (m_CurrentLM == m_MinimaList.end() || (*m_CurrentLM).Y != Y) return false; + locMin = &(*m_CurrentLM); + ++m_CurrentLM; + return true; +} +//------------------------------------------------------------------------------ + +IntRect ClipperBase::GetBounds() +{ + IntRect result; + MinimaList::iterator lm = m_MinimaList.begin(); + if (lm == m_MinimaList.end()) + { + result.left = result.top = result.right = result.bottom = 0; + return result; + } + result.left = lm->LeftBound->Bot.X; + result.top = lm->LeftBound->Bot.Y; + result.right = lm->LeftBound->Bot.X; + result.bottom = lm->LeftBound->Bot.Y; + while (lm != m_MinimaList.end()) + { + //todo - needs fixing for open paths + result.bottom = std::max(result.bottom, lm->LeftBound->Bot.Y); + TEdge* e = lm->LeftBound; + for (;;) { + TEdge* bottomE = e; + while (e->NextInLML) + { + if (e->Bot.X < result.left) result.left = e->Bot.X; + if (e->Bot.X > result.right) result.right = e->Bot.X; + e = e->NextInLML; + } + result.left = std::min(result.left, e->Bot.X); + result.right = std::max(result.right, e->Bot.X); + result.left = std::min(result.left, e->Top.X); + result.right = std::max(result.right, e->Top.X); + result.top = std::min(result.top, e->Top.Y); + if (bottomE == lm->LeftBound) e = lm->RightBound; + else break; + } + ++lm; + } + return result; +} +//------------------------------------------------------------------------------ + +void ClipperBase::InsertScanbeam(const cInt Y) +{ + m_Scanbeam.push(Y); +} +//------------------------------------------------------------------------------ + +bool ClipperBase::PopScanbeam(cInt &Y) +{ + if (m_Scanbeam.empty()) return false; + Y = m_Scanbeam.top(); + m_Scanbeam.pop(); + while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates. + return true; +} +//------------------------------------------------------------------------------ + +void ClipperBase::DisposeAllOutRecs(){ + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + DisposeOutRec(i); + m_PolyOuts.clear(); +} +//------------------------------------------------------------------------------ + +void ClipperBase::DisposeOutRec(PolyOutList::size_type index) +{ + OutRec *outRec = m_PolyOuts[index]; + if (outRec->Pts) DisposeOutPts(outRec->Pts); + delete outRec; + m_PolyOuts[index] = 0; +} +//------------------------------------------------------------------------------ + +void ClipperBase::DeleteFromAEL(TEdge *e) +{ + TEdge* AelPrev = e->PrevInAEL; + TEdge* AelNext = e->NextInAEL; + if (!AelPrev && !AelNext && (e != m_ActiveEdges)) return; //already deleted + if (AelPrev) AelPrev->NextInAEL = AelNext; + else m_ActiveEdges = AelNext; + if (AelNext) AelNext->PrevInAEL = AelPrev; + e->NextInAEL = 0; + e->PrevInAEL = 0; +} +//------------------------------------------------------------------------------ + +OutRec* ClipperBase::CreateOutRec() +{ + OutRec* result = new OutRec; + result->IsHole = false; + result->IsOpen = false; + result->FirstLeft = 0; + result->Pts = 0; + result->BottomPt = 0; + result->PolyNd = 0; + m_PolyOuts.push_back(result); + result->Idx = (int)m_PolyOuts.size() - 1; + return result; +} +//------------------------------------------------------------------------------ + +void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2) +{ + //check that one or other edge hasn't already been removed from AEL ... + if (Edge1->NextInAEL == Edge1->PrevInAEL || + Edge2->NextInAEL == Edge2->PrevInAEL) return; + + if (Edge1->NextInAEL == Edge2) + { + TEdge* Next = Edge2->NextInAEL; + if (Next) Next->PrevInAEL = Edge1; + TEdge* Prev = Edge1->PrevInAEL; + if (Prev) Prev->NextInAEL = Edge2; + Edge2->PrevInAEL = Prev; + Edge2->NextInAEL = Edge1; + Edge1->PrevInAEL = Edge2; + Edge1->NextInAEL = Next; + } + else if (Edge2->NextInAEL == Edge1) + { + TEdge* Next = Edge1->NextInAEL; + if (Next) Next->PrevInAEL = Edge2; + TEdge* Prev = Edge2->PrevInAEL; + if (Prev) Prev->NextInAEL = Edge1; + Edge1->PrevInAEL = Prev; + Edge1->NextInAEL = Edge2; + Edge2->PrevInAEL = Edge1; + Edge2->NextInAEL = Next; + } + else + { + TEdge* Next = Edge1->NextInAEL; + TEdge* Prev = Edge1->PrevInAEL; + Edge1->NextInAEL = Edge2->NextInAEL; + if (Edge1->NextInAEL) Edge1->NextInAEL->PrevInAEL = Edge1; + Edge1->PrevInAEL = Edge2->PrevInAEL; + if (Edge1->PrevInAEL) Edge1->PrevInAEL->NextInAEL = Edge1; + Edge2->NextInAEL = Next; + if (Edge2->NextInAEL) Edge2->NextInAEL->PrevInAEL = Edge2; + Edge2->PrevInAEL = Prev; + if (Edge2->PrevInAEL) Edge2->PrevInAEL->NextInAEL = Edge2; + } + + if (!Edge1->PrevInAEL) m_ActiveEdges = Edge1; + else if (!Edge2->PrevInAEL) m_ActiveEdges = Edge2; +} +//------------------------------------------------------------------------------ + +void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e) +{ + if (!e->NextInLML) + throw clipperException("UpdateEdgeIntoAEL: invalid call"); + + e->NextInLML->OutIdx = e->OutIdx; + TEdge* AelPrev = e->PrevInAEL; + TEdge* AelNext = e->NextInAEL; + if (AelPrev) AelPrev->NextInAEL = e->NextInLML; + else m_ActiveEdges = e->NextInLML; + if (AelNext) AelNext->PrevInAEL = e->NextInLML; + e->NextInLML->Side = e->Side; + e->NextInLML->WindDelta = e->WindDelta; + e->NextInLML->WindCnt = e->WindCnt; + e->NextInLML->WindCnt2 = e->WindCnt2; + e = e->NextInLML; + e->Curr = e->Bot; + e->PrevInAEL = AelPrev; + e->NextInAEL = AelNext; + if (!IsHorizontal(*e)) InsertScanbeam(e->Top.Y); +} +//------------------------------------------------------------------------------ + +bool ClipperBase::LocalMinimaPending() +{ + return (m_CurrentLM != m_MinimaList.end()); +} + +//------------------------------------------------------------------------------ +// TClipper methods ... +//------------------------------------------------------------------------------ + +Clipper::Clipper(int initOptions) : ClipperBase() //constructor +{ + m_ExecuteLocked = false; + m_UseFullRange = false; + m_ReverseOutput = ((initOptions & ioReverseSolution) != 0); + m_StrictSimple = ((initOptions & ioStrictlySimple) != 0); + m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0); + m_HasOpenPaths = false; +#ifdef use_xyz + m_ZFill = 0; +#endif +} +//------------------------------------------------------------------------------ + +#ifdef use_xyz +void Clipper::ZFillFunction(ZFillCallback zFillFunc) +{ + m_ZFill = zFillFunc; +} +//------------------------------------------------------------------------------ +#endif + +bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType) +{ + return Execute(clipType, solution, fillType, fillType); +} +//------------------------------------------------------------------------------ + +bool Clipper::Execute(ClipType clipType, PolyTree &polytree, PolyFillType fillType) +{ + return Execute(clipType, polytree, fillType, fillType); +} +//------------------------------------------------------------------------------ + +bool Clipper::Execute(ClipType clipType, Paths &solution, + PolyFillType subjFillType, PolyFillType clipFillType) +{ + if( m_ExecuteLocked ) return false; + if (m_HasOpenPaths) + throw clipperException("Error: PolyTree struct is needed for open path clipping."); + m_ExecuteLocked = true; + solution.resize(0); + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + m_UsingPolyTree = false; + bool succeeded = ExecuteInternal(); + if (succeeded) BuildResult(solution); + DisposeAllOutRecs(); + m_ExecuteLocked = false; + return succeeded; +} +//------------------------------------------------------------------------------ + +bool Clipper::Execute(ClipType clipType, PolyTree& polytree, + PolyFillType subjFillType, PolyFillType clipFillType) +{ + if( m_ExecuteLocked ) return false; + m_ExecuteLocked = true; + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + m_UsingPolyTree = true; + bool succeeded = ExecuteInternal(); + if (succeeded) BuildResult2(polytree); + DisposeAllOutRecs(); + m_ExecuteLocked = false; + return succeeded; +} +//------------------------------------------------------------------------------ + +void Clipper::FixHoleLinkage(OutRec &outrec) +{ + //skip OutRecs that (a) contain outermost polygons or + //(b) already have the correct owner/child linkage ... + if (!outrec.FirstLeft || + (outrec.IsHole != outrec.FirstLeft->IsHole && + outrec.FirstLeft->Pts)) return; + + OutRec* orfl = outrec.FirstLeft; + while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts)) + orfl = orfl->FirstLeft; + outrec.FirstLeft = orfl; +} +//------------------------------------------------------------------------------ + +bool Clipper::ExecuteInternal() +{ + bool succeeded = true; + try { + Reset(); + m_Maxima = MaximaList(); + m_SortedEdges = 0; + + succeeded = true; + cInt botY, topY; + if (!PopScanbeam(botY)) return false; + InsertLocalMinimaIntoAEL(botY); + while (PopScanbeam(topY) || LocalMinimaPending()) + { + ProcessHorizontals(); + ClearGhostJoins(); + if (!ProcessIntersections(topY)) + { + succeeded = false; + break; + } + ProcessEdgesAtTopOfScanbeam(topY); + botY = topY; + InsertLocalMinimaIntoAEL(botY); + } + } + catch(...) + { + succeeded = false; + } + + if (succeeded) + { + //fix orientations ... + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec *outRec = m_PolyOuts[i]; + if (!outRec->Pts || outRec->IsOpen) continue; + if ((outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0)) + ReversePolyPtLinks(outRec->Pts); + } + + if (!m_Joins.empty()) JoinCommonEdges(); + + //unfortunately FixupOutPolygon() must be done after JoinCommonEdges() + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec *outRec = m_PolyOuts[i]; + if (!outRec->Pts) continue; + if (outRec->IsOpen) + FixupOutPolyline(*outRec); + else + FixupOutPolygon(*outRec); + } + + if (m_StrictSimple) DoSimplePolygons(); + } + + ClearJoins(); + ClearGhostJoins(); + return succeeded; +} +//------------------------------------------------------------------------------ + +void Clipper::SetWindingCount(TEdge &edge) +{ + TEdge *e = edge.PrevInAEL; + //find the edge of the same polytype that immediately preceeds 'edge' in AEL + while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL; + if (!e) + { + if (edge.WindDelta == 0) + { + PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType); + edge.WindCnt = (pft == pftNegative ? -1 : 1); + } + else + edge.WindCnt = edge.WindDelta; + edge.WindCnt2 = 0; + e = m_ActiveEdges; //ie get ready to calc WindCnt2 + } + else if (edge.WindDelta == 0 && m_ClipType != ctUnion) + { + edge.WindCnt = 1; + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 + } + else if (IsEvenOddFillType(edge)) + { + //EvenOdd filling ... + if (edge.WindDelta == 0) + { + //are we inside a subj polygon ... + bool Inside = true; + TEdge *e2 = e->PrevInAEL; + while (e2) + { + if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0) + Inside = !Inside; + e2 = e2->PrevInAEL; + } + edge.WindCnt = (Inside ? 0 : 1); + } + else + { + edge.WindCnt = edge.WindDelta; + } + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 + } + else + { + //nonZero, Positive or Negative filling ... + if (e->WindCnt * e->WindDelta < 0) + { + //prev edge is 'decreasing' WindCount (WC) toward zero + //so we're outside the previous polygon ... + if (Abs(e->WindCnt) > 1) + { + //outside prev poly but still inside another. + //when reversing direction of prev poly use the same WC + if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; + //otherwise continue to 'decrease' WC ... + else edge.WindCnt = e->WindCnt + edge.WindDelta; + } + else + //now outside all polys of same polytype so set own WC ... + edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); + } else + { + //prev edge is 'increasing' WindCount (WC) away from zero + //so we're inside the previous polygon ... + if (edge.WindDelta == 0) + edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1); + //if wind direction is reversing prev then use same WC + else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; + //otherwise add to WC ... + else edge.WindCnt = e->WindCnt + edge.WindDelta; + } + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 + } + + //update WindCnt2 ... + if (IsEvenOddAltFillType(edge)) + { + //EvenOdd filling ... + while (e != &edge) + { + if (e->WindDelta != 0) + edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0); + e = e->NextInAEL; + } + } else + { + //nonZero, Positive or Negative filling ... + while ( e != &edge ) + { + edge.WindCnt2 += e->WindDelta; + e = e->NextInAEL; + } + } +} +//------------------------------------------------------------------------------ + +bool Clipper::IsEvenOddFillType(const TEdge& edge) const +{ + if (edge.PolyTyp == ptSubject) + return m_SubjFillType == pftEvenOdd; else + return m_ClipFillType == pftEvenOdd; +} +//------------------------------------------------------------------------------ + +bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const +{ + if (edge.PolyTyp == ptSubject) + return m_ClipFillType == pftEvenOdd; else + return m_SubjFillType == pftEvenOdd; +} +//------------------------------------------------------------------------------ + +bool Clipper::IsContributing(const TEdge& edge) const +{ + PolyFillType pft, pft2; + if (edge.PolyTyp == ptSubject) + { + pft = m_SubjFillType; + pft2 = m_ClipFillType; + } else + { + pft = m_ClipFillType; + pft2 = m_SubjFillType; + } + + switch(pft) + { + case pftEvenOdd: + //return false if a subj line has been flagged as inside a subj polygon + if (edge.WindDelta == 0 && edge.WindCnt != 1) return false; + break; + case pftNonZero: + if (Abs(edge.WindCnt) != 1) return false; + break; + case pftPositive: + if (edge.WindCnt != 1) return false; + break; + default: //pftNegative + if (edge.WindCnt != -1) return false; + } + + switch(m_ClipType) + { + case ctIntersection: + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 != 0); + case pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + break; + case ctUnion: + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 == 0); + case pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + break; + case ctDifference: + if (edge.PolyTyp == ptSubject) + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 == 0); + case pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + else + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 != 0); + case pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + break; + case ctXor: + if (edge.WindDelta == 0) //XOr always contributing unless open + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 == 0); + case pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + else + return true; + break; + default: + return true; + } +} +//------------------------------------------------------------------------------ + +OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) +{ + OutPt* result; + TEdge *e, *prevE; + if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx )) + { + result = AddOutPt(e1, Pt); + e2->OutIdx = e1->OutIdx; + e1->Side = esLeft; + e2->Side = esRight; + e = e1; + if (e->PrevInAEL == e2) + prevE = e2->PrevInAEL; + else + prevE = e->PrevInAEL; + } else + { + result = AddOutPt(e2, Pt); + e1->OutIdx = e2->OutIdx; + e1->Side = esRight; + e2->Side = esLeft; + e = e2; + if (e->PrevInAEL == e1) + prevE = e1->PrevInAEL; + else + prevE = e->PrevInAEL; + } + + if (prevE && prevE->OutIdx >= 0 && prevE->Top.Y < Pt.Y && e->Top.Y < Pt.Y) + { + cInt xPrev = TopX(*prevE, Pt.Y); + cInt xE = TopX(*e, Pt.Y); + if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) && + SlopesEqual(IntPoint(xPrev, Pt.Y), prevE->Top, IntPoint(xE, Pt.Y), e->Top, m_UseFullRange)) + { + OutPt* outPt = AddOutPt(prevE, Pt); + AddJoin(result, outPt, e->Top); + } + } + return result; +} +//------------------------------------------------------------------------------ + +void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) +{ + AddOutPt( e1, Pt ); + if (e2->WindDelta == 0) AddOutPt(e2, Pt); + if( e1->OutIdx == e2->OutIdx ) + { + e1->OutIdx = Unassigned; + e2->OutIdx = Unassigned; + } + else if (e1->OutIdx < e2->OutIdx) + AppendPolygon(e1, e2); + else + AppendPolygon(e2, e1); +} +//------------------------------------------------------------------------------ + +void Clipper::AddEdgeToSEL(TEdge *edge) +{ + //SEL pointers in PEdge are reused to build a list of horizontal edges. + //However, we don't need to worry about order with horizontal edge processing. + if( !m_SortedEdges ) + { + m_SortedEdges = edge; + edge->PrevInSEL = 0; + edge->NextInSEL = 0; + } + else + { + edge->NextInSEL = m_SortedEdges; + edge->PrevInSEL = 0; + m_SortedEdges->PrevInSEL = edge; + m_SortedEdges = edge; + } +} +//------------------------------------------------------------------------------ + +bool Clipper::PopEdgeFromSEL(TEdge *&edge) +{ + if (!m_SortedEdges) return false; + edge = m_SortedEdges; + DeleteFromSEL(m_SortedEdges); + return true; +} +//------------------------------------------------------------------------------ + +void Clipper::CopyAELToSEL() +{ + TEdge* e = m_ActiveEdges; + m_SortedEdges = e; + while ( e ) + { + e->PrevInSEL = e->PrevInAEL; + e->NextInSEL = e->NextInAEL; + e = e->NextInAEL; + } +} +//------------------------------------------------------------------------------ + +void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt) +{ + Join* j = new Join; + j->OutPt1 = op1; + j->OutPt2 = op2; + j->OffPt = OffPt; + m_Joins.push_back(j); +} +//------------------------------------------------------------------------------ + +void Clipper::ClearJoins() +{ + for (JoinList::size_type i = 0; i < m_Joins.size(); i++) + delete m_Joins[i]; + m_Joins.resize(0); +} +//------------------------------------------------------------------------------ + +void Clipper::ClearGhostJoins() +{ + for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++) + delete m_GhostJoins[i]; + m_GhostJoins.resize(0); +} +//------------------------------------------------------------------------------ + +void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt) +{ + Join* j = new Join; + j->OutPt1 = op; + j->OutPt2 = 0; + j->OffPt = OffPt; + m_GhostJoins.push_back(j); +} +//------------------------------------------------------------------------------ + +void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) +{ + const LocalMinimum *lm; + while (PopLocalMinima(botY, lm)) + { + TEdge* lb = lm->LeftBound; + TEdge* rb = lm->RightBound; + + OutPt *Op1 = 0; + if (!lb) + { + //nb: don't insert LB into either AEL or SEL + InsertEdgeIntoAEL(rb, 0); + SetWindingCount(*rb); + if (IsContributing(*rb)) + Op1 = AddOutPt(rb, rb->Bot); + } + else if (!rb) + { + InsertEdgeIntoAEL(lb, 0); + SetWindingCount(*lb); + if (IsContributing(*lb)) + Op1 = AddOutPt(lb, lb->Bot); + InsertScanbeam(lb->Top.Y); + } + else + { + InsertEdgeIntoAEL(lb, 0); + InsertEdgeIntoAEL(rb, lb); + SetWindingCount( *lb ); + rb->WindCnt = lb->WindCnt; + rb->WindCnt2 = lb->WindCnt2; + if (IsContributing(*lb)) + Op1 = AddLocalMinPoly(lb, rb, lb->Bot); + InsertScanbeam(lb->Top.Y); + } + + if (rb) + { + if (IsHorizontal(*rb)) + { + AddEdgeToSEL(rb); + if (rb->NextInLML) + InsertScanbeam(rb->NextInLML->Top.Y); + } + else InsertScanbeam( rb->Top.Y ); + } + + if (!lb || !rb) continue; + + //if any output polygons share an edge, they'll need joining later ... + if (Op1 && IsHorizontal(*rb) && + m_GhostJoins.size() > 0 && (rb->WindDelta != 0)) + { + for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i) + { + Join* jr = m_GhostJoins[i]; + //if the horizontal Rb and a 'ghost' horizontal overlap, then convert + //the 'ghost' join to a real join ready for later ... + if (HorzSegmentsOverlap(jr->OutPt1->Pt.X, jr->OffPt.X, rb->Bot.X, rb->Top.X)) + AddJoin(jr->OutPt1, Op1, jr->OffPt); + } + } + + if (lb->OutIdx >= 0 && lb->PrevInAEL && + lb->PrevInAEL->Curr.X == lb->Bot.X && + lb->PrevInAEL->OutIdx >= 0 && + SlopesEqual(lb->PrevInAEL->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) && + (lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0)) + { + OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot); + AddJoin(Op1, Op2, lb->Top); + } + + if(lb->NextInAEL != rb) + { + + if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 && + SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) && + (rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0)) + { + OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot); + AddJoin(Op1, Op2, rb->Top); + } + + TEdge* e = lb->NextInAEL; + if (e) + { + while( e != rb ) + { + //nb: For calculating winding counts etc, IntersectEdges() assumes + //that param1 will be to the Right of param2 ABOVE the intersection ... + IntersectEdges(rb , e , lb->Curr); //order important here + e = e->NextInAEL; + } + } + } + + } +} +//------------------------------------------------------------------------------ + +void Clipper::DeleteFromSEL(TEdge *e) +{ + TEdge* SelPrev = e->PrevInSEL; + TEdge* SelNext = e->NextInSEL; + if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted + if( SelPrev ) SelPrev->NextInSEL = SelNext; + else m_SortedEdges = SelNext; + if( SelNext ) SelNext->PrevInSEL = SelPrev; + e->NextInSEL = 0; + e->PrevInSEL = 0; +} +//------------------------------------------------------------------------------ + +#ifdef use_xyz +void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2) +{ + if (pt.Z != 0 || !m_ZFill) return; + else if (pt == e1.Bot) pt.Z = e1.Bot.Z; + else if (pt == e1.Top) pt.Z = e1.Top.Z; + else if (pt == e2.Bot) pt.Z = e2.Bot.Z; + else if (pt == e2.Top) pt.Z = e2.Top.Z; + else (*m_ZFill)(e1.Bot, e1.Top, e2.Bot, e2.Top, pt); +} +//------------------------------------------------------------------------------ +#endif + +void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt) +{ + bool e1Contributing = ( e1->OutIdx >= 0 ); + bool e2Contributing = ( e2->OutIdx >= 0 ); + +#ifdef use_xyz + SetZ(Pt, *e1, *e2); +#endif + +#ifdef use_lines + //if either edge is on an OPEN path ... + if (e1->WindDelta == 0 || e2->WindDelta == 0) + { + //ignore subject-subject open path intersections UNLESS they + //are both open paths, AND they are both 'contributing maximas' ... + if (e1->WindDelta == 0 && e2->WindDelta == 0) return; + + //if intersecting a subj line with a subj poly ... + else if (e1->PolyTyp == e2->PolyTyp && + e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion) + { + if (e1->WindDelta == 0) + { + if (e2Contributing) + { + AddOutPt(e1, Pt); + if (e1Contributing) e1->OutIdx = Unassigned; + } + } + else + { + if (e1Contributing) + { + AddOutPt(e2, Pt); + if (e2Contributing) e2->OutIdx = Unassigned; + } + } + } + else if (e1->PolyTyp != e2->PolyTyp) + { + //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ... + if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 && + (m_ClipType != ctUnion || e2->WindCnt2 == 0)) + { + AddOutPt(e1, Pt); + if (e1Contributing) e1->OutIdx = Unassigned; + } + else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) && + (m_ClipType != ctUnion || e1->WindCnt2 == 0)) + { + AddOutPt(e2, Pt); + if (e2Contributing) e2->OutIdx = Unassigned; + } + } + return; + } +#endif + + //update winding counts... + //assumes that e1 will be to the Right of e2 ABOVE the intersection + if ( e1->PolyTyp == e2->PolyTyp ) + { + if ( IsEvenOddFillType( *e1) ) + { + int oldE1WindCnt = e1->WindCnt; + e1->WindCnt = e2->WindCnt; + e2->WindCnt = oldE1WindCnt; + } else + { + if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt; + else e1->WindCnt += e2->WindDelta; + if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt; + else e2->WindCnt -= e1->WindDelta; + } + } else + { + if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta; + else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0; + if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta; + else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0; + } + + PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; + if (e1->PolyTyp == ptSubject) + { + e1FillType = m_SubjFillType; + e1FillType2 = m_ClipFillType; + } else + { + e1FillType = m_ClipFillType; + e1FillType2 = m_SubjFillType; + } + if (e2->PolyTyp == ptSubject) + { + e2FillType = m_SubjFillType; + e2FillType2 = m_ClipFillType; + } else + { + e2FillType = m_ClipFillType; + e2FillType2 = m_SubjFillType; + } + + cInt e1Wc, e2Wc; + switch (e1FillType) + { + case pftPositive: e1Wc = e1->WindCnt; break; + case pftNegative: e1Wc = -e1->WindCnt; break; + default: e1Wc = Abs(e1->WindCnt); + } + switch(e2FillType) + { + case pftPositive: e2Wc = e2->WindCnt; break; + case pftNegative: e2Wc = -e2->WindCnt; break; + default: e2Wc = Abs(e2->WindCnt); + } + + if ( e1Contributing && e2Contributing ) + { + if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || + (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) ) + { + AddLocalMaxPoly(e1, e2, Pt); + } + else + { + AddOutPt(e1, Pt); + AddOutPt(e2, Pt); + SwapSides( *e1 , *e2 ); + SwapPolyIndexes( *e1 , *e2 ); + } + } + else if ( e1Contributing ) + { + if (e2Wc == 0 || e2Wc == 1) + { + AddOutPt(e1, Pt); + SwapSides(*e1, *e2); + SwapPolyIndexes(*e1, *e2); + } + } + else if ( e2Contributing ) + { + if (e1Wc == 0 || e1Wc == 1) + { + AddOutPt(e2, Pt); + SwapSides(*e1, *e2); + SwapPolyIndexes(*e1, *e2); + } + } + else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1)) + { + //neither edge is currently contributing ... + + cInt e1Wc2, e2Wc2; + switch (e1FillType2) + { + case pftPositive: e1Wc2 = e1->WindCnt2; break; + case pftNegative : e1Wc2 = -e1->WindCnt2; break; + default: e1Wc2 = Abs(e1->WindCnt2); + } + switch (e2FillType2) + { + case pftPositive: e2Wc2 = e2->WindCnt2; break; + case pftNegative: e2Wc2 = -e2->WindCnt2; break; + default: e2Wc2 = Abs(e2->WindCnt2); + } + + if (e1->PolyTyp != e2->PolyTyp) + { + AddLocalMinPoly(e1, e2, Pt); + } + else if (e1Wc == 1 && e2Wc == 1) + switch( m_ClipType ) { + case ctIntersection: + if (e1Wc2 > 0 && e2Wc2 > 0) + AddLocalMinPoly(e1, e2, Pt); + break; + case ctUnion: + if ( e1Wc2 <= 0 && e2Wc2 <= 0 ) + AddLocalMinPoly(e1, e2, Pt); + break; + case ctDifference: + if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || + ((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) + AddLocalMinPoly(e1, e2, Pt); + break; + case ctXor: + AddLocalMinPoly(e1, e2, Pt); + } + else + SwapSides( *e1, *e2 ); + } +} +//------------------------------------------------------------------------------ + +void Clipper::SetHoleState(TEdge *e, OutRec *outrec) +{ + TEdge *e2 = e->PrevInAEL; + TEdge *eTmp = 0; + while (e2) + { + if (e2->OutIdx >= 0 && e2->WindDelta != 0) + { + if (!eTmp) eTmp = e2; + else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0; + } + e2 = e2->PrevInAEL; + } + if (!eTmp) + { + outrec->FirstLeft = 0; + outrec->IsHole = false; + } + else + { + outrec->FirstLeft = m_PolyOuts[eTmp->OutIdx]; + outrec->IsHole = !outrec->FirstLeft->IsHole; + } +} +//------------------------------------------------------------------------------ + +OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) +{ + //work out which polygon fragment has the correct hole state ... + if (!outRec1->BottomPt) + outRec1->BottomPt = GetBottomPt(outRec1->Pts); + if (!outRec2->BottomPt) + outRec2->BottomPt = GetBottomPt(outRec2->Pts); + OutPt *OutPt1 = outRec1->BottomPt; + OutPt *OutPt2 = outRec2->BottomPt; + if (OutPt1->Pt.Y > OutPt2->Pt.Y) return outRec1; + else if (OutPt1->Pt.Y < OutPt2->Pt.Y) return outRec2; + else if (OutPt1->Pt.X < OutPt2->Pt.X) return outRec1; + else if (OutPt1->Pt.X > OutPt2->Pt.X) return outRec2; + else if (OutPt1->Next == OutPt1) return outRec2; + else if (OutPt2->Next == OutPt2) return outRec1; + else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1; + else return outRec2; +} +//------------------------------------------------------------------------------ + +bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2) +{ + do + { + outRec1 = outRec1->FirstLeft; + if (outRec1 == outRec2) return true; + } while (outRec1); + return false; +} +//------------------------------------------------------------------------------ + +OutRec* Clipper::GetOutRec(int Idx) +{ + OutRec* outrec = m_PolyOuts[Idx]; + while (outrec != m_PolyOuts[outrec->Idx]) + outrec = m_PolyOuts[outrec->Idx]; + return outrec; +} +//------------------------------------------------------------------------------ + +void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) +{ + //get the start and ends of both output polygons ... + OutRec *outRec1 = m_PolyOuts[e1->OutIdx]; + OutRec *outRec2 = m_PolyOuts[e2->OutIdx]; + + OutRec *holeStateRec; + if (OutRec1RightOfOutRec2(outRec1, outRec2)) + holeStateRec = outRec2; + else if (OutRec1RightOfOutRec2(outRec2, outRec1)) + holeStateRec = outRec1; + else + holeStateRec = GetLowermostRec(outRec1, outRec2); + + //get the start and ends of both output polygons and + //join e2 poly onto e1 poly and delete pointers to e2 ... + + OutPt* p1_lft = outRec1->Pts; + OutPt* p1_rt = p1_lft->Prev; + OutPt* p2_lft = outRec2->Pts; + OutPt* p2_rt = p2_lft->Prev; + + //join e2 poly onto e1 poly and delete pointers to e2 ... + if( e1->Side == esLeft ) + { + if( e2->Side == esLeft ) + { + //z y x a b c + ReversePolyPtLinks(p2_lft); + p2_lft->Next = p1_lft; + p1_lft->Prev = p2_lft; + p1_rt->Next = p2_rt; + p2_rt->Prev = p1_rt; + outRec1->Pts = p2_rt; + } else + { + //x y z a b c + p2_rt->Next = p1_lft; + p1_lft->Prev = p2_rt; + p2_lft->Prev = p1_rt; + p1_rt->Next = p2_lft; + outRec1->Pts = p2_lft; + } + } else + { + if( e2->Side == esRight ) + { + //a b c z y x + ReversePolyPtLinks(p2_lft); + p1_rt->Next = p2_rt; + p2_rt->Prev = p1_rt; + p2_lft->Next = p1_lft; + p1_lft->Prev = p2_lft; + } else + { + //a b c x y z + p1_rt->Next = p2_lft; + p2_lft->Prev = p1_rt; + p1_lft->Prev = p2_rt; + p2_rt->Next = p1_lft; + } + } + + outRec1->BottomPt = 0; + if (holeStateRec == outRec2) + { + if (outRec2->FirstLeft != outRec1) + outRec1->FirstLeft = outRec2->FirstLeft; + outRec1->IsHole = outRec2->IsHole; + } + outRec2->Pts = 0; + outRec2->BottomPt = 0; + outRec2->FirstLeft = outRec1; + + int OKIdx = e1->OutIdx; + int ObsoleteIdx = e2->OutIdx; + + e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly + e2->OutIdx = Unassigned; + + TEdge* e = m_ActiveEdges; + while( e ) + { + if( e->OutIdx == ObsoleteIdx ) + { + e->OutIdx = OKIdx; + e->Side = e1->Side; + break; + } + e = e->NextInAEL; + } + + outRec2->Idx = outRec1->Idx; +} +//------------------------------------------------------------------------------ + +OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt) +{ + if( e->OutIdx < 0 ) + { + OutRec *outRec = CreateOutRec(); + outRec->IsOpen = (e->WindDelta == 0); + OutPt* newOp = new OutPt; + outRec->Pts = newOp; + newOp->Idx = outRec->Idx; + newOp->Pt = pt; + newOp->Next = newOp; + newOp->Prev = newOp; + if (!outRec->IsOpen) + SetHoleState(e, outRec); + e->OutIdx = outRec->Idx; + return newOp; + } else + { + OutRec *outRec = m_PolyOuts[e->OutIdx]; + //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most' + OutPt* op = outRec->Pts; + + bool ToFront = (e->Side == esLeft); + if (ToFront && (pt == op->Pt)) return op; + else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev; + + OutPt* newOp = new OutPt; + newOp->Idx = outRec->Idx; + newOp->Pt = pt; + newOp->Next = op; + newOp->Prev = op->Prev; + newOp->Prev->Next = newOp; + op->Prev = newOp; + if (ToFront) outRec->Pts = newOp; + return newOp; + } +} +//------------------------------------------------------------------------------ + +OutPt* Clipper::GetLastOutPt(TEdge *e) +{ + OutRec *outRec = m_PolyOuts[e->OutIdx]; + if (e->Side == esLeft) + return outRec->Pts; + else + return outRec->Pts->Prev; +} +//------------------------------------------------------------------------------ + +void Clipper::ProcessHorizontals() +{ + TEdge* horzEdge; + while (PopEdgeFromSEL(horzEdge)) + ProcessHorizontal(horzEdge); +} +//------------------------------------------------------------------------------ + +inline bool IsMinima(TEdge *e) +{ + return e && (e->Prev->NextInLML != e) && (e->Next->NextInLML != e); +} +//------------------------------------------------------------------------------ + +inline bool IsMaxima(TEdge *e, const cInt Y) +{ + return e && e->Top.Y == Y && !e->NextInLML; +} +//------------------------------------------------------------------------------ + +inline bool IsIntermediate(TEdge *e, const cInt Y) +{ + return e->Top.Y == Y && e->NextInLML; +} +//------------------------------------------------------------------------------ + +TEdge *GetMaximaPair(TEdge *e) +{ + if ((e->Next->Top == e->Top) && !e->Next->NextInLML) + return e->Next; + else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML) + return e->Prev; + else return 0; +} +//------------------------------------------------------------------------------ + +TEdge *GetMaximaPairEx(TEdge *e) +{ + //as GetMaximaPair() but returns 0 if MaxPair isn't in AEL (unless it's horizontal) + TEdge* result = GetMaximaPair(e); + if (result && (result->OutIdx == Skip || + (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0; + return result; +} +//------------------------------------------------------------------------------ + +void Clipper::SwapPositionsInSEL(TEdge *Edge1, TEdge *Edge2) +{ + if( !( Edge1->NextInSEL ) && !( Edge1->PrevInSEL ) ) return; + if( !( Edge2->NextInSEL ) && !( Edge2->PrevInSEL ) ) return; + + if( Edge1->NextInSEL == Edge2 ) + { + TEdge* Next = Edge2->NextInSEL; + if( Next ) Next->PrevInSEL = Edge1; + TEdge* Prev = Edge1->PrevInSEL; + if( Prev ) Prev->NextInSEL = Edge2; + Edge2->PrevInSEL = Prev; + Edge2->NextInSEL = Edge1; + Edge1->PrevInSEL = Edge2; + Edge1->NextInSEL = Next; + } + else if( Edge2->NextInSEL == Edge1 ) + { + TEdge* Next = Edge1->NextInSEL; + if( Next ) Next->PrevInSEL = Edge2; + TEdge* Prev = Edge2->PrevInSEL; + if( Prev ) Prev->NextInSEL = Edge1; + Edge1->PrevInSEL = Prev; + Edge1->NextInSEL = Edge2; + Edge2->PrevInSEL = Edge1; + Edge2->NextInSEL = Next; + } + else + { + TEdge* Next = Edge1->NextInSEL; + TEdge* Prev = Edge1->PrevInSEL; + Edge1->NextInSEL = Edge2->NextInSEL; + if( Edge1->NextInSEL ) Edge1->NextInSEL->PrevInSEL = Edge1; + Edge1->PrevInSEL = Edge2->PrevInSEL; + if( Edge1->PrevInSEL ) Edge1->PrevInSEL->NextInSEL = Edge1; + Edge2->NextInSEL = Next; + if( Edge2->NextInSEL ) Edge2->NextInSEL->PrevInSEL = Edge2; + Edge2->PrevInSEL = Prev; + if( Edge2->PrevInSEL ) Edge2->PrevInSEL->NextInSEL = Edge2; + } + + if( !Edge1->PrevInSEL ) m_SortedEdges = Edge1; + else if( !Edge2->PrevInSEL ) m_SortedEdges = Edge2; +} +//------------------------------------------------------------------------------ + +TEdge* GetNextInAEL(TEdge *e, Direction dir) +{ + return dir == dLeftToRight ? e->NextInAEL : e->PrevInAEL; +} +//------------------------------------------------------------------------------ + +void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right) +{ + if (HorzEdge.Bot.X < HorzEdge.Top.X) + { + Left = HorzEdge.Bot.X; + Right = HorzEdge.Top.X; + Dir = dLeftToRight; + } else + { + Left = HorzEdge.Top.X; + Right = HorzEdge.Bot.X; + Dir = dRightToLeft; + } +} +//------------------------------------------------------------------------ + +/******************************************************************************* +* Notes: Horizontal edges (HEs) at scanline intersections (ie at the Top or * +* Bottom of a scanbeam) are processed as if layered. The order in which HEs * +* are processed doesn't matter. HEs intersect with other HE Bot.Xs only [#] * +* (or they could intersect with Top.Xs only, ie EITHER Bot.Xs OR Top.Xs), * +* and with other non-horizontal edges [*]. Once these intersections are * +* processed, intermediate HEs then 'promote' the Edge above (NextInLML) into * +* the AEL. These 'promoted' edges may in turn intersect [%] with other HEs. * +*******************************************************************************/ + +void Clipper::ProcessHorizontal(TEdge *horzEdge) +{ + Direction dir; + cInt horzLeft, horzRight; + bool IsOpen = (horzEdge->WindDelta == 0); + + GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); + + TEdge* eLastHorz = horzEdge, *eMaxPair = 0; + while (eLastHorz->NextInLML && IsHorizontal(*eLastHorz->NextInLML)) + eLastHorz = eLastHorz->NextInLML; + if (!eLastHorz->NextInLML) + eMaxPair = GetMaximaPair(eLastHorz); + + MaximaList::const_iterator maxIt; + MaximaList::const_reverse_iterator maxRit; + if (m_Maxima.size() > 0) + { + //get the first maxima in range (X) ... + if (dir == dLeftToRight) + { + maxIt = m_Maxima.begin(); + while (maxIt != m_Maxima.end() && *maxIt <= horzEdge->Bot.X) maxIt++; + if (maxIt != m_Maxima.end() && *maxIt >= eLastHorz->Top.X) + maxIt = m_Maxima.end(); + } + else + { + maxRit = m_Maxima.rbegin(); + while (maxRit != m_Maxima.rend() && *maxRit > horzEdge->Bot.X) maxRit++; + if (maxRit != m_Maxima.rend() && *maxRit <= eLastHorz->Top.X) + maxRit = m_Maxima.rend(); + } + } + + OutPt* op1 = 0; + + for (;;) //loop through consec. horizontal edges + { + + bool IsLastHorz = (horzEdge == eLastHorz); + TEdge* e = GetNextInAEL(horzEdge, dir); + while(e) + { + + //this code block inserts extra coords into horizontal edges (in output + //polygons) whereever maxima touch these horizontal edges. This helps + //'simplifying' polygons (ie if the Simplify property is set). + if (m_Maxima.size() > 0) + { + if (dir == dLeftToRight) + { + while (maxIt != m_Maxima.end() && *maxIt < e->Curr.X) + { + if (horzEdge->OutIdx >= 0 && !IsOpen) + AddOutPt(horzEdge, IntPoint(*maxIt, horzEdge->Bot.Y)); + maxIt++; + } + } + else + { + while (maxRit != m_Maxima.rend() && *maxRit > e->Curr.X) + { + if (horzEdge->OutIdx >= 0 && !IsOpen) + AddOutPt(horzEdge, IntPoint(*maxRit, horzEdge->Bot.Y)); + maxRit++; + } + } + }; + + if ((dir == dLeftToRight && e->Curr.X > horzRight) || + (dir == dRightToLeft && e->Curr.X < horzLeft)) break; + + //Also break if we've got to the end of an intermediate horizontal edge ... + //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal. + if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML && + e->Dx < horzEdge->NextInLML->Dx) break; + + if (horzEdge->OutIdx >= 0 && !IsOpen) //note: may be done multiple times + { +#ifdef use_xyz + if (dir == dLeftToRight) SetZ(e->Curr, *horzEdge, *e); + else SetZ(e->Curr, *e, *horzEdge); +#endif + op1 = AddOutPt(horzEdge, e->Curr); + TEdge* eNextHorz = m_SortedEdges; + while (eNextHorz) + { + if (eNextHorz->OutIdx >= 0 && + HorzSegmentsOverlap(horzEdge->Bot.X, + horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X)) + { + OutPt* op2 = GetLastOutPt(eNextHorz); + AddJoin(op2, op1, eNextHorz->Top); + } + eNextHorz = eNextHorz->NextInSEL; + } + AddGhostJoin(op1, horzEdge->Bot); + } + + //OK, so far we're still in range of the horizontal Edge but make sure + //we're at the last of consec. horizontals when matching with eMaxPair + if(e == eMaxPair && IsLastHorz) + { + if (horzEdge->OutIdx >= 0) + AddLocalMaxPoly(horzEdge, eMaxPair, horzEdge->Top); + DeleteFromAEL(horzEdge); + DeleteFromAEL(eMaxPair); + return; + } + + if(dir == dLeftToRight) + { + IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); + IntersectEdges(horzEdge, e, Pt); + } + else + { + IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); + IntersectEdges( e, horzEdge, Pt); + } + TEdge* eNext = GetNextInAEL(e, dir); + SwapPositionsInAEL( horzEdge, e ); + e = eNext; + } //end while(e) + + //Break out of loop if HorzEdge.NextInLML is not also horizontal ... + if (!horzEdge->NextInLML || !IsHorizontal(*horzEdge->NextInLML)) break; + + UpdateEdgeIntoAEL(horzEdge); + if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot); + GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); + + } //end for (;;) + + if (horzEdge->OutIdx >= 0 && !op1) + { + op1 = GetLastOutPt(horzEdge); + TEdge* eNextHorz = m_SortedEdges; + while (eNextHorz) + { + if (eNextHorz->OutIdx >= 0 && + HorzSegmentsOverlap(horzEdge->Bot.X, + horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X)) + { + OutPt* op2 = GetLastOutPt(eNextHorz); + AddJoin(op2, op1, eNextHorz->Top); + } + eNextHorz = eNextHorz->NextInSEL; + } + AddGhostJoin(op1, horzEdge->Top); + } + + if (horzEdge->NextInLML) + { + if(horzEdge->OutIdx >= 0) + { + op1 = AddOutPt( horzEdge, horzEdge->Top); + UpdateEdgeIntoAEL(horzEdge); + if (horzEdge->WindDelta == 0) return; + //nb: HorzEdge is no longer horizontal here + TEdge* ePrev = horzEdge->PrevInAEL; + TEdge* eNext = horzEdge->NextInAEL; + if (ePrev && ePrev->Curr.X == horzEdge->Bot.X && + ePrev->Curr.Y == horzEdge->Bot.Y && ePrev->WindDelta != 0 && + (ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y && + SlopesEqual(*horzEdge, *ePrev, m_UseFullRange))) + { + OutPt* op2 = AddOutPt(ePrev, horzEdge->Bot); + AddJoin(op1, op2, horzEdge->Top); + } + else if (eNext && eNext->Curr.X == horzEdge->Bot.X && + eNext->Curr.Y == horzEdge->Bot.Y && eNext->WindDelta != 0 && + eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y && + SlopesEqual(*horzEdge, *eNext, m_UseFullRange)) + { + OutPt* op2 = AddOutPt(eNext, horzEdge->Bot); + AddJoin(op1, op2, horzEdge->Top); + } + } + else + UpdateEdgeIntoAEL(horzEdge); + } + else + { + if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Top); + DeleteFromAEL(horzEdge); + } +} +//------------------------------------------------------------------------------ + +bool Clipper::ProcessIntersections(const cInt topY) +{ + if( !m_ActiveEdges ) return true; + try { + BuildIntersectList(topY); + size_t IlSize = m_IntersectList.size(); + if (IlSize == 0) return true; + if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList(); + else return false; + } + catch(...) + { + m_SortedEdges = 0; + DisposeIntersectNodes(); + throw clipperException("ProcessIntersections error"); + } + m_SortedEdges = 0; + return true; +} +//------------------------------------------------------------------------------ + +void Clipper::DisposeIntersectNodes() +{ + for (size_t i = 0; i < m_IntersectList.size(); ++i ) + delete m_IntersectList[i]; + m_IntersectList.clear(); +} +//------------------------------------------------------------------------------ + +void Clipper::BuildIntersectList(const cInt topY) +{ + if ( !m_ActiveEdges ) return; + + //prepare for sorting ... + TEdge* e = m_ActiveEdges; + m_SortedEdges = e; + while( e ) + { + e->PrevInSEL = e->PrevInAEL; + e->NextInSEL = e->NextInAEL; + e->Curr.X = TopX( *e, topY ); + e = e->NextInAEL; + } + + //bubblesort ... + bool isModified; + do + { + isModified = false; + e = m_SortedEdges; + while( e->NextInSEL ) + { + TEdge *eNext = e->NextInSEL; + IntPoint Pt; + if(e->Curr.X > eNext->Curr.X) + { + IntersectPoint(*e, *eNext, Pt); + if (Pt.Y < topY) Pt = IntPoint(TopX(*e, topY), topY); + IntersectNode * newNode = new IntersectNode; + newNode->Edge1 = e; + newNode->Edge2 = eNext; + newNode->Pt = Pt; + m_IntersectList.push_back(newNode); + + SwapPositionsInSEL(e, eNext); + isModified = true; + } + else + e = eNext; + } + if( e->PrevInSEL ) e->PrevInSEL->NextInSEL = 0; + else break; + } + while ( isModified ); + m_SortedEdges = 0; //important +} +//------------------------------------------------------------------------------ + + +void Clipper::ProcessIntersectList() +{ + for (size_t i = 0; i < m_IntersectList.size(); ++i) + { + IntersectNode* iNode = m_IntersectList[i]; + { + IntersectEdges( iNode->Edge1, iNode->Edge2, iNode->Pt); + SwapPositionsInAEL( iNode->Edge1 , iNode->Edge2 ); + } + delete iNode; + } + m_IntersectList.clear(); +} +//------------------------------------------------------------------------------ + +bool IntersectListSort(IntersectNode* node1, IntersectNode* node2) +{ + return node2->Pt.Y < node1->Pt.Y; +} +//------------------------------------------------------------------------------ + +inline bool EdgesAdjacent(const IntersectNode &inode) +{ + return (inode.Edge1->NextInSEL == inode.Edge2) || + (inode.Edge1->PrevInSEL == inode.Edge2); +} +//------------------------------------------------------------------------------ + +bool Clipper::FixupIntersectionOrder() +{ + //pre-condition: intersections are sorted Bottom-most first. + //Now it's crucial that intersections are made only between adjacent edges, + //so to ensure this the order of intersections may need adjusting ... + CopyAELToSEL(); + std::sort(m_IntersectList.begin(), m_IntersectList.end(), IntersectListSort); + size_t cnt = m_IntersectList.size(); + for (size_t i = 0; i < cnt; ++i) + { + if (!EdgesAdjacent(*m_IntersectList[i])) + { + size_t j = i + 1; + while (j < cnt && !EdgesAdjacent(*m_IntersectList[j])) j++; + if (j == cnt) return false; + std::swap(m_IntersectList[i], m_IntersectList[j]); + } + SwapPositionsInSEL(m_IntersectList[i]->Edge1, m_IntersectList[i]->Edge2); + } + return true; +} +//------------------------------------------------------------------------------ + +void Clipper::DoMaxima(TEdge *e) +{ + TEdge* eMaxPair = GetMaximaPairEx(e); + if (!eMaxPair) + { + if (e->OutIdx >= 0) + AddOutPt(e, e->Top); + DeleteFromAEL(e); + return; + } + + TEdge* eNext = e->NextInAEL; + while(eNext && eNext != eMaxPair) + { + IntersectEdges(e, eNext, e->Top); + SwapPositionsInAEL(e, eNext); + eNext = e->NextInAEL; + } + + if(e->OutIdx == Unassigned && eMaxPair->OutIdx == Unassigned) + { + DeleteFromAEL(e); + DeleteFromAEL(eMaxPair); + } + else if( e->OutIdx >= 0 && eMaxPair->OutIdx >= 0 ) + { + if (e->OutIdx >= 0) AddLocalMaxPoly(e, eMaxPair, e->Top); + DeleteFromAEL(e); + DeleteFromAEL(eMaxPair); + } +#ifdef use_lines + else if (e->WindDelta == 0) + { + if (e->OutIdx >= 0) + { + AddOutPt(e, e->Top); + e->OutIdx = Unassigned; + } + DeleteFromAEL(e); + + if (eMaxPair->OutIdx >= 0) + { + AddOutPt(eMaxPair, e->Top); + eMaxPair->OutIdx = Unassigned; + } + DeleteFromAEL(eMaxPair); + } +#endif + else throw clipperException("DoMaxima error"); +} +//------------------------------------------------------------------------------ + +void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) +{ + TEdge* e = m_ActiveEdges; + while( e ) + { + //1. process maxima, treating them as if they're 'bent' horizontal edges, + // but exclude maxima with horizontal edges. nb: e can't be a horizontal. + bool IsMaximaEdge = IsMaxima(e, topY); + + if(IsMaximaEdge) + { + TEdge* eMaxPair = GetMaximaPairEx(e); + IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair)); + } + + if(IsMaximaEdge) + { + if (m_StrictSimple) m_Maxima.push_back(e->Top.X); + TEdge* ePrev = e->PrevInAEL; + DoMaxima(e); + if( !ePrev ) e = m_ActiveEdges; + else e = ePrev->NextInAEL; + } + else + { + //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ... + if (IsIntermediate(e, topY) && IsHorizontal(*e->NextInLML)) + { + UpdateEdgeIntoAEL(e); + if (e->OutIdx >= 0) + AddOutPt(e, e->Bot); + AddEdgeToSEL(e); + } + else + { + e->Curr.X = TopX( *e, topY ); + e->Curr.Y = topY; +#ifdef use_xyz + e->Curr.Z = topY == e->Top.Y ? e->Top.Z : (topY == e->Bot.Y ? e->Bot.Z : 0); +#endif + } + + //When StrictlySimple and 'e' is being touched by another edge, then + //make sure both edges have a vertex here ... + if (m_StrictSimple) + { + TEdge* ePrev = e->PrevInAEL; + if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) && + (ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0)) + { + IntPoint pt = e->Curr; +#ifdef use_xyz + SetZ(pt, *ePrev, *e); +#endif + OutPt* op = AddOutPt(ePrev, pt); + OutPt* op2 = AddOutPt(e, pt); + AddJoin(op, op2, pt); //StrictlySimple (type-3) join + } + } + + e = e->NextInAEL; + } + } + + //3. Process horizontals at the Top of the scanbeam ... + m_Maxima.sort(); + ProcessHorizontals(); + m_Maxima.clear(); + + //4. Promote intermediate vertices ... + e = m_ActiveEdges; + while(e) + { + if(IsIntermediate(e, topY)) + { + OutPt* op = 0; + if( e->OutIdx >= 0 ) + op = AddOutPt(e, e->Top); + UpdateEdgeIntoAEL(e); + + //if output polygons share an edge, they'll need joining later ... + TEdge* ePrev = e->PrevInAEL; + TEdge* eNext = e->NextInAEL; + if (ePrev && ePrev->Curr.X == e->Bot.X && + ePrev->Curr.Y == e->Bot.Y && op && + ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y && + SlopesEqual(e->Curr, e->Top, ePrev->Curr, ePrev->Top, m_UseFullRange) && + (e->WindDelta != 0) && (ePrev->WindDelta != 0)) + { + OutPt* op2 = AddOutPt(ePrev, e->Bot); + AddJoin(op, op2, e->Top); + } + else if (eNext && eNext->Curr.X == e->Bot.X && + eNext->Curr.Y == e->Bot.Y && op && + eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y && + SlopesEqual(e->Curr, e->Top, eNext->Curr, eNext->Top, m_UseFullRange) && + (e->WindDelta != 0) && (eNext->WindDelta != 0)) + { + OutPt* op2 = AddOutPt(eNext, e->Bot); + AddJoin(op, op2, e->Top); + } + } + e = e->NextInAEL; + } +} +//------------------------------------------------------------------------------ + +void Clipper::FixupOutPolyline(OutRec &outrec) +{ + OutPt *pp = outrec.Pts; + OutPt *lastPP = pp->Prev; + while (pp != lastPP) + { + pp = pp->Next; + if (pp->Pt == pp->Prev->Pt) + { + if (pp == lastPP) lastPP = pp->Prev; + OutPt *tmpPP = pp->Prev; + tmpPP->Next = pp->Next; + pp->Next->Prev = tmpPP; + delete pp; + pp = tmpPP; + } + } + + if (pp == pp->Prev) + { + DisposeOutPts(pp); + outrec.Pts = 0; + return; + } +} +//------------------------------------------------------------------------------ + +void Clipper::FixupOutPolygon(OutRec &outrec) +{ + //FixupOutPolygon() - removes duplicate points and simplifies consecutive + //parallel edges by removing the middle vertex. + OutPt *lastOK = 0; + outrec.BottomPt = 0; + OutPt *pp = outrec.Pts; + bool preserveCol = m_PreserveCollinear || m_StrictSimple; + + for (;;) + { + if (pp->Prev == pp || pp->Prev == pp->Next) + { + DisposeOutPts(pp); + outrec.Pts = 0; + return; + } + + //test for duplicate points and collinear edges ... + if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) || + (SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) && + (!preserveCol || !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt)))) + { + lastOK = 0; + OutPt *tmp = pp; + pp->Prev->Next = pp->Next; + pp->Next->Prev = pp->Prev; + pp = pp->Prev; + delete tmp; + } + else if (pp == lastOK) break; + else + { + if (!lastOK) lastOK = pp; + pp = pp->Next; + } + } + outrec.Pts = pp; +} +//------------------------------------------------------------------------------ + +int PointCount(OutPt *Pts) +{ + if (!Pts) return 0; + int result = 0; + OutPt* p = Pts; + do + { + result++; + p = p->Next; + } + while (p != Pts); + return result; +} +//------------------------------------------------------------------------------ + +void Clipper::BuildResult(Paths &polys) +{ + polys.reserve(m_PolyOuts.size()); + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + if (!m_PolyOuts[i]->Pts) continue; + Path pg; + OutPt* p = m_PolyOuts[i]->Pts->Prev; + int cnt = PointCount(p); + if (cnt < 2) continue; + pg.reserve(cnt); + for (int i = 0; i < cnt; ++i) + { + pg.push_back(p->Pt); + p = p->Prev; + } + polys.push_back(pg); + } +} +//------------------------------------------------------------------------------ + +void Clipper::BuildResult2(PolyTree& polytree) +{ + polytree.Clear(); + polytree.AllNodes.reserve(m_PolyOuts.size()); + //add each output polygon/contour to polytree ... + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) + { + OutRec* outRec = m_PolyOuts[i]; + int cnt = PointCount(outRec->Pts); + if ((outRec->IsOpen && cnt < 2) || (!outRec->IsOpen && cnt < 3)) continue; + FixHoleLinkage(*outRec); + PolyNode* pn = new PolyNode(); + //nb: polytree takes ownership of all the PolyNodes + polytree.AllNodes.push_back(pn); + outRec->PolyNd = pn; + pn->Parent = 0; + pn->Index = 0; + pn->Contour.reserve(cnt); + OutPt *op = outRec->Pts->Prev; + for (int j = 0; j < cnt; j++) + { + pn->Contour.push_back(op->Pt); + op = op->Prev; + } + } + + //fixup PolyNode links etc ... + polytree.Childs.reserve(m_PolyOuts.size()); + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) + { + OutRec* outRec = m_PolyOuts[i]; + if (!outRec->PolyNd) continue; + if (outRec->IsOpen) + { + outRec->PolyNd->m_IsOpen = true; + polytree.AddChild(*outRec->PolyNd); + } + else if (outRec->FirstLeft && outRec->FirstLeft->PolyNd) + outRec->FirstLeft->PolyNd->AddChild(*outRec->PolyNd); + else + polytree.AddChild(*outRec->PolyNd); + } +} +//------------------------------------------------------------------------------ + +void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2) +{ + //just swap the contents (because fIntersectNodes is a single-linked-list) + IntersectNode inode = int1; //gets a copy of Int1 + int1.Edge1 = int2.Edge1; + int1.Edge2 = int2.Edge2; + int1.Pt = int2.Pt; + int2.Edge1 = inode.Edge1; + int2.Edge2 = inode.Edge2; + int2.Pt = inode.Pt; +} +//------------------------------------------------------------------------------ + +inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2) +{ + if (e2.Curr.X == e1.Curr.X) + { + if (e2.Top.Y > e1.Top.Y) + return e2.Top.X < TopX(e1, e2.Top.Y); + else return e1.Top.X > TopX(e2, e1.Top.Y); + } + else return e2.Curr.X < e1.Curr.X; +} +//------------------------------------------------------------------------------ + +bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2, + cInt& Left, cInt& Right) +{ + if (a1 < a2) + { + if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);} + else {Left = std::max(a1,b2); Right = std::min(a2,b1);} + } + else + { + if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);} + else {Left = std::max(a2,b2); Right = std::min(a1,b1);} + } + return Left < Right; +} +//------------------------------------------------------------------------------ + +inline void UpdateOutPtIdxs(OutRec& outrec) +{ + OutPt* op = outrec.Pts; + do + { + op->Idx = outrec.Idx; + op = op->Prev; + } + while(op != outrec.Pts); +} +//------------------------------------------------------------------------------ + +void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge) +{ + if(!m_ActiveEdges) + { + edge->PrevInAEL = 0; + edge->NextInAEL = 0; + m_ActiveEdges = edge; + } + else if(!startEdge && E2InsertsBeforeE1(*m_ActiveEdges, *edge)) + { + edge->PrevInAEL = 0; + edge->NextInAEL = m_ActiveEdges; + m_ActiveEdges->PrevInAEL = edge; + m_ActiveEdges = edge; + } + else + { + if(!startEdge) startEdge = m_ActiveEdges; + while(startEdge->NextInAEL && + !E2InsertsBeforeE1(*startEdge->NextInAEL , *edge)) + startEdge = startEdge->NextInAEL; + edge->NextInAEL = startEdge->NextInAEL; + if(startEdge->NextInAEL) startEdge->NextInAEL->PrevInAEL = edge; + edge->PrevInAEL = startEdge; + startEdge->NextInAEL = edge; + } +} +//---------------------------------------------------------------------- + +OutPt* DupOutPt(OutPt* outPt, bool InsertAfter) +{ + OutPt* result = new OutPt; + result->Pt = outPt->Pt; + result->Idx = outPt->Idx; + if (InsertAfter) + { + result->Next = outPt->Next; + result->Prev = outPt; + outPt->Next->Prev = result; + outPt->Next = result; + } + else + { + result->Prev = outPt->Prev; + result->Next = outPt; + outPt->Prev->Next = result; + outPt->Prev = result; + } + return result; +} +//------------------------------------------------------------------------------ + +bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, + const IntPoint Pt, bool DiscardLeft) +{ + Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight); + Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight); + if (Dir1 == Dir2) return false; + + //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we + //want Op1b to be on the Right. (And likewise with Op2 and Op2b.) + //So, to facilitate this while inserting Op1b and Op2b ... + //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b, + //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.) + if (Dir1 == dLeftToRight) + { + while (op1->Next->Pt.X <= Pt.X && + op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) + op1 = op1->Next; + if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; + op1b = DupOutPt(op1, !DiscardLeft); + if (op1b->Pt != Pt) + { + op1 = op1b; + op1->Pt = Pt; + op1b = DupOutPt(op1, !DiscardLeft); + } + } + else + { + while (op1->Next->Pt.X >= Pt.X && + op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) + op1 = op1->Next; + if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; + op1b = DupOutPt(op1, DiscardLeft); + if (op1b->Pt != Pt) + { + op1 = op1b; + op1->Pt = Pt; + op1b = DupOutPt(op1, DiscardLeft); + } + } + + if (Dir2 == dLeftToRight) + { + while (op2->Next->Pt.X <= Pt.X && + op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) + op2 = op2->Next; + if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; + op2b = DupOutPt(op2, !DiscardLeft); + if (op2b->Pt != Pt) + { + op2 = op2b; + op2->Pt = Pt; + op2b = DupOutPt(op2, !DiscardLeft); + }; + } else + { + while (op2->Next->Pt.X >= Pt.X && + op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) + op2 = op2->Next; + if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; + op2b = DupOutPt(op2, DiscardLeft); + if (op2b->Pt != Pt) + { + op2 = op2b; + op2->Pt = Pt; + op2b = DupOutPt(op2, DiscardLeft); + }; + }; + + if ((Dir1 == dLeftToRight) == DiscardLeft) + { + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + } + else + { + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + } + return true; +} +//------------------------------------------------------------------------------ + +bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) +{ + OutPt *op1 = j->OutPt1, *op1b; + OutPt *op2 = j->OutPt2, *op2b; + + //There are 3 kinds of joins for output polygons ... + //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are vertices anywhere + //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal). + //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same + //location at the Bottom of the overlapping segment (& Join.OffPt is above). + //3. StrictSimple joins where edges touch but are not collinear and where + //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point. + bool isHorizontal = (j->OutPt1->Pt.Y == j->OffPt.Y); + + if (isHorizontal && (j->OffPt == j->OutPt1->Pt) && + (j->OffPt == j->OutPt2->Pt)) + { + //Strictly Simple join ... + if (outRec1 != outRec2) return false; + op1b = j->OutPt1->Next; + while (op1b != op1 && (op1b->Pt == j->OffPt)) + op1b = op1b->Next; + bool reverse1 = (op1b->Pt.Y > j->OffPt.Y); + op2b = j->OutPt2->Next; + while (op2b != op2 && (op2b->Pt == j->OffPt)) + op2b = op2b->Next; + bool reverse2 = (op2b->Pt.Y > j->OffPt.Y); + if (reverse1 == reverse2) return false; + if (reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + j->OutPt1 = op1; + j->OutPt2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + j->OutPt1 = op1; + j->OutPt2 = op1b; + return true; + } + } + else if (isHorizontal) + { + //treat horizontal joins differently to non-horizontal joins since with + //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt + //may be anywhere along the horizontal edge. + op1b = op1; + while (op1->Prev->Pt.Y == op1->Pt.Y && op1->Prev != op1b && op1->Prev != op2) + op1 = op1->Prev; + while (op1b->Next->Pt.Y == op1b->Pt.Y && op1b->Next != op1 && op1b->Next != op2) + op1b = op1b->Next; + if (op1b->Next == op1 || op1b->Next == op2) return false; //a flat 'polygon' + + op2b = op2; + while (op2->Prev->Pt.Y == op2->Pt.Y && op2->Prev != op2b && op2->Prev != op1b) + op2 = op2->Prev; + while (op2b->Next->Pt.Y == op2b->Pt.Y && op2b->Next != op2 && op2b->Next != op1) + op2b = op2b->Next; + if (op2b->Next == op2 || op2b->Next == op1) return false; //a flat 'polygon' + + cInt Left, Right; + //Op1 --> Op1b & Op2 --> Op2b are the extremites of the horizontal edges + if (!GetOverlap(op1->Pt.X, op1b->Pt.X, op2->Pt.X, op2b->Pt.X, Left, Right)) + return false; + + //DiscardLeftSide: when overlapping edges are joined, a spike will created + //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up + //on the discard Side as either may still be needed for other joins ... + IntPoint Pt; + bool DiscardLeftSide; + if (op1->Pt.X >= Left && op1->Pt.X <= Right) + { + Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X); + } + else if (op2->Pt.X >= Left&& op2->Pt.X <= Right) + { + Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X); + } + else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right) + { + Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X; + } + else + { + Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X); + } + j->OutPt1 = op1; j->OutPt2 = op2; + return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide); + } else + { + //nb: For non-horizontal joins ... + // 1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y + // 2. Jr.OutPt1.Pt > Jr.OffPt.Y + + //make sure the polygons are correctly oriented ... + op1b = op1->Next; + while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Next; + bool Reverse1 = ((op1b->Pt.Y > op1->Pt.Y) || + !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)); + if (Reverse1) + { + op1b = op1->Prev; + while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Prev; + if ((op1b->Pt.Y > op1->Pt.Y) || + !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)) return false; + }; + op2b = op2->Next; + while ((op2b->Pt == op2->Pt) && (op2b != op2))op2b = op2b->Next; + bool Reverse2 = ((op2b->Pt.Y > op2->Pt.Y) || + !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)); + if (Reverse2) + { + op2b = op2->Prev; + while ((op2b->Pt == op2->Pt) && (op2b != op2)) op2b = op2b->Prev; + if ((op2b->Pt.Y > op2->Pt.Y) || + !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)) return false; + } + + if ((op1b == op1) || (op2b == op2) || (op1b == op2b) || + ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false; + + if (Reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + j->OutPt1 = op1; + j->OutPt2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + j->OutPt1 = op1; + j->OutPt2 = op1b; + return true; + } + } +} +//---------------------------------------------------------------------- + +static OutRec* ParseFirstLeft(OutRec* FirstLeft) +{ + while (FirstLeft && !FirstLeft->Pts) + FirstLeft = FirstLeft->FirstLeft; + return FirstLeft; +} +//------------------------------------------------------------------------------ + +void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) +{ + //tests if NewOutRec contains the polygon before reassigning FirstLeft + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec* outRec = m_PolyOuts[i]; + OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft); + if (outRec->Pts && firstLeft == OldOutRec) + { + if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts)) + outRec->FirstLeft = NewOutRec; + } + } +} +//---------------------------------------------------------------------- + +void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec) +{ + //A polygon has split into two such that one is now the inner of the other. + //It's possible that these polygons now wrap around other polygons, so check + //every polygon that's also contained by OuterOutRec's FirstLeft container + //(including 0) to see if they've become inner to the new inner polygon ... + OutRec* orfl = OuterOutRec->FirstLeft; + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec* outRec = m_PolyOuts[i]; + + if (!outRec->Pts || outRec == OuterOutRec || outRec == InnerOutRec) + continue; + OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft); + if (firstLeft != orfl && firstLeft != InnerOutRec && firstLeft != OuterOutRec) + continue; + if (Poly2ContainsPoly1(outRec->Pts, InnerOutRec->Pts)) + outRec->FirstLeft = InnerOutRec; + else if (Poly2ContainsPoly1(outRec->Pts, OuterOutRec->Pts)) + outRec->FirstLeft = OuterOutRec; + else if (outRec->FirstLeft == InnerOutRec || outRec->FirstLeft == OuterOutRec) + outRec->FirstLeft = orfl; + } +} +//---------------------------------------------------------------------- +void Clipper::FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec) +{ + //reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec* outRec = m_PolyOuts[i]; + OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft); + if (outRec->Pts && firstLeft == OldOutRec) + outRec->FirstLeft = NewOutRec; + } +} +//---------------------------------------------------------------------- + +void Clipper::JoinCommonEdges() +{ + for (JoinList::size_type i = 0; i < m_Joins.size(); i++) + { + Join* join = m_Joins[i]; + + OutRec *outRec1 = GetOutRec(join->OutPt1->Idx); + OutRec *outRec2 = GetOutRec(join->OutPt2->Idx); + + if (!outRec1->Pts || !outRec2->Pts) continue; + if (outRec1->IsOpen || outRec2->IsOpen) continue; + + //get the polygon fragment with the correct hole state (FirstLeft) + //before calling JoinPoints() ... + OutRec *holeStateRec; + if (outRec1 == outRec2) holeStateRec = outRec1; + else if (OutRec1RightOfOutRec2(outRec1, outRec2)) holeStateRec = outRec2; + else if (OutRec1RightOfOutRec2(outRec2, outRec1)) holeStateRec = outRec1; + else holeStateRec = GetLowermostRec(outRec1, outRec2); + + if (!JoinPoints(join, outRec1, outRec2)) continue; + + if (outRec1 == outRec2) + { + //instead of joining two polygons, we've just created a new one by + //splitting one polygon into two. + outRec1->Pts = join->OutPt1; + outRec1->BottomPt = 0; + outRec2 = CreateOutRec(); + outRec2->Pts = join->OutPt2; + + //update all OutRec2.Pts Idx's ... + UpdateOutPtIdxs(*outRec2); + + if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts)) + { + //outRec1 contains outRec2 ... + outRec2->IsHole = !outRec1->IsHole; + outRec2->FirstLeft = outRec1; + + if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); + + if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0)) + ReversePolyPtLinks(outRec2->Pts); + + } else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts)) + { + //outRec2 contains outRec1 ... + outRec2->IsHole = outRec1->IsHole; + outRec1->IsHole = !outRec2->IsHole; + outRec2->FirstLeft = outRec1->FirstLeft; + outRec1->FirstLeft = outRec2; + + if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2); + + if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0)) + ReversePolyPtLinks(outRec1->Pts); + } + else + { + //the 2 polygons are completely separate ... + outRec2->IsHole = outRec1->IsHole; + outRec2->FirstLeft = outRec1->FirstLeft; + + //fixup FirstLeft pointers that may need reassigning to OutRec2 + if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2); + } + + } else + { + //joined 2 polygons together ... + + outRec2->Pts = 0; + outRec2->BottomPt = 0; + outRec2->Idx = outRec1->Idx; + + outRec1->IsHole = holeStateRec->IsHole; + if (holeStateRec == outRec2) + outRec1->FirstLeft = outRec2->FirstLeft; + outRec2->FirstLeft = outRec1; + + if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1); + } + } +} + +//------------------------------------------------------------------------------ +// ClipperOffset support functions ... +//------------------------------------------------------------------------------ + +DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2) +{ + if(pt2.X == pt1.X && pt2.Y == pt1.Y) + return DoublePoint(0, 0); + + double Dx = (double)(pt2.X - pt1.X); + double dy = (double)(pt2.Y - pt1.Y); + double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy ); + Dx *= f; + dy *= f; + return DoublePoint(dy, -Dx); +} + +//------------------------------------------------------------------------------ +// ClipperOffset class +//------------------------------------------------------------------------------ + +ClipperOffset::ClipperOffset(double miterLimit, double arcTolerance) +{ + this->MiterLimit = miterLimit; + this->ArcTolerance = arcTolerance; + m_lowest.X = -1; +} +//------------------------------------------------------------------------------ + +ClipperOffset::~ClipperOffset() +{ + Clear(); +} +//------------------------------------------------------------------------------ + +void ClipperOffset::Clear() +{ + for (int i = 0; i < m_polyNodes.ChildCount(); ++i) + delete m_polyNodes.Childs[i]; + m_polyNodes.Childs.clear(); + m_lowest.X = -1; +} +//------------------------------------------------------------------------------ + +void ClipperOffset::AddPath(const Path& path, JoinType joinType, EndType endType) +{ + int highI = (int)path.size() - 1; + if (highI < 0) return; + PolyNode* newNode = new PolyNode(); + newNode->m_jointype = joinType; + newNode->m_endtype = endType; + + //strip duplicate points from path and also get index to the lowest point ... + if (endType == etClosedLine || endType == etClosedPolygon) + while (highI > 0 && path[0] == path[highI]) highI--; + newNode->Contour.reserve(highI + 1); + newNode->Contour.push_back(path[0]); + int j = 0, k = 0; + for (int i = 1; i <= highI; i++) + if (newNode->Contour[j] != path[i]) + { + j++; + newNode->Contour.push_back(path[i]); + if (path[i].Y > newNode->Contour[k].Y || + (path[i].Y == newNode->Contour[k].Y && + path[i].X < newNode->Contour[k].X)) k = j; + } + if (endType == etClosedPolygon && j < 2) + { + delete newNode; + return; + } + m_polyNodes.AddChild(*newNode); + + //if this path's lowest pt is lower than all the others then update m_lowest + if (endType != etClosedPolygon) return; + if (m_lowest.X < 0) + m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k); + else + { + IntPoint ip = m_polyNodes.Childs[(int)m_lowest.X]->Contour[(int)m_lowest.Y]; + if (newNode->Contour[k].Y > ip.Y || + (newNode->Contour[k].Y == ip.Y && + newNode->Contour[k].X < ip.X)) + m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k); + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::AddPaths(const Paths& paths, JoinType joinType, EndType endType) +{ + for (Paths::size_type i = 0; i < paths.size(); ++i) + AddPath(paths[i], joinType, endType); +} +//------------------------------------------------------------------------------ + +void ClipperOffset::FixOrientations() +{ + //fixup orientations of all closed paths if the orientation of the + //closed path with the lowermost vertex is wrong ... + if (m_lowest.X >= 0 && + !Orientation(m_polyNodes.Childs[(int)m_lowest.X]->Contour)) + { + for (int i = 0; i < m_polyNodes.ChildCount(); ++i) + { + PolyNode& node = *m_polyNodes.Childs[i]; + if (node.m_endtype == etClosedPolygon || + (node.m_endtype == etClosedLine && Orientation(node.Contour))) + ReversePath(node.Contour); + } + } else + { + for (int i = 0; i < m_polyNodes.ChildCount(); ++i) + { + PolyNode& node = *m_polyNodes.Childs[i]; + if (node.m_endtype == etClosedLine && !Orientation(node.Contour)) + ReversePath(node.Contour); + } + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::Execute(Paths& solution, double delta) +{ + solution.clear(); + FixOrientations(); + DoOffset(delta); + + //now clean up 'corners' ... + Clipper clpr; + clpr.AddPaths(m_destPolys, ptSubject, true); + if (delta > 0) + { + clpr.Execute(ctUnion, solution, pftPositive, pftPositive); + } + else + { + IntRect r = clpr.GetBounds(); + Path outer(4); + outer[0] = IntPoint(r.left - 10, r.bottom + 10); + outer[1] = IntPoint(r.right + 10, r.bottom + 10); + outer[2] = IntPoint(r.right + 10, r.top - 10); + outer[3] = IntPoint(r.left - 10, r.top - 10); + + clpr.AddPath(outer, ptSubject, true); + clpr.ReverseSolution(true); + clpr.Execute(ctUnion, solution, pftNegative, pftNegative); + if (solution.size() > 0) solution.erase(solution.begin()); + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::Execute(PolyTree& solution, double delta) +{ + solution.Clear(); + FixOrientations(); + DoOffset(delta); + + //now clean up 'corners' ... + Clipper clpr; + clpr.AddPaths(m_destPolys, ptSubject, true); + if (delta > 0) + { + clpr.Execute(ctUnion, solution, pftPositive, pftPositive); + } + else + { + IntRect r = clpr.GetBounds(); + Path outer(4); + outer[0] = IntPoint(r.left - 10, r.bottom + 10); + outer[1] = IntPoint(r.right + 10, r.bottom + 10); + outer[2] = IntPoint(r.right + 10, r.top - 10); + outer[3] = IntPoint(r.left - 10, r.top - 10); + + clpr.AddPath(outer, ptSubject, true); + clpr.ReverseSolution(true); + clpr.Execute(ctUnion, solution, pftNegative, pftNegative); + //remove the outer PolyNode rectangle ... + if (solution.ChildCount() == 1 && solution.Childs[0]->ChildCount() > 0) + { + PolyNode* outerNode = solution.Childs[0]; + solution.Childs.reserve(outerNode->ChildCount()); + solution.Childs[0] = outerNode->Childs[0]; + solution.Childs[0]->Parent = outerNode->Parent; + for (int i = 1; i < outerNode->ChildCount(); ++i) + solution.AddChild(*outerNode->Childs[i]); + } + else + solution.Clear(); + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::DoOffset(double delta) +{ + m_destPolys.clear(); + m_delta = delta; + + //if Zero offset, just copy any CLOSED polygons to m_p and return ... + if (NEAR_ZERO(delta)) + { + m_destPolys.reserve(m_polyNodes.ChildCount()); + for (int i = 0; i < m_polyNodes.ChildCount(); i++) + { + PolyNode& node = *m_polyNodes.Childs[i]; + if (node.m_endtype == etClosedPolygon) + m_destPolys.push_back(node.Contour); + } + return; + } + + //see offset_triginometry3.svg in the documentation folder ... + if (MiterLimit > 2) m_miterLim = 2/(MiterLimit * MiterLimit); + else m_miterLim = 0.5; + + double y; + if (ArcTolerance <= 0.0) y = def_arc_tolerance; + else if (ArcTolerance > std::fabs(delta) * def_arc_tolerance) + y = std::fabs(delta) * def_arc_tolerance; + else y = ArcTolerance; + //see offset_triginometry2.svg in the documentation folder ... + double steps = pi / std::acos(1 - y / std::fabs(delta)); + if (steps > std::fabs(delta) * pi) + steps = std::fabs(delta) * pi; //ie excessive precision check + m_sin = std::sin(two_pi / steps); + m_cos = std::cos(two_pi / steps); + m_StepsPerRad = steps / two_pi; + if (delta < 0.0) m_sin = -m_sin; + + m_destPolys.reserve(m_polyNodes.ChildCount() * 2); + for (int i = 0; i < m_polyNodes.ChildCount(); i++) + { + PolyNode& node = *m_polyNodes.Childs[i]; + m_srcPoly = node.Contour; + + int len = (int)m_srcPoly.size(); + if (len == 0 || (delta <= 0 && (len < 3 || node.m_endtype != etClosedPolygon))) + continue; + + m_destPoly.clear(); + if (len == 1) + { + if (node.m_jointype == jtRound) + { + double X = 1.0, Y = 0.0; + for (cInt j = 1; j <= steps; j++) + { + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[0].X + X * delta), + Round(m_srcPoly[0].Y + Y * delta))); + double X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + } + else + { + double X = -1.0, Y = -1.0; + for (int j = 0; j < 4; ++j) + { + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[0].X + X * delta), + Round(m_srcPoly[0].Y + Y * delta))); + if (X < 0) X = 1; + else if (Y < 0) Y = 1; + else X = -1; + } + } + m_destPolys.push_back(m_destPoly); + continue; + } + //build m_normals ... + m_normals.clear(); + m_normals.reserve(len); + for (int j = 0; j < len - 1; ++j) + m_normals.push_back(GetUnitNormal(m_srcPoly[j], m_srcPoly[j + 1])); + if (node.m_endtype == etClosedLine || node.m_endtype == etClosedPolygon) + m_normals.push_back(GetUnitNormal(m_srcPoly[len - 1], m_srcPoly[0])); + else + m_normals.push_back(DoublePoint(m_normals[len - 2])); + + if (node.m_endtype == etClosedPolygon) + { + int k = len - 1; + for (int j = 0; j < len; ++j) + OffsetPoint(j, k, node.m_jointype); + m_destPolys.push_back(m_destPoly); + } + else if (node.m_endtype == etClosedLine) + { + int k = len - 1; + for (int j = 0; j < len; ++j) + OffsetPoint(j, k, node.m_jointype); + m_destPolys.push_back(m_destPoly); + m_destPoly.clear(); + //re-build m_normals ... + DoublePoint n = m_normals[len -1]; + for (int j = len - 1; j > 0; j--) + m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y); + m_normals[0] = DoublePoint(-n.X, -n.Y); + k = 0; + for (int j = len - 1; j >= 0; j--) + OffsetPoint(j, k, node.m_jointype); + m_destPolys.push_back(m_destPoly); + } + else + { + int k = 0; + for (int j = 1; j < len - 1; ++j) + OffsetPoint(j, k, node.m_jointype); + + IntPoint pt1; + if (node.m_endtype == etOpenButt) + { + int j = len - 1; + pt1 = IntPoint((cInt)Round(m_srcPoly[j].X + m_normals[j].X * + delta), (cInt)Round(m_srcPoly[j].Y + m_normals[j].Y * delta)); + m_destPoly.push_back(pt1); + pt1 = IntPoint((cInt)Round(m_srcPoly[j].X - m_normals[j].X * + delta), (cInt)Round(m_srcPoly[j].Y - m_normals[j].Y * delta)); + m_destPoly.push_back(pt1); + } + else + { + int j = len - 1; + k = len - 2; + m_sinA = 0; + m_normals[j] = DoublePoint(-m_normals[j].X, -m_normals[j].Y); + if (node.m_endtype == etOpenSquare) + DoSquare(j, k); + else + DoRound(j, k); + } + + //re-build m_normals ... + for (int j = len - 1; j > 0; j--) + m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y); + m_normals[0] = DoublePoint(-m_normals[1].X, -m_normals[1].Y); + + k = len - 1; + for (int j = k - 1; j > 0; --j) OffsetPoint(j, k, node.m_jointype); + + if (node.m_endtype == etOpenButt) + { + pt1 = IntPoint((cInt)Round(m_srcPoly[0].X - m_normals[0].X * delta), + (cInt)Round(m_srcPoly[0].Y - m_normals[0].Y * delta)); + m_destPoly.push_back(pt1); + pt1 = IntPoint((cInt)Round(m_srcPoly[0].X + m_normals[0].X * delta), + (cInt)Round(m_srcPoly[0].Y + m_normals[0].Y * delta)); + m_destPoly.push_back(pt1); + } + else + { + k = 1; + m_sinA = 0; + if (node.m_endtype == etOpenSquare) + DoSquare(0, 1); + else + DoRound(0, 1); + } + m_destPolys.push_back(m_destPoly); + } + } +} +//------------------------------------------------------------------------------ + +void ClipperOffset::OffsetPoint(int j, int& k, JoinType jointype) +{ + //cross product ... + m_sinA = (m_normals[k].X * m_normals[j].Y - m_normals[j].X * m_normals[k].Y); + if (std::fabs(m_sinA * m_delta) < 1.0) + { + //dot product ... + double cosA = (m_normals[k].X * m_normals[j].X + m_normals[j].Y * m_normals[k].Y ); + if (cosA > 0) // angle => 0 degrees + { + m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta), + Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta))); + return; + } + //else angle => 180 degrees + } + else if (m_sinA > 1.0) m_sinA = 1.0; + else if (m_sinA < -1.0) m_sinA = -1.0; + + if (m_sinA * m_delta < 0) + { + m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta), + Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta))); + m_destPoly.push_back(m_srcPoly[j]); + m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[j].X * m_delta), + Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta))); + } + else + switch (jointype) + { + case jtMiter: + { + double r = 1 + (m_normals[j].X * m_normals[k].X + + m_normals[j].Y * m_normals[k].Y); + if (r >= m_miterLim) DoMiter(j, k, r); else DoSquare(j, k); + break; + } + case jtSquare: DoSquare(j, k); break; + case jtRound: DoRound(j, k); break; + } + k = j; +} +//------------------------------------------------------------------------------ + +void ClipperOffset::DoSquare(int j, int k) +{ + double dx = std::tan(std::atan2(m_sinA, + m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y) / 4); + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[j].X + m_delta * (m_normals[k].X - m_normals[k].Y * dx)), + Round(m_srcPoly[j].Y + m_delta * (m_normals[k].Y + m_normals[k].X * dx)))); + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[j].X + m_delta * (m_normals[j].X + m_normals[j].Y * dx)), + Round(m_srcPoly[j].Y + m_delta * (m_normals[j].Y - m_normals[j].X * dx)))); +} +//------------------------------------------------------------------------------ + +void ClipperOffset::DoMiter(int j, int k, double r) +{ + double q = m_delta / r; + m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + (m_normals[k].X + m_normals[j].X) * q), + Round(m_srcPoly[j].Y + (m_normals[k].Y + m_normals[j].Y) * q))); +} +//------------------------------------------------------------------------------ + +void ClipperOffset::DoRound(int j, int k) +{ + double a = std::atan2(m_sinA, + m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y); + int steps = std::max((int)Round(m_StepsPerRad * std::fabs(a)), 1); + + double X = m_normals[k].X, Y = m_normals[k].Y, X2; + for (int i = 0; i < steps; ++i) + { + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[j].X + X * m_delta), + Round(m_srcPoly[j].Y + Y * m_delta))); + X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + m_destPoly.push_back(IntPoint( + Round(m_srcPoly[j].X + m_normals[j].X * m_delta), + Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta))); +} + +//------------------------------------------------------------------------------ +// Miscellaneous public functions +//------------------------------------------------------------------------------ + +void Clipper::DoSimplePolygons() +{ + PolyOutList::size_type i = 0; + while (i < m_PolyOuts.size()) + { + OutRec* outrec = m_PolyOuts[i++]; + OutPt* op = outrec->Pts; + if (!op || outrec->IsOpen) continue; + do //for each Pt in Polygon until duplicate found do ... + { + OutPt* op2 = op->Next; + while (op2 != outrec->Pts) + { + if ((op->Pt == op2->Pt) && op2->Next != op && op2->Prev != op) + { + //split the polygon into two ... + OutPt* op3 = op->Prev; + OutPt* op4 = op2->Prev; + op->Prev = op4; + op4->Next = op; + op2->Prev = op3; + op3->Next = op2; + + outrec->Pts = op; + OutRec* outrec2 = CreateOutRec(); + outrec2->Pts = op2; + UpdateOutPtIdxs(*outrec2); + if (Poly2ContainsPoly1(outrec2->Pts, outrec->Pts)) + { + //OutRec2 is contained by OutRec1 ... + outrec2->IsHole = !outrec->IsHole; + outrec2->FirstLeft = outrec; + if (m_UsingPolyTree) FixupFirstLefts2(outrec2, outrec); + } + else + if (Poly2ContainsPoly1(outrec->Pts, outrec2->Pts)) + { + //OutRec1 is contained by OutRec2 ... + outrec2->IsHole = outrec->IsHole; + outrec->IsHole = !outrec2->IsHole; + outrec2->FirstLeft = outrec->FirstLeft; + outrec->FirstLeft = outrec2; + if (m_UsingPolyTree) FixupFirstLefts2(outrec, outrec2); + } + else + { + //the 2 polygons are separate ... + outrec2->IsHole = outrec->IsHole; + outrec2->FirstLeft = outrec->FirstLeft; + if (m_UsingPolyTree) FixupFirstLefts1(outrec, outrec2); + } + op2 = op; //ie get ready for the Next iteration + } + op2 = op2->Next; + } + op = op->Next; + } + while (op != outrec->Pts); + } +} +//------------------------------------------------------------------------------ + +void ReversePath(Path& p) +{ + std::reverse(p.begin(), p.end()); +} +//------------------------------------------------------------------------------ + +void ReversePaths(Paths& p) +{ + for (Paths::size_type i = 0; i < p.size(); ++i) + ReversePath(p[i]); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType) +{ + Clipper c; + c.StrictlySimple(true); + c.AddPath(in_poly, ptSubject, true); + c.Execute(ctUnion, out_polys, fillType, fillType); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType) +{ + Clipper c; + c.StrictlySimple(true); + c.AddPaths(in_polys, ptSubject, true); + c.Execute(ctUnion, out_polys, fillType, fillType); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygons(Paths &polys, PolyFillType fillType) +{ + SimplifyPolygons(polys, polys, fillType); +} +//------------------------------------------------------------------------------ + +inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2) +{ + double Dx = ((double)pt1.X - pt2.X); + double dy = ((double)pt1.Y - pt2.Y); + return (Dx*Dx + dy*dy); +} +//------------------------------------------------------------------------------ + +double DistanceFromLineSqrd( + const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2) +{ + //The equation of a line in general form (Ax + By + C = 0) + //given 2 points (x¹,y¹) & (x²,y²) is ... + //(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0 + //A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹ + //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) + //see http://en.wikipedia.org/wiki/Perpendicular_distance + double A = double(ln1.Y - ln2.Y); + double B = double(ln2.X - ln1.X); + double C = A * ln1.X + B * ln1.Y; + C = A * pt.X + B * pt.Y - C; + return (C * C) / (A * A + B * B); +} +//--------------------------------------------------------------------------- + +bool SlopesNearCollinear(const IntPoint& pt1, + const IntPoint& pt2, const IntPoint& pt3, double distSqrd) +{ + //this function is more accurate when the point that's geometrically + //between the other 2 points is the one that's tested for distance. + //ie makes it more likely to pick up 'spikes' ... + if (Abs(pt1.X - pt2.X) > Abs(pt1.Y - pt2.Y)) + { + if ((pt1.X > pt2.X) == (pt1.X < pt3.X)) + return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd; + else if ((pt2.X > pt1.X) == (pt2.X < pt3.X)) + return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd; + else + return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd; + } + else + { + if ((pt1.Y > pt2.Y) == (pt1.Y < pt3.Y)) + return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd; + else if ((pt2.Y > pt1.Y) == (pt2.Y < pt3.Y)) + return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd; + else + return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd; + } +} +//------------------------------------------------------------------------------ + +bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd) +{ + double Dx = (double)pt1.X - pt2.X; + double dy = (double)pt1.Y - pt2.Y; + return ((Dx * Dx) + (dy * dy) <= distSqrd); +} +//------------------------------------------------------------------------------ + +OutPt* ExcludeOp(OutPt* op) +{ + OutPt* result = op->Prev; + result->Next = op->Next; + op->Next->Prev = result; + result->Idx = 0; + return result; +} +//------------------------------------------------------------------------------ + +void CleanPolygon(const Path& in_poly, Path& out_poly, double distance) +{ + //distance = proximity in units/pixels below which vertices + //will be stripped. Default ~= sqrt(2). + + size_t size = in_poly.size(); + + if (size == 0) + { + out_poly.clear(); + return; + } + + OutPt* outPts = new OutPt[size]; + for (size_t i = 0; i < size; ++i) + { + outPts[i].Pt = in_poly[i]; + outPts[i].Next = &outPts[(i + 1) % size]; + outPts[i].Next->Prev = &outPts[i]; + outPts[i].Idx = 0; + } + + double distSqrd = distance * distance; + OutPt* op = &outPts[0]; + while (op->Idx == 0 && op->Next != op->Prev) + { + if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd)) + { + op = ExcludeOp(op); + size--; + } + else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd)) + { + ExcludeOp(op->Next); + op = ExcludeOp(op); + size -= 2; + } + else if (SlopesNearCollinear(op->Prev->Pt, op->Pt, op->Next->Pt, distSqrd)) + { + op = ExcludeOp(op); + size--; + } + else + { + op->Idx = 1; + op = op->Next; + } + } + + if (size < 3) size = 0; + out_poly.resize(size); + for (size_t i = 0; i < size; ++i) + { + out_poly[i] = op->Pt; + op = op->Next; + } + delete [] outPts; +} +//------------------------------------------------------------------------------ + +void CleanPolygon(Path& poly, double distance) +{ + CleanPolygon(poly, poly, distance); +} +//------------------------------------------------------------------------------ + +void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance) +{ + out_polys.resize(in_polys.size()); + for (Paths::size_type i = 0; i < in_polys.size(); ++i) + CleanPolygon(in_polys[i], out_polys[i], distance); +} +//------------------------------------------------------------------------------ + +void CleanPolygons(Paths& polys, double distance) +{ + CleanPolygons(polys, polys, distance); +} +//------------------------------------------------------------------------------ + +void Minkowski(const Path& poly, const Path& path, + Paths& solution, bool isSum, bool isClosed) +{ + int delta = (isClosed ? 1 : 0); + size_t polyCnt = poly.size(); + size_t pathCnt = path.size(); + Paths pp; + pp.reserve(pathCnt); + if (isSum) + for (size_t i = 0; i < pathCnt; ++i) + { + Path p; + p.reserve(polyCnt); + for (size_t j = 0; j < poly.size(); ++j) + p.push_back(IntPoint(path[i].X + poly[j].X, path[i].Y + poly[j].Y)); + pp.push_back(p); + } + else + for (size_t i = 0; i < pathCnt; ++i) + { + Path p; + p.reserve(polyCnt); + for (size_t j = 0; j < poly.size(); ++j) + p.push_back(IntPoint(path[i].X - poly[j].X, path[i].Y - poly[j].Y)); + pp.push_back(p); + } + + solution.clear(); + solution.reserve((pathCnt + delta) * (polyCnt + 1)); + for (size_t i = 0; i < pathCnt - 1 + delta; ++i) + for (size_t j = 0; j < polyCnt; ++j) + { + Path quad; + quad.reserve(4); + quad.push_back(pp[i % pathCnt][j % polyCnt]); + quad.push_back(pp[(i + 1) % pathCnt][j % polyCnt]); + quad.push_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]); + quad.push_back(pp[i % pathCnt][(j + 1) % polyCnt]); + if (!Orientation(quad)) ReversePath(quad); + solution.push_back(quad); + } +} +//------------------------------------------------------------------------------ + +void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed) +{ + Minkowski(pattern, path, solution, true, pathIsClosed); + Clipper c; + c.AddPaths(solution, ptSubject, true); + c.Execute(ctUnion, solution, pftNonZero, pftNonZero); +} +//------------------------------------------------------------------------------ + +void TranslatePath(const Path& input, Path& output, const IntPoint delta) +{ + //precondition: input != output + output.resize(input.size()); + for (size_t i = 0; i < input.size(); ++i) + output[i] = IntPoint(input[i].X + delta.X, input[i].Y + delta.Y); +} +//------------------------------------------------------------------------------ + +void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed) +{ + Clipper c; + for (size_t i = 0; i < paths.size(); ++i) + { + Paths tmp; + Minkowski(pattern, paths[i], tmp, true, pathIsClosed); + c.AddPaths(tmp, ptSubject, true); + if (pathIsClosed) + { + Path tmp2; + TranslatePath(paths[i], tmp2, pattern[0]); + c.AddPath(tmp2, ptClip, true); + } + } + c.Execute(ctUnion, solution, pftNonZero, pftNonZero); +} +//------------------------------------------------------------------------------ + +void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution) +{ + Minkowski(poly1, poly2, solution, false, true); + Clipper c; + c.AddPaths(solution, ptSubject, true); + c.Execute(ctUnion, solution, pftNonZero, pftNonZero); +} +//------------------------------------------------------------------------------ + +enum NodeType {ntAny, ntOpen, ntClosed}; + +void AddPolyNodeToPaths(const PolyNode& polynode, NodeType nodetype, Paths& paths) +{ + bool match = true; + if (nodetype == ntClosed) match = !polynode.IsOpen(); + else if (nodetype == ntOpen) return; + + if (!polynode.Contour.empty() && match) + paths.push_back(polynode.Contour); + for (int i = 0; i < polynode.ChildCount(); ++i) + AddPolyNodeToPaths(*polynode.Childs[i], nodetype, paths); +} +//------------------------------------------------------------------------------ + +void PolyTreeToPaths(const PolyTree& polytree, Paths& paths) +{ + paths.resize(0); + paths.reserve(polytree.Total()); + AddPolyNodeToPaths(polytree, ntAny, paths); +} +//------------------------------------------------------------------------------ + +void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths) +{ + paths.resize(0); + paths.reserve(polytree.Total()); + AddPolyNodeToPaths(polytree, ntClosed, paths); +} +//------------------------------------------------------------------------------ + +void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths) +{ + paths.resize(0); + paths.reserve(polytree.Total()); + //Open paths are top level only, so ... + for (int i = 0; i < polytree.ChildCount(); ++i) + if (polytree.Childs[i]->IsOpen()) + paths.push_back(polytree.Childs[i]->Contour); +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, const IntPoint &p) +{ + s << "(" << p.X << "," << p.Y << ")"; + return s; +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, const Path &p) +{ + if (p.empty()) return s; + Path::size_type last = p.size() -1; + for (Path::size_type i = 0; i < last; i++) + s << "(" << p[i].X << "," << p[i].Y << "), "; + s << "(" << p[last].X << "," << p[last].Y << ")\n"; + return s; +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, const Paths &p) +{ + for (Paths::size_type i = 0; i < p.size(); i++) + s << p[i]; + s << "\n"; + return s; +} +//------------------------------------------------------------------------------ + +} //QtClipperLib namespace diff --git a/src/3rdparty/clipper/clipper.h b/src/3rdparty/clipper/clipper.h new file mode 100644 index 0000000..de4a540 --- /dev/null +++ b/src/3rdparty/clipper/clipper.h @@ -0,0 +1,404 @@ +/******************************************************************************* +* * +* Author : Angus Johnson * +* Version : 6.4.2 * +* Date : 27 February 2017 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2017 * +* * +* License: * +* Use, modification & distribution is subject to Boost Software License Ver 1. * +* http://www.boost.org/LICENSE_1_0.txt * +* * +* Attributions: * +* The code in this library is an extension of Bala Vatti's clipping algorithm: * +* "A generic solution to polygon clipping" * +* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * +* http://portal.acm.org/citation.cfm?id=129906 * +* * +* Computer graphics and geometric modeling: implementation and algorithms * +* By Max K. Agoston * +* Springer; 1 edition (January 4, 2005) * +* http://books.google.com/books?q=vatti+clipping+agoston * +* * +* See also: * +* "Polygon Offsetting by Computing Winding Numbers" * +* Paper no. DETC2005-85513 pp. 565-575 * +* ASME 2005 International Design Engineering Technical Conferences * +* and Computers and Information in Engineering Conference (IDETC/CIE2005) * +* September 24-28, 2005 , Long Beach, California, USA * +* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * +* * +*******************************************************************************/ + +#ifndef clipper_hpp +#define clipper_hpp + +#define CLIPPER_VERSION "6.4.2" + +//use_int32: When enabled 32bit ints are used instead of 64bit ints. This +//improve performance but coordinate values are limited to the range +/- 46340 +//#define use_int32 + +//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance. +//#define use_xyz + +//use_lines: Enables line clipping. Adds a very minor cost to performance. +#define use_lines + +//use_deprecated: Enables temporary support for the obsolete functions +//#define use_deprecated + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace QtClipperLib { + +enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; +enum PolyType { ptSubject, ptClip }; +//By far the most widely used winding rules for polygon filling are +//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32) +//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL) +//see http://glprogramming.com/red/chapter11.html +enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; + +#ifdef use_int32 + typedef int cInt; + static cInt const loRange = 0x7FFF; + static cInt const hiRange = 0x7FFF; +#else + typedef signed long long cInt; + static cInt const loRange = 0x3FFFFFFF; + static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL; + typedef signed long long long64; //used by Int128 class + typedef unsigned long long ulong64; + +#endif + +struct IntPoint { + cInt X; + cInt Y; +#ifdef use_xyz + cInt Z; + IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {}; +#else + IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {}; +#endif + + friend inline bool operator== (const IntPoint& a, const IntPoint& b) + { + return a.X == b.X && a.Y == b.Y; + } + friend inline bool operator!= (const IntPoint& a, const IntPoint& b) + { + return a.X != b.X || a.Y != b.Y; + } +}; +//------------------------------------------------------------------------------ + +typedef std::vector< IntPoint > Path; +typedef std::vector< Path > Paths; + +inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;} +inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;} + +std::ostream& operator <<(std::ostream &s, const IntPoint &p); +std::ostream& operator <<(std::ostream &s, const Path &p); +std::ostream& operator <<(std::ostream &s, const Paths &p); + +struct DoublePoint +{ + double X; + double Y; + DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} + DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {} +}; +//------------------------------------------------------------------------------ + +#ifdef use_xyz +typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt); +#endif + +enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4}; +enum JoinType {jtSquare, jtRound, jtMiter}; +enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound}; + +class PolyNode; +typedef std::vector< PolyNode* > PolyNodes; + +class PolyNode +{ +public: + PolyNode(); + virtual ~PolyNode(){}; + Path Contour; + PolyNodes Childs; + PolyNode* Parent; + PolyNode* GetNext() const; + bool IsHole() const; + bool IsOpen() const; + int ChildCount() const; +private: + unsigned Index; //node index in Parent.Childs + bool m_IsOpen; + JoinType m_jointype; + EndType m_endtype; + PolyNode* GetNextSiblingUp() const; + void AddChild(PolyNode& child); + friend class Clipper; //to access Index + friend class ClipperOffset; +}; + +class PolyTree: public PolyNode +{ +public: + ~PolyTree(){ Clear(); }; + PolyNode* GetFirst() const; + void Clear(); + int Total() const; +private: + PolyNodes AllNodes; + friend class Clipper; //to access AllNodes +}; + +bool Orientation(const Path &poly); +double Area(const Path &poly); +int PointInPolygon(const IntPoint &pt, const Path &path); + +void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd); +void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd); +void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd); + +void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415); +void CleanPolygon(Path& poly, double distance = 1.415); +void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415); +void CleanPolygons(Paths& polys, double distance = 1.415); + +void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed); +void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed); +void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution); + +void PolyTreeToPaths(const PolyTree& polytree, Paths& paths); +void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths); +void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths); + +void ReversePath(Path& p); +void ReversePaths(Paths& p); + +struct IntRect { cInt left; cInt top; cInt right; cInt bottom; }; + +//enums that are used internally ... +enum EdgeSide { esLeft = 1, esRight = 2}; + +//forward declarations (for stuff used internally) ... +struct TEdge; +struct IntersectNode; +struct LocalMinimum; +struct OutPt; +struct OutRec; +struct Join; + +typedef std::vector < OutRec* > PolyOutList; +typedef std::vector < TEdge* > EdgeList; +typedef std::vector < Join* > JoinList; +typedef std::vector < IntersectNode* > IntersectList; + +//------------------------------------------------------------------------------ + +//ClipperBase is the ancestor to the Clipper class. It should not be +//instantiated directly. This class simply abstracts the conversion of sets of +//polygon coordinates into edge objects that are stored in a LocalMinima list. +class ClipperBase +{ +public: + ClipperBase(); + virtual ~ClipperBase(); + virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); + bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); + virtual void Clear(); + IntRect GetBounds(); + bool PreserveCollinear() {return m_PreserveCollinear;}; + void PreserveCollinear(bool value) {m_PreserveCollinear = value;}; +protected: + void DisposeLocalMinimaList(); + TEdge* AddBoundsToLML(TEdge *e, bool IsClosed); + virtual void Reset(); + TEdge* ProcessBound(TEdge* E, bool IsClockwise); + void InsertScanbeam(const cInt Y); + bool PopScanbeam(cInt &Y); + bool LocalMinimaPending(); + bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin); + OutRec* CreateOutRec(); + void DisposeAllOutRecs(); + void DisposeOutRec(PolyOutList::size_type index); + void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); + void DeleteFromAEL(TEdge *e); + void UpdateEdgeIntoAEL(TEdge *&e); + + typedef std::vector MinimaList; + MinimaList::iterator m_CurrentLM; + MinimaList m_MinimaList; + + bool m_UseFullRange; + EdgeList m_edges; + bool m_PreserveCollinear; + bool m_HasOpenPaths; + PolyOutList m_PolyOuts; + TEdge *m_ActiveEdges; + + typedef std::priority_queue ScanbeamList; + ScanbeamList m_Scanbeam; +}; +//------------------------------------------------------------------------------ + +class Clipper : public virtual ClipperBase +{ +public: + Clipper(int initOptions = 0); + bool Execute(ClipType clipType, + Paths &solution, + PolyFillType fillType = pftEvenOdd); + bool Execute(ClipType clipType, + Paths &solution, + PolyFillType subjFillType, + PolyFillType clipFillType); + bool Execute(ClipType clipType, + PolyTree &polytree, + PolyFillType fillType = pftEvenOdd); + bool Execute(ClipType clipType, + PolyTree &polytree, + PolyFillType subjFillType, + PolyFillType clipFillType); + bool ReverseSolution() { return m_ReverseOutput; }; + void ReverseSolution(bool value) {m_ReverseOutput = value;}; + bool StrictlySimple() {return m_StrictSimple;}; + void StrictlySimple(bool value) {m_StrictSimple = value;}; + //set the callback function for z value filling on intersections (otherwise Z is 0) +#ifdef use_xyz + void ZFillFunction(ZFillCallback zFillFunc); +#endif +protected: + virtual bool ExecuteInternal(); +private: + JoinList m_Joins; + JoinList m_GhostJoins; + IntersectList m_IntersectList; + ClipType m_ClipType; + typedef std::list MaximaList; + MaximaList m_Maxima; + TEdge *m_SortedEdges; + bool m_ExecuteLocked; + PolyFillType m_ClipFillType; + PolyFillType m_SubjFillType; + bool m_ReverseOutput; + bool m_UsingPolyTree; + bool m_StrictSimple; +#ifdef use_xyz + ZFillCallback m_ZFill; //custom callback +#endif + void SetWindingCount(TEdge& edge); + bool IsEvenOddFillType(const TEdge& edge) const; + bool IsEvenOddAltFillType(const TEdge& edge) const; + void InsertLocalMinimaIntoAEL(const cInt botY); + void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge); + void AddEdgeToSEL(TEdge *edge); + bool PopEdgeFromSEL(TEdge *&edge); + void CopyAELToSEL(); + void DeleteFromSEL(TEdge *e); + void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); + bool IsContributing(const TEdge& edge) const; + bool IsTopHorz(const cInt XPos); + void DoMaxima(TEdge *e); + void ProcessHorizontals(); + void ProcessHorizontal(TEdge *horzEdge); + void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); + OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); + OutRec* GetOutRec(int idx); + void AppendPolygon(TEdge *e1, TEdge *e2); + void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt); + OutPt* AddOutPt(TEdge *e, const IntPoint &pt); + OutPt* GetLastOutPt(TEdge *e); + bool ProcessIntersections(const cInt topY); + void BuildIntersectList(const cInt topY); + void ProcessIntersectList(); + void ProcessEdgesAtTopOfScanbeam(const cInt topY); + void BuildResult(Paths& polys); + void BuildResult2(PolyTree& polytree); + void SetHoleState(TEdge *e, OutRec *outrec); + void DisposeIntersectNodes(); + bool FixupIntersectionOrder(); + void FixupOutPolygon(OutRec &outrec); + void FixupOutPolyline(OutRec &outrec); + bool IsHole(TEdge *e); + bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl); + void FixHoleLinkage(OutRec &outrec); + void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt); + void ClearJoins(); + void ClearGhostJoins(); + void AddGhostJoin(OutPt *op, const IntPoint offPt); + bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2); + void JoinCommonEdges(); + void DoSimplePolygons(); + void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec); + void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec); + void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec); +#ifdef use_xyz + void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2); +#endif +}; +//------------------------------------------------------------------------------ + +class ClipperOffset +{ +public: + ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25); + ~ClipperOffset(); + void AddPath(const Path& path, JoinType joinType, EndType endType); + void AddPaths(const Paths& paths, JoinType joinType, EndType endType); + void Execute(Paths& solution, double delta); + void Execute(PolyTree& solution, double delta); + void Clear(); + double MiterLimit; + double ArcTolerance; +private: + Paths m_destPolys; + Path m_srcPoly; + Path m_destPoly; + std::vector m_normals; + double m_delta, m_sinA, m_sin, m_cos; + double m_miterLim, m_StepsPerRad; + IntPoint m_lowest; + PolyNode m_polyNodes; + + void FixOrientations(); + void DoOffset(double delta); + void OffsetPoint(int j, int& k, JoinType jointype); + void DoSquare(int j, int k); + void DoMiter(int j, int k, double r); + void DoRound(int j, int k); +}; +//------------------------------------------------------------------------------ + +class clipperException : public std::exception +{ + public: + clipperException(const char* description): m_descr(description) {} + virtual ~clipperException() throw() {} + const char* what() const throw() override {return m_descr.c_str();} + private: + std::string m_descr; +}; +//------------------------------------------------------------------------------ + +} //QtClipperLib namespace + +#endif //clipper_hpp + + diff --git a/src/3rdparty/clipper/qt_attribution.json b/src/3rdparty/clipper/qt_attribution.json new file mode 100644 index 0000000..cc00a49 --- /dev/null +++ b/src/3rdparty/clipper/qt_attribution.json @@ -0,0 +1,13 @@ +{ + "Id": "clipper", + "Name": "Clipper Polygon Clipping Library", + "QDocModule": "qtpositioning", + "QtUsage": "Used in the QML plugin of Qt Location and in Qt Positioning.", + "Description": "The Clipper library performs line & polygon clipping - intersection, union, difference & exclusive-or, and line & polygon offsetting.", + "Homepage": "http://www.angusj.com/delphi/clipper.php", + "Version": "6.4.2", + "LicenseId": "BSL-1.0", + "License": "Boost Software License 1.0", + "LicenseFile": "LICENSE", + "Copyright": "Copyright Angus Johnson 2010-2017" +} diff --git a/src/3rdparty/poly2tri/AUTHORS b/src/3rdparty/poly2tri/AUTHORS new file mode 100644 index 0000000..d8f4899 --- /dev/null +++ b/src/3rdparty/poly2tri/AUTHORS @@ -0,0 +1,8 @@ +Primary Contributors: + + Mason Green (C++, Python) + Thomas Åhlén (Java) + +Other Contributors: + + diff --git a/src/3rdparty/poly2tri/CMakeLists.txt b/src/3rdparty/poly2tri/CMakeLists.txt new file mode 100644 index 0000000..167485d --- /dev/null +++ b/src/3rdparty/poly2tri/CMakeLists.txt @@ -0,0 +1,30 @@ +# Generated from poly2tri.pro. + +##################################################################### +## Bundled_Poly2Tri Generic Library: +##################################################################### + +qt_internal_add_3rdparty_library(Bundled_Poly2Tri + QMAKE_LIB_NAME _poly2tri + STATIC + SKIP_AUTOMOC # special case + SOURCES + common/shapes.cpp common/shapes.h + common/utils.h + poly2tri.h + sweep/advancing_front.cpp sweep/advancing_front.h + sweep/cdt.cpp sweep/cdt.h + sweep/sweep.cpp sweep/sweep.h + sweep/sweep_context.cpp sweep/sweep_context.h +) +qt_disable_warnings(Bundled_Poly2Tri) +qt_set_symbol_visibility_hidden(Bundled_Poly2Tri) + +## Scopes: +##################################################################### + +#### Keys ignored in scope 3:.:.:poly2tri.pro:GCC: +# QMAKE_CFLAGS_OPTIMIZE_FULL = "-ffast-math" + +#### Keys ignored in scope 4:.:.:poly2tri.pro:NOT CLANG AND NOT ICC AND NOT rim_qcc: +# QMAKE_CXXFLAGS_WARN_ON = "-Wno-error=return-type" diff --git a/src/3rdparty/poly2tri/LICENSE b/src/3rdparty/poly2tri/LICENSE new file mode 100644 index 0000000..9417c08 --- /dev/null +++ b/src/3rdparty/poly2tri/LICENSE @@ -0,0 +1,27 @@ +Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors +http://code.google.com/p/poly2tri/ + +All rights reserved. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of Poly2Tri nor the names of its contributors may be + used to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/3rdparty/poly2tri/common/shapes.cpp b/src/3rdparty/poly2tri/common/shapes.cpp new file mode 100644 index 0000000..2ac7e97 --- /dev/null +++ b/src/3rdparty/poly2tri/common/shapes.cpp @@ -0,0 +1,363 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "shapes.h" +#include + +namespace p2t { + +Triangle::Triangle(Point& a, Point& b, Point& c) +{ + points_[0] = &a; points_[1] = &b; points_[2] = &c; + neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL; + constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false; + delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false; + interior_ = false; +} + +// Update neighbor pointers +void Triangle::MarkNeighbor(Point* p1, Point* p2, Triangle* t) +{ + if ((p1 == points_[2] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[2])) + neighbors_[0] = t; + else if ((p1 == points_[0] && p2 == points_[2]) || (p1 == points_[2] && p2 == points_[0])) + neighbors_[1] = t; + else if ((p1 == points_[0] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[0])) + neighbors_[2] = t; + else + assert(0); +} + +// Exhaustive search to update neighbor pointers +void Triangle::MarkNeighbor(Triangle& t) +{ + if (t.Contains(points_[1], points_[2])) { + neighbors_[0] = &t; + t.MarkNeighbor(points_[1], points_[2], this); + } else if (t.Contains(points_[0], points_[2])) { + neighbors_[1] = &t; + t.MarkNeighbor(points_[0], points_[2], this); + } else if (t.Contains(points_[0], points_[1])) { + neighbors_[2] = &t; + t.MarkNeighbor(points_[0], points_[1], this); + } +} + +/** + * Clears all references to all other triangles and points + */ +void Triangle::Clear() +{ + Triangle *t; + for (int i=0; i<3; i++) + { + t = neighbors_[i]; + if (t != NULL) + { + t->ClearNeighbor( this ); + } + } + ClearNeighbors(); + points_[0]=points_[1]=points_[2] = NULL; +} + +void Triangle::ClearNeighbor(Triangle *triangle ) +{ + if (neighbors_[0] == triangle) + { + neighbors_[0] = NULL; + } + else if (neighbors_[1] == triangle) + { + neighbors_[1] = NULL; + } + else + { + neighbors_[2] = NULL; + } +} + +void Triangle::ClearNeighbors() +{ + neighbors_[0] = NULL; + neighbors_[1] = NULL; + neighbors_[2] = NULL; +} + +void Triangle::ClearDelunayEdges() +{ + delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false; +} + +Point* Triangle::OppositePoint(Triangle& t, Point& p) +{ + Point *cw = t.PointCW(p); + return PointCW(*cw); +} + +// Legalized triangle by rotating clockwise around point(0) +void Triangle::Legalize(Point& point) +{ + points_[1] = points_[0]; + points_[0] = points_[2]; + points_[2] = &point; +} + +// Legalize triagnle by rotating clockwise around oPoint +void Triangle::Legalize(Point& opoint, Point& npoint) +{ + if (&opoint == points_[0]) { + points_[1] = points_[0]; + points_[0] = points_[2]; + points_[2] = &npoint; + } else if (&opoint == points_[1]) { + points_[2] = points_[1]; + points_[1] = points_[0]; + points_[0] = &npoint; + } else if (&opoint == points_[2]) { + points_[0] = points_[2]; + points_[2] = points_[1]; + points_[1] = &npoint; + } else { + assert(0); + } +} + +int Triangle::Index(const Point* p) +{ + if (p == points_[0]) { + return 0; + } else if (p == points_[1]) { + return 1; + } else if (p == points_[2]) { + return 2; + } + assert(0); +} + +int Triangle::EdgeIndex(const Point* p1, const Point* p2) +{ + if (points_[0] == p1) { + if (points_[1] == p2) { + return 2; + } else if (points_[2] == p2) { + return 1; + } + } else if (points_[1] == p1) { + if (points_[2] == p2) { + return 0; + } else if (points_[0] == p2) { + return 2; + } + } else if (points_[2] == p1) { + if (points_[0] == p2) { + return 1; + } else if (points_[1] == p2) { + return 0; + } + } + return -1; +} + +void Triangle::MarkConstrainedEdge(const int index) +{ + constrained_edge[index] = true; +} + +void Triangle::MarkConstrainedEdge(Edge& edge) +{ + MarkConstrainedEdge(edge.p, edge.q); +} + +// Mark edge as constrained +void Triangle::MarkConstrainedEdge(Point* p, Point* q) +{ + if ((q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0])) { + constrained_edge[2] = true; + } else if ((q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0])) { + constrained_edge[1] = true; + } else if ((q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1])) { + constrained_edge[0] = true; + } +} + +// The point counter-clockwise to given point +Point* Triangle::PointCW(Point& point) +{ + if (&point == points_[0]) { + return points_[2]; + } else if (&point == points_[1]) { + return points_[0]; + } else if (&point == points_[2]) { + return points_[1]; + } + assert(0); +} + +// The point counter-clockwise to given point +Point* Triangle::PointCCW(Point& point) +{ + if (&point == points_[0]) { + return points_[1]; + } else if (&point == points_[1]) { + return points_[2]; + } else if (&point == points_[2]) { + return points_[0]; + } + assert(0); +} + +// The neighbor clockwise to given point +Triangle* Triangle::NeighborCW(Point& point) +{ + if (&point == points_[0]) { + return neighbors_[1]; + } else if (&point == points_[1]) { + return neighbors_[2]; + } + return neighbors_[0]; +} + +// The neighbor counter-clockwise to given point +Triangle* Triangle::NeighborCCW(Point& point) +{ + if (&point == points_[0]) { + return neighbors_[2]; + } else if (&point == points_[1]) { + return neighbors_[0]; + } + return neighbors_[1]; +} + +bool Triangle::GetConstrainedEdgeCCW(Point& p) +{ + if (&p == points_[0]) { + return constrained_edge[2]; + } else if (&p == points_[1]) { + return constrained_edge[0]; + } + return constrained_edge[1]; +} + +bool Triangle::GetConstrainedEdgeCW(Point& p) +{ + if (&p == points_[0]) { + return constrained_edge[1]; + } else if (&p == points_[1]) { + return constrained_edge[2]; + } + return constrained_edge[0]; +} + +void Triangle::SetConstrainedEdgeCCW(Point& p, bool ce) +{ + if (&p == points_[0]) { + constrained_edge[2] = ce; + } else if (&p == points_[1]) { + constrained_edge[0] = ce; + } else { + constrained_edge[1] = ce; + } +} + +void Triangle::SetConstrainedEdgeCW(Point& p, bool ce) +{ + if (&p == points_[0]) { + constrained_edge[1] = ce; + } else if (&p == points_[1]) { + constrained_edge[2] = ce; + } else { + constrained_edge[0] = ce; + } +} + +bool Triangle::GetDelunayEdgeCCW(Point& p) +{ + if (&p == points_[0]) { + return delaunay_edge[2]; + } else if (&p == points_[1]) { + return delaunay_edge[0]; + } + return delaunay_edge[1]; +} + +bool Triangle::GetDelunayEdgeCW(Point& p) +{ + if (&p == points_[0]) { + return delaunay_edge[1]; + } else if (&p == points_[1]) { + return delaunay_edge[2]; + } + return delaunay_edge[0]; +} + +void Triangle::SetDelunayEdgeCCW(Point& p, bool e) +{ + if (&p == points_[0]) { + delaunay_edge[2] = e; + } else if (&p == points_[1]) { + delaunay_edge[0] = e; + } else { + delaunay_edge[1] = e; + } +} + +void Triangle::SetDelunayEdgeCW(Point& p, bool e) +{ + if (&p == points_[0]) { + delaunay_edge[1] = e; + } else if (&p == points_[1]) { + delaunay_edge[2] = e; + } else { + delaunay_edge[0] = e; + } +} + +// The neighbor across to given point +Triangle& Triangle::NeighborAcross(Point& opoint) +{ + if (&opoint == points_[0]) { + return *neighbors_[0]; + } else if (&opoint == points_[1]) { + return *neighbors_[1]; + } + return *neighbors_[2]; +} + +void Triangle::DebugPrint() +{ + using namespace std; + cout << points_[0]->x << "," << points_[0]->y << " "; + cout << points_[1]->x << "," << points_[1]->y << " "; + cout << points_[2]->x << "," << points_[2]->y << endl; +} + +} + diff --git a/src/3rdparty/poly2tri/common/shapes.h b/src/3rdparty/poly2tri/common/shapes.h new file mode 100644 index 0000000..5b90ea6 --- /dev/null +++ b/src/3rdparty/poly2tri/common/shapes.h @@ -0,0 +1,325 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Include guard +#ifndef SHAPES_H +#define SHAPES_H + +#include +#include +#include +#include + +namespace p2t { + +struct Edge; + +struct Point { + + double x, y; + + /// Default constructor does nothing (for performance). + Point() + { + x = 0.0; + y = 0.0; + } + + /// The edges this point constitutes an upper ending point + std::vector edge_list; + + /// Construct using coordinates. + Point(double x, double y) : x(x), y(y) {} + + /// Set this point to all zeros. + void set_zero() + { + x = 0.0; + y = 0.0; + } + + /// Set this point to some specified coordinates. + void set(double x_, double y_) + { + x = x_; + y = y_; + } + + /// Negate this point. + Point operator -() const + { + Point v; + v.set(-x, -y); + return v; + } + + /// Add a point to this point. + void operator +=(const Point& v) + { + x += v.x; + y += v.y; + } + + /// Subtract a point from this point. + void operator -=(const Point& v) + { + x -= v.x; + y -= v.y; + } + + /// Multiply this point by a scalar. + void operator *=(double a) + { + x *= a; + y *= a; + } + + /// Get the length of this point (the norm). + double Length() const + { + return std::sqrt(x * x + y * y); + } + + /// Convert this point into a unit point. Returns the Length. + double Normalize() + { + double len = Length(); + x /= len; + y /= len; + return len; + } + +}; + +// Represents a simple polygon's edge +struct Edge { + + Point* p, *q; + + /// Constructor + Edge(Point& p1, Point& p2) : p(&p1), q(&p2) + { + if (p1.y > p2.y) { + q = &p1; + p = &p2; + } else if (p1.y == p2.y) { + if (p1.x > p2.x) { + q = &p1; + p = &p2; + } else if (p1.x == p2.x) { + // Repeat points + assert(false); + } + } + + q->edge_list.push_back(this); + } +}; + +// Triangle-based data structures are know to have better performance than quad-edge structures +// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator" +// "Triangulations in CGAL" +class Triangle { +public: + +/// Constructor +Triangle(Point& a, Point& b, Point& c); + +/// Flags to determine if an edge is a Constrained edge +bool constrained_edge[3]; +/// Flags to determine if an edge is a Delauney edge +bool delaunay_edge[3]; + +Point* GetPoint(const int& index); +Point* PointCW(Point& point); +Point* PointCCW(Point& point); +Point* OppositePoint(Triangle& t, Point& p); + +Triangle* GetNeighbor(const int& index); +void MarkNeighbor(Point* p1, Point* p2, Triangle* t); +void MarkNeighbor(Triangle& t); + +void MarkConstrainedEdge(const int index); +void MarkConstrainedEdge(Edge& edge); +void MarkConstrainedEdge(Point* p, Point* q); + +int Index(const Point* p); +int EdgeIndex(const Point* p1, const Point* p2); + +Triangle* NeighborCW(Point& point); +Triangle* NeighborCCW(Point& point); +bool GetConstrainedEdgeCCW(Point& p); +bool GetConstrainedEdgeCW(Point& p); +void SetConstrainedEdgeCCW(Point& p, bool ce); +void SetConstrainedEdgeCW(Point& p, bool ce); +bool GetDelunayEdgeCCW(Point& p); +bool GetDelunayEdgeCW(Point& p); +void SetDelunayEdgeCCW(Point& p, bool e); +void SetDelunayEdgeCW(Point& p, bool e); + +bool Contains(Point* p); +bool Contains(const Edge& e); +bool Contains(Point* p, Point* q); +void Legalize(Point& point); +void Legalize(Point& opoint, Point& npoint); +/** + * Clears all references to all other triangles and points + */ +void Clear(); +void ClearNeighbor(Triangle *triangle ); +void ClearNeighbors(); +void ClearDelunayEdges(); + +inline bool IsInterior(); +inline void IsInterior(bool b); + +Triangle& NeighborAcross(Point& opoint); + +void DebugPrint(); + +private: + +/// Triangle points +Point* points_[3]; +/// Neighbor list +Triangle* neighbors_[3]; + +/// Has this triangle been marked as an interior triangle? +bool interior_; +}; + +inline bool cmp(const Point* a, const Point* b) +{ + if (a->y < b->y) { + return true; + } else if (a->y == b->y) { + // Make sure q is point with greater x value + if (a->x < b->x) { + return true; + } + } + return false; +} + +/// Add two points_ component-wise. +inline Point operator +(const Point& a, const Point& b) +{ + return Point(a.x + b.x, a.y + b.y); +} + +/// Subtract two points_ component-wise. +inline Point operator -(const Point& a, const Point& b) +{ + return Point(a.x - b.x, a.y - b.y); +} + +/// Multiply point by scalar +inline Point operator *(double s, const Point& a) +{ + return Point(s * a.x, s * a.y); +} + +inline bool operator ==(const Point& a, const Point& b) +{ + return a.x == b.x && a.y == b.y; +} + +inline bool operator !=(const Point& a, const Point& b) +{ + return !(a.x == b.x) && !(a.y == b.y); +} + +/// Peform the dot product on two vectors. +inline double Dot(const Point& a, const Point& b) +{ + return a.x * b.x + a.y * b.y; +} + +/// Perform the cross product on two vectors. In 2D this produces a scalar. +inline double Cross(const Point& a, const Point& b) +{ + return a.x * b.y - a.y * b.x; +} + +/// Perform the cross product on a point and a scalar. In 2D this produces +/// a point. +inline Point Cross(const Point& a, double s) +{ + return Point(s * a.y, -s * a.x); +} + +/// Perform the cross product on a scalar and a point. In 2D this produces +/// a point. +inline Point Cross(const double s, const Point& a) +{ + return Point(-s * a.y, s * a.x); +} + +inline Point* Triangle::GetPoint(const int& index) +{ + return points_[index]; +} + +inline Triangle* Triangle::GetNeighbor(const int& index) +{ + return neighbors_[index]; +} + +inline bool Triangle::Contains(Point* p) +{ + return p == points_[0] || p == points_[1] || p == points_[2]; +} + +inline bool Triangle::Contains(const Edge& e) +{ + return Contains(e.p) && Contains(e.q); +} + +inline bool Triangle::Contains(Point* p, Point* q) +{ + return Contains(p) && Contains(q); +} + +inline bool Triangle::IsInterior() +{ + return interior_; +} + +inline void Triangle::IsInterior(bool b) +{ + interior_ = b; +} + +} + +#endif + + diff --git a/src/3rdparty/poly2tri/common/utils.h b/src/3rdparty/poly2tri/common/utils.h new file mode 100644 index 0000000..8744b6d --- /dev/null +++ b/src/3rdparty/poly2tri/common/utils.h @@ -0,0 +1,127 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UTILS_H +#define UTILS_H + +// Otherwise #defines like M_PI are undeclared under Visual Studio +#define _USE_MATH_DEFINES + +#include +#include + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +namespace p2t { + +const double PI_3div4 = 3 * M_PI / 4; +const double PI_div2 = 1.57079632679489661923; +const double EPSILON = 1e-12; + +enum Orientation { CW, CCW, COLLINEAR }; + +/** + * Forumla to calculate signed area
    + * Positive if CCW
    + * Negative if CW
    + * 0 if collinear
    + *
    + * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
    + *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
    + * 
    + */ +Orientation Orient2d(Point& pa, Point& pb, Point& pc) +{ + double detleft = (pa.x - pc.x) * (pb.y - pc.y); + double detright = (pa.y - pc.y) * (pb.x - pc.x); + double val = detleft - detright; + if (val > -EPSILON && val < EPSILON) { + return COLLINEAR; + } else if (val > 0) { + return CCW; + } + return CW; +} + +/* +bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd) +{ + double pdx = pd.x; + double pdy = pd.y; + double adx = pa.x - pdx; + double ady = pa.y - pdy; + double bdx = pb.x - pdx; + double bdy = pb.y - pdy; + + double adxbdy = adx * bdy; + double bdxady = bdx * ady; + double oabd = adxbdy - bdxady; + + if (oabd <= EPSILON) { + return false; + } + + double cdx = pc.x - pdx; + double cdy = pc.y - pdy; + + double cdxady = cdx * ady; + double adxcdy = adx * cdy; + double ocad = cdxady - adxcdy; + + if (ocad <= EPSILON) { + return false; + } + + return true; +} + +*/ + +bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd) +{ + double oadb = (pa.x - pb.x)*(pd.y - pb.y) - (pd.x - pb.x)*(pa.y - pb.y); + if (oadb >= -EPSILON) { + return false; + } + + double oadc = (pa.x - pc.x)*(pd.y - pc.y) - (pd.x - pc.x)*(pa.y - pc.y); + if (oadc <= EPSILON) { + return false; + } + return true; +} + +} + +#endif + diff --git a/src/3rdparty/poly2tri/poly2tri.h b/src/3rdparty/poly2tri/poly2tri.h new file mode 100644 index 0000000..042cb3d --- /dev/null +++ b/src/3rdparty/poly2tri/poly2tri.h @@ -0,0 +1,39 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef POLY2TRI_H +#define POLY2TRI_H + +#include "common/shapes.h" +#include "sweep/cdt.h" + +#endif + diff --git a/src/3rdparty/poly2tri/qt_attribution.json b/src/3rdparty/poly2tri/qt_attribution.json new file mode 100644 index 0000000..0571384 --- /dev/null +++ b/src/3rdparty/poly2tri/qt_attribution.json @@ -0,0 +1,13 @@ +{ + "Id": "poly2tri", + "Name": "Poly2Tri Polygon Triangulation Library", + "QDocModule": "qtpositioning", + "QtUsage": "Used in the QML plugin of Qt Location and in Qt Positioning.", + + "Description": "Poly2Tri is a sweepline constrained Delaunay Polygon Triangulation Library.", + "Homepage": "https://github.com/greenm01/poly2tri", + "LicenseId": "BSD-3-Clause", + "License": "BSD 3-clause \"New\" or \"Revised\" License", + "LicenseFile": "LICENSE", + "Copyright": "Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors" +} diff --git a/src/3rdparty/poly2tri/sweep/advancing_front.cpp b/src/3rdparty/poly2tri/sweep/advancing_front.cpp new file mode 100644 index 0000000..0377984 --- /dev/null +++ b/src/3rdparty/poly2tri/sweep/advancing_front.cpp @@ -0,0 +1,109 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "advancing_front.h" + +namespace p2t { + +AdvancingFront::AdvancingFront(Node& head, Node& tail) +{ + head_ = &head; + tail_ = &tail; + search_node_ = &head; +} + +Node* AdvancingFront::LocateNode(const double& x) +{ + Node* node = search_node_; + + if (x < node->value) { + while ((node = node->prev) != NULL) { + if (x >= node->value) { + search_node_ = node; + return node; + } + } + } else { + while ((node = node->next) != NULL) { + if (x < node->value) { + search_node_ = node->prev; + return node->prev; + } + } + } + return NULL; +} + +Node* AdvancingFront::FindSearchNode(const double& x) +{ + (void)x; // suppress compiler warnings "unused parameter 'x'" + // TODO: implement BST index + return search_node_; +} + +Node* AdvancingFront::LocatePoint(const Point* point) +{ + const double px = point->x; + Node* node = FindSearchNode(px); + const double nx = node->point->x; + + if (px == nx) { + if (point != node->point) { + // We might have two nodes with same x value for a short time + if (point == node->prev->point) { + node = node->prev; + } else if (point == node->next->point) { + node = node->next; + } else { + assert(0); + } + } + } else if (px < nx) { + while ((node = node->prev) != NULL) { + if (point == node->point) { + break; + } + } + } else { + while ((node = node->next) != NULL) { + if (point == node->point) + break; + } + } + if (node) search_node_ = node; + return node; +} + +AdvancingFront::~AdvancingFront() +{ +} + +} + diff --git a/src/3rdparty/poly2tri/sweep/advancing_front.h b/src/3rdparty/poly2tri/sweep/advancing_front.h new file mode 100644 index 0000000..bab73d4 --- /dev/null +++ b/src/3rdparty/poly2tri/sweep/advancing_front.h @@ -0,0 +1,118 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ADVANCED_FRONT_H +#define ADVANCED_FRONT_H + +#include "../common/shapes.h" + +namespace p2t { + +struct Node; + +// Advancing front node +struct Node { + Point* point; + Triangle* triangle; + + Node* next; + Node* prev; + + double value; + + Node(Point& p) : point(&p), triangle(NULL), next(NULL), prev(NULL), value(p.x) + { + } + + Node(Point& p, Triangle& t) : point(&p), triangle(&t), next(NULL), prev(NULL), value(p.x) + { + } + +}; + +// Advancing front +class AdvancingFront { +public: + +AdvancingFront(Node& head, Node& tail); +// Destructor +~AdvancingFront(); + +Node* head(); +void set_head(Node* node); +Node* tail(); +void set_tail(Node* node); +Node* search(); +void set_search(Node* node); + +/// Locate insertion point along advancing front +Node* LocateNode(const double& x); + +Node* LocatePoint(const Point* point); + +private: + +Node* head_, *tail_, *search_node_; + +Node* FindSearchNode(const double& x); +}; + +inline Node* AdvancingFront::head() +{ + return head_; +} +inline void AdvancingFront::set_head(Node* node) +{ + head_ = node; +} + +inline Node* AdvancingFront::tail() +{ + return tail_; +} +inline void AdvancingFront::set_tail(Node* node) +{ + tail_ = node; +} + +inline Node* AdvancingFront::search() +{ + return search_node_; +} + +inline void AdvancingFront::set_search(Node* node) +{ + search_node_ = node; +} + +} + +#endif diff --git a/src/3rdparty/poly2tri/sweep/cdt.cpp b/src/3rdparty/poly2tri/sweep/cdt.cpp new file mode 100644 index 0000000..e0b3ec7 --- /dev/null +++ b/src/3rdparty/poly2tri/sweep/cdt.cpp @@ -0,0 +1,72 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "cdt.h" + +namespace p2t { + +CDT::CDT(std::vector polyline) +{ + sweep_context_ = new SweepContext(polyline); + sweep_ = new Sweep; +} + +void CDT::AddHole(std::vector polyline) +{ + sweep_context_->AddHole(polyline); +} + +void CDT::AddPoint(Point* point) { + sweep_context_->AddPoint(point); +} + +void CDT::Triangulate() +{ + sweep_->Triangulate(*sweep_context_); +} + +std::vector CDT::GetTriangles() +{ + return sweep_context_->GetTriangles(); +} + +std::list CDT::GetMap() +{ + return sweep_context_->GetMap(); +} + +CDT::~CDT() +{ + delete sweep_context_; + delete sweep_; +} + +} + diff --git a/src/3rdparty/poly2tri/sweep/cdt.h b/src/3rdparty/poly2tri/sweep/cdt.h new file mode 100644 index 0000000..e7b703d --- /dev/null +++ b/src/3rdparty/poly2tri/sweep/cdt.h @@ -0,0 +1,105 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CDT_H +#define CDT_H + +#include "advancing_front.h" +#include "sweep_context.h" +#include "sweep.h" + +/** + * + * @author Mason Green + * + */ + +namespace p2t { + +class CDT +{ +public: + + /** + * Constructor - add polyline with non repeating points + * + * @param polyline + */ + CDT(std::vector polyline); + + /** + * Destructor - clean up memory + */ + ~CDT(); + + /** + * Add a hole + * + * @param polyline + */ + void AddHole(std::vector polyline); + + /** + * Add a steiner point + * + * @param point + */ + void AddPoint(Point* point); + + /** + * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points + */ + void Triangulate(); + + /** + * Get CDT triangles + */ + std::vector GetTriangles(); + + /** + * Get triangle map + */ + std::list GetMap(); + + private: + + /** + * Internals + */ + + SweepContext* sweep_context_; + Sweep* sweep_; + +}; + +} + +#endif diff --git a/src/3rdparty/poly2tri/sweep/sweep.cpp b/src/3rdparty/poly2tri/sweep/sweep.cpp new file mode 100644 index 0000000..954d2db --- /dev/null +++ b/src/3rdparty/poly2tri/sweep/sweep.cpp @@ -0,0 +1,814 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include "sweep.h" +#include "sweep_context.h" +#include "advancing_front.h" +#include "../common/utils.h" + +namespace p2t { + +// Triangulate simple polygon with holes +void Sweep::Triangulate(SweepContext& tcx) +{ + tcx.InitTriangulation(); + tcx.CreateAdvancingFront(nodes_); + // Sweep points; build mesh + SweepPoints(tcx); + // Clean up + FinalizationPolygon(tcx); +} + +void Sweep::SweepPoints(SweepContext& tcx) +{ + for (int i = 1; i < tcx.point_count(); i++) { + Point& point = *tcx.GetPoint(i); + Node* node = &PointEvent(tcx, point); + for (unsigned int i = 0; i < point.edge_list.size(); i++) { + EdgeEvent(tcx, point.edge_list[i], node); + } + } +} + +void Sweep::FinalizationPolygon(SweepContext& tcx) +{ + // Get an Internal triangle to start with + Triangle* t = tcx.front()->head()->next->triangle; + Point* p = tcx.front()->head()->next->point; + while (!t->GetConstrainedEdgeCW(*p)) { + t = t->NeighborCCW(*p); + } + + // Collect interior triangles constrained by edges + tcx.MeshClean(*t); +} + +Node& Sweep::PointEvent(SweepContext& tcx, Point& point) +{ + Node& node = tcx.LocateNode(point); + Node& new_node = NewFrontTriangle(tcx, point, node); + + // Only need to check +epsilon since point never have smaller + // x value than node due to how we fetch nodes from the front + if (point.x <= node.point->x + EPSILON) { + Fill(tcx, node); + } + + //tcx.AddNode(new_node); + + FillAdvancingFront(tcx, new_node); + return new_node; +} + +void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node* node) +{ + tcx.edge_event.constrained_edge = edge; + tcx.edge_event.right = (edge->p->x > edge->q->x); + + if (IsEdgeSideOfTriangle(*node->triangle, *edge->p, *edge->q)) { + return; + } + + // For now we will do all needed filling + // TODO: integrate with flip process might give some better performance + // but for now this avoid the issue with cases that needs both flips and fills + FillEdgeEvent(tcx, edge, node); + EdgeEvent(tcx, *edge->p, *edge->q, node->triangle, *edge->q); +} + +void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point) +{ + if (IsEdgeSideOfTriangle(*triangle, ep, eq)) { + return; + } + + Point* p1 = triangle->PointCCW(point); + Orientation o1 = Orient2d(eq, *p1, ep); + if (o1 == COLLINEAR) { + if ( triangle->Contains(&eq, p1)) { + triangle->MarkConstrainedEdge(&eq, p1 ); + // We are modifying the constraint maybe it would be better to + // not change the given constraint and just keep a variable for the new constraint + tcx.edge_event.constrained_edge->q = p1; + triangle = &triangle->NeighborAcross(point); + EdgeEvent( tcx, ep, *p1, triangle, *p1 ); + } else { + std::runtime_error("EdgeEvent - collinear points not supported"); + assert(0); + } + return; + } + + Point* p2 = triangle->PointCW(point); + Orientation o2 = Orient2d(eq, *p2, ep); + if (o2 == COLLINEAR) { + if ( triangle->Contains(&eq, p2)) { + triangle->MarkConstrainedEdge(&eq, p2 ); + // We are modifying the constraint maybe it would be better to + // not change the given constraint and just keep a variable for the new constraint + tcx.edge_event.constrained_edge->q = p2; + triangle = &triangle->NeighborAcross(point); + EdgeEvent( tcx, ep, *p2, triangle, *p2 ); + } else { + std::runtime_error("EdgeEvent - collinear points not supported"); + assert(0); + } + return; + } + + if (o1 == o2) { + // Need to decide if we are rotating CW or CCW to get to a triangle + // that will cross edge + if (o1 == CW) { + triangle = triangle->NeighborCCW(point); + } else{ + triangle = triangle->NeighborCW(point); + } + EdgeEvent(tcx, ep, eq, triangle, point); + } else { + // This triangle crosses constraint so lets flippin start! + FlipEdgeEvent(tcx, ep, eq, triangle, point); + } +} + +bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq) +{ + int index = triangle.EdgeIndex(&ep, &eq); + + if (index != -1) { + triangle.MarkConstrainedEdge(index); + Triangle* t = triangle.GetNeighbor(index); + if (t) { + t->MarkConstrainedEdge(&ep, &eq); + } + return true; + } + return false; +} + +Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node) +{ + Triangle* triangle = new Triangle(point, *node.point, *node.next->point); + + triangle->MarkNeighbor(*node.triangle); + tcx.AddToMap(triangle); + + Node* new_node = new Node(point); + nodes_.push_back(new_node); + + new_node->next = node.next; + new_node->prev = &node; + node.next->prev = new_node; + node.next = new_node; + + if (!Legalize(tcx, *triangle)) { + tcx.MapTriangleToNodes(*triangle); + } + + return *new_node; +} + +void Sweep::Fill(SweepContext& tcx, Node& node) +{ + Triangle* triangle = new Triangle(*node.prev->point, *node.point, *node.next->point); + + // TODO: should copy the constrained_edge value from neighbor triangles + // for now constrained_edge values are copied during the legalize + triangle->MarkNeighbor(*node.prev->triangle); + triangle->MarkNeighbor(*node.triangle); + + tcx.AddToMap(triangle); + + // Update the advancing front + node.prev->next = node.next; + node.next->prev = node.prev; + + // If it was legalized the triangle has already been mapped + if (!Legalize(tcx, *triangle)) { + tcx.MapTriangleToNodes(*triangle); + } + +} + +void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n) +{ + + // Fill right holes + Node* node = n.next; + + while (node->next) { + // if HoleAngle exceeds 90 degrees then break. + if (LargeHole_DontFill(node)) break; + Fill(tcx, *node); + node = node->next; + } + + // Fill left holes + node = n.prev; + + while (node->prev) { + // if HoleAngle exceeds 90 degrees then break. + if (LargeHole_DontFill(node)) break; + Fill(tcx, *node); + node = node->prev; + } + + // Fill right basins + if (n.next && n.next->next) { + double angle = BasinAngle(n); + if (angle < PI_3div4) { + FillBasin(tcx, n); + } + } +} + +// True if HoleAngle exceeds 90 degrees. +bool Sweep::LargeHole_DontFill(Node* node) { + + Node* nextNode = node->next; + Node* prevNode = node->prev; + if (!AngleExceeds90Degrees(node->point, nextNode->point, prevNode->point)) + return false; + + // Check additional points on front. + Node* next2Node = nextNode->next; + // "..Plus.." because only want angles on same side as point being added. + if ((next2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, next2Node->point, prevNode->point)) + return false; + + Node* prev2Node = prevNode->prev; + // "..Plus.." because only want angles on same side as point being added. + if ((prev2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, prev2Node->point)) + return false; + + return true; +} + +bool Sweep::AngleExceeds90Degrees(Point* origin, Point* pa, Point* pb) { + double angle = Angle(*origin, *pa, *pb); + bool exceeds90Degrees = ((angle > PI_div2) || (angle < -PI_div2)); + return exceeds90Degrees; +} + +bool Sweep::AngleExceedsPlus90DegreesOrIsNegative(Point* origin, Point* pa, Point* pb) { + double angle = Angle(*origin, *pa, *pb); + bool exceedsPlus90DegreesOrIsNegative = (angle > PI_div2) || (angle < 0); + return exceedsPlus90DegreesOrIsNegative; +} + +double Sweep::Angle(Point& origin, Point& pa, Point& pb) { + /* Complex plane + * ab = cosA +i*sinA + * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx) + * atan2(y,x) computes the principal value of the argument function + * applied to the complex number x+iy + * Where x = ax*bx + ay*by + * y = ax*by - ay*bx + */ + double px = origin.x; + double py = origin.y; + double ax = pa.x- px; + double ay = pa.y - py; + double bx = pb.x - px; + double by = pb.y - py; + double x = ax * by - ay * bx; + double y = ax * bx + ay * by; + double angle = atan2(x, y); + return angle; +} + +double Sweep::BasinAngle(Node& node) +{ + double ax = node.point->x - node.next->next->point->x; + double ay = node.point->y - node.next->next->point->y; + return atan2(ay, ax); +} + +double Sweep::HoleAngle(Node& node) +{ + /* Complex plane + * ab = cosA +i*sinA + * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx) + * atan2(y,x) computes the principal value of the argument function + * applied to the complex number x+iy + * Where x = ax*bx + ay*by + * y = ax*by - ay*bx + */ + double ax = node.next->point->x - node.point->x; + double ay = node.next->point->y - node.point->y; + double bx = node.prev->point->x - node.point->x; + double by = node.prev->point->y - node.point->y; + return atan2(ax * by - ay * bx, ax * bx + ay * by); +} + +bool Sweep::Legalize(SweepContext& tcx, Triangle& t) +{ + // To legalize a triangle we start by finding if any of the three edges + // violate the Delaunay condition + for (int i = 0; i < 3; i++) { + if (t.delaunay_edge[i]) + continue; + + Triangle* ot = t.GetNeighbor(i); + + if (ot) { + Point* p = t.GetPoint(i); + Point* op = ot->OppositePoint(t, *p); + int oi = ot->Index(op); + + // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization) + // then we should not try to legalize + if (ot->constrained_edge[oi] || ot->delaunay_edge[oi]) { + t.constrained_edge[i] = ot->constrained_edge[oi]; + continue; + } + + bool inside = Incircle(*p, *t.PointCCW(*p), *t.PointCW(*p), *op); + + if (inside) { + // Lets mark this shared edge as Delaunay + t.delaunay_edge[i] = true; + ot->delaunay_edge[oi] = true; + + // Lets rotate shared edge one vertex CW to legalize it + RotateTrianglePair(t, *p, *ot, *op); + + // We now got one valid Delaunay Edge shared by two triangles + // This gives us 4 new edges to check for Delaunay + + // Make sure that triangle to node mapping is done only one time for a specific triangle + bool not_legalized = !Legalize(tcx, t); + if (not_legalized) { + tcx.MapTriangleToNodes(t); + } + + not_legalized = !Legalize(tcx, *ot); + if (not_legalized) + tcx.MapTriangleToNodes(*ot); + + // Reset the Delaunay edges, since they only are valid Delaunay edges + // until we add a new triangle or point. + // XXX: need to think about this. Can these edges be tried after we + // return to previous recursive level? + t.delaunay_edge[i] = false; + ot->delaunay_edge[oi] = false; + + // If triangle have been legalized no need to check the other edges since + // the recursive legalization will handles those so we can end here. + return true; + } + } + } + return false; +} + +bool Sweep::Incircle(Point& pa, Point& pb, Point& pc, Point& pd) +{ + double adx = pa.x - pd.x; + double ady = pa.y - pd.y; + double bdx = pb.x - pd.x; + double bdy = pb.y - pd.y; + + double adxbdy = adx * bdy; + double bdxady = bdx * ady; + double oabd = adxbdy - bdxady; + + if (oabd <= 0) + return false; + + double cdx = pc.x - pd.x; + double cdy = pc.y - pd.y; + + double cdxady = cdx * ady; + double adxcdy = adx * cdy; + double ocad = cdxady - adxcdy; + + if (ocad <= 0) + return false; + + double bdxcdy = bdx * cdy; + double cdxbdy = cdx * bdy; + + double alift = adx * adx + ady * ady; + double blift = bdx * bdx + bdy * bdy; + double clift = cdx * cdx + cdy * cdy; + + double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd; + + return det > 0; +} + +void Sweep::RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op) +{ + Triangle* n1, *n2, *n3, *n4; + n1 = t.NeighborCCW(p); + n2 = t.NeighborCW(p); + n3 = ot.NeighborCCW(op); + n4 = ot.NeighborCW(op); + + bool ce1, ce2, ce3, ce4; + ce1 = t.GetConstrainedEdgeCCW(p); + ce2 = t.GetConstrainedEdgeCW(p); + ce3 = ot.GetConstrainedEdgeCCW(op); + ce4 = ot.GetConstrainedEdgeCW(op); + + bool de1, de2, de3, de4; + de1 = t.GetDelunayEdgeCCW(p); + de2 = t.GetDelunayEdgeCW(p); + de3 = ot.GetDelunayEdgeCCW(op); + de4 = ot.GetDelunayEdgeCW(op); + + t.Legalize(p, op); + ot.Legalize(op, p); + + // Remap delaunay_edge + ot.SetDelunayEdgeCCW(p, de1); + t.SetDelunayEdgeCW(p, de2); + t.SetDelunayEdgeCCW(op, de3); + ot.SetDelunayEdgeCW(op, de4); + + // Remap constrained_edge + ot.SetConstrainedEdgeCCW(p, ce1); + t.SetConstrainedEdgeCW(p, ce2); + t.SetConstrainedEdgeCCW(op, ce3); + ot.SetConstrainedEdgeCW(op, ce4); + + // Remap neighbors + // XXX: might optimize the markNeighbor by keeping track of + // what side should be assigned to what neighbor after the + // rotation. Now mark neighbor does lots of testing to find + // the right side. + t.ClearNeighbors(); + ot.ClearNeighbors(); + if (n1) ot.MarkNeighbor(*n1); + if (n2) t.MarkNeighbor(*n2); + if (n3) t.MarkNeighbor(*n3); + if (n4) ot.MarkNeighbor(*n4); + t.MarkNeighbor(ot); +} + +void Sweep::FillBasin(SweepContext& tcx, Node& node) +{ + if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) { + tcx.basin.left_node = node.next->next; + } else { + tcx.basin.left_node = node.next; + } + + // Find the bottom and right node + tcx.basin.bottom_node = tcx.basin.left_node; + while (tcx.basin.bottom_node->next + && tcx.basin.bottom_node->point->y >= tcx.basin.bottom_node->next->point->y) { + tcx.basin.bottom_node = tcx.basin.bottom_node->next; + } + if (tcx.basin.bottom_node == tcx.basin.left_node) { + // No valid basin + return; + } + + tcx.basin.right_node = tcx.basin.bottom_node; + while (tcx.basin.right_node->next + && tcx.basin.right_node->point->y < tcx.basin.right_node->next->point->y) { + tcx.basin.right_node = tcx.basin.right_node->next; + } + if (tcx.basin.right_node == tcx.basin.bottom_node) { + // No valid basins + return; + } + + tcx.basin.width = tcx.basin.right_node->point->x - tcx.basin.left_node->point->x; + tcx.basin.left_highest = tcx.basin.left_node->point->y > tcx.basin.right_node->point->y; + + FillBasinReq(tcx, tcx.basin.bottom_node); +} + +void Sweep::FillBasinReq(SweepContext& tcx, Node* node) +{ + // if shallow stop filling + if (IsShallow(tcx, *node)) { + return; + } + + Fill(tcx, *node); + + if (node->prev == tcx.basin.left_node && node->next == tcx.basin.right_node) { + return; + } else if (node->prev == tcx.basin.left_node) { + Orientation o = Orient2d(*node->point, *node->next->point, *node->next->next->point); + if (o == CW) { + return; + } + node = node->next; + } else if (node->next == tcx.basin.right_node) { + Orientation o = Orient2d(*node->point, *node->prev->point, *node->prev->prev->point); + if (o == CCW) { + return; + } + node = node->prev; + } else { + // Continue with the neighbor node with lowest Y value + if (node->prev->point->y < node->next->point->y) { + node = node->prev; + } else { + node = node->next; + } + } + + FillBasinReq(tcx, node); +} + +bool Sweep::IsShallow(SweepContext& tcx, Node& node) +{ + double height; + + if (tcx.basin.left_highest) { + height = tcx.basin.left_node->point->y - node.point->y; + } else { + height = tcx.basin.right_node->point->y - node.point->y; + } + + // if shallow stop filling + if (tcx.basin.width > height) { + return true; + } + return false; +} + +void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node) +{ + if (tcx.edge_event.right) { + FillRightAboveEdgeEvent(tcx, edge, node); + } else { + FillLeftAboveEdgeEvent(tcx, edge, node); + } +} + +void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node) +{ + while (node->next->point->x < edge->p->x) { + // Check if next node is below the edge + if (Orient2d(*edge->q, *node->next->point, *edge->p) == CCW) { + FillRightBelowEdgeEvent(tcx, edge, *node); + } else { + node = node->next; + } + } +} + +void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) +{ + if (node.point->x < edge->p->x) { + if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) { + // Concave + FillRightConcaveEdgeEvent(tcx, edge, node); + } else{ + // Convex + FillRightConvexEdgeEvent(tcx, edge, node); + // Retry this one + FillRightBelowEdgeEvent(tcx, edge, node); + } + } +} + +void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) +{ + Fill(tcx, *node.next); + if (node.next->point != edge->p) { + // Next above or below edge? + if (Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) { + // Below + if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) { + // Next is concave + FillRightConcaveEdgeEvent(tcx, edge, node); + } else { + // Next is convex + } + } + } + +} + +void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) +{ + // Next concave or convex? + if (Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point) == CCW) { + // Concave + FillRightConcaveEdgeEvent(tcx, edge, *node.next); + } else{ + // Convex + // Next above or below edge? + if (Orient2d(*edge->q, *node.next->next->point, *edge->p) == CCW) { + // Below + FillRightConvexEdgeEvent(tcx, edge, *node.next); + } else{ + // Above + } + } +} + +void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node) +{ + while (node->prev->point->x > edge->p->x) { + // Check if next node is below the edge + if (Orient2d(*edge->q, *node->prev->point, *edge->p) == CW) { + FillLeftBelowEdgeEvent(tcx, edge, *node); + } else { + node = node->prev; + } + } +} + +void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) +{ + if (node.point->x > edge->p->x) { + if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) { + // Concave + FillLeftConcaveEdgeEvent(tcx, edge, node); + } else { + // Convex + FillLeftConvexEdgeEvent(tcx, edge, node); + // Retry this one + FillLeftBelowEdgeEvent(tcx, edge, node); + } + } +} + +void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) +{ + // Next concave or convex? + if (Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) { + // Concave + FillLeftConcaveEdgeEvent(tcx, edge, *node.prev); + } else{ + // Convex + // Next above or below edge? + if (Orient2d(*edge->q, *node.prev->prev->point, *edge->p) == CW) { + // Below + FillLeftConvexEdgeEvent(tcx, edge, *node.prev); + } else{ + // Above + } + } +} + +void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) +{ + Fill(tcx, *node.prev); + if (node.prev->point != edge->p) { + // Next above or below edge? + if (Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) { + // Below + if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) { + // Next is concave + FillLeftConcaveEdgeEvent(tcx, edge, node); + } else{ + // Next is convex + } + } + } + +} + +void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p) +{ + Triangle& ot = t->NeighborAcross(p); + Point& op = *ot.OppositePoint(*t, p); + + if (&ot == NULL) { + // If we want to integrate the fillEdgeEvent do it here + // With current implementation we should never get here + //throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle"); + assert(0); + } + + if (InScanArea(p, *t->PointCCW(p), *t->PointCW(p), op)) { + // Lets rotate shared edge one vertex CW + RotateTrianglePair(*t, p, ot, op); + tcx.MapTriangleToNodes(*t); + tcx.MapTriangleToNodes(ot); + + if (p == eq && op == ep) { + if (eq == *tcx.edge_event.constrained_edge->q && ep == *tcx.edge_event.constrained_edge->p) { + t->MarkConstrainedEdge(&ep, &eq); + ot.MarkConstrainedEdge(&ep, &eq); + Legalize(tcx, *t); + Legalize(tcx, ot); + } else { + // XXX: I think one of the triangles should be legalized here? + } + } else { + Orientation o = Orient2d(eq, op, ep); + t = &NextFlipTriangle(tcx, (int)o, *t, ot, p, op); + FlipEdgeEvent(tcx, ep, eq, t, p); + } + } else { + Point& newP = NextFlipPoint(ep, eq, ot, op); + FlipScanEdgeEvent(tcx, ep, eq, *t, ot, newP); + EdgeEvent(tcx, ep, eq, t, p); + } +} + +Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op) +{ + if (o == CCW) { + // ot is not crossing edge after flip + int edge_index = ot.EdgeIndex(&p, &op); + ot.delaunay_edge[edge_index] = true; + Legalize(tcx, ot); + ot.ClearDelunayEdges(); + return t; + } + + // t is not crossing edge after flip + int edge_index = t.EdgeIndex(&p, &op); + + t.delaunay_edge[edge_index] = true; + Legalize(tcx, t); + t.ClearDelunayEdges(); + return ot; +} + +Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op) +{ + Orientation o2d = Orient2d(eq, op, ep); + if (o2d == CW) { + // Right + return *ot.PointCCW(op); + } else if (o2d == CCW) { + // Left + return *ot.PointCW(op); + } else{ + //throw new RuntimeException("[Unsupported] Opposing point on constrained edge"); + assert(0); + } +} + +void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, + Triangle& t, Point& p) +{ + Triangle& ot = t.NeighborAcross(p); + Point& op = *ot.OppositePoint(t, p); + + if (&t.NeighborAcross(p) == NULL) { + // If we want to integrate the fillEdgeEvent do it here + // With current implementation we should never get here + //throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle"); + assert(0); + } + + if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) { + // flip with new edge op->eq + FlipEdgeEvent(tcx, eq, op, &ot, op); + // TODO: Actually I just figured out that it should be possible to + // improve this by getting the next ot and op before the above + // flip and continue the flipScanEdgeEvent here + // set new ot and op here and loop back to inScanArea test + // also need to set a new flip_triangle first + // Turns out at first glance that this is somewhat complicated + // so it will have to wait. + } else{ + Point& newP = NextFlipPoint(ep, eq, ot, op); + FlipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP); + } +} + +Sweep::~Sweep() { + + // Clean up memory + for (size_t i = 0; i < nodes_.size(); i++) { + delete nodes_[i]; + } + +} + +} + diff --git a/src/3rdparty/poly2tri/sweep/sweep.h b/src/3rdparty/poly2tri/sweep/sweep.h new file mode 100644 index 0000000..9bb0b5d --- /dev/null +++ b/src/3rdparty/poly2tri/sweep/sweep.h @@ -0,0 +1,285 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * Sweep-line, Constrained Delauney Triangulation (CDT) See: Domiter, V. and + * Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation', + * International Journal of Geographical Information Science + * + * "FlipScan" Constrained Edge Algorithm invented by Thomas Åhlén, thahlen@gmail.com + */ + +#ifndef SWEEP_H +#define SWEEP_H + +#include + +namespace p2t { + +class SweepContext; +struct Node; +struct Point; +struct Edge; +class Triangle; + +class Sweep +{ +public: + + /** + * Triangulate + * + * @param tcx + */ + void Triangulate(SweepContext& tcx); + + /** + * Destructor - clean up memory + */ + ~Sweep(); + +private: + + /** + * Start sweeping the Y-sorted point set from bottom to top + * + * @param tcx + */ + void SweepPoints(SweepContext& tcx); + + /** + * Find closes node to the left of the new point and + * create a new triangle. If needed new holes and basins + * will be filled to. + * + * @param tcx + * @param point + * @return + */ + Node& PointEvent(SweepContext& tcx, Point& point); + + /** + * + * + * @param tcx + * @param edge + * @param node + */ + void EdgeEvent(SweepContext& tcx, Edge* edge, Node* node); + + void EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point); + + /** + * Creates a new front triangle and legalize it + * + * @param tcx + * @param point + * @param node + * @return + */ + Node& NewFrontTriangle(SweepContext& tcx, Point& point, Node& node); + + /** + * Adds a triangle to the advancing front to fill a hole. + * @param tcx + * @param node - middle node, that is the bottom of the hole + */ + void Fill(SweepContext& tcx, Node& node); + + /** + * Returns true if triangle was legalized + */ + bool Legalize(SweepContext& tcx, Triangle& t); + + /** + * Requirement:
    + * 1. a,b and c form a triangle.
    + * 2. a and d is know to be on opposite side of bc
    + *
    +   *                a
    +   *                +
    +   *               / \
    +   *              /   \
    +   *            b/     \c
    +   *            +-------+
    +   *           /    d    \
    +   *          /           \
    +   * 
    + * Fact: d has to be in area B to have a chance to be inside the circle formed by + * a,b and c
    + * d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW
    + * This preknowledge gives us a way to optimize the incircle test + * @param a - triangle point, opposite d + * @param b - triangle point + * @param c - triangle point + * @param d - point opposite a + * @return true if d is inside circle, false if on circle edge + */ + bool Incircle(Point& pa, Point& pb, Point& pc, Point& pd); + + /** + * Rotates a triangle pair one vertex CW + *
    +   *       n2                    n2
    +   *  P +-----+             P +-----+
    +   *    | t  /|               |\  t |
    +   *    |   / |               | \   |
    +   *  n1|  /  |n3           n1|  \  |n3
    +   *    | /   |    after CW   |   \ |
    +   *    |/ oT |               | oT \|
    +   *    +-----+ oP            +-----+
    +   *       n4                    n4
    +   * 
    + */ + void RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op); + + /** + * Fills holes in the Advancing Front + * + * + * @param tcx + * @param n + */ + void FillAdvancingFront(SweepContext& tcx, Node& n); + + // Decision-making about when to Fill hole. + // Contributed by ToolmakerSteve2 + bool LargeHole_DontFill(Node* node); + bool AngleExceeds90Degrees(Point* origin, Point* pa, Point* pb); + bool AngleExceedsPlus90DegreesOrIsNegative(Point* origin, Point* pa, Point* pb); + double Angle(Point& origin, Point& pa, Point& pb); + + /** + * + * @param node - middle node + * @return the angle between 3 front nodes + */ + double HoleAngle(Node& node); + + /** + * The basin angle is decided against the horizontal line [1,0] + */ + double BasinAngle(Node& node); + + /** + * Fills a basin that has formed on the Advancing Front to the right + * of given node.
    + * First we decide a left,bottom and right node that forms the + * boundaries of the basin. Then we do a reqursive fill. + * + * @param tcx + * @param node - starting node, this or next node will be left node + */ + void FillBasin(SweepContext& tcx, Node& node); + + /** + * Recursive algorithm to fill a Basin with triangles + * + * @param tcx + * @param node - bottom_node + * @param cnt - counter used to alternate on even and odd numbers + */ + void FillBasinReq(SweepContext& tcx, Node* node); + + bool IsShallow(SweepContext& tcx, Node& node); + + bool IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq); + + void FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node); + + void FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node); + + void FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); + + void FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); + + void FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); + + void FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node); + + void FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); + + void FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); + + void FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node); + + void FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p); + + /** + * After a flip we have two triangles and know that only one will still be + * intersecting the edge. So decide which to contiune with and legalize the other + * + * @param tcx + * @param o - should be the result of an orient2d( eq, op, ep ) + * @param t - triangle 1 + * @param ot - triangle 2 + * @param p - a point shared by both triangles + * @param op - another point shared by both triangles + * @return returns the triangle still intersecting the edge + */ + Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op); + + /** + * When we need to traverse from one triangle to the next we need + * the point in current triangle that is the opposite point to the next + * triangle. + * + * @param ep + * @param eq + * @param ot + * @param op + * @return + */ + Point& NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op); + + /** + * Scan part of the FlipScan algorithm
    + * When a triangle pair isn't flippable we will scan for the next + * point that is inside the flip triangle scan area. When found + * we generate a new flipEdgeEvent + * + * @param tcx + * @param ep - last point on the edge we are traversing + * @param eq - first point on the edge we are traversing + * @param flipTriangle - the current triangle sharing the point eq with edge + * @param t + * @param p + */ + void FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, Triangle& t, Point& p); + + void FinalizationPolygon(SweepContext& tcx); + + std::vector nodes_; + +}; + +} + +#endif diff --git a/src/3rdparty/poly2tri/sweep/sweep_context.cpp b/src/3rdparty/poly2tri/sweep/sweep_context.cpp new file mode 100644 index 0000000..24dde11 --- /dev/null +++ b/src/3rdparty/poly2tri/sweep/sweep_context.cpp @@ -0,0 +1,216 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "sweep_context.h" +#include +#include "advancing_front.h" + +namespace p2t { + +SweepContext::SweepContext(std::vector polyline) : + front_(0), + head_(0), + tail_(0), + af_head_(0), + af_middle_(0), + af_tail_(0) +{ + basin = Basin(); + edge_event = EdgeEvent(); + + points_ = polyline; + + InitEdges(points_); +} + +void SweepContext::AddHole(std::vector polyline) +{ + InitEdges(polyline); + for (unsigned int i = 0; i < polyline.size(); i++) { + points_.push_back(polyline[i]); + } +} + +void SweepContext::AddPoint(Point* point) { + points_.push_back(point); +} + +std::vector SweepContext::GetTriangles() +{ + return triangles_; +} + +std::list SweepContext::GetMap() +{ + return map_; +} + +void SweepContext::InitTriangulation() +{ + double xmax(points_[0]->x), xmin(points_[0]->x); + double ymax(points_[0]->y), ymin(points_[0]->y); + + // Calculate bounds. + for (unsigned int i = 0; i < points_.size(); i++) { + Point& p = *points_[i]; + if (p.x > xmax) + xmax = p.x; + if (p.x < xmin) + xmin = p.x; + if (p.y > ymax) + ymax = p.y; + if (p.y < ymin) + ymin = p.y; + } + + double dx = kAlpha * (xmax - xmin); + double dy = kAlpha * (ymax - ymin); + head_ = new Point(xmax + dx, ymin - dy); + tail_ = new Point(xmin - dx, ymin - dy); + + // Sort points along y-axis + std::sort(points_.begin(), points_.end(), cmp); + +} + +void SweepContext::InitEdges(std::vector polyline) +{ + int num_points = polyline.size(); + for (int i = 0; i < num_points; i++) { + int j = i < num_points - 1 ? i + 1 : 0; + edge_list.push_back(new Edge(*polyline[i], *polyline[j])); + } +} + +Point* SweepContext::GetPoint(const int& index) +{ + return points_[index]; +} + +void SweepContext::AddToMap(Triangle* triangle) +{ + map_.push_back(triangle); +} + +Node& SweepContext::LocateNode(Point& point) +{ + // TODO implement search tree + return *front_->LocateNode(point.x); +} + +void SweepContext::CreateAdvancingFront(std::vector nodes) +{ + + (void) nodes; + // Initial triangle + Triangle* triangle = new Triangle(*points_[0], *tail_, *head_); + + map_.push_back(triangle); + + af_head_ = new Node(*triangle->GetPoint(1), *triangle); + af_middle_ = new Node(*triangle->GetPoint(0), *triangle); + af_tail_ = new Node(*triangle->GetPoint(2)); + front_ = new AdvancingFront(*af_head_, *af_tail_); + + // TODO: More intuitive if head is middles next and not previous? + // so swap head and tail + af_head_->next = af_middle_; + af_middle_->next = af_tail_; + af_middle_->prev = af_head_; + af_tail_->prev = af_middle_; +} + +void SweepContext::RemoveNode(Node* node) +{ + delete node; +} + +void SweepContext::MapTriangleToNodes(Triangle& t) +{ + for (int i = 0; i < 3; i++) { + if (!t.GetNeighbor(i)) { + Node* n = front_->LocatePoint(t.PointCW(*t.GetPoint(i))); + if (n) + n->triangle = &t; + } + } +} + +void SweepContext::RemoveFromMap(Triangle* triangle) +{ + map_.remove(triangle); +} + +void SweepContext::MeshClean(Triangle& triangle) +{ + std::vector triangles; + triangles.push_back(&triangle); + + while(!triangles.empty()){ + Triangle *t = triangles.back(); + triangles.pop_back(); + + if (t != NULL && !t->IsInterior()) { + t->IsInterior(true); + triangles_.push_back(t); + for (int i = 0; i < 3; i++) { + if (!t->constrained_edge[i]) + triangles.push_back(t->GetNeighbor(i)); + } + } + } +} + +SweepContext::~SweepContext() +{ + + // Clean up memory + + delete head_; + delete tail_; + delete front_; + delete af_head_; + delete af_middle_; + delete af_tail_; + + typedef std::list type_list; + + for (type_list::iterator iter = map_.begin(); iter != map_.end(); ++iter) { + Triangle* ptr = *iter; + delete ptr; + } + + for (unsigned int i = 0; i < edge_list.size(); i++) { + delete edge_list[i]; + } + +} + +} diff --git a/src/3rdparty/poly2tri/sweep/sweep_context.h b/src/3rdparty/poly2tri/sweep/sweep_context.h new file mode 100644 index 0000000..c110a74 --- /dev/null +++ b/src/3rdparty/poly2tri/sweep/sweep_context.h @@ -0,0 +1,186 @@ +/* + * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors + * http://code.google.com/p/poly2tri/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Poly2Tri nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SWEEP_CONTEXT_H +#define SWEEP_CONTEXT_H + +#include +#include +#include + +namespace p2t { + +// Initial triangle factor, seed triangle will extend 30% of +// PointSet width to both left and right. +const double kAlpha = 0.3; + +struct Point; +class Triangle; +struct Node; +struct Edge; +class AdvancingFront; + +class SweepContext { +public: + +/// Constructor +SweepContext(std::vector polyline); +/// Destructor +~SweepContext(); + +void set_head(Point* p1); + +Point* head(); + +void set_tail(Point* p1); + +Point* tail(); + +int point_count(); + +Node& LocateNode(Point& point); + +void RemoveNode(Node* node); + +void CreateAdvancingFront(std::vector nodes); + +/// Try to map a node to all sides of this triangle that don't have a neighbor +void MapTriangleToNodes(Triangle& t); + +void AddToMap(Triangle* triangle); + +Point* GetPoint(const int& index); + +Point* GetPoints(); + +void RemoveFromMap(Triangle* triangle); + +void AddHole(std::vector polyline); + +void AddPoint(Point* point); + +AdvancingFront* front(); + +void MeshClean(Triangle& triangle); + +std::vector GetTriangles(); +std::list GetMap(); + +std::vector edge_list; + +struct Basin { + Node* left_node; + Node* bottom_node; + Node* right_node; + double width; + bool left_highest; + + Basin() : left_node(NULL), bottom_node(NULL), right_node(NULL), width(0.0), left_highest(false) + { + } + + void Clear() + { + left_node = NULL; + bottom_node = NULL; + right_node = NULL; + width = 0.0; + left_highest = false; + } +}; + +struct EdgeEvent { + Edge* constrained_edge; + bool right; + + EdgeEvent() : constrained_edge(NULL), right(false) + { + } +}; + +Basin basin; +EdgeEvent edge_event; + +private: + +friend class Sweep; + +std::vector triangles_; +std::list map_; +std::vector points_; + +// Advancing front +AdvancingFront* front_; +// head point used with advancing front +Point* head_; +// tail point used with advancing front +Point* tail_; + +Node *af_head_, *af_middle_, *af_tail_; + +void InitTriangulation(); +void InitEdges(std::vector polyline); + +}; + +inline AdvancingFront* SweepContext::front() +{ + return front_; +} + +inline int SweepContext::point_count() +{ + return int(points_.size()); +} + +inline void SweepContext::set_head(Point* p1) +{ + head_ = p1; +} + +inline Point* SweepContext::head() +{ + return head_; +} + +inline void SweepContext::set_tail(Point* p1) +{ + tail_ = p1; +} + +inline Point* SweepContext::tail() +{ + return tail_; +} + +} + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..4fb28c2 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,10 @@ +# special case begin +add_subdirectory(3rdparty/poly2tri) +add_subdirectory(3rdparty/clipper) +add_subdirectory(3rdparty/clip2tri) +add_subdirectory(positioning) +add_subdirectory(plugins) +if(TARGET Qt::Quick) + add_subdirectory(positioningquick) +endif() +# special case end diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt new file mode 100644 index 0000000..ba3fcd0 --- /dev/null +++ b/src/plugins/CMakeLists.txt @@ -0,0 +1,5 @@ +# Generated from plugins.pro. + +if(TARGET Qt::Positioning) + add_subdirectory(position) +endif() diff --git a/src/plugins/position/CMakeLists.txt b/src/plugins/position/CMakeLists.txt new file mode 100644 index 0000000..b9cb351 --- /dev/null +++ b/src/plugins/position/CMakeLists.txt @@ -0,0 +1,21 @@ +# Generated from position.pro. + +add_subdirectory(positionpoll) +if(TARGET Qt::DBus AND (FREEBSD OR LINUX OR OPENBSD OR NETBSD OR HURD)) + add_subdirectory(geoclue2) +endif() +if(QT_FEATURE_gypsy) + add_subdirectory(gypsy) +endif() +if(QT_FEATURE_winrt_geolocation) + add_subdirectory(winrt) +endif() +if(IOS OR MACOS OR TVOS) + add_subdirectory(corelocation) +endif() +if(ANDROID) + add_subdirectory(android) +endif() +if(TARGET Qt::SerialPort AND TARGET Qt::Network) + add_subdirectory(nmea) +endif() diff --git a/src/plugins/position/android/CMakeLists.txt b/src/plugins/position/android/CMakeLists.txt new file mode 100644 index 0000000..22fe2b6 --- /dev/null +++ b/src/plugins/position/android/CMakeLists.txt @@ -0,0 +1,4 @@ +# Generated from android.pro. + +add_subdirectory(jar) +add_subdirectory(src) diff --git a/src/plugins/position/android/jar/AndroidManifest.xml b/src/plugins/position/android/jar/AndroidManifest.xml new file mode 100644 index 0000000..2e847fd --- /dev/null +++ b/src/plugins/position/android/jar/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + diff --git a/src/plugins/position/android/jar/CMakeLists.txt b/src/plugins/position/android/jar/CMakeLists.txt new file mode 100644 index 0000000..8eadc79 --- /dev/null +++ b/src/plugins/position/android/jar/CMakeLists.txt @@ -0,0 +1,17 @@ +# Generated from jar.pro. + +set(java_sources + src/org/qtproject/qt/android/positioning/QtPositioning.java # special case +) + +qt_internal_add_jar(Qt${QtLocation_VERSION_MAJOR}AndroidPositioning # special case + INCLUDE_JARS ${QT_ANDROID_JAR} + SOURCES ${java_sources} + OUTPUT_DIR "${QT_BUILD_DIR}/jar" +) + +install_jar(Qt${QtLocation_VERSION_MAJOR}AndroidPositioning # special case + DESTINATION jar + COMPONENT Devel +) + diff --git a/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java b/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java new file mode 100644 index 0000000..fe9d071 --- /dev/null +++ b/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java @@ -0,0 +1,622 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +package org.qtproject.qt.android.positioning; + +import android.content.Context; +import android.location.GpsSatellite; +import android.location.GpsStatus; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.GnssStatus; +import android.location.GnssStatus.Callback; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Build; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import android.util.Log; + +public class QtPositioning implements LocationListener +{ + + private static final String TAG = "qt.positioning.android"; + static LocationManager locationManager = null; + static Object m_syncObject = new Object(); + static HashMap runningListeners = new HashMap(); + + /* + The positionInfo instance to which this + QtPositioning instance is attached to. + */ + private int nativeClassReference = 0; + + /* + The provider type requested by Qt + */ + private int expectedProviders = 0; + + public static final int QT_GPS_PROVIDER = 1; + public static final int QT_NETWORK_PROVIDER = 2; + + /* The following values must match the corresponding error enums in the Qt API*/ + public static final int QT_ACCESS_ERROR = 0; + public static final int QT_CLOSED_ERROR = 1; + public static final int QT_POSITION_UNKNOWN_SOURCE_ERROR = 2; + public static final int QT_POSITION_NO_ERROR = 3; + public static final int QT_SATELLITE_NO_ERROR = 2; + public static final int QT_SATELLITE_UNKNOWN_SOURCE_ERROR = -1; + + /* True, if updates were caused by requestUpdate() */ + private boolean isSingleUpdate = false; + /* The length requested for regular intervals in msec. */ + private int updateIntervalTime = 0; + + /* The last received GPS update */ + private Location lastGps = null; + /* The last received network update */ + private Location lastNetwork = null; + /* If true this class acts as satellite signal monitor rather than location monitor */ + private boolean isSatelliteUpdate = false; + + private PositioningLooperBase looperThread; + + private boolean isLocationProvidersDisabledInvoked = false; + + static public void setContext(Context context) + { + try { + locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); + } catch(Exception e) { + e.printStackTrace(); + } + } + + static private int[] providerList() + { + if (locationManager == null) { + Log.w(TAG, "No locationManager available in QtPositioning"); + return new int[0]; + } + List providers = locationManager.getProviders(true); + int retList[] = new int[providers.size()]; + for (int i = 0; i < providers.size(); i++) { + if (providers.get(i).equals(LocationManager.GPS_PROVIDER)) { + //must be in sync with AndroidPositioning::PositionProvider::PROVIDER_GPS + retList[i] = 0; + } else if (providers.get(i).equals(LocationManager.NETWORK_PROVIDER)) { + //must be in sync with AndroidPositioning::PositionProvider::PROVIDER_NETWORK + retList[i] = 1; + } else if (providers.get(i).equals(LocationManager.PASSIVE_PROVIDER)) { + //must be in sync with AndroidPositioning::PositionProvider::PROVIDER_PASSIVE + retList[i] = 2; + } else { + retList[i] = -1; + } + } + return retList; + } + + static public Location lastKnownPosition(boolean fromSatelliteOnly) + { + Location gps = null; + Location network = null; + try { + gps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + if (!fromSatelliteOnly) + network = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + } catch(Exception e) { + e.printStackTrace(); + gps = network = null; + } + + if (gps != null && network != null) { + //we return the most recent location but slightly prefer GPS + //prefer GPS if it is max 4 hrs older than network + long delta = network.getTime() - gps.getTime(); + if (delta < 4*60*60*1000) { + return gps; + } else { + return network; + } + } else if (gps != null ) { + return gps; + } else if (network != null) { + return network; + } + + return null; + } + + /* Returns true if at least on of the given providers is enabled. */ + static private boolean expectedProvidersAvailable(int desiredProviders) + { + List enabledProviders = locationManager.getProviders(true); + if ((desiredProviders & QT_GPS_PROVIDER) > 0) { //gps desired + if (enabledProviders.contains(LocationManager.GPS_PROVIDER)) { + return true; + } + } + if ((desiredProviders & QT_NETWORK_PROVIDER) > 0) { //network desired + if (enabledProviders.contains(LocationManager.NETWORK_PROVIDER)) { + return true; + } + } + + return false; + } + + + static private void addActiveListener(QtPositioning listener, String provider) + { + int androidClassKey = listener.nativeClassReference; + //start update thread + listener.setActiveLooper(true); + + if (runningListeners.containsKey(androidClassKey) && runningListeners.get(androidClassKey) != listener) { + removeActiveListener(androidClassKey); + } + + locationManager.requestSingleUpdate(provider, + listener, + listener.looper()); + + runningListeners.put(androidClassKey, listener); + } + + + static private void addActiveListener(QtPositioning listener, String provider, long minTime, float minDistance) + { + int androidClassKey = listener.nativeClassReference; + //start update thread + listener.setActiveLooper(true); + + if (runningListeners.containsKey(androidClassKey) && runningListeners.get(androidClassKey) != listener) { + removeActiveListener(androidClassKey); + } + + locationManager.requestLocationUpdates(provider, + minTime, minDistance, + listener, + listener.looper()); + + runningListeners.put(androidClassKey, listener); + } + + + static private void removeActiveListener(QtPositioning listener) + { + removeActiveListener(listener.nativeClassReference); + } + + + static private void removeActiveListener(int androidClassKey) + { + QtPositioning listener = runningListeners.remove(androidClassKey); + + if (listener != null) { + locationManager.removeUpdates(listener); + listener.setActiveLooper(false); + } + } + + + static public int startUpdates(int androidClassKey, int locationProvider, int updateInterval) + { + synchronized (m_syncObject) { + try { + boolean exceptionOccurred = false; + QtPositioning positioningListener = new QtPositioning(); + positioningListener.nativeClassReference = androidClassKey; + positioningListener.expectedProviders = locationProvider; + positioningListener.isSatelliteUpdate = false; + + if (updateInterval == 0) + updateInterval = 50; //don't update more often than once per 50ms + + positioningListener.updateIntervalTime = updateInterval; + if ((locationProvider & QT_GPS_PROVIDER) > 0) { + Log.d(TAG, "Regular updates using GPS " + updateInterval); + try { + addActiveListener(positioningListener, + LocationManager.GPS_PROVIDER, + updateInterval, 0); + } catch (SecurityException se) { + se.printStackTrace(); + exceptionOccurred = true; + } + } + + if ((locationProvider & QT_NETWORK_PROVIDER) > 0) { + Log.d(TAG, "Regular updates using network " + updateInterval); + try { + addActiveListener(positioningListener, + LocationManager.NETWORK_PROVIDER, + updateInterval, 0); + } catch (SecurityException se) { + se.printStackTrace(); + exceptionOccurred = true; + } + } + if (exceptionOccurred) { + removeActiveListener(positioningListener); + return QT_ACCESS_ERROR; + } + + if (!expectedProvidersAvailable(locationProvider)) { + //all location providers unavailbe -> when they come back we resume automatically + return QT_CLOSED_ERROR; + } + + } catch(Exception e) { + e.printStackTrace(); + return QT_POSITION_UNKNOWN_SOURCE_ERROR; + } + + return QT_POSITION_NO_ERROR; + } + } + + static public void stopUpdates(int androidClassKey) + { + synchronized (m_syncObject) { + try { + Log.d(TAG, "Stopping updates"); + removeActiveListener(androidClassKey); + } catch(Exception e) { + e.printStackTrace(); + return; + } + } + } + + static public int requestUpdate(int androidClassKey, int locationProvider) + { + synchronized (m_syncObject) { + try { + boolean exceptionOccurred = false; + QtPositioning positioningListener = new QtPositioning(); + positioningListener.nativeClassReference = androidClassKey; + positioningListener.isSingleUpdate = true; + positioningListener.expectedProviders = locationProvider; + positioningListener.isSatelliteUpdate = false; + + if ((locationProvider & QT_GPS_PROVIDER) > 0) { + Log.d(TAG, "Single update using GPS"); + try { + addActiveListener(positioningListener, LocationManager.GPS_PROVIDER); + } catch (SecurityException se) { + se.printStackTrace(); + exceptionOccurred = true; + } + } + + if ((locationProvider & QT_NETWORK_PROVIDER) > 0) { + Log.d(TAG, "Single update using network"); + try { + addActiveListener(positioningListener, LocationManager.NETWORK_PROVIDER); + } catch (SecurityException se) { + se.printStackTrace(); + exceptionOccurred = true; + } + } + if (exceptionOccurred) { + removeActiveListener(positioningListener); + return QT_ACCESS_ERROR; + } + + if (!expectedProvidersAvailable(locationProvider)) { + //all location providers unavailable -> when they come back we resume automatically + //in the mean time return ClosedError + return QT_CLOSED_ERROR; + } + + } catch(Exception e) { + e.printStackTrace(); + return QT_POSITION_UNKNOWN_SOURCE_ERROR; + } + + return QT_POSITION_NO_ERROR; + } + } + + static public int startSatelliteUpdates(int androidClassKey, int updateInterval, boolean isSingleRequest) + { + synchronized (m_syncObject) { + try { + boolean exceptionOccurred = false; + QtPositioning positioningListener = new QtPositioning(); + positioningListener.isSatelliteUpdate = true; + positioningListener.nativeClassReference = androidClassKey; + positioningListener.expectedProviders = 1; //always satellite provider + positioningListener.isSingleUpdate = isSingleRequest; + + if (updateInterval == 0) + updateInterval = 50; //don't update more often than once per 50ms + + if (isSingleRequest) + Log.d(TAG, "Single update for Satellites " + updateInterval); + else + Log.d(TAG, "Regular updates for Satellites " + updateInterval); + try { + addActiveListener(positioningListener, LocationManager.GPS_PROVIDER, + updateInterval, 0); + } catch (SecurityException se) { + se.printStackTrace(); + exceptionOccurred = true; + } + + if (exceptionOccurred) { + removeActiveListener(positioningListener); + return QT_ACCESS_ERROR; + } + + if (!expectedProvidersAvailable(positioningListener.expectedProviders)) { + //all location providers unavailable -> when they come back we resume automatically + //in the mean time return ClosedError + return QT_CLOSED_ERROR; + } + + } catch(Exception e) { + e.printStackTrace(); + return QT_SATELLITE_UNKNOWN_SOURCE_ERROR; + } + + return QT_SATELLITE_NO_ERROR; + } + } + + public QtPositioning() + { + // Use GpsStatus for API Level <= 23 (version M and below) and + // GnssStatus for other API levels. + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) + looperThread = new PositioningLooperGps(); + else + looperThread = new PositioningLooperGnss(); + } + + public Looper looper() + { + return looperThread.looper(); + } + + private void setActiveLooper(boolean setActive) + { + try{ + if (setActive) { + if (looperThread.isAlive()) + return; + + if (isSatelliteUpdate) + looperThread.isSatelliteListener(true); + + long start = System.currentTimeMillis(); + looperThread.start(); + + //busy wait but lasts ~20-30 ms only + while (!looperThread.isReady()); + + long stop = System.currentTimeMillis(); + Log.d(TAG, "Looper Thread startup time in ms: " + (stop-start)); + } else { + looperThread.quitLooper(); + } + } catch(Exception e) { + e.printStackTrace(); + } + } + + private abstract class PositioningLooperBase extends Thread + { + private boolean looperRunning; + private Looper posLooper; + private boolean isSatelliteLooper = false; + + abstract protected void addSatelliteInfoListener(); + abstract protected void removeSatelliteInfoListener(); + + private PositioningLooperBase() + { + looperRunning = false; + } + + public void run() + { + Looper.prepare(); + Handler handler = new Handler(); + + if (isSatelliteLooper) + addSatelliteInfoListener(); + + posLooper = Looper.myLooper(); + synchronized (this) { + looperRunning = true; + } + Looper.loop(); + synchronized (this) { + looperRunning = false; + } + } + + public void quitLooper() + { + if (isSatelliteLooper) + removeSatelliteInfoListener(); + looper().quit(); + } + + public synchronized boolean isReady() + { + return looperRunning; + } + + public void isSatelliteListener(boolean isListener) + { + isSatelliteLooper = isListener; + } + + public Looper looper() + { + return posLooper; + } + + } + + private class PositioningLooperGps extends PositioningLooperBase implements GpsStatus.Listener + { + @Override + protected void addSatelliteInfoListener() + { + try { + locationManager.addGpsStatusListener(this); + } catch(Exception e) { + e.printStackTrace(); + } + } + + @Override + protected void removeSatelliteInfoListener() + { + locationManager.removeGpsStatusListener(this); + } + + @Override + public void onGpsStatusChanged(int event) { + switch (event) { + case GpsStatus.GPS_EVENT_FIRST_FIX: + break; + case GpsStatus.GPS_EVENT_SATELLITE_STATUS: + GpsStatus status = locationManager.getGpsStatus(null); + Iterable iterable = status.getSatellites(); + Iterator it = iterable.iterator(); + + ArrayList list = new ArrayList(); + while (it.hasNext()) { + GpsSatellite sat = (GpsSatellite) it.next(); + list.add(sat); + } + GpsSatellite[] sats = list.toArray(new GpsSatellite[list.size()]); + satelliteGpsUpdated(sats, nativeClassReference, isSingleUpdate); + + break; + case GpsStatus.GPS_EVENT_STARTED: + break; + case GpsStatus.GPS_EVENT_STOPPED: + break; + } + } + } + + private class PositioningGnssListener extends GnssStatus.Callback + { + @Override + public void onSatelliteStatusChanged(GnssStatus status) + { + satelliteGnssUpdated(status, nativeClassReference, isSingleUpdate); + } + } + + private class PositioningLooperGnss extends PositioningLooperBase + { + private PositioningGnssListener gnssListener; + + private PositioningLooperGnss() + { + gnssListener = new PositioningGnssListener(); + } + + @Override + protected void addSatelliteInfoListener() + { + try { + locationManager.registerGnssStatusCallback(gnssListener); + } catch(Exception e) { + e.printStackTrace(); + } + } + + @Override + protected void removeSatelliteInfoListener() + { + locationManager.unregisterGnssStatusCallback(gnssListener); + } + } + + public static native void positionUpdated(Location update, int androidClassKey, boolean isSingleUpdate); + public static native void locationProvidersDisabled(int androidClassKey); + public static native void locationProvidersChanged(int androidClassKey); + public static native void satelliteGpsUpdated(GpsSatellite[] update, int androidClassKey, boolean isSingleUpdate); + public static native void satelliteGnssUpdated(GnssStatus update, int androidClassKey, boolean isSingleUpdate); + + @Override + public void onLocationChanged(Location location) { + //Log.d(TAG, "**** Position Update ****: " + location.toString() + " " + isSingleUpdate); + if (location == null) + return; + + if (isSatelliteUpdate) //we are a QGeoSatelliteInfoSource -> ignore + return; + + if (isSingleUpdate || expectedProviders < 3) { + positionUpdated(location, nativeClassReference, isSingleUpdate); + return; + } + + /* + We can use GPS and Network, pick the better location provider. + Generally we prefer GPS data due to their higher accurancy but we + let Network data pass until GPS fix is available + */ + + if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) { + lastGps = location; + + // assumption: GPS always better -> pass it on + positionUpdated(location, nativeClassReference, isSingleUpdate); + } else if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { + lastNetwork = location; + + if (lastGps == null) { //no GPS fix yet use network location + positionUpdated(location, nativeClassReference, isSingleUpdate); + return; + } + + long delta = location.getTime() - lastGps.getTime(); + + // Ignore if network update is older than last GPS (delta < 0) + // Ignore if gps update still has time to provide next location (delta < updateInterval) + if (delta < updateIntervalTime) + return; + + // Use network data -> GPS has timed out on updateInterval + positionUpdated(location, nativeClassReference, isSingleUpdate); + } + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) {} + + @Override + public void onProviderEnabled(String provider) { + Log.d(TAG, "Enabled provider: " + provider); + locationProvidersChanged(nativeClassReference); + if (isLocationProvidersDisabledInvoked && expectedProvidersAvailable(expectedProviders)) + isLocationProvidersDisabledInvoked = false; + } + + @Override + public void onProviderDisabled(String provider) { + Log.d(TAG, "Disabled provider: " + provider); + locationProvidersChanged(nativeClassReference); + if (!isLocationProvidersDisabledInvoked && !expectedProvidersAvailable(expectedProviders)) { + isLocationProvidersDisabledInvoked = true; + locationProvidersDisabled(nativeClassReference); + } + } +} diff --git a/src/plugins/position/android/src/CMakeLists.txt b/src/plugins/position/android/src/CMakeLists.txt new file mode 100644 index 0000000..b91181f --- /dev/null +++ b/src/plugins/position/android/src/CMakeLists.txt @@ -0,0 +1,23 @@ +# Generated from src.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryAndroid Plugin: +##################################################################### + +qt_internal_add_plugin(QGeoPositionInfoSourceFactoryAndroidPlugin + OUTPUT_NAME qtposition_android + CLASS_NAME QGeoPositionInfoSourceFactoryAndroid + PLUGIN_TYPE position + SOURCES + jnipositioning.cpp jnipositioning.h + positionfactory_android.cpp positionfactory_android.h + qgeopositioninfosource_android.cpp qgeopositioninfosource_android_p.h + qgeosatelliteinfosource_android.cpp qgeosatelliteinfosource_android_p.h + LIBRARIES + Qt::Core + Qt::CorePrivate + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:src.pro:: +# OTHER_FILES = "plugin.json" diff --git a/src/plugins/position/android/src/jnipositioning.cpp b/src/plugins/position/android/src/jnipositioning.cpp new file mode 100644 index 0000000..1fb73a0 --- /dev/null +++ b/src/plugins/position/android/src/jnipositioning.cpp @@ -0,0 +1,716 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qgeopositioninfosource_android_p.h" +#include "qgeosatelliteinfosource_android_p.h" +#include "jnipositioning.h" + +class GlobalClassRefWrapper +{ +public: + GlobalClassRefWrapper() = default; + ~GlobalClassRefWrapper() + { + if (m_classRef) { + QJniEnvironment env; + if (env.jniEnv()) + env->DeleteGlobalRef(m_classRef); + } + } + + bool init(const char *className) + { + QJniEnvironment env; + if (env.jniEnv()) { + if (m_classRef) { + env->DeleteGlobalRef(m_classRef); + m_classRef = nullptr; + } + + m_classRef = env.findClass(className); // it returns global ref! + } + return m_classRef != nullptr; + } + + jclass operator()() { return m_classRef; } + +private: + jclass m_classRef = nullptr; +}; + +static GlobalClassRefWrapper positioningClass; + +static jmethodID providerListMethodId; +static jmethodID lastKnownPositionMethodId; +static jmethodID startUpdatesMethodId; +static jmethodID stopUpdatesMethodId; +static jmethodID requestUpdateMethodId; +static jmethodID startSatelliteUpdatesMethodId; + +static const char logTag[] = "qt.positioning.android"; +static const char methodErrorMsg[] = "Can't find method \"%s%s\""; + +Q_LOGGING_CATEGORY(lcPositioning, logTag) + +namespace { + +/*! + \internal + This class encapsulates satellite system types, as defined by Android + GnssStatus API. Initialize during JNI_OnLoad() by the init() method, from + the Java side, rather than hard-coding. +*/ +class ConstellationMapper +{ +public: + static bool init() + { + m_gnssStatusObject = nullptr; + if (QNativeInterface::QAndroidApplication::sdkVersion() > 23) { + m_gnssStatusObject = QJniEnvironment().findClass("android/location/GnssStatus"); + if (!m_gnssStatusObject) + return false; + } + // no need to query it for API level <= 23 + return true; + } + + static QGeoSatelliteInfo::SatelliteSystem toSatelliteSystem(int constellationType) + { + if (!m_gnssStatusObject) + return QGeoSatelliteInfo::Undefined; + + static const int gps = + QJniObject::getStaticField(m_gnssStatusObject, "CONSTELLATION_GPS"); + static const int glonass = + QJniObject::getStaticField(m_gnssStatusObject, "CONSTELLATION_GLONASS"); + static const int galileo = + QJniObject::getStaticField(m_gnssStatusObject, "CONSTELLATION_GALILEO"); + static const int beidou = + QJniObject::getStaticField(m_gnssStatusObject, "CONSTELLATION_BEIDOU"); + static const int qzss = + QJniObject::getStaticField(m_gnssStatusObject, "CONSTELLATION_QZSS"); + + if (constellationType == gps) { + return QGeoSatelliteInfo::GPS; + } else if (constellationType == glonass) { + return QGeoSatelliteInfo::GLONASS; + } else if (constellationType == galileo) { + return QGeoSatelliteInfo::GALILEO; + } else if (constellationType == beidou) { + return QGeoSatelliteInfo::BEIDOU; + } else if (constellationType == qzss){ + return QGeoSatelliteInfo::QZSS; + } else { + qCWarning(lcPositioning) << "Unknown satellite system" << constellationType; + return QGeoSatelliteInfo::Undefined; + } + } + +private: + static jclass m_gnssStatusObject; +}; + +jclass ConstellationMapper::m_gnssStatusObject = nullptr; + +} // anonymous namespace + +namespace AndroidPositioning { + typedef QMap PositionSourceMap; + typedef QMap SatelliteSourceMap; + + Q_GLOBAL_STATIC(PositionSourceMap, idToPosSource) + + Q_GLOBAL_STATIC(SatelliteSourceMap, idToSatSource) + + int registerPositionInfoSource(QObject *obj) + { + int key = -1; + if (obj->inherits("QGeoPositionInfoSource")) { + QGeoPositionInfoSourceAndroid *src = qobject_cast(obj); + Q_ASSERT(src); + do { + key = qAbs(int(QRandomGenerator::global()->generate())); + } while (idToPosSource()->contains(key)); + + idToPosSource()->insert(key, src); + } else if (obj->inherits("QGeoSatelliteInfoSource")) { + QGeoSatelliteInfoSourceAndroid *src = qobject_cast(obj); + Q_ASSERT(src); + do { + key = qAbs(int(QRandomGenerator::global()->generate())); + } while (idToSatSource()->contains(key)); + + idToSatSource()->insert(key, src); + } + + return key; + } + + void unregisterPositionInfoSource(int key) + { + if (idToPosSource.exists()) + idToPosSource->remove(key); + + if (idToSatSource.exists()) + idToSatSource->remove(key); + } + + enum PositionProvider + { + PROVIDER_GPS = 0, + PROVIDER_NETWORK = 1, + PROVIDER_PASSIVE = 2 + }; + + + QGeoPositionInfoSource::PositioningMethods availableProviders() + { + QGeoPositionInfoSource::PositioningMethods ret = QGeoPositionInfoSource::NoPositioningMethods; + QJniEnvironment env; + if (!env.jniEnv()) + return ret; + QJniObject jniProvidersObj = + QJniObject::callStaticObjectMethod(positioningClass(), providerListMethodId); + jintArray jProviders = jniProvidersObj.object(); + jint *providers = env->GetIntArrayElements(jProviders, nullptr); + const int size = env->GetArrayLength(jProviders); + for (int i = 0; i < size; i++) { + switch (providers[i]) { + case PROVIDER_GPS: + ret |= QGeoPositionInfoSource::SatellitePositioningMethods; + break; + case PROVIDER_NETWORK: + ret |= QGeoPositionInfoSource::NonSatellitePositioningMethods; + break; + case PROVIDER_PASSIVE: + //we ignore as Qt doesn't have interface for it right now + break; + default: + __android_log_print(ANDROID_LOG_INFO, logTag, "Unknown positioningMethod"); + } + } + + env->ReleaseIntArrayElements(jProviders, providers, 0); + + return ret; + } + + QGeoPositionInfo positionInfoFromJavaLocation(const jobject &location) + { + QGeoPositionInfo info; + + QJniObject jniObject(location); + if (!jniObject.isValid()) + return QGeoPositionInfo(); + + const jdouble latitude = jniObject.callMethod("getLatitude"); + const jdouble longitude = jniObject.callMethod("getLongitude"); + + QGeoCoordinate coordinate(latitude, longitude); + + // altitude + jboolean attributeExists = jniObject.callMethod("hasAltitude"); + if (attributeExists) { + const jdouble value = jniObject.callMethod("getAltitude"); + if (!qFuzzyIsNull(value)) + coordinate.setAltitude(value); + } + + info.setCoordinate(coordinate); + + // time stamp + const jlong timestamp = jniObject.callMethod("getTime"); + info.setTimestamp(QDateTime::fromMSecsSinceEpoch(timestamp, Qt::UTC)); + + // horizontal accuracy + attributeExists = jniObject.callMethod("hasAccuracy"); + if (attributeExists) { + const jfloat accuracy = jniObject.callMethod("getAccuracy"); + if (!qFuzzyIsNull(accuracy)) + info.setAttribute(QGeoPositionInfo::HorizontalAccuracy, qreal(accuracy)); + } + + // vertical accuracy (available in API Level 26+) + if (QNativeInterface::QAndroidApplication::sdkVersion() > 25) { + attributeExists = jniObject.callMethod("hasVerticalAccuracy"); + if (attributeExists) { + const jfloat accuracy = jniObject.callMethod("getVerticalAccuracyMeters"); + if (!qFuzzyIsNull(accuracy)) + info.setAttribute(QGeoPositionInfo::VerticalAccuracy, qreal(accuracy)); + } + } + + // ground speed + attributeExists = jniObject.callMethod("hasSpeed"); + if (attributeExists) { + const jfloat speed = jniObject.callMethod("getSpeed"); + if (!qFuzzyIsNull(speed)) + info.setAttribute(QGeoPositionInfo::GroundSpeed, qreal(speed)); + } + + // bearing + attributeExists = jniObject.callMethod("hasBearing"); + if (attributeExists) { + const jfloat bearing = jniObject.callMethod("getBearing"); + if (!qFuzzyIsNull(bearing)) + info.setAttribute(QGeoPositionInfo::Direction, qreal(bearing)); + + // bearingAccuracy is available in API Level 26+ + if (QNativeInterface::QAndroidApplication::sdkVersion() > 25) { + const jfloat bearingAccuracy = + jniObject.callMethod("getBearingAccuracyDegrees"); + if (!qFuzzyIsNull(bearingAccuracy)) + info.setAttribute(QGeoPositionInfo::DirectionAccuracy, qreal(bearingAccuracy)); + } + } + + return info; + } + + QList satelliteInfoFromJavaLocation(JNIEnv *jniEnv, + jobjectArray satellites, + QList* usedInFix) + { + QList sats; + jsize length = jniEnv->GetArrayLength(satellites); + for (int i = 0; iGetObjectArrayElement(satellites, i); + if (QJniEnvironment::checkAndClearExceptions(jniEnv)) { + qCWarning(lcPositioning) << "Cannot process all satellite data due to exception."; + break; + } + + QJniObject jniObj = QJniObject::fromLocalRef(element); + if (!jniObj.isValid()) + continue; + + QGeoSatelliteInfo info; + + // signal strength + const jfloat snr = jniObj.callMethod("getSnr"); + info.setSignalStrength(int(snr)); + + // ignore any satellite with no signal whatsoever + if (qFuzzyIsNull(snr)) + continue; + + // prn + const jint prn = jniObj.callMethod("getPrn"); + info.setSatelliteIdentifier(prn); + + if (prn >= 1 && prn <= 32) + info.setSatelliteSystem(QGeoSatelliteInfo::GPS); + else if (prn >= 65 && prn <= 96) + info.setSatelliteSystem(QGeoSatelliteInfo::GLONASS); + else if (prn >= 193 && prn <= 200) + info.setSatelliteSystem(QGeoSatelliteInfo::QZSS); + else if ((prn >= 201 && prn <= 235) || (prn >= 401 && prn <= 437)) + info.setSatelliteSystem(QGeoSatelliteInfo::BEIDOU); + else if (prn >= 301 && prn <= 336) + info.setSatelliteSystem(QGeoSatelliteInfo::GALILEO); + + // azimuth + const jfloat azimuth = jniObj.callMethod("getAzimuth"); + info.setAttribute(QGeoSatelliteInfo::Azimuth, qreal(azimuth)); + + // elevation + const jfloat elevation = jniObj.callMethod("getElevation"); + info.setAttribute(QGeoSatelliteInfo::Elevation, qreal(elevation)); + + // Used in fix - true if this satellite is actually used in + // determining the position. + const jboolean inFix = jniObj.callMethod("usedInFix"); + + sats.append(info); + + if (inFix) + usedInFix->append(info); + } + + return sats; + } + + QList satelliteInfoFromJavaGnssStatus(jobject gnssStatus, + QList* usedInFix) + { + QJniObject jniStatus(gnssStatus); + QList sats; + + const int satellitesCount = jniStatus.callMethod("getSatelliteCount"); + for (int i = 0; i < satellitesCount; ++i) { + QGeoSatelliteInfo info; + + // signal strength - this is actually a carrier-to-noise density, + // but the values are very close to what was previously returned by + // getSnr() method of the GpsSatellite API. + const jfloat cn0 = jniStatus.callMethod("getCn0DbHz", "(I)F", i); + info.setSignalStrength(static_cast(cn0)); + + // satellite system + const jint constellationType = + jniStatus.callMethod("getConstellationType", "(I)I", i); + info.setSatelliteSystem(ConstellationMapper::toSatelliteSystem(constellationType)); + + // satellite identifier + const jint svId = jniStatus.callMethod("getSvid", "(I)I", i); + info.setSatelliteIdentifier(svId); + + // azimuth + const jfloat azimuth = jniStatus.callMethod("getAzimuthDegrees", "(I)F", i); + info.setAttribute(QGeoSatelliteInfo::Azimuth, static_cast(azimuth)); + + // elevation + const jfloat elevation = jniStatus.callMethod("getElevationDegrees", "(I)F", i); + info.setAttribute(QGeoSatelliteInfo::Elevation, static_cast(elevation)); + + // Used in fix - true if this satellite is actually used in + // determining the position. + const jboolean inFix = jniStatus.callMethod("usedInFix", "(I)Z", i); + + sats.append(info); + + if (inFix) + usedInFix->append(info); + } + + return sats; + } + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) + { + QJniEnvironment env; + if (!env.jniEnv()) + return QGeoPositionInfo(); + + if (!requestionPositioningPermissions()) + return {}; + + QJniObject locationObj = QJniObject::callStaticObjectMethod( + positioningClass(), lastKnownPositionMethodId, fromSatellitePositioningMethodsOnly); + jobject location = locationObj.object(); + if (location == nullptr) + return QGeoPositionInfo(); + + const QGeoPositionInfo info = positionInfoFromJavaLocation(location); + + return info; + } + + inline int positioningMethodToInt(QGeoPositionInfoSource::PositioningMethods m) + { + int providerSelection = 0; + if (m & QGeoPositionInfoSource::SatellitePositioningMethods) + providerSelection |= 1; + if (m & QGeoPositionInfoSource::NonSatellitePositioningMethods) + providerSelection |= 2; + + return providerSelection; + } + + QGeoPositionInfoSource::Error startUpdates(int androidClassKey) + { + QJniEnvironment env; + if (!env.jniEnv()) + return QGeoPositionInfoSource::UnknownSourceError; + + QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); + + if (source) { + if (!requestionPositioningPermissions()) + return QGeoPositionInfoSource::AccessError; + + int errorCode = QJniObject::callStaticMethod( + positioningClass(), startUpdatesMethodId, androidClassKey, + positioningMethodToInt(source->preferredPositioningMethods()), + source->updateInterval()); + switch (errorCode) { + case 0: + case 1: + case 2: + case 3: + return static_cast(errorCode); + default: + break; + } + } + + return QGeoPositionInfoSource::UnknownSourceError; + } + + //used for stopping regular and single updates + void stopUpdates(int androidClassKey) + { + QJniObject::callStaticMethod(positioningClass(), stopUpdatesMethodId, + androidClassKey); + } + + QGeoPositionInfoSource::Error requestUpdate(int androidClassKey) + { + QJniEnvironment env; + if (!env.jniEnv()) + return QGeoPositionInfoSource::UnknownSourceError; + + QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); + + if (source) { + if (!requestionPositioningPermissions()) + return QGeoPositionInfoSource::AccessError; + + int errorCode = QJniObject::callStaticMethod( + positioningClass(), requestUpdateMethodId, androidClassKey, + positioningMethodToInt(source->preferredPositioningMethods())); + switch (errorCode) { + case 0: + case 1: + case 2: + case 3: + return static_cast(errorCode); + default: + break; + } + } + return QGeoPositionInfoSource::UnknownSourceError; + } + + QGeoSatelliteInfoSource::Error startSatelliteUpdates(int androidClassKey, bool isSingleRequest, int requestTimeout) + { + QJniEnvironment env; + if (!env.jniEnv()) + return QGeoSatelliteInfoSource::UnknownSourceError; + + QGeoSatelliteInfoSourceAndroid *source = AndroidPositioning::idToSatSource()->value(androidClassKey); + + if (source) { + if (!requestionPositioningPermissions()) + return QGeoSatelliteInfoSource::AccessError; + + int interval = source->updateInterval(); + if (isSingleRequest) + interval = requestTimeout; + int errorCode = QJniObject::callStaticMethod(positioningClass(), + startSatelliteUpdatesMethodId, + androidClassKey, interval, + isSingleRequest); + switch (errorCode) { + case -1: + case 0: + case 1: + case 2: + return static_cast(errorCode); + default: + qCWarning(lcPositioning) + << "startSatelliteUpdates: Unknown error code" << errorCode; + break; + } + } + return QGeoSatelliteInfoSource::UnknownSourceError; + } + + bool requestionPositioningPermissions() + { + // If the code is running as a service, we can't request permissions. + // We can only check if we have the needed permissions. Also make sure + // to request the background location permissions. + if (!QNativeInterface::QAndroidApplication::isActivityContext()) { + const auto permission = QtAndroidPrivate::PreciseBackgroundLocation; + const auto result = QtAndroidPrivate::checkPermission(permission).result(); + if (result != QtAndroidPrivate::Authorized) { + qCWarning(lcPositioning) + << "Position data not available due to missing permission" << permission; + } + return result == QtAndroidPrivate::Authorized; + } else { + // Running from a normal Activity. Checking and requesting the + // permissions if necessary. + + // Android v23+ requires runtime permission check and requests + const auto permission = QtAndroidPrivate::PreciseLocation; + auto checkFuture = QtAndroidPrivate::checkPermission(permission); + if (checkFuture.result() == QtAndroidPrivate::Denied) { + auto requestFuture = QtAndroidPrivate::requestPermission(permission); + if (requestFuture.result() != QtAndroidPrivate::Authorized) { + qCWarning(lcPositioning) + << "Position data not available due to missing permission" + << permission; + return false; + } + } + + return true; + } + } +} + +static void positionUpdated(JNIEnv *env, jobject thiz, jobject location, + jint androidClassKey, jboolean isSingleUpdate) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + QGeoPositionInfo info = AndroidPositioning::positionInfoFromJavaLocation(location); + + QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); + if (!source) { + qCWarning(lcPositioning) << "positionUpdated: source == 0"; + return; + } + + //we need to invoke indirectly as the Looper thread is likely to be not the same thread + if (!isSingleUpdate) + QMetaObject::invokeMethod(source, "processPositionUpdate", Qt::AutoConnection, + Q_ARG(QGeoPositionInfo, info)); + else + QMetaObject::invokeMethod(source, "processSinglePositionUpdate", Qt::AutoConnection, + Q_ARG(QGeoPositionInfo, info)); +} + +static void locationProvidersDisabled(JNIEnv *env, jobject thiz, jint androidClassKey) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + QObject *source = AndroidPositioning::idToPosSource()->value(androidClassKey); + if (!source) + source = AndroidPositioning::idToSatSource()->value(androidClassKey); + if (!source) { + qCWarning(lcPositioning) << "locationProvidersDisabled: source == 0"; + return; + } + + QMetaObject::invokeMethod(source, "locationProviderDisabled", Qt::AutoConnection); +} + +static void locationProvidersChanged(JNIEnv *env, jobject thiz, jint androidClassKey) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + QObject *source = AndroidPositioning::idToPosSource()->value(androidClassKey); + if (!source) { + qCWarning(lcPositioning) << "locationProvidersChanged: source == 0"; + return; + } + + QMetaObject::invokeMethod(source, "locationProvidersChanged", Qt::AutoConnection); +} + +static void notifySatelliteInfoUpdated(const QList &inView, + const QList &inUse, + jint androidClassKey, jboolean isSingleUpdate) +{ + QGeoSatelliteInfoSourceAndroid *source = AndroidPositioning::idToSatSource()->value(androidClassKey); + if (!source) { + qCWarning(lcPositioning) << "notifySatelliteInfoUpdated: source == 0"; + return; + } + + QMetaObject::invokeMethod(source, "processSatelliteUpdateInView", Qt::AutoConnection, + Q_ARG(QList, inView), Q_ARG(bool, isSingleUpdate)); + + QMetaObject::invokeMethod(source, "processSatelliteUpdateInUse", Qt::AutoConnection, + Q_ARG(QList, inUse), Q_ARG(bool, isSingleUpdate)); +} + +static void satelliteGpsUpdated(JNIEnv *env, jobject thiz, jobjectArray satellites, + jint androidClassKey, jboolean isSingleUpdate) +{ + Q_UNUSED(thiz); + QList inUse; + QList sats = + AndroidPositioning::satelliteInfoFromJavaLocation(env, satellites, &inUse); + + notifySatelliteInfoUpdated(sats, inUse, androidClassKey, isSingleUpdate); +} + +static void satelliteGnssUpdated(JNIEnv *env, jobject thiz, jobject gnssStatus, + jint androidClassKey, jboolean isSingleUpdate) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + + QList inUse; + QList sats = + AndroidPositioning::satelliteInfoFromJavaGnssStatus(gnssStatus, &inUse); + + notifySatelliteInfoUpdated(sats, inUse, androidClassKey, isSingleUpdate); +} + +#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ + VAR = env.findStaticMethod(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ + if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, logTag, methodErrorMsg, METHOD_NAME, \ + METHOD_SIGNATURE); \ + return false; \ + } + +static bool registerNatives() +{ + const JNINativeMethod methods[] = { + {"positionUpdated", "(Landroid/location/Location;IZ)V", (void *)positionUpdated}, + {"locationProvidersDisabled", "(I)V", (void *) locationProvidersDisabled}, + {"satelliteGpsUpdated", "([Landroid/location/GpsSatellite;IZ)V", (void *)satelliteGpsUpdated}, + {"locationProvidersChanged", "(I)V", (void *) locationProvidersChanged}, + {"satelliteGnssUpdated", "(Landroid/location/GnssStatus;IZ)V", (void *)satelliteGnssUpdated} + }; + + QJniEnvironment env; + if (!env.jniEnv()) { + __android_log_print(ANDROID_LOG_FATAL, logTag, "Failed to create environment"); + return false; + } + + if (!positioningClass.init("org/qtproject/qt/android/positioning/QtPositioning")) { + __android_log_print(ANDROID_LOG_FATAL, logTag, "Failed to create global class ref"); + return false; + } + + if (!env.registerNativeMethods(positioningClass(), methods, + sizeof(methods) / sizeof(methods[0]))) { + __android_log_print(ANDROID_LOG_FATAL, logTag, "Failed to register native methods"); + return false; + } + + GET_AND_CHECK_STATIC_METHOD(providerListMethodId, positioningClass(), "providerList", "()[I"); + GET_AND_CHECK_STATIC_METHOD(lastKnownPositionMethodId, positioningClass(), "lastKnownPosition", + "(Z)Landroid/location/Location;"); + GET_AND_CHECK_STATIC_METHOD(startUpdatesMethodId, positioningClass(), "startUpdates", "(III)I"); + GET_AND_CHECK_STATIC_METHOD(stopUpdatesMethodId, positioningClass(), "stopUpdates", "(I)V"); + GET_AND_CHECK_STATIC_METHOD(requestUpdateMethodId, positioningClass(), "requestUpdate", + "(II)I"); + GET_AND_CHECK_STATIC_METHOD(startSatelliteUpdatesMethodId, positioningClass(), + "startSatelliteUpdates", "(IIZ)I"); + + return true; +} + +Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM * /*vm*/, void * /*reserved*/) +{ + static bool initialized = false; + if (initialized) + return JNI_VERSION_1_6; + initialized = true; + + __android_log_print(ANDROID_LOG_INFO, logTag, "Positioning start"); + + if (!registerNatives()) { + __android_log_print(ANDROID_LOG_FATAL, logTag, "registerNatives() failed"); + return -1; + } + + if (!ConstellationMapper::init()) { + __android_log_print(ANDROID_LOG_ERROR, logTag, + "Failed to extract constellation type constants. " + "Satellite system will be undefined!"); + } + + return JNI_VERSION_1_6; +} + diff --git a/src/plugins/position/android/src/jnipositioning.h b/src/plugins/position/android/src/jnipositioning.h new file mode 100644 index 0000000..0ebd57a --- /dev/null +++ b/src/plugins/position/android/src/jnipositioning.h @@ -0,0 +1,28 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef JNIPOSITIONING_H +#define JNIPOSITIONING_H + +#include +#include + +namespace AndroidPositioning +{ + int registerPositionInfoSource(QObject *obj); + void unregisterPositionInfoSource(int key); + + QGeoPositionInfoSource::PositioningMethods availableProviders(); + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly); + + QGeoPositionInfoSource::Error startUpdates(int androidClassKey); + void stopUpdates(int androidClassKey); + QGeoPositionInfoSource::Error requestUpdate(int androidClassKey); + + QGeoSatelliteInfoSource::Error startSatelliteUpdates(int androidClassKey, + bool isSingleRequest, + int updateRequestTimeout); + bool requestionPositioningPermissions(); +} + +#endif // JNIPOSITIONING_H diff --git a/src/plugins/position/android/src/plugin.json b/src/plugins/position/android/src/plugin.json new file mode 100644 index 0000000..4fd8789 --- /dev/null +++ b/src/plugins/position/android/src/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["android"], + "Provider": "android", + "Position": true, + "Satellite": true, + "Monitor": false, + "Priority": 1000, + "Testable": false +} diff --git a/src/plugins/position/android/src/positionfactory_android.cpp b/src/plugins/position/android/src/positionfactory_android.cpp new file mode 100644 index 0000000..9ca571f --- /dev/null +++ b/src/plugins/position/android/src/positionfactory_android.cpp @@ -0,0 +1,27 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "positionfactory_android.h" +#include "qgeopositioninfosource_android_p.h" +#include "qgeosatelliteinfosource_android_p.h" + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryAndroid::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parameters) + QGeoPositionInfoSourceAndroid *src = new QGeoPositionInfoSourceAndroid(parent); + return src; +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryAndroid::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parameters) + QGeoSatelliteInfoSourceAndroid *src = new QGeoSatelliteInfoSourceAndroid(parent); + return src; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryAndroid::areaMonitor(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} diff --git a/src/plugins/position/android/src/positionfactory_android.h b/src/plugins/position/android/src/positionfactory_android.h new file mode 100644 index 0000000..001ee5b --- /dev/null +++ b/src/plugins/position/android/src/positionfactory_android.h @@ -0,0 +1,22 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef POSITIONPOLLFACTORY_H +#define POSITIONPOLLFACTORY_H + +#include +#include + +class QGeoPositionInfoSourceFactoryAndroid : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +#endif // POSITIONPOLLFACTORY_H diff --git a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp new file mode 100644 index 0000000..1c47db0 --- /dev/null +++ b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp @@ -0,0 +1,259 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosource_android_p.h" +#include "jnipositioning.h" +#include + +static constexpr int kUpdateFromColdStart = 2 * 60 * 1000; +static constexpr int kRegularUpdatesTimerInterval = 30 * 1000; + +QGeoPositionInfoSourceAndroid::QGeoPositionInfoSourceAndroid(QObject *parent) : + QGeoPositionInfoSource(parent) +{ + androidClassKeyForUpdate = AndroidPositioning::registerPositionInfoSource(this); + androidClassKeyForSingleRequest = AndroidPositioning::registerPositionInfoSource(this); + + //by default use all methods + setPreferredPositioningMethods(AllPositioningMethods); + + m_requestTimer.setSingleShot(true); + connect(&m_requestTimer, &QTimer::timeout, this, + &QGeoPositionInfoSourceAndroid::requestTimeout); + + m_regularUpdatesTimer.setSingleShot(false); + connect(&m_regularUpdatesTimer, &QTimer::timeout, this, + &QGeoPositionInfoSourceAndroid::regularUpdatesTimeout); +} + +QGeoPositionInfoSourceAndroid::~QGeoPositionInfoSourceAndroid() +{ + stopUpdates(); + + if (m_requestTimer.isActive()) { + m_requestTimer.stop(); + AndroidPositioning::stopUpdates(androidClassKeyForSingleRequest); + } + + AndroidPositioning::unregisterPositionInfoSource(androidClassKeyForUpdate); + AndroidPositioning::unregisterPositionInfoSource(androidClassKeyForSingleRequest); +} + +void QGeoPositionInfoSourceAndroid::setUpdateInterval(int msec) +{ + int previousInterval = updateInterval(); + msec = (((msec > 0) && (msec < minimumUpdateInterval())) || msec < 0)? minimumUpdateInterval() : msec; + + if (msec == previousInterval) + return; + + QGeoPositionInfoSource::setUpdateInterval(msec); + + if (updatesRunning) + reconfigureRunningSystem(); +} + +QGeoPositionInfo QGeoPositionInfoSourceAndroid::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const +{ + return AndroidPositioning::lastKnownPosition(fromSatellitePositioningMethodsOnly); +} + +QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceAndroid::supportedPositioningMethods() const +{ + return AndroidPositioning::availableProviders(); +} + +void QGeoPositionInfoSourceAndroid::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods) +{ + PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods(); + QGeoPositionInfoSource::setPreferredPositioningMethods(methods); + if (previousPreferredPositioningMethods == preferredPositioningMethods()) + return; + + if (updatesRunning) + reconfigureRunningSystem(); +} + +int QGeoPositionInfoSourceAndroid::minimumUpdateInterval() const +{ + return 50; +} + +QGeoPositionInfoSource::Error QGeoPositionInfoSourceAndroid::error() const +{ + return m_error; +} + +void QGeoPositionInfoSourceAndroid::setError(Error error) +{ + m_error = error; + if (error != QGeoPositionInfoSource::NoError) + emit QGeoPositionInfoSource::errorOccurred(m_error); +} + +void QGeoPositionInfoSourceAndroid::startUpdates() +{ + if (updatesRunning) + return; + + m_error = QGeoPositionInfoSource::NoError; + + if (preferredPositioningMethods() == 0) { + setError(UnknownSourceError); + return; + } + + updatesRunning = true; + // Start calculating updates from now. + m_lastUpdateTime = QDateTime::currentMSecsSinceEpoch(); + m_regularUpdatesErrorRaised = false; + QGeoPositionInfoSource::Error error = AndroidPositioning::startUpdates(androidClassKeyForUpdate); + if (error != QGeoPositionInfoSource::NoError) { + updatesRunning = false; + setError(error); + } else { + m_regularUpdatesTimer.start(kRegularUpdatesTimerInterval); + } +} + +void QGeoPositionInfoSourceAndroid::stopUpdates() +{ + if (!updatesRunning) + return; + + updatesRunning = false; + m_regularUpdatesTimer.stop(); + AndroidPositioning::stopUpdates(androidClassKeyForUpdate); +} + +void QGeoPositionInfoSourceAndroid::requestUpdate(int timeout) +{ + if (m_requestTimer.isActive()) + return; + + m_error = QGeoPositionInfoSource::NoError; + + if (timeout != 0 && timeout < minimumUpdateInterval()) { + setError(QGeoPositionInfoSource::UpdateTimeoutError); + return; + } + + if (timeout == 0) + timeout = kUpdateFromColdStart; + + m_requestTimer.start(timeout); + + // if updates already running with interval equal to timeout + // then we wait for next update coming through + // assume that a single update will not be quicker than regular updates anyway + if (updatesRunning && updateInterval() <= timeout) + return; + + QGeoPositionInfoSource::Error error = AndroidPositioning::requestUpdate(androidClassKeyForSingleRequest); + if (error != QGeoPositionInfoSource::NoError) { + m_requestTimer.stop(); + setError(error); + } +} + +void QGeoPositionInfoSourceAndroid::processPositionUpdate(const QGeoPositionInfo &pInfo) +{ + //single update request and served as part of regular update + if (m_requestTimer.isActive()) + m_requestTimer.stop(); + + m_lastUpdateTime = QDateTime::currentMSecsSinceEpoch(); + m_regularUpdatesErrorRaised = false; + + emit positionUpdated(pInfo); +} + +// Might still be called multiple times (once for each provider) +void QGeoPositionInfoSourceAndroid::processSinglePositionUpdate(const QGeoPositionInfo &pInfo) +{ + //timeout but we received a late update -> ignore + if (!m_requestTimer.isActive()) + return; + + queuedSingleUpdates.append(pInfo); +} + +void QGeoPositionInfoSourceAndroid::locationProviderDisabled() +{ + if (updatesRunning && !m_regularUpdatesErrorRaised) { + m_regularUpdatesErrorRaised = true; + setError(QGeoPositionInfoSource::UpdateTimeoutError); + } + + setError(QGeoPositionInfoSource::ClosedError); +} + +void QGeoPositionInfoSourceAndroid::locationProvidersChanged() +{ + emit supportedPositioningMethodsChanged(); +} + +void QGeoPositionInfoSourceAndroid::requestTimeout() +{ + AndroidPositioning::stopUpdates(androidClassKeyForSingleRequest); + //no queued update to process -> timeout + + if (queuedSingleUpdates.isEmpty()) { + setError(QGeoPositionInfoSource::UpdateTimeoutError); + return; + } + + //pick best + QGeoPositionInfo best = queuedSingleUpdates[0]; + for (qsizetype i = 1; i < queuedSingleUpdates.size(); ++i) { + const QGeoPositionInfo info = queuedSingleUpdates[i]; + + //anything newer by 20s is always better + const qint64 timeDelta = best.timestamp().secsTo(info.timestamp()); + if (abs(timeDelta) > 20) { + if (timeDelta > 0) + best = info; + continue; + } + + //compare accuracy + if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) && + best.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) + { + best = info.attribute(QGeoPositionInfo::HorizontalAccuracy) < + best.attribute(QGeoPositionInfo::HorizontalAccuracy) ? info : best; + continue; + } + + //prefer info with accuracy information + if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) + best = info; + } + + queuedSingleUpdates.clear(); + emit positionUpdated(best); +} + +void QGeoPositionInfoSourceAndroid::regularUpdatesTimeout() +{ + if (!m_regularUpdatesErrorRaised) { + const auto now = QDateTime::currentMSecsSinceEpoch(); + if ((now - m_lastUpdateTime) > (updateInterval() + kUpdateFromColdStart)) { + m_regularUpdatesErrorRaised = true; + setError(QGeoPositionInfoSource::UpdateTimeoutError); + } + } +} + +/* + Updates the system assuming that updateInterval + and/or preferredPositioningMethod have changed. + */ +void QGeoPositionInfoSourceAndroid::reconfigureRunningSystem() +{ + if (!updatesRunning) + return; + + stopUpdates(); + startUpdates(); +} diff --git a/src/plugins/position/android/src/qgeopositioninfosource_android_p.h b/src/plugins/position/android/src/qgeopositioninfosource_android_p.h new file mode 100644 index 0000000..76a5121 --- /dev/null +++ b/src/plugins/position/android/src/qgeopositioninfosource_android_p.h @@ -0,0 +1,66 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCE_ANDROID_P_H +#define QGEOPOSITIONINFOSOURCE_ANDROID_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 +#include + +class QGeoPositionInfoSourceAndroid : public QGeoPositionInfoSource +{ + Q_OBJECT +public: + QGeoPositionInfoSourceAndroid(QObject *parent = 0); + ~QGeoPositionInfoSourceAndroid(); + + // From QGeoPositionInfoSource + void setUpdateInterval(int msec) override; + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override; + PositioningMethods supportedPositioningMethods() const override; + void setPreferredPositioningMethods(PositioningMethods methods) override; + int minimumUpdateInterval() const override; + Error error() const override; + +public Q_SLOTS: + virtual void startUpdates() override; + virtual void stopUpdates() override; + + virtual void requestUpdate(int timeout = 0) override; + + void processPositionUpdate(const QGeoPositionInfo& pInfo); + void processSinglePositionUpdate(const QGeoPositionInfo& pInfo); + + void locationProviderDisabled(); + void locationProvidersChanged(); +private Q_SLOTS: + void requestTimeout(); + void regularUpdatesTimeout(); + +private: + void reconfigureRunningSystem(); + void setError(Error error); + + bool updatesRunning = false; + int androidClassKeyForUpdate; + int androidClassKeyForSingleRequest; + QList queuedSingleUpdates; + Error m_error = NoError; + QTimer m_requestTimer; + QTimer m_regularUpdatesTimer; + qint64 m_lastUpdateTime = 0; + bool m_regularUpdatesErrorRaised = false; +}; + +#endif // QGEOPOSITIONINFOSOURCE_ANDROID_P_H diff --git a/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp b/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp new file mode 100644 index 0000000..edc6137 --- /dev/null +++ b/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp @@ -0,0 +1,186 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include + +#include "qgeosatelliteinfosource_android_p.h" +#include "jnipositioning.h" + +Q_DECLARE_METATYPE(QList) + +#define UPDATE_FROM_COLD_START 2*60*1000 + +QGeoSatelliteInfoSourceAndroid::QGeoSatelliteInfoSourceAndroid(QObject *parent) : + QGeoSatelliteInfoSource(parent), m_error(NoError), updatesRunning(false) +{ + qRegisterMetaType< QGeoSatelliteInfo >(); + qRegisterMetaType< QList >(); + androidClassKeyForUpdate = AndroidPositioning::registerPositionInfoSource(this); + androidClassKeyForSingleRequest = AndroidPositioning::registerPositionInfoSource(this); + + requestTimer.setSingleShot(true); + QObject::connect(&requestTimer, SIGNAL(timeout()), + this, SLOT(requestTimeout())); +} + +QGeoSatelliteInfoSourceAndroid::~QGeoSatelliteInfoSourceAndroid() +{ + stopUpdates(); + + if (requestTimer.isActive()) { + requestTimer.stop(); + AndroidPositioning::stopUpdates(androidClassKeyForSingleRequest); + } + + AndroidPositioning::unregisterPositionInfoSource(androidClassKeyForUpdate); + AndroidPositioning::unregisterPositionInfoSource(androidClassKeyForSingleRequest); +} + + +void QGeoSatelliteInfoSourceAndroid::setUpdateInterval(int msec) +{ + int previousInterval = updateInterval(); + msec = (((msec > 0) && (msec < minimumUpdateInterval())) || msec < 0)? minimumUpdateInterval() : msec; + + if (msec == previousInterval) + return; + + QGeoSatelliteInfoSource::setUpdateInterval(msec); + + if (updatesRunning) + reconfigureRunningSystem(); +} + +int QGeoSatelliteInfoSourceAndroid::minimumUpdateInterval() const +{ + return 50; +} + +QGeoSatelliteInfoSource::Error QGeoSatelliteInfoSourceAndroid::error() const +{ + return m_error; +} + +void QGeoSatelliteInfoSourceAndroid::startUpdates() +{ + if (updatesRunning) + return; + + updatesRunning = true; + + m_error = QGeoSatelliteInfoSource::NoError; + + QGeoSatelliteInfoSource::Error error = AndroidPositioning::startSatelliteUpdates( + androidClassKeyForUpdate, false, updateInterval()); + if (error != QGeoSatelliteInfoSource::NoError) { + updatesRunning = false; + setError(error); + } +} + +void QGeoSatelliteInfoSourceAndroid::stopUpdates() +{ + if (!updatesRunning) + return; + + updatesRunning = false; + AndroidPositioning::stopUpdates(androidClassKeyForUpdate); +} + +void QGeoSatelliteInfoSourceAndroid::requestUpdate(int timeout) +{ + if (requestTimer.isActive()) + return; + + m_error = QGeoSatelliteInfoSource::NoError; + + if (timeout != 0 && timeout < minimumUpdateInterval()) { + setError(QGeoSatelliteInfoSource::UpdateTimeoutError); + return; + } + + if (timeout == 0) + timeout = UPDATE_FROM_COLD_START; + + requestTimer.start(timeout); + + // if updates already running with interval equal or less then timeout + // then we wait for next update coming through + // assume that a single update will not be quicker than regular updates anyway + if (updatesRunning && updateInterval() <= timeout) + return; + + QGeoSatelliteInfoSource::Error error = AndroidPositioning::startSatelliteUpdates( + androidClassKeyForSingleRequest, true, timeout); + if (error != QGeoSatelliteInfoSource::NoError) { + requestTimer.stop(); + setError(error); + } +} + +void QGeoSatelliteInfoSourceAndroid::processSatelliteUpdateInView(const QList &satsInView, bool isSingleUpdate) +{ + if (!isSingleUpdate) { + //if requested while regular updates were running + if (requestTimer.isActive()) + requestTimer.stop(); + emit QGeoSatelliteInfoSource::satellitesInViewUpdated(satsInView); + return; + } + + m_satsInView = satsInView; +} + +void QGeoSatelliteInfoSourceAndroid::processSatelliteUpdateInUse(const QList &satsInUse, bool isSingleUpdate) +{ + if (!isSingleUpdate) { + //if requested while regular updates were running + if (requestTimer.isActive()) + requestTimer.stop(); + emit QGeoSatelliteInfoSource::satellitesInUseUpdated(satsInUse); + return; + } + + m_satsInUse = satsInUse; +} + +void QGeoSatelliteInfoSourceAndroid::requestTimeout() +{ + AndroidPositioning::stopUpdates(androidClassKeyForSingleRequest); + + if (m_satsInView.isEmpty()) { + setError(QGeoSatelliteInfoSource::UpdateTimeoutError); + return; + } + + emit QGeoSatelliteInfoSource::satellitesInViewUpdated(m_satsInView); + emit QGeoSatelliteInfoSource::satellitesInUseUpdated(m_satsInUse); + + m_satsInUse.clear(); + m_satsInView.clear(); +} + +/* + Updates the system assuming that updateInterval + and/or preferredPositioningMethod have changed. + */ +void QGeoSatelliteInfoSourceAndroid::reconfigureRunningSystem() +{ + if (!updatesRunning) + return; + + stopUpdates(); + startUpdates(); +} + +void QGeoSatelliteInfoSourceAndroid::setError(QGeoSatelliteInfoSource::Error error) +{ + m_error = error; + if (m_error != QGeoSatelliteInfoSource::NoError) + emit QGeoSatelliteInfoSource::errorOccurred(m_error); +} + +void QGeoSatelliteInfoSourceAndroid::locationProviderDisabled() +{ + setError(QGeoSatelliteInfoSource::ClosedError); +} diff --git a/src/plugins/position/android/src/qgeosatelliteinfosource_android_p.h b/src/plugins/position/android/src/qgeosatelliteinfosource_android_p.h new file mode 100644 index 0000000..404136d --- /dev/null +++ b/src/plugins/position/android/src/qgeosatelliteinfosource_android_p.h @@ -0,0 +1,62 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#ifndef QGEOSATELLITEINFOSOURCEANDROID_H +#define QGEOSATELLITEINFOSOURCEANDROID_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 +#include + +class QGeoSatelliteInfoSourceAndroid : public QGeoSatelliteInfoSource +{ + Q_OBJECT +public: + explicit QGeoSatelliteInfoSourceAndroid(QObject *parent = 0); + ~QGeoSatelliteInfoSourceAndroid(); + + //From QGeoSatelliteInfoSource + void setUpdateInterval(int msec) override; + int minimumUpdateInterval() const override; + + Error error() const override; + +public Q_SLOTS: + void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 0) override; + + void processSatelliteUpdateInView(const QList &satsInView, bool isSingleUpdate); + void processSatelliteUpdateInUse(const QList &satsInUse, bool isSingleUpdate); + + void locationProviderDisabled(); +private Q_SLOTS: + void requestTimeout(); + +private: + void reconfigureRunningSystem(); + void setError(QGeoSatelliteInfoSource::Error error); + + Error m_error; + int androidClassKeyForUpdate; + int androidClassKeyForSingleRequest; + bool updatesRunning; + + QTimer requestTimer; + QList m_satsInUse; + QList m_satsInView; + +}; + +#endif // QGEOSATELLITEINFOSOURCEANDROID_H diff --git a/src/plugins/position/corelocation/CMakeLists.txt b/src/plugins/position/corelocation/CMakeLists.txt new file mode 100644 index 0000000..0126aa6 --- /dev/null +++ b/src/plugins/position/corelocation/CMakeLists.txt @@ -0,0 +1,36 @@ +# Generated from corelocation.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryCL Plugin: +##################################################################### + +qt_internal_add_plugin(QGeoPositionInfoSourceFactoryCLPlugin + OUTPUT_NAME qtposition_cl + CLASS_NAME QGeoPositionInfoSourceFactoryCL + PLUGIN_TYPE position + SOURCES + qgeopositioninfosource_cl.mm qgeopositioninfosource_cl_p.h + qgeopositioninfosourcefactory_cl.h qgeopositioninfosourcefactory_cl.mm + LIBRARIES + ${FWCoreLocation} + ${FWFoundation} + Qt::Core + Qt::CorePrivate + Qt::Positioning +) + +# special case begin +set_target_properties(QGeoPositionInfoSourceFactoryCLPlugin + PROPERTIES + DISABLE_PRECOMPILE_HEADERS ON +) +# special case end + +#### Keys ignored in scope 1:.:.:corelocation.pro:: +# OTHER_FILES = "plugin.json" + +## Scopes: +##################################################################### + +#### Keys ignored in scope 2:.:.:corelocation.pro:NOT APPLE: +# DISTFILES = "$$OBJECTIVE_SOURCES" diff --git a/src/plugins/position/corelocation/plugin.json b/src/plugins/position/corelocation/plugin.json new file mode 100644 index 0000000..58e3acd --- /dev/null +++ b/src/plugins/position/corelocation/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["corelocation"], + "Provider": "corelocation", + "Position": true, + "Satellite": false, + "Monitor" : false, + "Priority": 1000, + "Testable": false +} diff --git a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm new file mode 100644 index 0000000..c67989a --- /dev/null +++ b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm @@ -0,0 +1,294 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include +#include +#include +#include + +#include "qgeopositioninfosource_cl_p.h" + +#define MINIMUM_UPDATE_INTERVAL 1000 + +@interface PositionLocationDelegate : NSObject +@end + +@implementation PositionLocationDelegate +{ + QGeoPositionInfoSourceCL *m_positionInfoSource; +} + +- (instancetype)initWithInfoSource:(QGeoPositionInfoSourceCL*) positionInfoSource +{ + if ((self = [self init])) { + m_positionInfoSource = positionInfoSource; + } + return self; +} +- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status +{ + Q_UNUSED(manager); + m_positionInfoSource->changeAuthorizationStatus(status); +} + +- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation +{ + Q_UNUSED(manager); + Q_UNUSED(oldLocation); + + // Convert location timestamp to QDateTime + NSTimeInterval locationTimeStamp = [newLocation.timestamp timeIntervalSince1970]; + const QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(qRound64(locationTimeStamp * 1000), Qt::UTC); + + // Construct position info from location data + QGeoPositionInfo location(QGeoCoordinate(newLocation.coordinate.latitude, + newLocation.coordinate.longitude, + newLocation.altitude), + timeStamp); + if (newLocation.horizontalAccuracy >= 0) + location.setAttribute(QGeoPositionInfo::HorizontalAccuracy, newLocation.horizontalAccuracy); + if (newLocation.verticalAccuracy >= 0) + location.setAttribute(QGeoPositionInfo::VerticalAccuracy, newLocation.verticalAccuracy); +#ifndef Q_OS_TVOS + if (newLocation.course >= 0) { + location.setAttribute(QGeoPositionInfo::Direction, newLocation.course); + if (__builtin_available(iOS 13.4, watchOS 6.2, macOS 10.15.4, *)) { + if (newLocation.courseAccuracy >= 0) { + location.setAttribute(QGeoPositionInfo::DirectionAccuracy, + newLocation.courseAccuracy); + } + } + } + if (newLocation.speed >= 0) + location.setAttribute(QGeoPositionInfo::GroundSpeed, newLocation.speed); +#endif + + m_positionInfoSource->locationDataAvailable(location); +} + +- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error +{ + Q_UNUSED(manager); + m_positionInfoSource->setError(QGeoPositionInfoSource::AccessError); + + qWarning() << QString::fromNSString([error localizedDescription]); + + if ([error code] == 0 + && QString::fromNSString([error domain]) == QStringLiteral("kCLErrorDomain")) + qWarning() << "(is Wi-Fi turned on?)"; +} +@end + +QT_BEGIN_NAMESPACE + +QGeoPositionInfoSourceCL::QGeoPositionInfoSourceCL(QObject *parent) + : QGeoPositionInfoSource(parent), + m_locationManager(0), + m_updatesWanted(false), + m_updateTimer(0), + m_updateTimeout(0), + m_positionError(QGeoPositionInfoSource::NoError) +{ +} + +QGeoPositionInfoSourceCL::~QGeoPositionInfoSourceCL() +{ + stopUpdates(); + [m_locationManager release]; +} + +void QGeoPositionInfoSourceCL::setUpdateInterval(int msec) +{ + // If msec is 0 we send updates as data becomes available, otherwise we force msec to be equal + // to or larger than the minimum update interval. + if (msec != 0 && msec < minimumUpdateInterval()) + msec = minimumUpdateInterval(); + + QGeoPositionInfoSource::setUpdateInterval(msec); + + // Must timeout if update takes longer than specified interval + m_updateTimeout = msec; + if (m_updatesWanted) + setTimeoutInterval(m_updateTimeout); +} + +bool QGeoPositionInfoSourceCL::enableLocationManager() +{ + if (!m_locationManager) { + m_locationManager = [[CLLocationManager alloc] init]; + +#if defined(Q_OS_IOS) || defined(Q_OS_WATCHOS) + if (__builtin_available(watchOS 4.0, *)) { + NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; + if (id value = [infoDict objectForKey:@"UIBackgroundModes"]) { + if ([value isKindOfClass:[NSArray class]]) { + NSArray *modes = static_cast(value); + for (id mode in modes) { + if ([@"location" isEqualToString:mode]) { + m_locationManager.allowsBackgroundLocationUpdates = YES; + break; + } + } + } + } + } +#endif + + m_locationManager.desiredAccuracy = kCLLocationAccuracyBest; + m_locationManager.delegate = [[PositionLocationDelegate alloc] initWithInfoSource:this]; + + // -requestAlwaysAuthorization is available on iOS (>= 8.0) and watchOS (>= 2.0). + // This method requires both NSLocationAlwaysAndWhenInUseUsageDescription and + // NSLocationWhenInUseUsageDescription entries present in Info.plist (otherwise, + // while probably a noop, the call generates a warning). + // -requestWhenInUseAuthorization only requires NSLocationWhenInUseUsageDescription + // entry in Info.plist (available on iOS (>= 8.0), tvOS (>= 9.0) and watchOS (>= 2.0). + } + +#ifndef Q_OS_MACOS + NSDictionary *infoDict = NSBundle.mainBundle.infoDictionary; + const bool hasAlwaysUseUsage = !![infoDict objectForKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"]; + const bool hasWhenInUseUsage = !![infoDict objectForKey:@"NSLocationWhenInUseUsageDescription"]; +#ifndef Q_OS_TVOS + if (hasAlwaysUseUsage && hasWhenInUseUsage) + [m_locationManager requestAlwaysAuthorization]; + else +#endif // !Q_OS_TVOS + if (hasWhenInUseUsage) + [m_locationManager requestWhenInUseAuthorization]; +#endif // !Q_OS_MACOS + + return (m_locationManager != nullptr); +} + +void QGeoPositionInfoSourceCL::setTimeoutInterval(int msec) +{ + // Start timeout timer + if (m_updateTimer) killTimer(m_updateTimer); + if (msec > 0) m_updateTimer = startTimer(msec); + else m_updateTimer = 0; +} + +void QGeoPositionInfoSourceCL::startUpdates() +{ + m_positionError = QGeoPositionInfoSource::NoError; + m_updatesWanted = true; + if (enableLocationManager()) { +#ifdef Q_OS_TVOS + [m_locationManager requestLocation]; // service will run long enough for one location update +#else + [m_locationManager startUpdatingLocation]; +#endif + setTimeoutInterval(m_updateTimeout); + } else { + setError(QGeoPositionInfoSource::AccessError); + } +} + +void QGeoPositionInfoSourceCL::stopUpdates() +{ + if (m_locationManager) { + [m_locationManager stopUpdatingLocation]; + m_updatesWanted = false; + + // Stop timeout timer + setTimeoutInterval(0); + } else { + setError(QGeoPositionInfoSource::AccessError); + } +} + +void QGeoPositionInfoSourceCL::requestUpdate(int timeout) +{ + // Get a single update within timeframe + m_positionError = QGeoPositionInfoSource::NoError; + if (timeout < minimumUpdateInterval() && timeout != 0) + setError(QGeoPositionInfoSource::UpdateTimeoutError); + else if (enableLocationManager()) { + // This will force LM to generate a new update + [m_locationManager stopUpdatingLocation]; +#ifdef Q_OS_TVOS + [m_locationManager requestLocation]; // service will run long enough for one location update +#else + [m_locationManager startUpdatingLocation]; +#endif + + setTimeoutInterval(timeout); + } else { + setError(QGeoPositionInfoSource::AccessError); + } +} + +void QGeoPositionInfoSourceCL::changeAuthorizationStatus(CLAuthorizationStatus status) +{ + if (status == kCLAuthorizationStatusAuthorizedAlways +#ifndef Q_OS_MACOS + || status == kCLAuthorizationStatusAuthorizedWhenInUse +#endif + ) { + if (m_updatesWanted) + startUpdates(); + } +} + +void QGeoPositionInfoSourceCL::timerEvent( QTimerEvent * event ) +{ + // Update timed out? + if (event->timerId() == m_updateTimer) { + setError(QGeoPositionInfoSource::UpdateTimeoutError); + + // Only timeout once since last data + setTimeoutInterval(0); + + // Started for single update? + if (!m_updatesWanted) + stopUpdates(); + } +} + +QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceCL::supportedPositioningMethods() const +{ + // CoreLocation doesn't say which positioning method(s) it used + return QGeoPositionInfoSource::AllPositioningMethods; +} + +int QGeoPositionInfoSourceCL::minimumUpdateInterval() const +{ + return MINIMUM_UPDATE_INTERVAL; +} + +void QGeoPositionInfoSourceCL::locationDataAvailable(QGeoPositionInfo location) +{ + // Signal position data available + m_lastUpdate = location; + emit positionUpdated(location); + + // Started for single update? + if (!m_updatesWanted) + stopUpdates(); + // ...otherwise restart timeout timer + else setTimeoutInterval(m_updateTimeout); +} + +QGeoPositionInfo QGeoPositionInfoSourceCL::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const +{ + Q_UNUSED(fromSatellitePositioningMethodsOnly); + + return m_lastUpdate; +} + +QGeoPositionInfoSource::Error QGeoPositionInfoSourceCL::error() const +{ + return m_positionError; +} + +void QGeoPositionInfoSourceCL::setError(QGeoPositionInfoSource::Error positionError) +{ + m_positionError = positionError; + if (m_positionError != QGeoPositionInfoSource::NoError) + emit QGeoPositionInfoSource::errorOccurred(positionError); +} + +QT_END_NAMESPACE + +#include "moc_qgeopositioninfosource_cl_p.cpp" diff --git a/src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h b/src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h new file mode 100644 index 0000000..f49951d --- /dev/null +++ b/src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h @@ -0,0 +1,71 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCECL_H +#define QGEOPOSITIONINFOSOURCECL_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. +// + +#import + +#include "qgeopositioninfosource.h" +#include "qgeopositioninfo.h" + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfoSourceCL : public QGeoPositionInfoSource +{ + Q_OBJECT +public: + QGeoPositionInfoSourceCL(QObject *parent = 0); + ~QGeoPositionInfoSourceCL(); + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override; + PositioningMethods supportedPositioningMethods() const override; + + void setUpdateInterval(int msec) override; + int minimumUpdateInterval() const override; + Error error() const override; + + void locationDataAvailable(QGeoPositionInfo location); + void setError(QGeoPositionInfoSource::Error positionError); + void changeAuthorizationStatus(CLAuthorizationStatus status); + +private: + bool enableLocationManager(); + void setTimeoutInterval(int msec); + +public Q_SLOTS: + void startUpdates() override; + void stopUpdates() override; + + void requestUpdate(int timeout = 0) override; + +protected: + void timerEvent(QTimerEvent *event) override; + +private: + Q_DISABLE_COPY(QGeoPositionInfoSourceCL); + CLLocationManager *m_locationManager; + bool m_updatesWanted; + + QGeoPositionInfo m_lastUpdate; + + int m_updateTimer; + int m_updateTimeout; + + QGeoPositionInfoSource::Error m_positionError; +}; + +QT_END_NAMESPACE + +#endif // QGEOPOSITIONINFOSOURCECL_H diff --git a/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.h b/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.h new file mode 100644 index 0000000..fa97977 --- /dev/null +++ b/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.h @@ -0,0 +1,22 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCEFACTORY_CL_H +#define QGEOPOSITIONINFOSOURCEFACTORY_CL_H + +#include +#include + +class QGeoPositionInfoSourceFactoryCL : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +#endif // QGEOPOSITIONINFOSOURCEFACTORY_CL_H diff --git a/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm b/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm new file mode 100644 index 0000000..0979422 --- /dev/null +++ b/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm @@ -0,0 +1,25 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosource_cl_p.h" +#include "qgeopositioninfosourcefactory_cl.h" + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryCL::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parameters) + return new QGeoPositionInfoSourceCL(parent); +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryCL::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryCL::areaMonitor(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} diff --git a/src/plugins/position/geoclue2/CMakeLists.txt b/src/plugins/position/geoclue2/CMakeLists.txt new file mode 100644 index 0000000..c573ee1 --- /dev/null +++ b/src/plugins/position/geoclue2/CMakeLists.txt @@ -0,0 +1,31 @@ +# Generated from geoclue2.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryGeoclue2 Plugin: +##################################################################### + +qt_internal_add_plugin(QGeoPositionInfoSourceFactoryGeoclue2Plugin + OUTPUT_NAME qtposition_geoclue2 + CLASS_NAME QGeoPositionInfoSourceFactoryGeoclue2 + PLUGIN_TYPE position + SOURCES + geocluetypes.cpp geocluetypes.h + qgeopositioninfosource_geoclue2.cpp qgeopositioninfosource_geoclue2_p.h + qgeopositioninfosourcefactory_geoclue2.cpp qgeopositioninfosourcefactory_geoclue2.h + DBUS_INTERFACE_SOURCES + org.freedesktop.GeoClue2.Client.xml + org.freedesktop.GeoClue2.Location.xml + org.freedesktop.GeoClue2.Manager.xml + DBUS_INTERFACE_FLAGS + -N -i geocluetypes.h # special case + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_BINARY_DIR} + core.location.includes + LIBRARIES + Qt::Core + Qt::DBus + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:geoclue2.pro:: +# OTHER_FILES = "plugin.json" diff --git a/src/plugins/position/geoclue2/geocluetypes.cpp b/src/plugins/position/geoclue2/geocluetypes.cpp new file mode 100644 index 0000000..b58842f --- /dev/null +++ b/src/plugins/position/geoclue2/geocluetypes.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2018 Denis Shienkov +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "geocluetypes.h" + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(Timestamp) + +QDBusArgument &operator<<(QDBusArgument &arg, const Timestamp &ts) +{ + arg.beginStructure(); + arg << ts.m_seconds; + arg << ts.m_microseconds; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, Timestamp &ts) +{ + arg.beginStructure(); + arg >> ts.m_seconds; + arg >> ts.m_microseconds; + arg.endStructure(); + return arg; +} + +QT_END_NAMESPACE diff --git a/src/plugins/position/geoclue2/geocluetypes.h b/src/plugins/position/geoclue2/geocluetypes.h new file mode 100644 index 0000000..374601d --- /dev/null +++ b/src/plugins/position/geoclue2/geocluetypes.h @@ -0,0 +1,27 @@ +// Copyright (C) 2018 Denis Shienkov +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef GEOCLUETYPES_H +#define GEOCLUETYPES_H + +#include + +class Timestamp +{ +public: + quint64 m_seconds = 0; + quint64 m_microseconds = 0; +}; + +QT_BEGIN_NAMESPACE + +Q_DECLARE_TYPEINFO(Timestamp, Q_RELOCATABLE_TYPE); + +QDBusArgument &operator<<(QDBusArgument &arg, const Timestamp &ts); +const QDBusArgument &operator>>(const QDBusArgument &arg, Timestamp &ts); + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(Timestamp, /* not exported */) + +#endif // GEOCLUETYPES_H diff --git a/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Client.xml b/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Client.xml new file mode 100644 index 0000000..4a9399b --- /dev/null +++ b/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Client.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Location.xml b/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Location.xml new file mode 100644 index 0000000..ebf2ea6 --- /dev/null +++ b/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Location.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Manager.xml b/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Manager.xml new file mode 100644 index 0000000..cf9590f --- /dev/null +++ b/src/plugins/position/geoclue2/org.freedesktop.GeoClue2.Manager.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/plugins/position/geoclue2/plugin.json b/src/plugins/position/geoclue2/plugin.json new file mode 100644 index 0000000..c23d40e --- /dev/null +++ b/src/plugins/position/geoclue2/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["geoclue2"], + "Provider": "geoclue2", + "Position": true, + "Satellite": false, + "Monitor": false, + "Priority": 1000, + "Testable": false +} diff --git a/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp new file mode 100644 index 0000000..737d62d --- /dev/null +++ b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp @@ -0,0 +1,430 @@ +// Copyright (C) 2018 Denis Shienkov +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosource_geoclue2_p.h" + +#include +#include +#include +#include +#include + +// Auto-generated D-Bus files. +#include +#include "moc_client_interface.cpp" // includemocs +#include +#include "moc_location_interface.cpp" // includemocs +#include "moc_manager_interface.cpp" // includemocs + +Q_DECLARE_LOGGING_CATEGORY(lcPositioningGeoclue2) + +QT_BEGIN_NAMESPACE + +namespace { + +// NOTE: Copied from the /usr/include/libgeoclue-2.0/gclue-client.h +enum GClueAccuracyLevel { + GCLUE_ACCURACY_LEVEL_NONE = 0, + GCLUE_ACCURACY_LEVEL_COUNTRY = 1, + GCLUE_ACCURACY_LEVEL_CITY = 4, + GCLUE_ACCURACY_LEVEL_NEIGHBORHOOD = 5, + GCLUE_ACCURACY_LEVEL_STREET = 6, + GCLUE_ACCURACY_LEVEL_EXACT = 8 +}; + +const char GEOCLUE2_SERVICE_NAME[] = "org.freedesktop.GeoClue2"; +const int MINIMUM_UPDATE_INTERVAL = 1000; +const int UPDATE_TIMEOUT_COLD_START = 120000; +static const auto desktopIdParameter = "desktopId"; + +static QString lastPositionFilePath() +{ + return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + + QStringLiteral("/qtposition-geoclue2"); +} + +} // namespace + +QGeoPositionInfoSourceGeoclue2::QGeoPositionInfoSourceGeoclue2(const QVariantMap ¶meters, + QObject *parent) + : QGeoPositionInfoSource(parent) + , m_requestTimer(new QTimer(this)) + , m_manager(QLatin1String(GEOCLUE2_SERVICE_NAME), + QStringLiteral("/org/freedesktop/GeoClue2/Manager"), + QDBusConnection::systemBus(), + this) +{ + parseParameters(parameters); + + qDBusRegisterMetaType(); + + restoreLastPosition(); + + m_requestTimer->setSingleShot(true); + connect(m_requestTimer, &QTimer::timeout, + this, &QGeoPositionInfoSourceGeoclue2::requestUpdateTimeout); +} + +QGeoPositionInfoSourceGeoclue2::~QGeoPositionInfoSourceGeoclue2() +{ + saveLastPosition(); +} + +void QGeoPositionInfoSourceGeoclue2::setUpdateInterval(int msec) +{ + QGeoPositionInfoSource::setUpdateInterval(msec); + configureClient(); +} + +QGeoPositionInfo QGeoPositionInfoSourceGeoclue2::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const +{ + if (fromSatellitePositioningMethodsOnly && !m_lastPositionFromSatellite) + return QGeoPositionInfo(); + return m_lastPosition; +} + +QGeoPositionInfoSourceGeoclue2::PositioningMethods QGeoPositionInfoSourceGeoclue2::supportedPositioningMethods() const +{ + bool ok; + const auto accuracy = m_manager.property("AvailableAccuracyLevel").toUInt(&ok); + if (!ok) { + const_cast(this)->setError(AccessError); + return NoPositioningMethods; + } + + switch (accuracy) { + case GCLUE_ACCURACY_LEVEL_COUNTRY: + case GCLUE_ACCURACY_LEVEL_CITY: + case GCLUE_ACCURACY_LEVEL_NEIGHBORHOOD: + case GCLUE_ACCURACY_LEVEL_STREET: + return NonSatellitePositioningMethods; + case GCLUE_ACCURACY_LEVEL_EXACT: + return AllPositioningMethods; + case GCLUE_ACCURACY_LEVEL_NONE: + default: + return NoPositioningMethods; + } +} + +void QGeoPositionInfoSourceGeoclue2::setPreferredPositioningMethods(PositioningMethods methods) +{ + QGeoPositionInfoSource::setPreferredPositioningMethods(methods); + configureClient(); +} + +int QGeoPositionInfoSourceGeoclue2::minimumUpdateInterval() const +{ + return MINIMUM_UPDATE_INTERVAL; +} + +QGeoPositionInfoSource::Error QGeoPositionInfoSourceGeoclue2::error() const +{ + return m_error; +} + +void QGeoPositionInfoSourceGeoclue2::startUpdates() +{ + if (m_running) { + qCWarning(lcPositioningGeoclue2) << "Already running"; + return; + } + + qCDebug(lcPositioningGeoclue2) << "Starting updates"; + + m_error = QGeoPositionInfoSource::NoError; + + m_running = true; + + startClient(); + + if (m_lastPosition.isValid()) { + QMetaObject::invokeMethod(this, "positionUpdated", Qt::QueuedConnection, + Q_ARG(QGeoPositionInfo, m_lastPosition)); + } +} + +void QGeoPositionInfoSourceGeoclue2::stopUpdates() +{ + if (!m_running) { + qCWarning(lcPositioningGeoclue2) << "Already stopped"; + return; + } + + qCDebug(lcPositioningGeoclue2) << "Stopping updates"; + m_running = false; + + stopClient(); +} + +void QGeoPositionInfoSourceGeoclue2::requestUpdate(int timeout) +{ + if (m_requestTimer->isActive()) { + qCDebug(lcPositioningGeoclue2) << "Request timer was active, ignoring startUpdates"; + return; + } + + m_error = QGeoPositionInfoSource::NoError; + + if (timeout < minimumUpdateInterval() && timeout != 0) { + setError(QGeoPositionInfoSource::UpdateTimeoutError); + return; + } + + m_requestTimer->start(timeout ? timeout : UPDATE_TIMEOUT_COLD_START); + startClient(); +} + +void QGeoPositionInfoSourceGeoclue2::setError(QGeoPositionInfoSource::Error error) +{ + m_error = error; + if (m_error != QGeoPositionInfoSource::NoError) + emit QGeoPositionInfoSource::errorOccurred(m_error); +} + +void QGeoPositionInfoSourceGeoclue2::restoreLastPosition() +{ +#if !defined(QT_NO_DATASTREAM) + const auto filePath = lastPositionFilePath(); + QFile file(filePath); + if (file.open(QIODevice::ReadOnly)) { + QDataStream out(&file); + out >> m_lastPosition; + } +#endif +} + +void QGeoPositionInfoSourceGeoclue2::saveLastPosition() +{ +#if !defined(QT_NO_DATASTREAM) && QT_CONFIG(temporaryfile) + if (!m_lastPosition.isValid()) + return; + + const auto filePath = lastPositionFilePath(); + QSaveFile file(filePath); + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + QDataStream out(&file); + // Only save position and timestamp. + out << QGeoPositionInfo(m_lastPosition.coordinate(), m_lastPosition.timestamp()); + file.commit(); + } +#endif +} + +void QGeoPositionInfoSourceGeoclue2::createClient() +{ + const QDBusPendingReply reply = m_manager.GetClient(); + const auto watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + [this](QDBusPendingCallWatcher *watcher) { + const QScopedPointer + scopedWatcher(watcher); + const QDBusPendingReply reply = *scopedWatcher; + if (reply.isError()) { + const auto error = reply.error(); + qCWarning(lcPositioningGeoclue2) << "Unable to obtain the client patch:" + << error.name() + error.message(); + setError(AccessError); + } else { + const QString clientPath = reply.value().path(); + qCDebug(lcPositioningGeoclue2) << "Client path is:" + << clientPath; + delete m_client; + m_client = new OrgFreedesktopGeoClue2ClientInterface( + QLatin1String(GEOCLUE2_SERVICE_NAME), + clientPath, + QDBusConnection::systemBus(), + this); + if (!m_client->isValid()) { + const auto error = m_client->lastError(); + qCCritical(lcPositioningGeoclue2) << "Unable to create the client object:" + << error.name() << error.message(); + setError(AccessError); + delete m_client; + } else { + connect(m_client.data(), &OrgFreedesktopGeoClue2ClientInterface::LocationUpdated, + this, &QGeoPositionInfoSourceGeoclue2::handleNewLocation); + + if (configureClient()) + startClient(); + } + } + }); +} + +void QGeoPositionInfoSourceGeoclue2::startClient() +{ + // only start the client if someone asked for it already + if (!m_running && !m_requestTimer->isActive()) + return; + + if (!m_client) { + createClient(); + return; + } + + const QDBusPendingReply<> reply = m_client->Start(); + const auto watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + [this](QDBusPendingCallWatcher *watcher) { + const QScopedPointer + scopedWatcher(watcher); + const QDBusPendingReply<> reply = *scopedWatcher; + if (reply.isError()) { + const auto error = reply.error(); + qCCritical(lcPositioningGeoclue2) << "Unable to start the client:" + << error.name() << error.message(); + setError(AccessError); + delete m_client; + } else { + qCDebug(lcPositioningGeoclue2) << "Client successfully started"; + + const QDBusObjectPath location = m_client->location(); + const QString path = location.path(); + if (path.isEmpty() || path == QLatin1String("/")) + return; + + handleNewLocation({}, location); + } + }); +} + +void QGeoPositionInfoSourceGeoclue2::stopClient() +{ + // Only stop client if updates are no longer wanted. + if (m_requestTimer->isActive() || m_running || !m_client) + return; + + const QDBusPendingReply<> reply = m_client->Stop(); + const auto watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + [this](QDBusPendingCallWatcher *watcher) { + const QScopedPointer + scopedWatcher(watcher); + const QDBusPendingReply<> reply = *scopedWatcher; + if (reply.isError()) { + const auto error = reply.error(); + qCCritical(lcPositioningGeoclue2) << "Unable to stop the client:" + << error.name() << error.message(); + setError(AccessError); + } else { + qCDebug(lcPositioningGeoclue2) << "Client successfully stopped"; + } + delete m_client; + }); +} + +bool QGeoPositionInfoSourceGeoclue2::configureClient() +{ + if (!m_client) + return false; + + if (m_desktopId.isEmpty()) { + qCCritical(lcPositioningGeoclue2) + << "Unable to configure the client due to the desktop id is not set via" + << desktopIdParameter << "plugin parameter or QCoreApplication::applicationName"; + setError(AccessError); + return false; + } + + m_client->setDesktopId(m_desktopId); + + const auto msecs = updateInterval(); + const uint secs = qMax(uint(msecs), 0u) / 1000u; + m_client->setTimeThreshold(secs); + + const auto methods = preferredPositioningMethods(); + switch (methods) { + case SatellitePositioningMethods: + m_client->setRequestedAccuracyLevel(GCLUE_ACCURACY_LEVEL_EXACT); + break; + case NonSatellitePositioningMethods: + m_client->setRequestedAccuracyLevel(GCLUE_ACCURACY_LEVEL_STREET); + break; + case AllPositioningMethods: + m_client->setRequestedAccuracyLevel(GCLUE_ACCURACY_LEVEL_EXACT); + break; + default: + m_client->setRequestedAccuracyLevel(GCLUE_ACCURACY_LEVEL_NONE); + break; + } + + return true; +} + +void QGeoPositionInfoSourceGeoclue2::requestUpdateTimeout() +{ + qCDebug(lcPositioningGeoclue2) << "Request update timeout occurred"; + + setError(QGeoPositionInfoSource::UpdateTimeoutError); + + stopClient(); +} + +void QGeoPositionInfoSourceGeoclue2::handleNewLocation(const QDBusObjectPath &oldLocation, + const QDBusObjectPath &newLocation) +{ + if (m_requestTimer->isActive()) + m_requestTimer->stop(); + + const auto oldPath = oldLocation.path(); + const auto newPath = newLocation.path(); + qCDebug(lcPositioningGeoclue2) << "Old location object path:" << oldPath; + qCDebug(lcPositioningGeoclue2) << "New location object path:" << newPath; + + OrgFreedesktopGeoClue2LocationInterface location( + QLatin1String(GEOCLUE2_SERVICE_NAME), + newPath, + QDBusConnection::systemBus(), + this); + if (!location.isValid()) { + const auto error = location.lastError(); + qCCritical(lcPositioningGeoclue2) << "Unable to create the location object:" + << error.name() << error.message(); + } else { + QGeoCoordinate coordinate(location.latitude(), + location.longitude()); + const auto altitude = location.altitude(); + if (altitude > std::numeric_limits::lowest()) + coordinate.setAltitude(altitude); + + const Timestamp ts = location.timestamp(); + if (ts.m_seconds == 0 && ts.m_microseconds == 0) { + const auto dt = QDateTime::currentDateTime(); + m_lastPosition = QGeoPositionInfo(coordinate, dt); + } else { + auto dt = QDateTime::fromSecsSinceEpoch(qint64(ts.m_seconds)); + dt = dt.addMSecs(ts.m_microseconds / 1000); + m_lastPosition = QGeoPositionInfo(coordinate, dt); + } + + const auto accuracy = location.accuracy(); + // We assume that an accuracy as 0.0 means that it comes from a sattelite. + m_lastPositionFromSatellite = qFuzzyCompare(accuracy, 0.0); + + m_lastPosition.setAttribute(QGeoPositionInfo::HorizontalAccuracy, accuracy); + const auto speed = location.speed(); + if (speed >= 0.0) + m_lastPosition.setAttribute(QGeoPositionInfo::GroundSpeed, speed); + const auto heading = location.heading(); + if (heading >= 0.0) + m_lastPosition.setAttribute(QGeoPositionInfo::Direction, heading); + + emit positionUpdated(m_lastPosition); + qCDebug(lcPositioningGeoclue2) << "New position:" << m_lastPosition; + } + + stopClient(); +} + +void QGeoPositionInfoSourceGeoclue2::parseParameters(const QVariantMap ¶meters) +{ + if (parameters.contains(desktopIdParameter)) + m_desktopId = parameters.value(desktopIdParameter).toString(); + + if (m_desktopId.isEmpty()) + m_desktopId = QCoreApplication::applicationName(); +} + +QT_END_NAMESPACE + +#include "moc_qgeopositioninfosource_geoclue2_p.cpp" diff --git a/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2_p.h b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2_p.h new file mode 100644 index 0000000..9ba27af --- /dev/null +++ b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2_p.h @@ -0,0 +1,64 @@ +// Copyright (C) 2018 Denis Shienkov +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCE_GEOCLUE2_P_H +#define QGEOPOSITIONINFOSOURCE_GEOCLUE2_P_H + +#include +#include +#include + +class OrgFreedesktopGeoClue2ClientInterface; + +QT_BEGIN_NAMESPACE +class QDBusObjectPath; +class QTimer; + +class QGeoPositionInfoSourceGeoclue2 : public QGeoPositionInfoSource +{ + Q_OBJECT + +public: + explicit QGeoPositionInfoSourceGeoclue2(const QVariantMap ¶meters, + QObject *parent = nullptr); + ~QGeoPositionInfoSourceGeoclue2(); + + // From QGeoPositionInfoSource + void setUpdateInterval(int msec) override; + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override; + PositioningMethods supportedPositioningMethods() const override; + void setPreferredPositioningMethods(PositioningMethods methods) override; + int minimumUpdateInterval() const override; + + Error error() const override; + + void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 5000) override; + +private: + void setError(QGeoPositionInfoSource::Error error); + void restoreLastPosition(); + void saveLastPosition(); + void createClient(); + bool configureClient(); + void startClient(); + void stopClient(); + void requestUpdateTimeout(); + void handleNewLocation(const QDBusObjectPath &oldLocation, + const QDBusObjectPath &newLocation); + void parseParameters(const QVariantMap ¶meters); + + QTimer *m_requestTimer = nullptr; + OrgFreedesktopGeoClue2ManagerInterface m_manager; + QPointer m_client; + bool m_running = false; + bool m_lastPositionFromSatellite = false; + QGeoPositionInfoSource::Error m_error = NoError; + QGeoPositionInfo m_lastPosition; + QString m_desktopId; +}; + +QT_END_NAMESPACE + +#endif // QGEOPOSITIONINFOSOURCE_GEOCLUE2_P_H diff --git a/src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.cpp b/src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.cpp new file mode 100644 index 0000000..0e85b6c --- /dev/null +++ b/src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.cpp @@ -0,0 +1,35 @@ +// Copyright (C) 2018 Denis Shienkov +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosource_geoclue2_p.h" +#include "qgeopositioninfosourcefactory_geoclue2.h" + +#include + +Q_LOGGING_CATEGORY(lcPositioningGeoclue2, "qt.positioning.geoclue2") + +QT_BEGIN_NAMESPACE + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryGeoclue2::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parameters) + return new QGeoPositionInfoSourceGeoclue2(parameters, parent); +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryGeoclue2::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryGeoclue2::areaMonitor(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} + +QT_END_NAMESPACE + +#include "moc_qgeopositioninfosourcefactory_geoclue2.cpp" diff --git a/src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.h b/src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.h new file mode 100644 index 0000000..b403d10 --- /dev/null +++ b/src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.h @@ -0,0 +1,32 @@ +// Copyright (C) 2018 Denis Shienkov +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCEFACTORY_GEOCLUE2_H +#define QGEOPOSITIONINFOSOURCEFACTORY_GEOCLUE2_H + +#include +#include + +QT_BEGIN_NAMESPACE + +/* + Qt Positioning plugin for Geoclue. This plugin supports Geoclue version 2.x. +*/ +class QGeoPositionInfoSourceFactoryGeoclue2 : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + + Q_INTERFACES(QGeoPositionInfoSourceFactory) + +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +QT_END_NAMESPACE + +#endif // QGEOPOSITIONINFOSOURCEFACTORY_GEOCLUE2_H diff --git a/src/plugins/position/gypsy/CMakeLists.txt b/src/plugins/position/gypsy/CMakeLists.txt new file mode 100644 index 0000000..1791bdc --- /dev/null +++ b/src/plugins/position/gypsy/CMakeLists.txt @@ -0,0 +1,24 @@ +# Generated from gypsy.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryGypsy Plugin: +##################################################################### + +qt_internal_add_plugin(QGeoPositionInfoSourceFactoryGypsyPlugin + OUTPUT_NAME qtposition_gypsy + CLASS_NAME QGeoPositionInfoSourceFactoryGypsy + PLUGIN_TYPE position + SOURCES + qgeopositioninfosourcefactory_gypsy.cpp qgeopositioninfosourcefactory_gypsy.h + qgeosatelliteinfosource_gypsy.cpp qgeosatelliteinfosource_gypsy_p.h +# special case begin + LIBRARIES + Gypsy::Gypsy + Gconf::Gconf + Qt::Core + Qt::Positioning +# special case end +) + +#### Keys ignored in scope 1:.:.:gypsy.pro:: +# OTHER_FILES = "plugin.json" diff --git a/src/plugins/position/gypsy/plugin.json b/src/plugins/position/gypsy/plugin.json new file mode 100644 index 0000000..9cef03f --- /dev/null +++ b/src/plugins/position/gypsy/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["gypsy"], + "Provider": "gypsy", + "Position": false, + "Satellite": true, + "Monitor" : false, + "Priority": 1000, + "Testable": false +} diff --git a/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp b/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp new file mode 100644 index 0000000..d467db8 --- /dev/null +++ b/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosourcefactory_gypsy.h" +#include "qgeosatelliteinfosource_gypsy_p.h" + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryGypsy::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryGypsy::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parameters) + QGeoSatelliteInfoSourceGypsy *src = new QGeoSatelliteInfoSourceGypsy(parent); + if (src->init(parameters) < 0) { + delete src; + src = nullptr; + } + return src; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryGypsy::areaMonitor(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} diff --git a/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h b/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h new file mode 100644 index 0000000..86b567f --- /dev/null +++ b/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h @@ -0,0 +1,23 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCEFACTORY_GYPSY_H +#define QGEOPOSITIONINFOSOURCEFACTORY_GYPSY_H + +#include +#include + +class QGeoPositionInfoSourceFactoryGypsy : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) + +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +#endif diff --git a/src/plugins/position/gypsy/qgeosatelliteinfosource_gypsy.cpp b/src/plugins/position/gypsy/qgeosatelliteinfosource_gypsy.cpp new file mode 100644 index 0000000..49bbb68 --- /dev/null +++ b/src/plugins/position/gypsy/qgeosatelliteinfosource_gypsy.cpp @@ -0,0 +1,406 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeosatelliteinfosource_gypsy_p.h" + +#ifdef Q_LOCATION_GYPSY_DEBUG +#include +#endif +#include +#include + +QT_BEGIN_NAMESPACE + +#define UPDATE_TIMEOUT_COLD_START 120000 + +static const auto deviceNameParameter = "deviceName"; +static const auto gconfKeyParameter = "gconfKey"; +static const auto defaultGconfKey = "/apps/geoclue/master/org.freedesktop.Geoclue.GPSDevice"; + +// Callback function for 'satellites-changed' -signal +static void satellites_changed (GypsySatellite *satellite, + GPtrArray *satellites, + gpointer userdata) +{ +#ifdef Q_LOCATION_GYPSY_DEBUG + qDebug() << "QGeoSatelliteInfoSourceGypsy Gypsy satellites-changed -signal received."; +#endif + ((QGeoSatelliteInfoSourceGypsy *)userdata)->satellitesChanged(satellite, satellites); +} + +SatelliteGypsyEngine::SatelliteGypsyEngine(QGeoSatelliteInfoSource *parent) : + m_owner(parent) +{ +} +SatelliteGypsyEngine::~SatelliteGypsyEngine() +{ +} + +// Glib symbols +gulong SatelliteGypsyEngine::eng_g_signal_connect(gpointer instance, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data) +{ + return ::g_signal_connect(instance, detailed_signal, c_handler, data); +} +guint SatelliteGypsyEngine::eng_g_signal_handlers_disconnect_by_func (gpointer instance, + gpointer func, + gpointer data) +{ + return ::g_signal_handlers_disconnect_by_func(instance, func, data); +} + +void SatelliteGypsyEngine::eng_g_free(gpointer mem) +{ + return ::g_free(mem); +} +// Gypsy symbols +GypsyControl *SatelliteGypsyEngine::eng_gypsy_control_get_default (void) +{ + return ::gypsy_control_get_default(); +} +char *SatelliteGypsyEngine::eng_gypsy_control_create (GypsyControl *control, const char *device_name, GError **error) +{ + return ::gypsy_control_create(control, device_name, error); +} +GypsyDevice *SatelliteGypsyEngine::eng_gypsy_device_new (const char *object_path) +{ + return ::gypsy_device_new(object_path); +} +GypsySatellite *SatelliteGypsyEngine::eng_gypsy_satellite_new (const char *object_path) +{ + return ::gypsy_satellite_new (object_path); +} +gboolean SatelliteGypsyEngine::eng_gypsy_device_start (GypsyDevice *device, GError **error) +{ + return ::gypsy_device_start(device, error); +} +gboolean SatelliteGypsyEngine::eng_gypsy_device_stop (GypsyDevice *device, GError **error) +{ + // Unfortunately this cannot be done; calling this will stop the GPS device + // (basically makes gypsy-daemon unusable for anyone), regardless of applications + // using it (see bug http://bugs.meego.com/show_bug.cgi?id=11707). + Q_UNUSED(device); + Q_UNUSED(error); + return true; + //return ::gypsy_device_stop (device, error); +} +GypsyDeviceFixStatus SatelliteGypsyEngine::eng_gypsy_device_get_fix_status (GypsyDevice *device, GError **error) +{ + return ::gypsy_device_get_fix_status (device, error); +} +GPtrArray *SatelliteGypsyEngine::eng_gypsy_satellite_get_satellites (GypsySatellite *satellite, GError **error) +{ + return ::gypsy_satellite_get_satellites (satellite, error); +} +void SatelliteGypsyEngine::eng_gypsy_satellite_free_satellite_array (GPtrArray *satellites) +{ + return ::gypsy_satellite_free_satellite_array(satellites); +} +// GConf symbols (mockability due to X11 requirement) +GConfClient *SatelliteGypsyEngine::eng_gconf_client_get_default(void) +{ + return ::gconf_client_get_default(); +} +gchar *SatelliteGypsyEngine::eng_gconf_client_get_string(GConfClient *client, const gchar *key, GError** err) +{ + return ::gconf_client_get_string(client, key, err); +} + +QGeoSatelliteInfoSourceGypsy::QGeoSatelliteInfoSourceGypsy(QObject *parent) + : QGeoSatelliteInfoSource(parent), m_engine(0), m_satellite(0), m_device(0), + m_requestTimer(this), m_updatesOngoing(false), m_requestOngoing(false) +{ + m_requestTimer.setSingleShot(true); + QObject::connect(&m_requestTimer, SIGNAL(timeout()), this, SLOT(requestUpdateTimeout())); +} + +void QGeoSatelliteInfoSourceGypsy::createEngine() +{ + delete m_engine; + m_engine = new SatelliteGypsyEngine(this); +} + +QGeoSatelliteInfoSourceGypsy::~QGeoSatelliteInfoSourceGypsy() +{ + GError *error = NULL; + if (m_device) { + m_engine->eng_gypsy_device_stop (m_device, &error); + g_object_unref(m_device); + } + if (m_satellite) + g_object_unref(m_satellite); + if (m_control) + g_object_unref(m_control); + if (error) + g_error_free(error); + delete m_engine; +} + +static QGeoSatelliteInfo::SatelliteSystem idToSystem(int prn) +{ + if (prn >= 1 && prn <= 32) + return QGeoSatelliteInfo::GPS; + else if (prn >= 65 && prn <= 96) + return QGeoSatelliteInfo::GLONASS; + else if (prn >= 193 && prn <= 200) + return QGeoSatelliteInfo::QZSS; + else if ((prn >= 201 && prn <= 235) || (prn >= 401 && prn <= 437)) + return QGeoSatelliteInfo::BEIDOU; + else if (prn >= 301 && prn <= 336) + return QGeoSatelliteInfo::GALILEO; + return QGeoSatelliteInfo::Undefined; +} + +void QGeoSatelliteInfoSourceGypsy::satellitesChanged(GypsySatellite *satellite, + GPtrArray *satellites) +{ + if (!satellite || !satellites) + return; + // We have satellite data and assume it is valid. + // If a single updateRequest was active, send signals right away. + // If a periodic timer was running (meaning that the client wishes + // to have updates at defined intervals), store the data for later sending. + QList lastSatellitesInView; + QList lastSatellitesInUse; + + unsigned int i; + for (i = 0; i < satellites->len; i++) { + GypsySatelliteDetails *details = (GypsySatelliteDetails *)satellites->pdata[i]; + QGeoSatelliteInfo info; + info.setSatelliteIdentifier(details->satellite_id); + info.setSatelliteSystem(idToSystem(details->satellite_id)); + info.setAttribute(QGeoSatelliteInfo::Elevation, details->elevation); + info.setAttribute(QGeoSatelliteInfo::Azimuth, details->azimuth); + info.setSignalStrength(details->snr); + if (details->in_use) + lastSatellitesInUse.append(info); + lastSatellitesInView.append(info); + } + bool sendUpdates(false); + // If a single updateRequest() has been issued: + if (m_requestOngoing) { + sendUpdates = true; + m_requestTimer.stop(); + m_requestOngoing = false; + // If there is no regular updates ongoing, disconnect now. + if (!m_updatesOngoing) { + m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (void *)satellites_changed, this); + } + } + // If regular updates are to be delivered as they come: + if (m_updatesOngoing) + sendUpdates = true; + + if (sendUpdates) { + emit satellitesInUseUpdated(lastSatellitesInUse); + emit satellitesInViewUpdated(lastSatellitesInView); + } +} + +QString QGeoSatelliteInfoSourceGypsy::extractDeviceNameFromParameters(const QVariantMap ¶meters) const +{ + // The logic is as follows: + // 1. If the deviceNameParameter is specified, its value is used to get the + // device name. + // 2. If the gconfKeyParameter is specified, its value is used as a key to + // extract the device name from GConf. + // 3. If nothing is specified, defaultGconfKey is used as a key to extract + // the device name from GConf. + if (parameters.contains(deviceNameParameter)) + return parameters.value(deviceNameParameter).toString(); + + QString gconfKey = parameters.value(gconfKeyParameter).toString(); + if (gconfKey.isEmpty()) + gconfKey = defaultGconfKey; + + if (!m_engine) + return QString(); + + GConfClient *client = m_engine->eng_gconf_client_get_default(); + if (!client) + return QString(); + + gchar *device_name = m_engine->eng_gconf_client_get_string(client, + gconfKey.toLatin1().constData(), + nullptr); + g_object_unref(client); + + const QString deviceName = QString::fromLatin1(device_name); + m_engine->eng_g_free(device_name); + + return deviceName; +} + +int QGeoSatelliteInfoSourceGypsy::init(const QVariantMap parameters) +{ + GError *error = NULL; + char *path; + +#if !GLIB_CHECK_VERSION(2, 36, 0) + g_type_init (); // this function was deprecated in glib 2.36 +#endif + createEngine(); + + const QString deviceName = extractDeviceNameFromParameters(parameters); + + if (deviceName.isEmpty() || + (deviceName.trimmed().at(0) == '/' && !QFile::exists(deviceName.trimmed()))) { + qWarning ("QGeoSatelliteInfoSourceGypsy Empty/nonexistent GPS device name detected."); + qWarning("Use '%s' plugin parameter to specify device name directly", deviceNameParameter); + qWarning("or use '%s' plugin parameter to specify a GConf key to extract the device name.", + gconfKeyParameter); + qWarning ("If the GConf key is used, the gconftool-2 tool can be used to set device name " + "for the selected key, e.g. on terminal:"); + qWarning ("gconftool-2 -t string -s %s /dev/ttyUSB0", gconfKeyParameter); + return -1; + } + m_control = m_engine->eng_gypsy_control_get_default(); + if (!m_control) { + qWarning("QGeoSatelliteInfoSourceGypsy unable to create Gypsy control."); + return -1; + } + // (path is the DBus path) + path = m_engine->eng_gypsy_control_create(m_control, deviceName.toLatin1().constData(), &error); + if (!path) { + qWarning ("QGeoSatelliteInfoSourceGypsy error creating client."); + if (error) { + qWarning ("error message: %s", error->message); + g_error_free (error); + } + return -1; + } + m_device = m_engine->eng_gypsy_device_new (path); + m_satellite = m_engine->eng_gypsy_satellite_new (path); + m_engine->eng_g_free(path); + if (!m_device || !m_satellite) { + qWarning ("QGeoSatelliteInfoSourceGypsy error creating satellite device."); + qWarning ("Please check that the GPS device is specified correctly."); + qWarning("Use '%s' plugin parameter to specify device name directly", deviceNameParameter); + qWarning("or use '%s' plugin parameter to specify a GConf key to extract the device name.", + gconfKeyParameter); + qWarning ("If the GConf key is used, the gconftool-2 tool can be used to set device name " + "for the selected key, e.g. on terminal:"); + qWarning ("gconftool-2 -t string -s %s /dev/ttyUSB0", gconfKeyParameter); + if (m_device) + g_object_unref(m_device); + if (m_satellite) + g_object_unref(m_satellite); + return -1; + } + m_engine->eng_gypsy_device_start (m_device, &error); + if (error) { + qWarning ("QGeoSatelliteInfoSourceGypsy error starting device: %s ", + error->message); + g_error_free(error); + g_object_unref(m_device); + g_object_unref(m_satellite); + return -1; + } + return 0; +} + +int QGeoSatelliteInfoSourceGypsy::minimumUpdateInterval() const +{ + return 1; +} + +QGeoSatelliteInfoSource::Error QGeoSatelliteInfoSourceGypsy::error() const +{ + return m_error; +} + +void QGeoSatelliteInfoSourceGypsy::startUpdates() +{ + if (m_updatesOngoing) + return; + + m_error = QGeoSatelliteInfoSource::NoError; + + // If there is a request timer ongoing, we've connected to the signal already + if (!m_requestTimer.isActive()) { + m_engine->eng_g_signal_connect (m_satellite, "satellites-changed", + G_CALLBACK (satellites_changed), this); + } + m_updatesOngoing = true; +} + +void QGeoSatelliteInfoSourceGypsy::stopUpdates() +{ + if (!m_updatesOngoing) + return; + m_updatesOngoing = false; + // Disconnect only if there is no single update request ongoing. Once single update request + // is completed and it notices that there is no active update ongoing, it will disconnect + // the signal. + if (!m_requestTimer.isActive()) + m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (void *)satellites_changed, this); +} + +void QGeoSatelliteInfoSourceGypsy::requestUpdate(int timeout) +{ + if (m_requestOngoing) + return; + + m_error = QGeoSatelliteInfoSource::NoError; + + if (timeout < 0) { + setError(QGeoSatelliteInfoSource::UpdateTimeoutError); + return; + } + m_requestOngoing = true; + GError *error = 0; + // If GPS has a fix a already, request current data. + GypsyDeviceFixStatus fixStatus = m_engine->eng_gypsy_device_get_fix_status(m_device, &error); + if (!error && (fixStatus != GYPSY_DEVICE_FIX_STATUS_INVALID && + fixStatus != GYPSY_DEVICE_FIX_STATUS_NONE)) { +#ifdef Q_LOCATION_GYPSY_DEBUG + qDebug() << "QGeoSatelliteInfoSourceGypsy fix available, requesting current satellite data"; +#endif + GPtrArray *satelliteData = m_engine->eng_gypsy_satellite_get_satellites(m_satellite, &error); + if (!error) { + // The fix was available and we have satellite data to deliver right away. + satellitesChanged(m_satellite, satelliteData); + m_engine->eng_gypsy_satellite_free_satellite_array(satelliteData); + return; + } + } + // No fix is available. If updates are not ongoing already, start them. + m_requestTimer.setInterval(timeout == 0? UPDATE_TIMEOUT_COLD_START: timeout); + if (!m_updatesOngoing) { + m_engine->eng_g_signal_connect (m_satellite, "satellites-changed", + G_CALLBACK (satellites_changed), this); + } + m_requestTimer.start(); + if (error) { +#ifdef Q_LOCATION_GYPSY_DEBUG + qDebug() << "QGeoSatelliteInfoSourceGypsy error asking fix status or satellite data: " << error->message; +#endif + g_error_free(error); + } +} + +void QGeoSatelliteInfoSourceGypsy::requestUpdateTimeout() +{ +#ifdef Q_LOCATION_GYPSY_DEBUG + qDebug("QGeoSatelliteInfoSourceGypsy request update timeout occurred."); +#endif + // If we end up here, there has not been valid satellite update. + // Emit timeout and disconnect from signal if regular updates are not + // ongoing (as we were listening just for one single requestUpdate). + if (!m_updatesOngoing) { + m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (void *)satellites_changed, this); + } + m_requestOngoing = false; + setError(QGeoSatelliteInfoSource::UpdateTimeoutError); +} + +void QGeoSatelliteInfoSourceGypsy::setError(QGeoSatelliteInfoSource::Error error) +{ + m_error = error; + if (m_error != QGeoSatelliteInfoSource::NoError) + emit QGeoSatelliteInfoSource::errorOccurred(m_error); +} + +QT_END_NAMESPACE diff --git a/src/plugins/position/gypsy/qgeosatelliteinfosource_gypsy_p.h b/src/plugins/position/gypsy/qgeosatelliteinfosource_gypsy_p.h new file mode 100644 index 0000000..4a836ba --- /dev/null +++ b/src/plugins/position/gypsy/qgeosatelliteinfosource_gypsy_p.h @@ -0,0 +1,107 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOSATELLITEINFOSOURCE_GYPSY_H +#define QGEOSATELLITEINFOSOURCE_GYPSY_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 "qgeosatelliteinfosource.h" +#include "qgeosatelliteinfo.h" +#include +#include +#include +#include +#include + +// #define Q_LOCATION_GYPSY_DEBUG + +QT_BEGIN_NAMESPACE + +// An engine that encapsulates all symbols we want +// to be able to mock (for unit/autotest purposes). +class SatelliteGypsyEngine +{ +public: + SatelliteGypsyEngine(QGeoSatelliteInfoSource *parent = 0); + virtual ~SatelliteGypsyEngine(); + // Glib symbols + virtual gulong eng_g_signal_connect(gpointer instance, + const gchar *detailed_signal, + GCallback c_handler, + gpointer data); + virtual guint eng_g_signal_handlers_disconnect_by_func(gpointer instance, + gpointer func, + gpointer data); + virtual void eng_g_free(gpointer mem); + // Gypsy symbols + virtual GypsyControl *eng_gypsy_control_get_default (void); + virtual char *eng_gypsy_control_create (GypsyControl *control, const char *device_name, GError **error); + virtual GypsyDevice *eng_gypsy_device_new (const char *object_path); + virtual GypsySatellite *eng_gypsy_satellite_new (const char *object_path); + virtual gboolean eng_gypsy_device_start (GypsyDevice *device, GError **error); + virtual gboolean eng_gypsy_device_stop (GypsyDevice *device, GError **error); + virtual GypsyDeviceFixStatus eng_gypsy_device_get_fix_status (GypsyDevice *device, GError **error); + virtual GPtrArray *eng_gypsy_satellite_get_satellites (GypsySatellite *satellite, GError **error); + virtual void eng_gypsy_satellite_free_satellite_array (GPtrArray *satellites); + // GConf symbols (mockability due to X11 requirement) + virtual GConfClient *eng_gconf_client_get_default(void); + virtual gchar *eng_gconf_client_get_string(GConfClient *client, const gchar *key, GError** err); +protected: + QGeoSatelliteInfoSource *m_owner; +}; + +class QGeoSatelliteInfoSourceGypsy : public QGeoSatelliteInfoSource + { + Q_OBJECT + +public: + explicit QGeoSatelliteInfoSourceGypsy(QObject *parent = 0); + ~QGeoSatelliteInfoSourceGypsy(); + int init(const QVariantMap parameters); + + int minimumUpdateInterval() const override; + Error error() const override; + +public slots: + virtual void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 5000) override; + void satellitesChanged(GypsySatellite *satellite, GPtrArray *satellites); + +private slots: + void requestUpdateTimeout(); + +private: + void setError(QGeoSatelliteInfoSource::Error error); + QString extractDeviceNameFromParameters(const QVariantMap ¶meters) const; + +protected: + // Creates an engine which encapsulates all used symbols + // that we want to be also able to mock. + virtual void createEngine(); + SatelliteGypsyEngine *m_engine; + +private: + Q_DISABLE_COPY(QGeoSatelliteInfoSourceGypsy) + GypsySatellite *m_satellite; + GypsyDevice *m_device; + QTimer m_requestTimer; + bool m_updatesOngoing; + bool m_requestOngoing; + QGeoSatelliteInfoSource::Error m_error = QGeoSatelliteInfoSource::NoError; + GypsyControl *m_control = nullptr; + }; + +QT_END_NAMESPACE + +#endif // QGEOSATELLITEINFOSOURCE_GYPSY_H diff --git a/src/plugins/position/nmea/CMakeLists.txt b/src/plugins/position/nmea/CMakeLists.txt new file mode 100644 index 0000000..73c5a3b --- /dev/null +++ b/src/plugins/position/nmea/CMakeLists.txt @@ -0,0 +1,22 @@ +# Generated from nmea.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryNmea Plugin: +##################################################################### + +qt_internal_add_plugin(QGeoPositionInfoSourceFactoryNmeaPlugin + OUTPUT_NAME qtposition_nmea + CLASS_NAME QGeoPositionInfoSourceFactoryNmea + PLUGIN_TYPE position + SOURCES + qgeopositioninfosourcefactory_nmea.cpp qgeopositioninfosourcefactory_nmea.h + qiopipe.cpp qiopipe_p.h + LIBRARIES + Qt::CorePrivate + Qt::Positioning + Qt::SerialPort + Qt::Network +) + +#### Keys ignored in scope 1:.:.:serialnmea.pro:: +# OTHER_FILES = "plugin.json" diff --git a/src/plugins/position/nmea/plugin.json b/src/plugins/position/nmea/plugin.json new file mode 100644 index 0000000..a60f947 --- /dev/null +++ b/src/plugins/position/nmea/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["nmea"], + "Provider": "nmea", + "Position": true, + "Satellite": true, + "Monitor" : false, + "Priority": 900, + "Testable": false +} diff --git a/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp b/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp new file mode 100644 index 0000000..9ff6cd8 --- /dev/null +++ b/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp @@ -0,0 +1,472 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosourcefactory_nmea.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qiopipe_p.h" + +Q_LOGGING_CATEGORY(lcNmea, "qt.positioning.nmea") + +QT_BEGIN_NAMESPACE + +static const auto sourceParameterName = QStringLiteral("nmea.source"); +static const auto socketScheme = QStringLiteral("socket:"); +static const auto serialScheme = QStringLiteral("serial:"); + +// This class is used only for SerialPort devices, because we can't open the +// same serial port twice. +// In case of files and sockets it's easier to explicitly create a QIODevice for +// each new instance of Nmea*InfoSource. +// Also QFile can't be directly used with QIOPipe, because QFile is not a +// sequential device. +// TcpSocket could be used with QIOPipe, but it complicates error handling +// dramatically, as we would need to somehow forward socket errors through +// QIOPipes to the clients. +class IODeviceContainer +{ +public: + IODeviceContainer() {} + IODeviceContainer(IODeviceContainer const&) = delete; + void operator=(IODeviceContainer const&) = delete; + + QSharedPointer serial(const QString &portName) + { + if (m_serialPorts.contains(portName)) { + m_serialPorts[portName].refs++; + QIOPipe *endPipe = new QIOPipe(m_serialPorts[portName].proxy); + m_serialPorts[portName].proxy->addChildPipe(endPipe); + return QSharedPointer(endPipe); + } + IODevice device; + QSerialPort *port = new QSerialPort(portName); + port->setBaudRate(4800); + qCDebug(lcNmea) << "Opening serial port" << portName; + if (!port->open(QIODevice::ReadOnly)) { + qWarning("nmea: Failed to open %s", qPrintable(portName)); + delete port; + return {}; + } + qCDebug(lcNmea) << "Opened successfully"; + device.device = port; + device.refs = 1; + device.proxy = new QIOPipe(port, QIOPipe::ProxyPipe); + m_serialPorts[portName] = device; + QIOPipe *endPipe = new QIOPipe(device.proxy); + device.proxy->addChildPipe(endPipe); + return QSharedPointer(endPipe); + } + + void releaseSerial(const QString &portName, QSharedPointer &pipe) + { + if (!m_serialPorts.contains(portName)) + return; + + pipe.clear(); // make sure to release the pipe returned by getSerial, or else, if there are still refs, data will be leaked through it + IODevice &device = m_serialPorts[portName]; + if (device.refs > 1) { + device.refs--; + return; + } + + IODevice taken = m_serialPorts.take(portName); + taken.device->deleteLater(); + } + +private: + + struct IODevice { + QIODevice *device = nullptr; + QIOPipe *proxy = nullptr; // adding client pipes as children of proxy + // allows to dynamically add clients to one device. + unsigned int refs = 1; + }; + + QMap m_serialPorts; +}; + +Q_GLOBAL_STATIC(IODeviceContainer, deviceContainer) + +// We use a string prefix to distinguish between the different data sources. +// "socket:" means that we use a socket connection +// "serial:" means that we use a serial port connection +// "file:///", "qrc:///" and just plain strings mean that we try to use local +// file. +// Note: if we do not specify anything, or specify "serial:" without specifying +// the port name, then we will try to search for a well-known serial port +// device. +class NmeaSource : public QNmeaPositionInfoSource +{ + Q_OBJECT +public: + NmeaSource(QObject *parent, const QVariantMap ¶meters); + NmeaSource(QObject *parent, const QString &fileName); + ~NmeaSource() override; + bool isValid() const + { + return !m_dataSource.isNull() || !m_fileSource.isNull() || !m_socket.isNull(); + } + +private slots: + void onSocketError(QAbstractSocket::SocketError error); + +private: + void parseSourceParameter(const QString &source); + void addSerialDevice(const QString &requestedPort); + void setFileName(const QString &fileName); + void connectSocket(const QString &source); + + QSharedPointer m_dataSource; + QScopedPointer m_fileSource; + QScopedPointer m_socket; + QString m_sourceName; +}; + +NmeaSource::NmeaSource(QObject *parent, const QVariantMap ¶meters) + : QNmeaPositionInfoSource(RealTimeMode, parent) +{ + const QString source = parameters.value(sourceParameterName).toString(); + parseSourceParameter(source); +} + +NmeaSource::NmeaSource(QObject *parent, const QString &fileName) + : QNmeaPositionInfoSource(SimulationMode, parent) +{ + setFileName(fileName); +} + +NmeaSource::~NmeaSource() +{ + if (deviceContainer.exists()) + deviceContainer->releaseSerial(m_sourceName, m_dataSource); +} + +void NmeaSource::onSocketError(QAbstractSocket::SocketError error) +{ + m_socket->close(); + + switch (error) { + case QAbstractSocket::UnknownSocketError: + setError(QGeoPositionInfoSource::UnknownSourceError); + break; + case QAbstractSocket::SocketAccessError: + setError(QGeoPositionInfoSource::AccessError); + break; + case QAbstractSocket::RemoteHostClosedError: + setError(QGeoPositionInfoSource::ClosedError); + break; + default: + qWarning() << "Connection failed! QAbstractSocket::SocketError" << error; + // TODO - introduce new type of error. TransportError? + setError(QGeoPositionInfoSource::UnknownSourceError); + break; + } +} + +void NmeaSource::parseSourceParameter(const QString &source) +{ + if (source.startsWith(socketScheme)) { + // This is a socket + connectSocket(source); + } else { + // Last chance - this can be serial device. + // Note: File is handled in a separate case. + addSerialDevice(source); + } +} + +static QString tryFindSerialDevice(const QString &requestedPort) +{ + QString portName; + if (requestedPort.isEmpty()) { + const QList ports = QSerialPortInfo::availablePorts(); + qCDebug(lcNmea) << "Found" << ports.size() << "serial ports"; + if (ports.isEmpty()) { + qWarning("nmea: No serial ports found"); + return portName; + } + + // Try to find a well-known device. + QSet supportedDevices; + supportedDevices << 0x67b; // GlobalSat (BU-353S4 and probably others) + supportedDevices << 0xe8d; // Qstarz MTK II + for (const QSerialPortInfo& port : ports) { + if (port.hasVendorIdentifier() && supportedDevices.contains(port.vendorIdentifier())) { + portName = port.portName(); + break; + } + } + + if (portName.isEmpty()) { + qWarning("nmea: No known GPS device found."); + } + } else { + portName = requestedPort; + if (portName.startsWith(serialScheme)) + portName.remove(0, 7); + } + return portName; +} + +void NmeaSource::addSerialDevice(const QString &requestedPort) +{ + m_sourceName = tryFindSerialDevice(requestedPort); + if (m_sourceName.isEmpty()) + return; + + m_dataSource = deviceContainer->serial(m_sourceName); + if (!m_dataSource) + return; + + setDevice(m_dataSource.data()); +} + +void NmeaSource::setFileName(const QString &fileName) +{ + m_sourceName = fileName; + + m_fileSource.reset(new QFile(fileName)); + qCDebug(lcNmea) << "Opening file" << fileName; + if (!m_fileSource->open(QIODevice::ReadOnly)) { + qWarning("nmea: failed to open file %s", qPrintable(fileName)); + m_fileSource.reset(); + } + + if (!m_fileSource) + return; + + qCDebug(lcNmea) << "Opened successfully"; + + setDevice(m_fileSource.data()); +} + +void NmeaSource::connectSocket(const QString &source) +{ + const QUrl url(source); + const QString host = url.host(); + const int port = url.port(); + if (!host.isEmpty() && (port > 0)) { + m_socket.reset(new QTcpSocket); + // no need to explicitly connect to connected() signal + connect(m_socket.get(), &QTcpSocket::errorOccurred, this, &NmeaSource::onSocketError); + m_socket->connectToHost(host, port, QTcpSocket::ReadOnly); + m_sourceName = source; + + setDevice(m_socket.data()); + } else { + qWarning("nmea: incorrect socket parameters %s:%d", qPrintable(host), port); + } +} + +class NmeaSatelliteSource : public QNmeaSatelliteInfoSource +{ + Q_OBJECT +public: + NmeaSatelliteSource(QObject *parent, const QVariantMap ¶meters); + NmeaSatelliteSource(QObject *parent, const QString &fileName, const QVariantMap ¶meters); + ~NmeaSatelliteSource(); + + bool isValid() const { return !m_port.isNull() || !m_file.isNull() || !m_socket.isNull(); } + +private slots: + void onSocketError(QAbstractSocket::SocketError error); + +private: + void parseRealtimeSource(const QString &source); + void parseSimulationSource(const QString &localFileName); + + QSharedPointer m_port; + QScopedPointer m_file; + QScopedPointer m_socket; + QString m_sourceName; +}; + +NmeaSatelliteSource::NmeaSatelliteSource(QObject *parent, const QVariantMap ¶meters) + : QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode, parent) +{ + const QString source = parameters.value(sourceParameterName).toString(); + parseRealtimeSource(source); +} + +// We can use a QNmeaSatelliteInfoSource::SimulationUpdateInterval parameter to +// set the file read frequency in simulation mode. We use setBackendProperty() +// for it. The value can't be smaller than minimumUpdateInterval(). +// This check is done on the QNmeaSatelliteInfoSource level +NmeaSatelliteSource::NmeaSatelliteSource(QObject *parent, const QString &fileName, + const QVariantMap ¶meters) + : QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::SimulationMode, parent) +{ + bool ok = false; + const int interval = + parameters.value(QNmeaSatelliteInfoSource::SimulationUpdateInterval).toInt(&ok); + if (ok) + setBackendProperty(QNmeaSatelliteInfoSource::SimulationUpdateInterval, interval); + parseSimulationSource(fileName); +} + +NmeaSatelliteSource::~NmeaSatelliteSource() +{ + if (deviceContainer.exists()) + deviceContainer->releaseSerial(m_sourceName, m_port); +} + +void NmeaSatelliteSource::onSocketError(QAbstractSocket::SocketError error) +{ + m_socket->close(); + + switch (error) { + case QAbstractSocket::UnknownSocketError: + setError(QGeoSatelliteInfoSource::UnknownSourceError); + break; + case QAbstractSocket::SocketAccessError: + setError(QGeoSatelliteInfoSource::AccessError); + break; + case QAbstractSocket::RemoteHostClosedError: + setError(QGeoSatelliteInfoSource::ClosedError); + break; + default: + qWarning() << "Connection failed! QAbstractSocket::SocketError" << error; + // TODO - introduce new type of error. TransportError? + setError(QGeoSatelliteInfoSource::UnknownSourceError); + break; + } +} + +void NmeaSatelliteSource::parseRealtimeSource(const QString &source) +{ + if (source.startsWith(socketScheme)) { + // This is a socket. + const QUrl url(source); + const QString host = url.host(); + const int port = url.port(); + if (!host.isEmpty() && (port > 0)) { + m_socket.reset(new QTcpSocket); + // no need to explicitly connect to connected() signal + connect(m_socket.get(), &QTcpSocket::errorOccurred, + this, &NmeaSatelliteSource::onSocketError); + m_socket->connectToHost(host, port, QTcpSocket::ReadOnly); + m_sourceName = source; + + setDevice(m_socket.data()); + } else { + qWarning("nmea: incorrect socket parameters %s:%d", qPrintable(host), port); + } + } else { + // Last chance - this can be serial device. + m_sourceName = tryFindSerialDevice(source); + if (m_sourceName.isEmpty()) + return; + + m_port = deviceContainer->serial(m_sourceName); + if (!m_port) + return; + + setDevice(m_port.data()); + } +} + +void NmeaSatelliteSource::parseSimulationSource(const QString &localFileName) +{ + // This is a text file. + m_sourceName = localFileName; + + qCDebug(lcNmea) << "Opening file" << localFileName; + m_file.reset(new QFile(localFileName)); + if (!m_file->open(QIODevice::ReadOnly)) { + qWarning("nmea: failed to open file %s", qPrintable(localFileName)); + m_file.reset(); + return; + } + qCDebug(lcNmea) << "Opened successfully"; + + setDevice(m_file.data()); +} + +/*! + \internal + Returns a local file name if \a source represents it. + The returned value can be different from \a source, as the method tries to + modify the path +*/ +static QString checkSourceIsFile(const QString &source) +{ + if (source.isEmpty()) + return QString(); + + QString localFileName = source; + + if (!QFile::exists(localFileName)) { + if (localFileName.startsWith(QStringLiteral("qrc:///"))) + localFileName.remove(0, 7); + else if (localFileName.startsWith(QStringLiteral("file:///"))) + localFileName.remove(0, 7); + else if (localFileName.startsWith(QStringLiteral("qrc:/"))) + localFileName.remove(0, 5); + + if (!QFile::exists(localFileName) && localFileName.startsWith(QLatin1Char('/'))) + localFileName.remove(0, 1); + } + if (!QFile::exists(localFileName)) + localFileName.prepend(QLatin1Char(':')); + + const bool isLocalFile = QFile::exists(localFileName); + return isLocalFile ? localFileName : QString(); +} + +/*! + \internal + Returns a local file name if file exists, or an empty string otherwise +*/ +static QString extractLocalFileName(const QVariantMap ¶meters) +{ + QString localFileName = parameters.value(sourceParameterName).toString(); + return checkSourceIsFile(localFileName); +} + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryNmea::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + std::unique_ptr src = nullptr; + + const QString localFileName = extractLocalFileName(parameters); + if (localFileName.isEmpty()) + src = std::make_unique(parent, parameters); // use RealTimeMode + else + src = std::make_unique(parent, localFileName); // use SimulationMode + + return (src && src->isValid()) ? src.release() : nullptr; +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryNmea::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + std::unique_ptr src = nullptr; + + const QString localFileName = extractLocalFileName(parameters); + if (localFileName.isEmpty()) { + // use RealTimeMode + src = std::make_unique(parent, parameters); + } else { + // use SimulationMode + src = std::make_unique(parent, localFileName, parameters); + } + return (src && src->isValid()) ? src.release() : nullptr; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryNmea::areaMonitor(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent); + Q_UNUSED(parameters); + return nullptr; +} + +QT_END_NAMESPACE + +#include "moc_qgeopositioninfosourcefactory_nmea.cpp" +#include "qgeopositioninfosourcefactory_nmea.moc" diff --git a/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.h b/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.h new file mode 100644 index 0000000..d3cae3b --- /dev/null +++ b/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.h @@ -0,0 +1,27 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCEFACTORY_NMEA_H +#define QGEOPOSITIONINFOSOURCEFACTORY_NMEA_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfoSourceFactoryNmea : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) + +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/position/nmea/qiopipe.cpp b/src/plugins/position/nmea/qiopipe.cpp new file mode 100644 index 0000000..6d4075c --- /dev/null +++ b/src/plugins/position/nmea/qiopipe.cpp @@ -0,0 +1,164 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qiopipe_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +/* + proxying means do *not* emit readyRead, and instead pump data + into child pipes directly in a zero-copy fashion. +*/ +QIOPipePrivate::QIOPipePrivate(QIODevice *iodevice, bool proxying) + : m_proxying(proxying), source(iodevice) +{ +} + +QIOPipePrivate::~QIOPipePrivate() +{ +} + +void QIOPipePrivate::initialize() +{ + const QIOPipe *parentPipe = qobject_cast(source); + if (parentPipe && parentPipe->d_func()->m_proxying) // with proxying parent, + return; // don't do anything + + // read available data, does not emit. + readAvailableData(); + // connect readyRead to onReadyRead + QObjectPrivate::connect(source, &QIODevice::readyRead, this, &QIOPipePrivate::_q_onReadyRead); +} + +bool QIOPipePrivate::readAvailableData() { + if (!source) + return false; + QByteArray ba = source->readAll(); + if (ba.isEmpty()) + return false; + + pumpData(ba); + return true; +} + +void QIOPipePrivate::pumpData(const QByteArray &ba) +{ + if (m_proxying) { + auto isNull = [](const auto &cp) { return cp == nullptr; }; + childPipes.removeIf(isNull); + for (const auto &cp : std::as_const(childPipes)) + cp->d_func()->pushData(ba); + } else { + for (auto &buffer : readBuffers) + buffer.append(ba); + } +} + +void QIOPipePrivate::pushData(const QByteArray &ba) +{ + Q_Q(QIOPipe); + if (ba.isEmpty()) + return; + + pumpData(ba); + if (!m_proxying) + emit q->readyRead(); +} + +void QIOPipePrivate::_q_onReadyRead() +{ + Q_Q(QIOPipe); + if (readAvailableData() && !m_proxying) + emit q->readyRead(); +} + +void QIOPipePrivate::addChildPipe(QIOPipe *childPipe) +{ + if (childPipes.contains(childPipe)) + return; + childPipes.append(childPipe); +} + +void QIOPipePrivate::removeChildPipe(QIOPipe *childPipe) +{ + childPipes.removeOne(childPipe); +} + +QIOPipe::QIOPipe(QIODevice *parent, Mode mode) + : QIODevice(*new QIOPipePrivate(parent, mode == ProxyPipe), parent) +{ + this->d_func()->initialize(); + if (!parent->isOpen() && !parent->open(QIODevice::ReadOnly)) { + qWarning() << "QIOPipe: Failed to open " << parent; + return; + } + open(ReadOnly); +} + +QIOPipe::~QIOPipe() +{ + +} + +bool QIOPipe::open(QIODevice::OpenMode mode) +{ + if (isOpen()) + return true; + + static const OpenMode supportedOpenMode = ReadOnly; // Currently limit it to read only + if (!(mode & supportedOpenMode)) { + qFatal("Unsupported open mode"); + return false; + } + + return QIODevice::open(mode); +} + +bool QIOPipe::isSequential() const +{ + return true; +} + +void QIOPipe::setReadChannelCount(int count) +{ + Q_D(QIOPipe); + d->setReadChannelCount(qMax(count, 1)); +} + +void QIOPipe::addChildPipe(QIOPipe *childPipe) +{ + Q_D(QIOPipe); + d->addChildPipe(childPipe); +} + +/*! + \reimp + + \omit + This function does not really read anything, as we use QIODevicePrivate's + buffer. The buffer will be read inside of QIODevice before this + method will be called. + See QIODevicePrivate::read, buffer.read(data, maxSize). + \endomit +*/ +qint64 QIOPipe::readData(char *data, qint64 maxlen) +{ + Q_UNUSED(data); + Q_UNUSED(maxlen); + + // return 0 indicating there may be more data in the future + // Returning -1 means no more data in the future (end of stream). + return qint64(0); +} + +qint64 QIOPipe::writeData(const char * /*data*/, qint64 /*len*/) +{ + qFatal("QIOPipe is a read-only device"); + return qint64(0); +} + +QT_END_NAMESPACE + +#include "moc_qiopipe_p.cpp" diff --git a/src/plugins/position/nmea/qiopipe_p.h b/src/plugins/position/nmea/qiopipe_p.h new file mode 100644 index 0000000..65b2367 --- /dev/null +++ b/src/plugins/position/nmea/qiopipe_p.h @@ -0,0 +1,78 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QIOPIPE_P_H +#define QIOPIPE_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 +#include +#include + +QT_BEGIN_NAMESPACE + +class QObject; +class QIOPipePrivate; + +class QIOPipe : public QIODevice +{ + Q_OBJECT + +public: + enum Mode { + EndPipe = 0x0000, + ProxyPipe = 0x0001 + }; + + explicit QIOPipe(QIODevice *parent, Mode mode = EndPipe); + ~QIOPipe() override; + + bool open(OpenMode openMode) override; + bool isSequential() const override; + void setReadChannelCount(int count); + void addChildPipe(QIOPipe *childPipe); + +protected: + qint64 readData(char *data, qint64 maxlen) override; + qint64 writeData(const char *data, qint64 len) override; + +private: + Q_DECLARE_PRIVATE(QIOPipe) + Q_DISABLE_COPY(QIOPipe) +}; + +class QIOPipePrivate : public QIODevicePrivate +{ +public: + Q_DECLARE_PUBLIC(QIOPipe) + + explicit QIOPipePrivate(QIODevice *iodevice, bool proxying); + ~QIOPipePrivate() override; + + void initialize(); + bool readAvailableData(); + void pumpData(const QByteArray &ba); + void pushData(const QByteArray &ba); + void _q_onReadyRead(); + void addChildPipe(QIOPipe *childPipe); + void removeChildPipe(QIOPipe *childPipe); + + bool m_proxying = false; + QPointer source; + QList> childPipes; +}; + +QT_END_NAMESPACE + +#endif // QIOPIPE_P_H + diff --git a/src/plugins/position/positionpoll/CMakeLists.txt b/src/plugins/position/positionpoll/CMakeLists.txt new file mode 100644 index 0000000..59810be --- /dev/null +++ b/src/plugins/position/positionpoll/CMakeLists.txt @@ -0,0 +1,20 @@ +# Generated from positionpoll.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryPoll Plugin: +##################################################################### + +qt_internal_add_plugin(QGeoPositionInfoSourceFactoryPollPlugin + OUTPUT_NAME qtposition_positionpoll + CLASS_NAME QGeoPositionInfoSourceFactoryPoll + PLUGIN_TYPE position + SOURCES + positionpollfactory.cpp positionpollfactory.h + qgeoareamonitor_polling.cpp qgeoareamonitor_polling.h + LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:positionpoll.pro:: +# OTHER_FILES = "plugin.json" diff --git a/src/plugins/position/positionpoll/plugin.json b/src/plugins/position/positionpoll/plugin.json new file mode 100644 index 0000000..df1f47d --- /dev/null +++ b/src/plugins/position/positionpoll/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["positionpoll"], + "Provider": "positionpoll", + "Position": false, + "Satellite": false, + "Monitor": true, + "Priority": 1000, + "Testable": true +} diff --git a/src/plugins/position/positionpoll/positionpollfactory.cpp b/src/plugins/position/positionpoll/positionpollfactory.cpp new file mode 100644 index 0000000..d9da674 --- /dev/null +++ b/src/plugins/position/positionpoll/positionpollfactory.cpp @@ -0,0 +1,35 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "positionpollfactory.h" +#include "qgeoareamonitor_polling.h" + +QT_BEGIN_NAMESPACE + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryPoll::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryPoll::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryPoll::areaMonitor(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parameters) + QGeoAreaMonitorPolling *ret = new QGeoAreaMonitorPolling(parent); + if (ret && ret->isValid()) + return ret; + delete ret; + return nullptr; +} + +QT_END_NAMESPACE + +#include "moc_positionpollfactory.cpp" diff --git a/src/plugins/position/positionpoll/positionpollfactory.h b/src/plugins/position/positionpoll/positionpollfactory.h new file mode 100644 index 0000000..d7eba9a --- /dev/null +++ b/src/plugins/position/positionpoll/positionpollfactory.h @@ -0,0 +1,26 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef POSITIONPOLLFACTORY_H +#define POSITIONPOLLFACTORY_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfoSourceFactoryPoll : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +QT_END_NAMESPACE + +#endif // POSITIONPOLLFACTORY_H diff --git a/src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp b/src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp new file mode 100644 index 0000000..25dd5bc --- /dev/null +++ b/src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp @@ -0,0 +1,474 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeoareamonitor_polling.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define UPDATE_INTERVAL_5S 5000 + +typedef QHash MonitorTable; + + +static QMetaMethod areaEnteredSignal() +{ + static QMetaMethod signal = QMetaMethod::fromSignal(&QGeoAreaMonitorPolling::areaEntered); + return signal; +} + +static QMetaMethod areaExitedSignal() +{ + static QMetaMethod signal = QMetaMethod::fromSignal(&QGeoAreaMonitorPolling::areaExited); + return signal; +} + +static QMetaMethod monitorExpiredSignal() +{ + static QMetaMethod signal = QMetaMethod::fromSignal(&QGeoAreaMonitorPolling::monitorExpired); + return signal; +} + +class QGeoAreaMonitorPollingPrivate : public QObject +{ + Q_OBJECT +public: + QGeoAreaMonitorPollingPrivate() + { + nextExpiryTimer = new QTimer(this); + nextExpiryTimer->setSingleShot(true); + connect(nextExpiryTimer, SIGNAL(timeout()), + this, SLOT(timeout())); + } + + void startMonitoring(const QGeoAreaMonitorInfo &monitor) + { + const std::lock_guard locker(mutex); + + activeMonitorAreas.insert(monitor.identifier(), monitor); + singleShotTrigger.remove(monitor.identifier()); + + checkStartStop(); + setupNextExpiryTimeout(); + } + + void requestUpdate(const QGeoAreaMonitorInfo &monitor, int signalId) + { + const std::lock_guard locker(mutex); + + activeMonitorAreas.insert(monitor.identifier(), monitor); + singleShotTrigger.insert(monitor.identifier(), signalId); + + checkStartStop(); + setupNextExpiryTimeout(); + } + + QGeoAreaMonitorInfo stopMonitoring(const QGeoAreaMonitorInfo &monitor) + { + const std::lock_guard locker(mutex); + + QGeoAreaMonitorInfo mon = activeMonitorAreas.take(monitor.identifier()); + + checkStartStop(); + setupNextExpiryTimeout(); + + return mon; + } + + void registerClient(QGeoAreaMonitorPolling *client) + { + const std::lock_guard locker(mutex); + + connect(this, SIGNAL(timeout(QGeoAreaMonitorInfo)), + client, SLOT(timeout(QGeoAreaMonitorInfo))); + + connect(this, SIGNAL(positionError(QGeoPositionInfoSource::Error)), + client, SLOT(positionError(QGeoPositionInfoSource::Error))); + + connect(this, SIGNAL(areaEventDetected(QGeoAreaMonitorInfo,QGeoPositionInfo,bool)), + client, SLOT(processAreaEvent(QGeoAreaMonitorInfo,QGeoPositionInfo,bool))); + + registeredClients.append(client); + } + + void deregisterClient(QGeoAreaMonitorPolling *client) + { + const std::lock_guard locker(mutex); + + registeredClients.removeAll(client); + if (registeredClients.isEmpty()) + checkStartStop(); + } + + void setPositionSource(QGeoPositionInfoSource *newSource) + { + const std::lock_guard locker(mutex); + + if (newSource == source) + return; + + if (source) + delete source; + + source = newSource; + + if (source) { + source->setParent(this); + source->moveToThread(this->thread()); + if (source->updateInterval() == 0) + source->setUpdateInterval(UPDATE_INTERVAL_5S); + disconnect(source, 0, 0, 0); //disconnect all + connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), + this, SLOT(positionUpdated(QGeoPositionInfo))); + connect(source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error)), + this, SIGNAL(positionError(QGeoPositionInfoSource::Error))); + checkStartStop(); + } + } + + QGeoPositionInfoSource* positionSource() const + { + const std::lock_guard locker(mutex); + return source; + } + + MonitorTable activeMonitors() const + { + const std::lock_guard locker(mutex); + + return activeMonitorAreas; + } + + void checkStartStop() + { + const std::lock_guard locker(mutex); + + bool signalsConnected = false; + foreach (const QGeoAreaMonitorPolling *client, registeredClients) { + if (client->hasConnections()) { + signalsConnected = true; + break; + } + } + + if (signalsConnected && !activeMonitorAreas.isEmpty()) { + if (source) + source->startUpdates(); + else + //translated to InsufficientPositionInfo + emit positionError(QGeoPositionInfoSource::ClosedError); + } else { + if (source) + source->stopUpdates(); + } + } + +private: + void setupNextExpiryTimeout() + { + nextExpiryTimer->stop(); + activeExpiry.first = QDateTime(); + activeExpiry.second = QString(); + + foreach (const QGeoAreaMonitorInfo &info, activeMonitors()) { + if (info.expiration().isValid()) { + if (!activeExpiry.first.isValid()) { + activeExpiry.first = info.expiration(); + activeExpiry.second = info.identifier(); + continue; + } + if (info.expiration() < activeExpiry.first) { + activeExpiry.first = info.expiration(); + activeExpiry.second = info.identifier(); + } + } + } + + if (activeExpiry.first.isValid()) + nextExpiryTimer->start(QDateTime::currentDateTime().msecsTo(activeExpiry.first)); + } + + + //returns true if areaEntered should be emitted + bool processInsideArea(const QString &monitorIdent) + { + if (!insideArea.contains(monitorIdent)) { + if (singleShotTrigger.value(monitorIdent, -1) == areaEnteredSignal().methodIndex()) { + //this is the finishing singleshot event + singleShotTrigger.remove(monitorIdent); + activeMonitorAreas.remove(monitorIdent); + setupNextExpiryTimeout(); + } else { + insideArea.insert(monitorIdent); + } + return true; + } + + return false; + } + + //returns true if areaExited should be emitted + bool processOutsideArea(const QString &monitorIdent) + { + if (insideArea.contains(monitorIdent)) { + if (singleShotTrigger.value(monitorIdent, -1) == areaExitedSignal().methodIndex()) { + //this is the finishing singleShot event + singleShotTrigger.remove(monitorIdent); + activeMonitorAreas.remove(monitorIdent); + setupNextExpiryTimeout(); + } else { + insideArea.remove(monitorIdent); + } + return true; + } + return false; + } + + + +Q_SIGNALS: + void timeout(const QGeoAreaMonitorInfo &info); + void positionError(const QGeoPositionInfoSource::Error error); + void areaEventDetected(const QGeoAreaMonitorInfo &minfo, + const QGeoPositionInfo &pinfo, bool isEnteredEvent); +private Q_SLOTS: + void timeout() + { + /* + * Don't block timer firing even if monitorExpiredSignal is not connected. + * This allows us to continue to remove the existing monitors as they expire. + **/ + const QGeoAreaMonitorInfo info = activeMonitorAreas.take(activeExpiry.second); + setupNextExpiryTimeout(); + emit timeout(info); + + } + + void positionUpdated(const QGeoPositionInfo &info) + { + foreach (const QGeoAreaMonitorInfo &monInfo, activeMonitors()) { + const QString identifier = monInfo.identifier(); + if (monInfo.area().contains(info.coordinate())) { + if (processInsideArea(identifier)) + emit areaEventDetected(monInfo, info, true); + } else { + if (processOutsideArea(identifier)) + emit areaEventDetected(monInfo, info, false); + } + } + } + +private: + QPair activeExpiry; + QHash singleShotTrigger; + QTimer* nextExpiryTimer; + QSet insideArea; + + MonitorTable activeMonitorAreas; + + QGeoPositionInfoSource* source = nullptr; + QList registeredClients; + mutable QRecursiveMutex mutex; +}; + +Q_GLOBAL_STATIC(QGeoAreaMonitorPollingPrivate, pollingPrivate) + +QGeoAreaMonitorPolling::QGeoAreaMonitorPolling(QObject *parent) : QGeoAreaMonitorSource(parent) +{ + d = pollingPrivate(); + d->registerClient(this); + //hookup to default source if existing + if (!positionInfoSource()) + setPositionInfoSource(QGeoPositionInfoSource::createDefaultSource(this)); +} + +QGeoAreaMonitorPolling::~QGeoAreaMonitorPolling() +{ + d->deregisterClient(this); +} + +QGeoPositionInfoSource* QGeoAreaMonitorPolling::positionInfoSource() const +{ + return d->positionSource(); +} + +void QGeoAreaMonitorPolling::setPositionInfoSource(QGeoPositionInfoSource *source) +{ + d->setPositionSource(source); +} + +QGeoAreaMonitorSource::Error QGeoAreaMonitorPolling::error() const +{ + return lastError; +} + +bool QGeoAreaMonitorPolling::startMonitoring(const QGeoAreaMonitorInfo &monitor) +{ + if (!monitor.isValid()) + return false; + + //reject an expiry in the past + if (monitor.expiration().isValid() && + (monitor.expiration() < QDateTime::currentDateTime())) + return false; + + //don't accept persistent monitor since we don't support it + if (monitor.isPersistent()) + return false; + + lastError = QGeoAreaMonitorSource::NoError; + + //update or insert + d->startMonitoring(monitor); + + return true; +} + +int QGeoAreaMonitorPolling::idForSignal(const char *signal) +{ + const QByteArray sig = QMetaObject::normalizedSignature(signal + 1); + const QMetaObject * const mo = metaObject(); + + return mo->indexOfSignal(sig.constData()); +} + +bool QGeoAreaMonitorPolling::hasConnections() const +{ + // This method is internal and requires the mutex to be already locked. + return signalConnections > 0; +} + +bool QGeoAreaMonitorPolling::requestUpdate(const QGeoAreaMonitorInfo &monitor, const char *signal) +{ + if (!monitor.isValid()) + return false; + //reject an expiry in the past + if (monitor.expiration().isValid() && + (monitor.expiration() < QDateTime::currentDateTime())) + return false; + + //don't accept persistent monitor since we don't support it + if (monitor.isPersistent()) + return false; + + if (!signal) + return false; + + const int signalId = idForSignal(signal); + if (signalId < 0) + return false; + + //only accept area entered or exit signal + if (signalId != areaEnteredSignal().methodIndex() && + signalId != areaExitedSignal().methodIndex()) + { + return false; + } + + lastError = QGeoAreaMonitorSource::NoError; + + d->requestUpdate(monitor, signalId); + + return true; +} + +bool QGeoAreaMonitorPolling::stopMonitoring(const QGeoAreaMonitorInfo &monitor) +{ + QGeoAreaMonitorInfo info = d->stopMonitoring(monitor); + + return info.isValid(); +} + +QList QGeoAreaMonitorPolling::activeMonitors() const +{ + return d->activeMonitors().values(); +} + +QList QGeoAreaMonitorPolling::activeMonitors(const QGeoShape ®ion) const +{ + QList results; + if (region.isEmpty()) + return results; + + const MonitorTable list = d->activeMonitors(); + foreach (const QGeoAreaMonitorInfo &monitor, list) { + if (region.contains(monitor.area().center())) + results.append(monitor); + } + + return results; +} + +QGeoAreaMonitorSource::AreaMonitorFeatures QGeoAreaMonitorPolling::supportedAreaMonitorFeatures() const +{ + return {}; +} + +void QGeoAreaMonitorPolling::connectNotify(const QMetaMethod &signal) +{ + QMutexLocker locker(&connectionMutex); + if (signal == areaEnteredSignal() || signal == areaExitedSignal()) { + const bool alreadyConnected = hasConnections(); + signalConnections++; + if (!alreadyConnected) + d->checkStartStop(); + } +} + +void QGeoAreaMonitorPolling::disconnectNotify(const QMetaMethod &signal) +{ + QMutexLocker locker(&connectionMutex); + if (signal == areaEnteredSignal() || signal == areaExitedSignal()) { + if (hasConnections()) + signalConnections--; + if (!hasConnections()) + d->checkStartStop(); + } +} + +void QGeoAreaMonitorPolling::positionError(const QGeoPositionInfoSource::Error error) +{ + switch (error) { + case QGeoPositionInfoSource::AccessError: + lastError = QGeoAreaMonitorSource::AccessError; + break; + case QGeoPositionInfoSource::UnknownSourceError: + lastError = QGeoAreaMonitorSource::UnknownSourceError; + break; + case QGeoPositionInfoSource::ClosedError: + case QGeoPositionInfoSource::UpdateTimeoutError: + lastError = QGeoAreaMonitorSource::InsufficientPositionInfo; + break; + case QGeoPositionInfoSource::NoError: + return; + } + + emit QGeoAreaMonitorSource::errorOccurred(lastError); +} + +void QGeoAreaMonitorPolling::timeout(const QGeoAreaMonitorInfo& monitor) +{ + if (isSignalConnected(monitorExpiredSignal())) + emit monitorExpired(monitor); +} + +void QGeoAreaMonitorPolling::processAreaEvent(const QGeoAreaMonitorInfo &minfo, + const QGeoPositionInfo &pinfo, bool isEnteredEvent) +{ + if (isEnteredEvent) + emit areaEntered(minfo, pinfo); + else + emit areaExited(minfo, pinfo); +} + +#include "qgeoareamonitor_polling.moc" +#include "moc_qgeoareamonitor_polling.cpp" diff --git a/src/plugins/position/positionpoll/qgeoareamonitor_polling.h b/src/plugins/position/positionpoll/qgeoareamonitor_polling.h new file mode 100644 index 0000000..3bee9d8 --- /dev/null +++ b/src/plugins/position/positionpoll/qgeoareamonitor_polling.h @@ -0,0 +1,64 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOAREAMONITORPOLLING_H +#define QGEOAREAMONITORPOLLING_H + +#include +#include +#include + +/** + * QGeoAreaMonitorPolling + * + */ + +class QGeoAreaMonitorPollingPrivate; +class QGeoAreaMonitorPolling : public QGeoAreaMonitorSource +{ + Q_OBJECT +public : + explicit QGeoAreaMonitorPolling(QObject *parent = 0); + ~QGeoAreaMonitorPolling(); + + void setPositionInfoSource(QGeoPositionInfoSource *source) override; + QGeoPositionInfoSource* positionInfoSource() const override; + + Error error() const override; + + bool startMonitoring(const QGeoAreaMonitorInfo &monitor) override; + bool requestUpdate(const QGeoAreaMonitorInfo &monitor, + const char *signal) override; + bool stopMonitoring(const QGeoAreaMonitorInfo &monitor) override; + + QList activeMonitors() const override; + QList activeMonitors(const QGeoShape ®ion) const override; + + QGeoAreaMonitorSource::AreaMonitorFeatures supportedAreaMonitorFeatures() const override; + + inline bool isValid() { return positionInfoSource(); } + +private Q_SLOTS: + void positionError(QGeoPositionInfoSource::Error error); + void timeout(const QGeoAreaMonitorInfo &monitor); + void processAreaEvent(const QGeoAreaMonitorInfo &minfo, const QGeoPositionInfo &pinfo, bool isEnteredEvent); + +private: + QGeoAreaMonitorPollingPrivate* d; + QGeoAreaMonitorSource::Error lastError = QGeoAreaMonitorSource::NoError; + friend class QGeoAreaMonitorPollingPrivate; + + int signalConnections = 0; + // connectNotify() and disconnectNotify() can be called from a different + // thread, so we need to synchronize the access to signalConnections + QMutex connectionMutex; + + void connectNotify(const QMetaMethod &signal) override; + void disconnectNotify(const QMetaMethod &signal) override; + + int idForSignal(const char *signal); + + bool hasConnections() const; +}; + +#endif // QGEOAREAMONITORPOLLING_H diff --git a/src/plugins/position/winrt/CMakeLists.txt b/src/plugins/position/winrt/CMakeLists.txt new file mode 100644 index 0000000..98bd15c --- /dev/null +++ b/src/plugins/position/winrt/CMakeLists.txt @@ -0,0 +1,29 @@ +# Generated from winrt.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryWinRT Plugin: +##################################################################### + +qt_internal_add_plugin(QGeoPositionInfoSourceFactoryWinRTPlugin + OUTPUT_NAME qtposition_winrt + CLASS_NAME QGeoPositionInfoSourceFactoryWinRT + PLUGIN_TYPE position + SOURCES + qgeopositioninfosource_winrt.cpp qgeopositioninfosource_winrt_p.h + qgeopositioninfosourcefactory_winrt.cpp qgeopositioninfosourcefactory_winrt.h + LIBRARIES + Qt::Core + Qt::CorePrivate + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:winrt.pro:: +# OTHER_FILES = "plugin.json" + +## Scopes: +##################################################################### + +qt_internal_extend_target(QGeoPositionInfoSourceFactoryWinRTPlugin CONDITION MSVC AND NOT WINRT + LIBRARIES + runtimeobject +) diff --git a/src/plugins/position/winrt/plugin.json b/src/plugins/position/winrt/plugin.json new file mode 100644 index 0000000..0696cb0 --- /dev/null +++ b/src/plugins/position/winrt/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["winrt"], + "Provider": "winrt", + "Position": true, + "Satellite": false, + "Monitor" : false, + "Priority": 1000, + "Testable": false +} diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp new file mode 100644 index 0000000..f104dbf --- /dev/null +++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp @@ -0,0 +1,642 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosource_winrt_p.h" + +#include +#include +#include +#include +#ifdef Q_OS_WINRT +#include +#endif + +#include +#include +#include +#include +#include + +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace ABI::Windows::Devices::Geolocation; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; + +typedef ITypedEventHandler GeoLocatorPositionHandler; +typedef ITypedEventHandler GeoLocatorStatusHandler; +typedef IAsyncOperationCompletedHandler PositionHandler; +typedef IAsyncOperationCompletedHandler AccessHandler; + +Q_DECLARE_LOGGING_CATEGORY(lcPositioningWinRT) + +Q_DECLARE_METATYPE(QGeoPositionInfoSource::Error) + +QT_BEGIN_NAMESPACE + +#ifndef Q_OS_WINRT +namespace QEventDispatcherWinRT { +HRESULT runOnXamlThread(const std::function &delegate, bool waitForRun = true) +{ + Q_UNUSED(waitForRun); + return delegate(); +} +} + +static inline HRESULT await(const ComPtr> &asyncOp, + GeolocationAccessStatus *result) +{ + ComPtr asyncInfo; + HRESULT hr = asyncOp.As(&asyncInfo); + if (FAILED(hr)) + return hr; + + AsyncStatus status; + while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) + QThread::yieldCurrentThread(); + + if (FAILED(hr) || status != AsyncStatus::Completed) { + HRESULT ec; + hr = asyncInfo->get_ErrorCode(&ec); + if (FAILED(hr)) + return hr; + hr = asyncInfo->Close(); + if (FAILED(hr)) + return hr; + return ec; + } + + if (FAILED(hr)) + return hr; + + return asyncOp->GetResults(result); +} +#endif // !Q_OS_WINRT + +enum class InitializationState { + Uninitialized, + Initializing, + Initialized +}; + +class QGeoPositionInfoSourceWinRTPrivate { +public: + ComPtr locator; + mutable ComPtr statics; + QTimer periodicTimer; + QTimer singleUpdateTimer; + QGeoPositionInfo lastPosition; + QGeoPositionInfoSource::Error positionError = QGeoPositionInfoSource::NoError; + EventRegistrationToken statusToken; + EventRegistrationToken positionToken; + QMutex mutex; + bool updatesOngoing = false; + int minimumUpdateInterval = -1; + int updateInterval = -1; + InitializationState initState = InitializationState::Uninitialized; + + PositionStatus positionStatus = PositionStatus_NotInitialized; +}; + +QGeoPositionInfoSourceWinRT::QGeoPositionInfoSourceWinRT(QObject *parent) + : QGeoPositionInfoSource(parent) + , d_ptr(new QGeoPositionInfoSourceWinRTPrivate) +{ + qRegisterMetaType(); + qCDebug(lcPositioningWinRT) << __FUNCTION__; + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + Q_D(QGeoPositionInfoSourceWinRT); + d->positionError = QGeoPositionInfoSource::NoError; + d->updatesOngoing = false; + d->positionToken.value = 0; + d->statusToken.value = 0; +} + +QGeoPositionInfoSourceWinRT::~QGeoPositionInfoSourceWinRT() +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + CoUninitialize(); +} + +int QGeoPositionInfoSourceWinRT::init() +{ + Q_D(QGeoPositionInfoSourceWinRT); + Q_ASSERT(d->initState != InitializationState::Initializing); + if (d->initState == InitializationState::Initialized) + return 0; + + qCDebug(lcPositioningWinRT) << __FUNCTION__; + d->initState = InitializationState::Initializing; + if (!requestAccess()) { + d->initState = InitializationState::Uninitialized; + setError(QGeoPositionInfoSource::AccessError); + qWarning ("Location access failed."); + return -1; + } + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() { + HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(), + &d->locator); + RETURN_HR_IF_FAILED("Could not initialize native location services."); + + if (d->minimumUpdateInterval == -1) { + UINT32 interval; + hr = d->locator->get_ReportInterval(&interval); + RETURN_HR_IF_FAILED("Could not retrieve report interval."); + d->minimumUpdateInterval = static_cast(interval); + } + if (d->updateInterval == -1) + d->updateInterval = d->minimumUpdateInterval; + setUpdateInterval(d->updateInterval); + + return hr; + }); + if (FAILED(hr)) { + d->initState = InitializationState::Uninitialized; + setError(QGeoPositionInfoSource::UnknownSourceError); + return -1; + } + + d->periodicTimer.setSingleShot(true); + connect(&d->periodicTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::virtualPositionUpdate); + + d->singleUpdateTimer.setSingleShot(true); + connect(&d->singleUpdateTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::singleUpdateTimeOut); + + QGeoPositionInfoSource::PositioningMethods preferredMethods = preferredPositioningMethods(); + if (preferredMethods == QGeoPositionInfoSource::NoPositioningMethods) + preferredMethods = QGeoPositionInfoSource::AllPositioningMethods; + setPreferredPositioningMethods(preferredMethods); + + connect(this, &QGeoPositionInfoSourceWinRT::nativePositionUpdate, this, &QGeoPositionInfoSourceWinRT::updateSynchronized); + d->initState = InitializationState::Initialized; + return 0; +} + +QGeoPositionInfo QGeoPositionInfoSourceWinRT::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_D(const QGeoPositionInfoSourceWinRT); + Q_UNUSED(fromSatellitePositioningMethodsOnly); + return d->lastPosition; +} + +QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinRT::supportedPositioningMethods() const +{ + return requestAccess() ? QGeoPositionInfoSource::AllPositioningMethods + : QGeoPositionInfoSource::NoPositioningMethods; +} + +void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods) +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__ << methods; + Q_D(QGeoPositionInfoSourceWinRT); + + PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods(); + QGeoPositionInfoSource::setPreferredPositioningMethods(methods); + if (previousPreferredPositioningMethods == preferredPositioningMethods() + || d->initState == InitializationState::Uninitialized) { + return; + } + + const bool needsRestart = d->positionToken.value != 0 || d->statusToken.value != 0; + + if (needsRestart) + stopHandler(); + + PositionAccuracy acc = methods & PositioningMethod::SatellitePositioningMethods ? + PositionAccuracy::PositionAccuracy_High : + PositionAccuracy::PositionAccuracy_Default; + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, acc]() { + return d->locator->put_DesiredAccuracy(acc); + }); + RETURN_VOID_IF_FAILED("Could not set positioning accuracy."); + + if (needsRestart) + startHandler(); +} + +void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec) +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__ << msec; + Q_D(QGeoPositionInfoSourceWinRT); + if (d->initState == InitializationState::Uninitialized) { + d->updateInterval = msec; + return; + } + + // minimumUpdateInterval is initialized to the lowest possible update interval in init(). + // Passing 0 will cause an error on Windows 10. + // See https://docs.microsoft.com/en-us/uwp/api/windows.devices.geolocation.geolocator.reportinterval + if (msec != 0 && msec < minimumUpdateInterval()) + msec = minimumUpdateInterval(); + + const bool needsRestart = d->positionToken.value != 0 || d->statusToken.value != 0; + + if (needsRestart) + stopHandler(); + + HRESULT hr = d->locator->put_ReportInterval(static_cast(msec)); + if (FAILED(hr)) { + setError(QGeoPositionInfoSource::UnknownSourceError); + qErrnoWarning(hr, "Failed to set update interval"); + return; + } + + d->updateInterval = msec; + d->periodicTimer.setInterval(d->updateInterval); + + QGeoPositionInfoSource::setUpdateInterval(d->updateInterval); + + if (needsRestart) + startHandler(); +} + +int QGeoPositionInfoSourceWinRT::minimumUpdateInterval() const +{ + Q_D(const QGeoPositionInfoSourceWinRT); + return d->minimumUpdateInterval == -1 ? 1000 : d->minimumUpdateInterval; +} + +void QGeoPositionInfoSourceWinRT::startUpdates() +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_D(QGeoPositionInfoSourceWinRT); + + setError(QGeoPositionInfoSource::NoError); + if (init() < 0) + return; + + if (d->updatesOngoing) + return; + + if (!startHandler()) + return; + d->updatesOngoing = true; + d->periodicTimer.start(); +} + +void QGeoPositionInfoSourceWinRT::stopUpdates() +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_D(QGeoPositionInfoSourceWinRT); + + if (init() < 0) + return; + + stopHandler(); + d->updatesOngoing = false; + d->periodicTimer.stop(); +} + +bool QGeoPositionInfoSourceWinRT::startHandler() +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_D(QGeoPositionInfoSourceWinRT); + + // Check if already attached + if (d->positionToken.value != 0) + return true; + + if (preferredPositioningMethods() == QGeoPositionInfoSource::NoPositioningMethods) { + setError(QGeoPositionInfoSource::UnknownSourceError); + return false; + } + + if (!requestAccess()) { + setError(QGeoPositionInfoSource::AccessError); + return false; + } + + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() { + HRESULT hr; + + // We need to call this at least once on Windows 10 Mobile. + // Unfortunately this operation does not have a completion handler + // registered. That could have helped in the single update case + ComPtr> op; + hr = d->locator->GetGeopositionAsync(&op); + RETURN_HR_IF_FAILED("Could not start position operation"); + + hr = d->locator->add_PositionChanged(Callback(this, + &QGeoPositionInfoSourceWinRT::onPositionChanged).Get(), + &d->positionToken); + RETURN_HR_IF_FAILED("Could not add position handler"); + + hr = d->locator->add_StatusChanged(Callback(this, + &QGeoPositionInfoSourceWinRT::onStatusChanged).Get(), + &d->statusToken); + RETURN_HR_IF_FAILED("Could not add status handler"); + return hr; + }); + if (FAILED(hr)) { + setError(QGeoPositionInfoSource::UnknownSourceError); + return false; + } + + return true; +} + +void QGeoPositionInfoSourceWinRT::stopHandler() +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_D(QGeoPositionInfoSourceWinRT); + + if (!d->positionToken.value) + return; + QEventDispatcherWinRT::runOnXamlThread([d]() { + d->locator->remove_PositionChanged(d->positionToken); + d->locator->remove_StatusChanged(d->statusToken); + return S_OK; + }); + d->positionToken.value = 0; + d->statusToken.value = 0; +} + +void QGeoPositionInfoSourceWinRT::requestUpdate(int timeout) +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__ << timeout; + Q_D(QGeoPositionInfoSourceWinRT); + + if (init() < 0) + return; + + setError(QGeoPositionInfoSource::NoError); + if (timeout != 0 && timeout < minimumUpdateInterval()) { + d->positionError = QGeoPositionInfoSource::UpdateTimeoutError; + emit QGeoPositionInfoSource::errorOccurred(d->positionError); + return; + } + + if (timeout == 0) + timeout = 2*60*1000; // Maximum time for cold start (see Android) + + startHandler(); + d->singleUpdateTimer.start(timeout); +} + +void QGeoPositionInfoSourceWinRT::virtualPositionUpdate() +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_D(QGeoPositionInfoSourceWinRT); + QMutexLocker locker(&d->mutex); + + // The operating system did not provide information in time + // Hence we send a virtual position update to keep same behavior + // between backends. + // This only applies to the periodic timer, not for single requests + // We can only do this if we received a valid position before + if (d->lastPosition.isValid()) { + QGeoPositionInfo sent = d->lastPosition; + sent.setTimestamp(sent.timestamp().addMSecs(updateInterval())); + d->lastPosition = sent; + emit positionUpdated(sent); + } + d->periodicTimer.start(); +} + +void QGeoPositionInfoSourceWinRT::singleUpdateTimeOut() +{ + Q_D(QGeoPositionInfoSourceWinRT); + QMutexLocker locker(&d->mutex); + + if (d->singleUpdateTimer.isActive()) { + d->positionError = QGeoPositionInfoSource::UpdateTimeoutError; + emit QGeoPositionInfoSource::errorOccurred(d->positionError); + if (!d->updatesOngoing) + stopHandler(); + } +} + +void QGeoPositionInfoSourceWinRT::updateSynchronized(QGeoPositionInfo currentInfo) +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__ << currentInfo; + Q_D(QGeoPositionInfoSourceWinRT); + QMutexLocker locker(&d->mutex); + + d->periodicTimer.stop(); + d->lastPosition = currentInfo; + + if (d->updatesOngoing) + d->periodicTimer.start(); + + if (d->singleUpdateTimer.isActive()) { + d->singleUpdateTimer.stop(); + if (!d->updatesOngoing) + stopHandler(); + } + + emit positionUpdated(currentInfo); +} + +QGeoPositionInfoSource::Error QGeoPositionInfoSourceWinRT::error() const +{ + Q_D(const QGeoPositionInfoSourceWinRT); + qCDebug(lcPositioningWinRT) << __FUNCTION__ << d->positionError; + + // If the last encountered error was "Access denied", it is possible that the location service + // has been enabled by now so that we are clear again. + if ((d->positionError == QGeoPositionInfoSource::AccessError + || d->positionError == QGeoPositionInfoSource::UnknownSourceError) && requestAccess()) + return QGeoPositionInfoSource::NoError; + + return d->positionError; +} + +void QGeoPositionInfoSourceWinRT::setError(QGeoPositionInfoSource::Error positionError) +{ + Q_D(QGeoPositionInfoSourceWinRT); + + if (positionError == d->positionError) + return; + + qCDebug(lcPositioningWinRT) << __FUNCTION__ << positionError; + d->positionError = positionError; + if (positionError != QGeoPositionInfoSource::NoError) + emit QGeoPositionInfoSource::errorOccurred(positionError); +} + +void QGeoPositionInfoSourceWinRT::reactOnError(QGeoPositionInfoSource::Error positionError) +{ + setError(positionError); + stopUpdates(); +} + +HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPositionChangedEventArgs *args) +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_UNUSED(locator); + + HRESULT hr; + ComPtr position; + hr = args->get_Position(&position); + RETURN_HR_IF_FAILED("Could not access position object."); + + QGeoPositionInfo currentInfo; + + ComPtr coord; + hr = position->get_Coordinate(&coord); + if (FAILED(hr)) + qErrnoWarning(hr, "Could not access coordinate"); + + ComPtr pointCoordinate; + hr = coord.As(&pointCoordinate); + if (FAILED(hr)) + qErrnoWarning(hr, "Could not cast coordinate."); + + ComPtr point; + hr = pointCoordinate->get_Point(&point); + if (FAILED(hr)) + qErrnoWarning(hr, "Could not obtain coordinate's point."); + + BasicGeoposition pos; + hr = point->get_Position(&pos); + if (FAILED(hr)) + qErrnoWarning(hr, "Could not obtain point's position."); + + DOUBLE lat = pos.Latitude; + DOUBLE lon = pos.Longitude; + DOUBLE alt = pos.Altitude; + + bool altitudeAvailable = false; + ComPtr shape; + hr = point.As(&shape); + if (SUCCEEDED(hr) && shape) { + AltitudeReferenceSystem altitudeSystem; + hr = shape->get_AltitudeReferenceSystem(&altitudeSystem); + if (SUCCEEDED(hr) && altitudeSystem == AltitudeReferenceSystem_Geoid) + altitudeAvailable = true; + } + if (altitudeAvailable) + currentInfo.setCoordinate(QGeoCoordinate(lat, lon, alt)); + else + currentInfo.setCoordinate(QGeoCoordinate(lat, lon)); + + DOUBLE accuracy; + hr = coord->get_Accuracy(&accuracy); + if (SUCCEEDED(hr)) + currentInfo.setAttribute(QGeoPositionInfo::HorizontalAccuracy, accuracy); + + IReference *altAccuracy; + hr = coord->get_AltitudeAccuracy(&altAccuracy); + if (SUCCEEDED(hr) && altAccuracy) { + double value; + hr = altAccuracy->get_Value(&value); + currentInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy, value); + } + + IReference *speed; + hr = coord->get_Speed(&speed); + if (SUCCEEDED(hr) && speed) { + double value; + hr = speed->get_Value(&value); + currentInfo.setAttribute(QGeoPositionInfo::GroundSpeed, value); + } + + IReference *heading; + hr = coord->get_Heading(&heading); + if (SUCCEEDED(hr) && heading) { + double value; + hr = heading->get_Value(&value); + double mod = 0; + value = modf(value, &mod); + value += static_cast(mod) % 360; + if (value >=0 && value <= 359) // get_Value might return nan/-nan + currentInfo.setAttribute(QGeoPositionInfo::Direction, value); + } + + DateTime dateTime; + hr = coord->get_Timestamp(&dateTime); + + if (dateTime.UniversalTime > 0) { + ULARGE_INTEGER uLarge; + uLarge.QuadPart = dateTime.UniversalTime; + FILETIME fileTime; + fileTime.dwHighDateTime = uLarge.HighPart; + fileTime.dwLowDateTime = uLarge.LowPart; + SYSTEMTIME systemTime; + if (FileTimeToSystemTime(&fileTime, &systemTime)) { + currentInfo.setTimestamp(QDateTime(QDate(systemTime.wYear, systemTime.wMonth, + systemTime.wDay), + QTime(systemTime.wHour, systemTime.wMinute, + systemTime.wSecond, systemTime.wMilliseconds), + Qt::UTC)); + } + } + + emit nativePositionUpdate(currentInfo); + + return S_OK; +} + +static inline bool isDisabledStatus(PositionStatus status) +{ + return status == PositionStatus_NoData || status == PositionStatus_Disabled + || status == PositionStatus_NotAvailable; +} + +HRESULT QGeoPositionInfoSourceWinRT::onStatusChanged(IGeolocator *, IStatusChangedEventArgs *args) +{ + Q_D(QGeoPositionInfoSourceWinRT); + + const PositionStatus oldStatus = d->positionStatus; + HRESULT hr = args->get_Status(&d->positionStatus); + RETURN_HR_IF_FAILED("Could not obtain position status"); + qCDebug(lcPositioningWinRT) << __FUNCTION__ << d->positionStatus; + QGeoPositionInfoSource::Error error = QGeoPositionInfoSource::NoError; + switch (d->positionStatus) { + case PositionStatus::PositionStatus_NotAvailable: + error = QGeoPositionInfoSource::UnknownSourceError; + break; + case PositionStatus::PositionStatus_Disabled: + error = QGeoPositionInfoSource::AccessError; + break; + case PositionStatus::PositionStatus_NoData: + error = QGeoPositionInfoSource::ClosedError; + break; + } + if (error != QGeoPositionInfoSource::NoError) { + QMetaObject::invokeMethod(this, "reactOnError", Qt::QueuedConnection, + Q_ARG(QGeoPositionInfoSource::Error, + QGeoPositionInfoSource::UnknownSourceError)); + } + + if (isDisabledStatus(oldStatus) != isDisabledStatus(d->positionStatus)) + emit supportedPositioningMethodsChanged(); + + return S_OK; +} + +bool QGeoPositionInfoSourceWinRT::requestAccess() const +{ + Q_D(const QGeoPositionInfoSourceWinRT); + qCDebug(lcPositioningWinRT) << __FUNCTION__; + GeolocationAccessStatus accessStatus; + + ComPtr> op; + HRESULT hr; + hr = QEventDispatcherWinRT::runOnXamlThread([&op, d]() { + HRESULT hr; + if (!d->statics) { + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(), + IID_PPV_ARGS(&d->statics)); + RETURN_HR_IF_FAILED("Could not access Geolocation Statics."); + } + + hr = d->statics->RequestAccessAsync(&op); + return hr; + }); + if (FAILED(hr)) { + qCDebug(lcPositioningWinRT) << __FUNCTION__ << "Requesting access from Xaml thread failed"; + return false; + } + + // We cannot wait inside the XamlThread as that would deadlock +#ifdef Q_OS_WINRT + QWinRTFunctions::await(op, &accessStatus); +#else + await(op, &accessStatus); +#endif + return accessStatus == GeolocationAccessStatus_Allowed; +} + +QT_END_NAMESPACE diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h new file mode 100644 index 0000000..f4467f1 --- /dev/null +++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h @@ -0,0 +1,91 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCEWINRT_H +#define QGEOPOSITIONINFOSOURCEWINRT_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 "qgeopositioninfosource.h" +#include "qgeopositioninfo.h" + +#include + +#include +#include + +namespace ABI { + namespace Windows { + namespace Devices { + namespace Geolocation{ + struct IGeolocator; + struct IPositionChangedEventArgs; + struct IStatusChangedEventArgs; + } + } + } +} + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfoSourceWinRTPrivate; + +class QGeoPositionInfoSourceWinRT : public QGeoPositionInfoSource +{ + Q_OBJECT +public: + QGeoPositionInfoSourceWinRT(QObject *parent = nullptr); + ~QGeoPositionInfoSourceWinRT() override; + int init(); + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override; + PositioningMethods supportedPositioningMethods() const override; + + void setPreferredPositioningMethods(PositioningMethods methods) override; + + void setUpdateInterval(int msec) override; + int minimumUpdateInterval() const override; + Error error() const override; + + HRESULT onPositionChanged(ABI::Windows::Devices::Geolocation::IGeolocator *locator, + ABI::Windows::Devices::Geolocation::IPositionChangedEventArgs *args); + HRESULT onStatusChanged(ABI::Windows::Devices::Geolocation::IGeolocator *locator, + ABI::Windows::Devices::Geolocation::IStatusChangedEventArgs *args); + + bool requestAccess() const; +Q_SIGNALS: + void nativePositionUpdate(const QGeoPositionInfo); +public slots: + void startUpdates() override; + void stopUpdates() override; + + void requestUpdate(int timeout = 0) override; + +private slots: + void stopHandler(); + void virtualPositionUpdate(); + void singleUpdateTimeOut(); + void updateSynchronized(const QGeoPositionInfo info); + void reactOnError(QGeoPositionInfoSource::Error positionError); +private: + bool startHandler(); + + Q_DISABLE_COPY(QGeoPositionInfoSourceWinRT) + void setError(QGeoPositionInfoSource::Error positionError); + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(QGeoPositionInfoSourceWinRT) +}; + +QT_END_NAMESPACE + +#endif // QGEOPOSITIONINFOSOURCEWINRT_H diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp new file mode 100644 index 0000000..fe9bcaf --- /dev/null +++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp @@ -0,0 +1,37 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosourcefactory_winrt.h" +#include "qgeopositioninfosource_winrt_p.h" + +#include + +Q_LOGGING_CATEGORY(lcPositioningWinRT, "qt.positioning.winrt") + +QT_BEGIN_NAMESPACE + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryWinRT::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_UNUSED(parameters) + QGeoPositionInfoSourceWinRT *src = new QGeoPositionInfoSourceWinRT(parent); + return src; +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryWinRT::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryWinRT::areaMonitor(QObject *parent, const QVariantMap ¶meters) +{ + qCDebug(lcPositioningWinRT) << __FUNCTION__; + Q_UNUSED(parent) + Q_UNUSED(parameters) + return nullptr; +} + +QT_END_NAMESPACE diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h new file mode 100644 index 0000000..2a24781 --- /dev/null +++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h @@ -0,0 +1,26 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCEFACTORY_WINRT_H +#define QGEOPOSITIONINFOSOURCEFACTORY_WINRT_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfoSourceFactoryWinRT : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +QT_END_NAMESPACE + +#endif // QGEOPOSITIONINFOSOURCEFACTORY_WINRT_H diff --git a/src/positioning/CMakeLists.txt b/src/positioning/CMakeLists.txt new file mode 100644 index 0000000..2791d55 --- /dev/null +++ b/src/positioning/CMakeLists.txt @@ -0,0 +1,68 @@ +# Generated from positioning.pro. + +##################################################################### +## Positioning Module: +##################################################################### + +qt_internal_add_module(Positioning + PLUGIN_TYPES position + SOURCES + qclipperutils.cpp qclipperutils_p.h + qdoublematrix4x4.cpp qdoublematrix4x4_p.h + qdoublevector2d.cpp qdoublevector2d_p.h + qdoublevector3d.cpp qdoublevector3d_p.h + qgeoaddress.cpp qgeoaddress.h qgeoaddress_p.h + qgeoareamonitorinfo.cpp qgeoareamonitorinfo.h + qgeoareamonitorsource.cpp qgeoareamonitorsource.h + qgeocircle.cpp qgeocircle.h qgeocircle_p.h + qgeocoordinate.cpp qgeocoordinate.h qgeocoordinate_p.h + qgeocoordinateobject.cpp qgeocoordinateobject_p.h + qgeolocation.cpp qgeolocation.h qgeolocation_p.h + qgeopath.cpp qgeopath.h qgeopath_p.h + qgeopolygon.cpp qgeopolygon.h qgeopolygon_p.h + qgeopositioninfo.cpp qgeopositioninfo.h qgeopositioninfo_p.h + qgeopositioninfosource.cpp qgeopositioninfosource.h qgeopositioninfosource_p.h + qgeopositioninfosourcefactory.cpp qgeopositioninfosourcefactory.h + qgeorectangle.cpp qgeorectangle.h qgeorectangle_p.h + qgeosatelliteinfo.cpp qgeosatelliteinfo.h qgeosatelliteinfo_p.h + qgeosatelliteinfosource.cpp qgeosatelliteinfosource.h qgeosatelliteinfosource_p.h + qgeoshape.cpp qgeoshape.h qgeoshape_p.h + qlocationutils.cpp qlocationutils_p.h + qnmeapositioninfosource.cpp qnmeapositioninfosource.h qnmeapositioninfosource_p.h + qnmeasatelliteinfosource.cpp qnmeasatelliteinfosource.h qnmeasatelliteinfosource_p.h + qpositioningglobal.h qpositioningglobal_p.h + qwebmercator.cpp qwebmercator_p.h + INCLUDE_DIRECTORIES + ../3rdparty/clip2tri + ../3rdparty/clipper + LIBRARIES + Qt::CorePrivate + Qt::Bundled_Clip2Tri + PUBLIC_LIBRARIES + Qt::Core + PRIVATE_MODULE_INTERFACE + Qt::CorePrivate + GENERATE_CPP_EXPORTS + GENERATE_PRIVATE_CPP_EXPORTS +) + +if(ANDROID) + set_property(TARGET Positioning APPEND PROPERTY QT_ANDROID_BUNDLED_JAR_DEPENDENCIES + jar/Qt${QtLocation_VERSION_MAJOR}AndroidPositioning.jar:org.qtproject.qt.android.positioning.QtPositioning # special case + ) + set_property(TARGET Positioning APPEND PROPERTY QT_ANDROID_LIB_DEPENDENCIES + plugins/position/libplugins_position_qtposition_android.so + ) + set_property(TARGET Positioning APPEND PROPERTY QT_ANDROID_PERMISSIONS + android.permission.ACCESS_FINE_LOCATION + ) +endif() + +#### Keys ignored in scope 1:.:.:positioning.pro:: +# ANDROID_FEATURES = "android.hardware.location.gps" +# MODULE_WINRT_CAPABILITIES_DEVICE = "location" +# OTHER_FILES = "configure.json" "doc/src/*.qdoc" "doc/src/plugins/*.qdoc" +qt_internal_add_docs(Positioning + doc/qtpositioning.qdocconf +) + diff --git a/src/positioning/configure.cmake b/src/positioning/configure.cmake new file mode 100644 index 0000000..979c143 --- /dev/null +++ b/src/positioning/configure.cmake @@ -0,0 +1,28 @@ +# begin special case + +#### Libraries + +qt_find_package(Gypsy PROVIDED_TARGETS Gypsy::Gypsy) +qt_find_package(Gconf PROVIDED_TARGETS Gconf::Gconf) + +#### Tests + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../config.tests/winrt/CMakeLists.txt") + qt_config_compile_test("winrt_geolocation" + LABEL "WinRT geolocation" + PROJECT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../config.tests/winrt") +endif() + +#### Features + +qt_feature("gypsy" PUBLIC + LABEL "Gypsy - A GPS Multiplexing Daemon" + CONDITION Gypsy_FOUND AND Gconf_FOUND +) + +qt_feature("winrt_geolocation" PRIVATE + LABEL "WinRT geolocation API" + CONDITION WIN32 AND TEST_winrt_geolocation +) + +# end special case diff --git a/src/positioning/configure.json b/src/positioning/configure.json new file mode 100644 index 0000000..49e32be --- /dev/null +++ b/src/positioning/configure.json @@ -0,0 +1,48 @@ +{ + "module": "positioning", + "testDir": "../../config.tests", + + "libraries": { + "gypsy": { + "label": "Gypsy", + "test": "gypsy", + "sources": [ + { "type": "pkgConfig", "args": "gypsy gconf-2.0" } + ] + } + }, + + "tests": { + "winrt_geolocation": { + "label": "WinRT Geolocation API", + "type": "compile", + "test": "winrt" + } + }, + + "features": { + "gypsy": { + "label": "Gypsy GPS Daemon", + "condition": "libs.gypsy", + "output": [ "privateFeature" ] + }, + "winrt_geolocation": { + "label": "WinRT Geolocation API", + "condition": "tests.winrt_geolocation", + "output": [ "privateFeature" ] + } + }, + + "report": [ + ], + + "summary": [ + { + "section": "Qt Positioning", + "entries": [ + "gypsy", + "winrt_geolocation" + ] + } + ] +} diff --git a/src/positioning/doc/images/permissions.png b/src/positioning/doc/images/permissions.png new file mode 100644 index 0000000000000000000000000000000000000000..bd8c48501ef0d4bdb151794479f8e0f870e581ab GIT binary patch literal 19306 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 V31msa!?REiWtHw1N*lcUKLA@?{zCu& literal 0 HcmV?d00001 diff --git a/src/positioning/doc/qtpositioning.qdocconf b/src/positioning/doc/qtpositioning.qdocconf new file mode 100644 index 0000000..052801d --- /dev/null +++ b/src/positioning/doc/qtpositioning.qdocconf @@ -0,0 +1,53 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include($QT_INSTALL_DOCS/config/exampleurl-qtlocation.qdocconf) + +project = QtPositioning +description = Qt Positioning Reference Documentation +version = $QT_VERSION + + + +qhp.projects = QtPositioning + +qhp.QtPositioning.file = qtpositioning.qhp +qhp.QtPositioning.namespace = org.qt-project.qtpositioning.$QT_VERSION_TAG +qhp.QtPositioning.virtualFolder = qtpositioning +qhp.QtPositioning.indexTitle = Qt Positioning +qhp.QtPositioning.indexRoot = + +qhp.QtPositioning.subprojects = classes qml examples +qhp.QtPositioning.subprojects.classes.title = C++ Classes +qhp.QtPositioning.subprojects.classes.indexTitle = Qt Positioning C++ Classes +qhp.QtPositioning.subprojects.classes.selectors = class fake:headerfile +qhp.QtPositioning.subprojects.classes.sortPages = true +qhp.QtPositioning.subprojects.qml.title = QML Types +qhp.QtPositioning.subprojects.qml.indexTitle = Qt Positioning QML Types +qhp.QtPositioning.subprojects.qml.selectors = qmlclass +qhp.QtPositioning.subprojects.qml.sortPages = true +qhp.QtPositioning.subprojects.examples.title = Qt Positioning Examples +qhp.QtPositioning.subprojects.examples.indexTitle = Qt Positioning Examples +qhp.QtPositioning.subprojects.examples.selectors = fake:example + +tagfile = ../../../doc/qtpositioning/qtpositioning.tags + +depends += qtcore qtdoc qtquick qtqml qtnetwork qtqmlxmllistmodel qmake qtcmake + +headerdirs += .. \ + ../../positioningquick + +sourcedirs += .. \ + ../../positioningquick + +examplesinstallpath = positioning + +exampledirs += ../../../examples/positioning \ + snippets/ + + +imagedirs += images + +navigation.landingpage = "Qt Positioning" +navigation.cppclassespage = "Qt Positioning C++ Classes" +navigation.qmltypespage = "Qt Positioning QML Types" + +manifestmeta.thumbnail.names += "QtPositioning/Log File*" diff --git a/src/positioning/doc/snippets/CMakeLists.txt b/src/positioning/doc/snippets/CMakeLists.txt new file mode 100644 index 0000000..2322a85 --- /dev/null +++ b/src/positioning/doc/snippets/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(cpp) diff --git a/src/positioning/doc/snippets/cpp/CMakeLists.txt b/src/positioning/doc/snippets/cpp/CMakeLists.txt new file mode 100644 index 0000000..1927766 --- /dev/null +++ b/src/positioning/doc/snippets/cpp/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.16) +project(positioning_cppsnippet LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Positioning) + +qt_add_executable(positioning_cppsnippet + cppqml.cpp + main.cpp +) +set_target_properties(positioning_cppsnippet PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(positioning_cppsnippet PRIVATE + Qt::Core + Qt::Positioning +) diff --git a/src/positioning/doc/snippets/cpp/cppqml.cpp b/src/positioning/doc/snippets/cpp/cppqml.cpp new file mode 100644 index 0000000..19dd718 --- /dev/null +++ b/src/positioning/doc/snippets/cpp/cppqml.cpp @@ -0,0 +1,71 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include +#include +#include +#include +#include +#include +#include + +void cppQmlInterface(QObject *qmlObject) +{ + //! [Address get] + QGeoAddress geoAddress = qmlObject->property("address").value(); + //! [Address get] + + //! [Address set] + qmlObject->setProperty("address", QVariant::fromValue(geoAddress)); + //! [Address set] + + //! [Location get] + QGeoLocation geoLocation = qmlObject->property("location").value(); + //! [Location get] + + //! [Location set] + qmlObject->setProperty("location", QVariant::fromValue(geoLocation)); + //! [Location set] +} + +class MyClass : public QObject +{ + Q_OBJECT +//! [BigBen] +public: + MyClass() : QObject() + { + QGeoAreaMonitorSource *monitor = QGeoAreaMonitorSource::createDefaultSource(this); + if (monitor) { + connect(monitor, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)), + this, SLOT(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo))); + connect(monitor, SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)), + this, SLOT(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo))); + + QGeoAreaMonitorInfo bigBen("Big Ben"); + QGeoCoordinate position(51.50104, -0.124632); + bigBen.setArea(QGeoCircle(position, 100)); + + monitor->startMonitoring(bigBen); + + } else { + qDebug() << "Could not create default area monitor"; + } + } + +public Q_SLOTS: + void areaEntered(const QGeoAreaMonitorInfo &mon, const QGeoPositionInfo &update) + { + Q_UNUSED(mon); + + qDebug() << "Now within 100 meters, current position is" << update.coordinate(); + } + + void areaExited(const QGeoAreaMonitorInfo &mon, const QGeoPositionInfo &update) + { + Q_UNUSED(mon); + + qDebug() << "No longer within 100 meters, current position is" << update.coordinate(); + } +//! [BigBen] +}; diff --git a/src/positioning/doc/snippets/cpp/main.cpp b/src/positioning/doc/snippets/cpp/main.cpp new file mode 100644 index 0000000..fb6724d --- /dev/null +++ b/src/positioning/doc/snippets/cpp/main.cpp @@ -0,0 +1,8 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +int main(int /*argc*/, char ** /*argv*/) +{ + return 0; +} + diff --git a/src/positioning/doc/snippets/doc_src_qtpositioning.qml b/src/positioning/doc/snippets/doc_src_qtpositioning.qml new file mode 100644 index 0000000..8dac7dc --- /dev/null +++ b/src/positioning/doc/snippets/doc_src_qtpositioning.qml @@ -0,0 +1,10 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +//! [import] +import QtPositioning +//! [import] + +Item { +} + diff --git a/src/positioning/doc/src/cpp-position.qdoc b/src/positioning/doc/src/cpp-position.qdoc new file mode 100644 index 0000000..924e457 --- /dev/null +++ b/src/positioning/doc/src/cpp-position.qdoc @@ -0,0 +1,170 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page location-positioning-cpp.html + +\title Positioning (C++) + +\brief The Location Positioning API enables location positioning by means of +GPS or an NMEA data source. + +\section1 Positioning + +The Positioning component of the Qt Location API is about the geographical +position, size, and address of some place. Positioning contains a +\l QGeoCoordinate class, containing latitude, longitude and altitude in meters. +\l QGeoLocation contains a \l QGeoCoordinate plus address and size information +(a bounding box) so that positions can be more than mathematical points. +Movement into or out of the defined bounding box areas can be monitored. The API +also allows the developer to control the source of the positional information +as well. + +Location data involves a precisely specified position on the Earth's +surface \unicode {0x2014} as provided by a latitude-longitude coordinate +\unicode {0x2014} along with associated data, such as: + + \list + \li The date and time at which the position was reported + \li The velocity of the device that reported the position + \li The altitude of the reported position (height above sea level) + \li The bearing of the device in degrees, relative to true north + \endlist + +This data can be extracted through a variety of methods. One of the most +well known methods of positioning is GPS (Global Positioning System), a +publicly available system that uses radiowave signals received from +Earth-orbiting satellites to calculate the precise position and time of +the receiver. Another popular method is 'Cell Identifier Positioning', which uses +the cell identifier of the cell site that is currently serving the receiving +device to calculate its approximate location. These and other positioning +methods can all be used with the Location API; the only requirement for a +location data source within the API is that it provides a +latitude-longitude coordinate with a date/time value, with the option of +providing the other attributes listed above. + + +Location data sources are created by subclassing \l QGeoPositionInfoSource and +providing \l QGeoPositionInfo objects through the +\l {QGeoPositionInfoSource::positionUpdated()} signal. Clients that require +location data can connect to the +\l{QGeoPositionInfoSource::positionUpdated()}{positionUpdated()} signal and +call \l{QGeoPositionInfoSource::startUpdates()}{startUpdates()} or +\l{QGeoPositionInfoSource::requestUpdate()}{requestUpdate()} to trigger the +distribution of location data. The location data distribution can be stopped by +calling the \l {QGeoPositionInfoSource::stopUpdates()}{stopUpdates()} function. + +A default position source may be available on some platforms. Call +\l {QGeoPositionInfoSource::createDefaultSource()} to create an instance of the +default position source. The method returns \c nullptr if no default source is +available for the platform. + +If a problem occurs with access to the information source then an +\l {QGeoPositionInfoSource::errorOccurred()}{errorOccurred()} signal is emitted. + +The \l QGeoAreaMonitorSource class enables client applications to be notified +when the receiving device has moved into or out of a particular area, as +specified by a coordinate and radius. If the platform provides built-in support +for area monitoring, the \l {QGeoAreaMonitorSource::createDefaultSource()} +method returns an instance of the default area monitor. + +Satellite information can also be distributed through the +\l QGeoSatelliteInfoSource class. Call +\l {QGeoSatelliteInfoSource::createDefaultSource()} to create an instance of the +default satellite data source for the platform if one is available. +Alternatively, clients can subclass it to provide a custom satellite data +source. + + + +\section2 Requesting Location Data from Data Sources + +To receive data from a source, connect to its +\l{QGeoPositionInfoSource::positionUpdated()}{positionUpdated()} signal, +then call either \l{QGeoPositionInfoSource::startUpdates()}{startUpdates()} +or \l{QGeoPositionInfoSource::requestUpdate()}{requestUpdate()} to begin. + +Here is an example of a client that receives data from the default location +data source, as returned by \l {QGeoPositionInfoSource::createDefaultSource()}: + +\code +class MyClass : public QObject +{ + Q_OBJECT +public: + MyClass(QObject *parent = 0) + : QObject(parent) + { + QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this); + if (source) { + connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), + this, SLOT(positionUpdated(QGeoPositionInfo))); + source->startUpdates(); + } + } + +private slots: + void positionUpdated(const QGeoPositionInfo &info) + { + qDebug() << "Position updated:" << info; + } +}; + +\endcode + +\section2 Controlling Aspects of Data Sources + +The \l {QGeoPositionInfoSource::setUpdateInterval()} method can be used to +control the rate at which position updates are received. For example, if +the client application only requires updates once every 30 seconds, it can +call \c setUpdateInterval(30000). If no update interval is set, or +\l {QGeoPositionInfoSource::}{setUpdateInterval()} is called with a value of 0, +the source uses a default interval or some other internal logic to determine +when updates should be provided. + +\l {QGeoPositionInfoSource::setPreferredPositioningMethods()} enables client +applications to request that a certain type of positioning method be used. +For example, if the application prefers to use only satellite positioning, +which offers fairly precise outdoor positioning but can be a heavy user of +power resources, it can call this method with the +\l {QGeoPositionInfoSource::SatellitePositioningMethods} value. However, this +method should only be used in specialized client applications; in most +cases, the default positioning methods should not be changed, as a source +may internally use a variety of positioning methods that can be useful to +the application. + +\section2 NMEA Data + +\l {http://en.wikipedia.org/wiki/NMEA_0183}{NMEA} is a common text-based +protocol for specifying navigational data. For convenience, the +\l QNmeaPositionInfoSource is provided to enable client applications to read +and distribute NMEA data in either real-time mode (for example, when +streaming from a GPS device) or simulation mode (for example, when reading +from a NMEA log file). In simulation mode, the source will emit updates +according to the time stamp of each NMEA sentence to produce a "replay" +of the recorded data. + +Generally, the capabilities provided by the default position source as +returned by \l {QGeoPositionInfoSource::createDefaultSource()}, along with the +\l QNmeaPositionInfoSource class, are sufficient for retrieving location +data. However, in some cases developers may wish to write their own custom +location data source. + +The \l {Log File Position Source (C++)} example demonstrates how to subclass +\l QGeoPositionInfoSource to create a custom positioning source. + + +\section1 Examples + +\section3 \b{Flickr Example} + +The \l{GeoFlickr QML}{Flickr Example} uses the current location to download thumbnail +images from Flickr relevant to the current location. + + + +\section1 Positioning Classes + +\annotatedlist QtPositioning-positioning + +*/ diff --git a/src/positioning/doc/src/cpp-qml-positioning.qdoc b/src/positioning/doc/src/cpp-qml-positioning.qdoc new file mode 100644 index 0000000..905ea3d --- /dev/null +++ b/src/positioning/doc/src/cpp-qml-positioning.qdoc @@ -0,0 +1,90 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page positioning-cpp-qml.html +\title Interfaces between C++ and QML Code in Qt Positioning + +\brief Describes the methods used to exchange position data between C++ and QML +code. + +\section1 Overview + +Qt Positioning utilizes two methods to simplify exchange of position data +between C++ and QML code. + +\target Cpp_value_integration_positioning +\section1 Direct C++ Value Integration in QtPositioning + +Starting with Qt 5.5, it has become much easier to integrate non-QObject based +data types into QML. This is achieved by adding \l Q_GADGET support to \l QtQml. +The macro converts classes into a light-weight version of a \l QObject without +the required \l QObject inheritance. At the same time, it retains the reflection +capabilities of \l QMetaObject. As a result, they can be directly exposed to +QML. + +A significant number of Position related data types were converted to +\l {Q_GADGET}s. They retain their API and value type character but have become +introspectable via \l QMetaObject. + +The \l QML_ANONYMOUS macro is used to expose these types to the QML environment. +See the \l QQmlEngine documentation for more details and the full list of +available macros. + +The classes, however, are not directly extended with this macro, because we do +not want Qt Positioning to depend on \l QtQml. So a helper class is created for +each of them, and the \l QML_FOREIGN macro is used: + +\code +struct QGeoCoordinateForeign +{ + Q_GADGET + QML_FOREIGN(QGeoCoordinate) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; +\endcode + +The above registration of Positioning types is automatically done once by the +QtPositioning QML plugin. + +\section1 QVariant Based integration + +This section provides information on how to integrate QGeoAddress and +QGeoLocation. + +\section2 Address - QGeoAddress + +The \l {QtPositioning::Address::address} {Address.address} property is used to +provide an interface between C++ and QML code. First a pointer to an +\l {QtPositioning::}{Address} object must be obtained from C++, then the +\l {QObject::}{property()} and \l {QObject::}{setProperty()} functions must be +used to get and set the \c address property. + +The following piece of code gets the \l QGeoAddress object from C++: + +\snippet cpp/cppqml.cpp Address get + +The following piece of code sets the address property of the QML object based +on a \l QGeoAddress object from C++: + +\snippet cpp/cppqml.cpp Address set + + +\section2 Location - QGeoLocation +The \l {Location::location} {Location.location} property is used to provide an +interface between C++ and QML code. First a pointer to a \l Location object +must be obtained from C++, then the \l {QObject::}{property()} and +\l {QObject::}{setProperty()} functions must be used to get and set the +\c location property. + +The following piece of code gets the \l QGeoLocation object from C++: + +\snippet cpp/cppqml.cpp Location get + +The following piece of code sets the location property of the QML object based +on a \l QGeoLocation object from C++: + +\snippet cpp/cppqml.cpp Location set + +*/ diff --git a/src/positioning/doc/src/external-resources.qdoc b/src/positioning/doc/src/external-resources.qdoc new file mode 100644 index 0000000..9a136b0 --- /dev/null +++ b/src/positioning/doc/src/external-resources.qdoc @@ -0,0 +1,47 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\externalpage https://developer.android.com/about/versions/oreo/background-location-limits +\title Background Location Limits +*/ + +/*! +\externalpage https://developer.android.com/guide/components/foreground-services +\title Foreground Service +*/ + +/*! +\externalpage https://developer.android.com/reference/android/Manifest.permission#ACCESS_BACKGROUND_LOCATION +\title ACCESS_BACKGROUND_LOCATION +*/ + +/*! +\externalpage https://developer.android.com/training/location/background +\title Access Location in the Background +*/ + +/*! +\externalpage https://gitlab.freedesktop.org/geoclue/geoclue/-/wikis/home +\title GeoClue service +*/ + +/*! +\externalpage https://www.freedesktop.org/software/geoclue/docs/gdbus-org.freedesktop.GeoClue2.Client.html#gdbus-property-org-freedesktop-GeoClue2-Client.DesktopId +\title GeoClue DesktopId property +*/ + +/*! +\externalpage https://gypsy.freedesktop.org/wiki/ +\title Gypsy daemon +*/ + +/*! +\externalpage https://developer.android.com/reference/android/location/Location.html#getBearingAccuracyDegrees%28%29 +\title Android getBearingAccuracyDegrees +*/ + +/*! +\externalpage https://developer.apple.com/documentation/corelocation/cllocation/3524338-courseaccuracy?language=objc +\title iOS courseAccuracy +*/ diff --git a/src/positioning/doc/src/plugins/geoclue2.qdoc b/src/positioning/doc/src/plugins/geoclue2.qdoc new file mode 100644 index 0000000..df95d33 --- /dev/null +++ b/src/positioning/doc/src/plugins/geoclue2.qdoc @@ -0,0 +1,62 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page position-plugin-geoclue2.html +\title Qt Positioning GeoClue v2 plugin +\ingroup QtPositioning-plugins + +\brief Uses the GeoClue v2 library to provide positioning updates + +\section1 Overview + +This plugin is an interface to the \l {GeoClue service}{GeoClue v2} library. +It requires this library to be installed on the system to function. + +The plugin uses D-Bus to establish communication with the GeoClue v2 D-Bus +service and to provide positioning information. + +The plugin can be used to receive only the positioning information. +It \e {does not} provide satellite information. + +The plugin can be loaded by using the provider name \b geoclue2. + +\section1 Parameters + +The following table lists parameters that \e can be passed to the geoclue2 +plugin. + +\table +\header + \li Parameter + \li Description +\row + \li desktopId + \li The \l {GeoClue DesktopId property}{Desktop Id} property used by the + D-Bus service. If the parameter is not specified, the application name + provided by \l QCoreApplication::applicationName() is used. +\endtable + +\section1 Usage example + +The following examples show how to create a \b geoclue2 PositionSource from +C++ and QML. + +\section2 QML + +\code +PositionSource { + name: "geoclue2" + PluginParameter { name: "desktopId"; value: "SomeIdentifierString" } +} +\endcode + +\section2 C++ + +\code +QVariantMap params; +params["desktopId"] = "SomeIdentifierString"; +QGeoPositionInfoSource *positionSource = QGeoPositionInfoSource::createSource("geoclue2", params, this); +\endcode + +*/ diff --git a/src/positioning/doc/src/plugins/gypsy.qdoc b/src/positioning/doc/src/plugins/gypsy.qdoc new file mode 100644 index 0000000..34640d9 --- /dev/null +++ b/src/positioning/doc/src/plugins/gypsy.qdoc @@ -0,0 +1,91 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page position-plugin-gypsy.html +\title Qt Positioning Gypsy plugin +\ingroup QtPositioning-plugins + +\brief Uses the Gypsy daemon to provide satellite information + +\section1 Overview + +The plugin is an interface to the \l {Gypsy daemon}. It requires the daemon +to be installed and running on the system to function. + +The plugin uses D-Bus and GLib to connect to GPS device and provide satellite +information. + +Currently the plugin \e {does not} provide positioning information. + +The plugin can be loaded using provider name \b gypsy. + +\section1 Parameters + +The following table lists parameters that \e can be passed to the gypsy +plugin. + +\table +\header + \li Parameter + \li Description +\row + \li deviceName + \li The name of the device (or path to the device file) that will be used + to provide satellite information. The typical values can be + \c {/dev/ttyUSB0} or \c {/dev/ttyACM0}. +\row + \li gconfKey + \li The key that will be used to extract device name from the GConf + configuration system. +\endtable + +The plugin supports two ways of specifying the device name: +\list + \li Specify the device name directly with the \e deviceName plugin + parameter. + \li Specify the configuration key using \e gconfKey plugin parameter and + extract the device name from the GConf configuration system. This + approach is useful when the device name is already specified for some + other GConf-based application. +\endlist + +By default, when none of the parameters is specified, the plugin will try to +extract the device name from the GConf configuration system using the following +hardcoded key: + +\badcode +/apps/geoclue/master/org.freedesktop.Geoclue.GPSDevice +\endcode + +\section2 Using GConf to set parameters + +To specify a value for a key in the GConf configuration system, use +\e {gconftool-2} as follows: + +\badcode +gconftool-2 -t string -s /apps/geoclue/master/org.freedesktop.Geoclue.GPSDevice /dev/ttyUSB0 +\endcode + +\section1 Usage example + +The following examples show how to create a \b gypsy satellite info source +from C++. + +Specifying device name directly: + +\code +QVariantMap parameters; +parameters["deviceName"] = "/dev/ttyACM0"; +QGeoSatelliteInfoSource *source = QGeoSatelliteInfoSource::createSource("gypsy", parameters, this); +\endcode + +Using GConf key: + +\code +QVariantMap parameters; +parameters["gconfKey"] = "/apps/myapp/mykey"; +QGeoSatelliteInfoSource *source = QGeoSatelliteInfoSource::createSource("gypsy", parameters, this); +\endcode + +*/ diff --git a/src/positioning/doc/src/plugins/nmea.qdoc b/src/positioning/doc/src/plugins/nmea.qdoc new file mode 100644 index 0000000..8cbc23d --- /dev/null +++ b/src/positioning/doc/src/plugins/nmea.qdoc @@ -0,0 +1,177 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page position-plugin-nmea.html +\title Qt Positioning NMEA plugin +\ingroup QtPositioning-plugins + +\brief Reads the NMEA stream to provide position updates. + +\section1 Overview + +Included with Qt Positioning is a position plugin which parses NMEA sentences +into position updates. This plugin can use serial port, socket or file as a +source. + +This plugin can be loaded by using the provider name \b nmea. + +\section1 Parameters + +The following table lists parameters that \e can be passed to the nmea plugin. + +\table +\header + \li Parameter + \li Description +\row + \li nmea.source + \li The source that will be used to get NMEA data. +\row + \li nmea.satellite_info_simulation_interval + \li The interval for reading satellite information data from the file in + simulation mode. +\endtable + +Different sources require different ways of providing the data. The following +table lists different ways of providing \c {nmea.source} parameter for socket, +serial port and file inputs. + +\table +\header + \li Scheme + \li Example + \li Description +\row + \li socket://hostname:port + \li \c {socket://localhost:12345} + \li Use \b {socket:} keyword to specify that you want to get the nmea data + from the socket. A TCP socket will be created, which will try to connect + to host \c hostname using port \c port. Upon successful connection + a text NMEA stream is expected to be received from the server. +\row + \li {1, 3} serial:portname + \li \c {serial:/dev/ttyUSB0} + \li {1, 3} Use \b {serial:} keyword to specify that you want to get the nmea + data from the serial port. The plugin will try to establish a connection + to port \c portname with baudrate = 4800 Bd. Upon successful connection + a text NMEA stream is expected to be received from the serial port. + If you use \b {serial:} without any port name, the plugin will try to + find one of the well known serial devices using vendor identifier. Note + however that this is not a recommended way of using the serial port + connection, as the list of well-known devices is small and most probably + does not include your hardware. +\row + \li \c {serial:COM1} +\row + \li \c {serial:} +\row + \li filepath + \li \c {/home/user/nmealog.txt} + \li {1, 2} Use \b {file:///} or just full file path to specify a path to a + local file. +\row + \li file:///filepath + \li \c {file:///home/user/nmealog.txt} +\row + \li qrc:///filepath + \li \c {qrc:///nmealog.txt} + \li Use \b {qrc:///} prefix to specify a path to a file in the application + resources. +\endtable + +\note If \c {nmea.source} parameter is not specified, the plugin will try to +locate one of the well-known serial devices (as if \c {nmea.source = serial:} +was specified). + +\section1 Position source usage example + +The following examples show how to create a \b nmea PositionSource +using different data sources. + +\section2 QML + +\code +// text file +PositionSource { + name: "nmea" + PluginParameter { name: "nmea.source"; value: "qrc:///nmealog.txt" } +} + +// socket +PositionSource { + name: "nmea" + PluginParameter { name: "nmea.source"; value: "socket://localhost:22222" } +} + +// serial port +PositionSource { + name: "nmea" + PluginParameter { name: "nmea.source"; value: "serial:/dev/ttyACM0" } +} +\endcode + +\section2 C++ + +\code +// text file +QVariantMap params; +params["nmea.source"] = "qrc:///nmealog.txt"; +QGeoPositionInfoSource *textPositionSource = QGeoPositionInfoSource::createSource("nmea", params, this); + +// socket +params["nmea.source"] = "socket://localhost:22222"; +QGeoPositionInfoSource *socketPositionSource = QGeoPositionInfoSource::createSource("nmea", params, this); + +// serial port +params["nmea.source"] = "serial:/dev/ttyACM0"; +QGeoPositionInfoSource *serialPositionSource = QGeoPositionInfoSource::createSource("nmea", params, this); +\endcode + +\note Once a PositionSource is created, it can't be reconfigured to use other +type of source data. + +\section1 Satellite information source usage example + +Apart from the position information, \b nmea plugin is also capable of providing +satellite information. For now it does not have any QML object, but can be +created directly from C++ code. + +\code +// serial port +QVariantMap parameters; +parameters["nmea.source"] = "serial:/dev/ttyUSB0"; +QGeoSatelliteInfoSource *serialSource = QGeoSatelliteInfoSource::createSource("nmea", parameters, this); + +// socket +parameters["nmea.source"] = "socket://localhost:22222"; +QGeoSatelliteInfoSource *socketSource = QGeoSatelliteInfoSource::createSource("nmea", parameters, this); +\endcode + +If you want to use \l QGeoSatelliteInfoSource to read file with NMEA stream, you +can also use additional parameter \c "nmea.satellite_info_simulation_interval". +This parameter is used to specify the playback rate (in milliseconds) for the +satellite info messages. The minimum allowed frequency is specified by +\l {QGeoSatelliteInfoSource::}{minimumUpdateInterval()}. If you specify a +smaller value, it will be ignored. If no value is specified, the default value +is \c {qMax(100, minimumUpdateInterval())}. +At runtime \l {QNmeaSatelliteInfoSource::setBackendProperty()} method can be +used to update this parameter. + +\code +// file +QVariantMap parameters; +parameters["nmea.source"] = "qrc:///nmealog.txt"; +parameters["nmea.satellite_info_simulation_interval"] = 1000; +QGeoSatelliteInfoSource *fileSource = QGeoSatelliteInfoSource::createSource("nmea", parameters, this); +\endcode + +This parameter is not applicable to position source because NMEA protocol +already has timestamps in position messages. These timestamps are used to +simulate the correct message rate while using \l QGeoPositionInfoSource with +file as a data source. + +\note Once a \l QGeoSatelliteInfoSource is created, it can't be reconfigured to +use other type of source data. + +*/ diff --git a/src/positioning/doc/src/qml-position.qdoc b/src/positioning/doc/src/qml-position.qdoc new file mode 100644 index 0000000..ea422d2 --- /dev/null +++ b/src/positioning/doc/src/qml-position.qdoc @@ -0,0 +1,88 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page location-positioning-qml.html + +\title Positioning (QML) + +\brief The Location Positioning API enables location positioning by means of +GPS or an NMEA data source. + +\section1 Location Positioning + +Location data involves a precisely specified position on the Earth's +surface \unicode {0x2014} as provided by a latitude-longitude coordinate +\unicode {0x2014} along with associated data, such as: + + \list + \li The date and time at which the position was reported + \li The velocity of the device that reported the position + \li The altitude of the reported position (height above sea level) + \li The bearing of the device in degrees, relative to true north + \endlist + +For more information see +\l {http://en.wikipedia.org/wiki/Geographic_coordinate}{Geographic Coordinate}. + +This data can be extracted through a variety of methods. One of the most +well known methods of positioning is GPS (Global Positioning System), a +publicly available system that uses radiowave signals received from +Earth-orbiting satellites to calculate the precise position and time of +the receiver. Another popular method is 'Cell Identifier Positioning', which uses +the cell identifier of the cell site that is currently serving the receiving +device to calculate its approximate location. These and other positioning +methods can all be used with the Location API; the only requirement for a +location data source within the API is that it provides a +latitude-longitude coordinate with a date/time value, with the option of +providing the other attributes listed above. + +\section2 Coordinates + +The \l {coordinate} is a basic unit of geographical information. The +\l {coordinate} type has attributes to hold the \c {latitude}, +\c longitude and \c altitude. + +\section2 Positions + +The three dimensional position of an object such as a mobile device can be specified by giving +the latitude, longitude and altitude. That is the values held in the +\l {coordinate} type. Additionally for computation of future +positions we would like to know if the object is moving, what \l [QML] {Position::}{speed} it is +doing and what is the \l {Position::timestamp}{timestamp} of the last position data. Position +therefore includes values for the \l {Position::coordinate}{coordinate}, +\l {Position::speed}{speed} and a \l {Position::timestamp}{timestamp}. \l Position also takes +responsibility for validation of sensible values for these properties. These are exposed as +the \l {Position::latitudeValid}{latitudeValid}, \l {Position::longitudeValid}{longitudeValid}, +\l {Position::altitudeValid}{altitudeValid}, \l {Position::speedValid}{speedValid}, +\l {Position::horizontalAccuracyValid}{horizontalAccuracyValid}, and +\l {Position::verticalAccuracyValid}{verticalAccuracyValid} properties. + + +\section2 PositionSource Type + +We have a \l Position type, a \l {coordinate} type but where does the data come +from? Also it is a good idea to be able to indicate alternative sources. +Perhaps instead of directly picking up GPS satellites it might be desirable to +do some testing using a datafile. + +The \l PositionSource type provides the developer with control, within the +limits allowed by the platform, of the source of the geographical data. +\l PositionSource supports multiple plugins, including an +\l {Qt Positioning NMEA plugin}{NMEA} plugin. + +\l {http://en.wikipedia.org/wiki/NMEA}{NMEA} is a common text-based +protocol for specifying navigational data. The \l PositionSource +\l {Qt Positioning NMEA plugin}{NMEA} plugin supports multiple data sources, +including raw file or TCP socket. The source will emit updates according to the +time stamp of each NMEA sentence to produce a "replay" of the recorded data. + +See the \l {Qt Positioning NMEA plugin}{plugin description} for usage examples. + + +\section2 GeoFlickr Example + +The \l{GeoFlickr (QML)}{GeoFlickr Example} uses the \l PositionSource to +download thumbnail images from Flickr relevant to the current location. + +*/ diff --git a/src/positioning/doc/src/qt6-changes.qdoc b/src/positioning/doc/src/qt6-changes.qdoc new file mode 100644 index 0000000..fa3fd68 --- /dev/null +++ b/src/positioning/doc/src/qt6-changes.qdoc @@ -0,0 +1,209 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qtpositioning-changes-qt6.html + \title Changes to Qt Positioning + \ingroup changes-qt-5-to-6 + \brief Migrate Qt Positioning to Qt 6. + + Qt 6 is a result of the conscious effort to make the framework more + efficient and easy to use. + + We try to maintain binary and source compatibility for all the public + APIs in each release. But some changes were inevitable in an effort to + make Qt a better framework. + + In this topic we summarize those changes in Qt Positioning, and provide + guidance to handle them. + + \section1 Breaking public API changes + + This section contains information about API changes that break source + compatibility. + + \section2 Rename QGeoPolygon::path() + + The \c QGeoPolygon::path() and \c QGeoPolygon::setPath() methods are renamed + to \l QGeoPolygon::perimeter() and \l QGeoPolygon::setPerimeter() + respectively. On the QML side the \l QGeoPolygon::perimeter property can be + used without any changes. + + \section2 Use \l QGeoShape for \l QGeoLocation bounding area + + The \l QGeoLocation class and its \l [QML] Location QML counterpart are + updated to use \l QGeoShape instead of \l QGeoRectangle for a bounding area. + + \section3 C++ + + The \c QGeoLocation::boundingBox() and \c QGeoLocation::setBoundingBox() + are replaced by \l QGeoLocation::boundingShape() and + \l QGeoLocation::setBoundingShape() respectively. A \l QGeoShape object + is now used as an underlying data storage. + + \section3 QML + + The \c QGeoLocation::boundingBox property is replaced by + \l QGeoLocation::boundingShape. This property is available since + QtPositioning 6.2, so make sure to update the import version in the QML + files. + + \code + import QtPositioning 6.2 + \endcode + + \section2 Remove QGeoShape::extendShape() + + The \c QGeoShape::extendShape() method was deprecated in Qt 5.9 and finally + removed in Qt 6. Use \l QGeoRectangle::extendRectangle() and + \l QGeoCircle::extendCircle() if you need this functionality for these + classes. + + \section2 Rename signal error to errorOccurred + + In Qt 5 multiple Qt Positioning classes had the \c error() signal, which was + clashing with the \c error() method. In Qt 6 we renamed these signals to + \c errorOccurred(). Specifically: + + \list + + \li \c QGeoAreaMonitorSource::error() is renamed to + \l QGeoAreaMonitorSource::errorOccurred(). + + \li \c QGeoPositionInfoSource::error() is renamed to + \l QGeoPositionInfoSource::errorOccurred(). + + \li \c QGeoSatelliteInfoSource::error() is renamed to + \l QGeoSatelliteInfoSource::errorOccurred(). + + \endlist + + \section2 Remove update timeout signals + + In Qt 5 \c {QGeoPositionInfoSource::updateTimeout()} and + \c {QGeoSatelliteInfoSource::requestTimeout()} signals were used to notify + about the cases when the current position or satellite information could + not be retrieved within specified timeout. These signals were removed in + Qt 6. The \c {errorOccurred()} signals with the new error types are + used instead. Specifically: + + \list + + \li \l QGeoPositionInfoSource uses an \l {QGeoPositionInfoSource::} + {errorOccurred()} signal with a new + \l QGeoPositionInfoSource::UpdateTimeoutError error code. + + \li \l QGeoSatelliteInfoSource uses an \l {QGeoSatelliteInfoSource::} + {errorOccurred()} signal with a new + \l QGeoSatelliteInfoSource::UpdateTimeoutError error code. + + \endlist + + Same changes apply to \l [QML] PositionSource QML object. The + \c {PositionSource::updateTimeout()} signal is removed. + \l [QML] {PositionSource::sourceError} property with a + \c {PositionSource.UpdateTimeoutError} is used instead. + + \section2 Redesign NMEA support + + In Qt 5 we had a \b serialnmea positioning plugin and a \c nmeaSource + property in \l [QML] {PositionSource} object. + + The plugin provided access to NMEA streams via serial port, while the QML + object was responsible for reading NMEA stream from TCP socket or local + file. + + In Qt 6 we joined all these features in the plugin, which is now renamed to + \b nmea. It is now capable of working with all three NMEA data sources: + serial port, TCP socket and local file. See \l {Qt Positioning NMEA plugin} + {plugin description} for more details. + + The \c nmeaSource property of \l [QML] {PositionSource} object is now + removed. + + \section1 Other API changes + + This section contains API improvements that do not break source + compatibility. However they might have an impact on the application logic, + so it is still useful to know about them. + + \section2 Reset errors properly + + In Qt 5 the errors for \l QGeoAreaMonitorSource, \l QGeoPositionInfoSource + and \l QGeoSatelliteInfoSource classes were never reset. This behavior is + not logical, as calling \c {startUpdates()}, \c {startMonitoring()} or + \c {requestUpdates()} on one of these classes or their subclasses + effectively means starting a new work sessions, which means that we should + not care about previous errors. Since Qt 6 we reset the error to \c NoError + once one of the aforementioned methods is called. + + \section2 Add \l QGeoAddress::streetNumber + + The \l QGeoAddress class is extended with \l {QGeoAddress::}{streetNumber} + property, which holds the information about street number, building name, or + anything else that might be used to distinguish one address from another. + Use \l {QGeoAddress::}{streetNumber()} and \l {QGeoAddress::} + {setStreetNumber()} to access this property from C++ code. + + The \l QGeoAddress::street now holds only the street name. + + Same applies to \l [QML] {Address} QML counterpart. The \l [QML] + {Address::street} property is now used only for street name, while the + \l [QML] {Address::streetNumber} property is used for other important + address details. + + \section2 Add timeout argument to \l [QML] {PositionSource::update()} + + The \c timeout is specified in milliseconds. If the \c timeout is zero + (the default value), it defaults to a reasonable timeout period as + appropriate for the source. + + \section2 Refactor \l QGeoSatelliteInfo, \l QGeoPositionInfo and \l QGeoAreaMonitorInfo classes + + These classes now use \l QExplicitlySharedDataPointer in their + implementation. It means that the classes implement copy-on-write. It makes + them cheap to copy, so that they can be passed by value. + + Another improvement is the addition of support for the efficient move + operations. + + \section1 Changes in Qt Positioning plugin implementation + + This section provides information about the changes in plugin interface. + + In Qt 5 for we had two versions of plugin interface: + + \list + + \li \c QGeoPositionInfoSourceFactory which provided the basic features. + \li \c QGeoPositionInfoSourceFactoryV2 which extended the base class with + the possibility to provide custom parameters for the created objects. + + \endlist + + In Qt 6 we merged these two implementations into one, leaving only the + \l QGeoPositionInfoSourceFactory class. Its methods now allow to pass + custom parameters. + + \note The interface \e identifier is updated to reflect the major version + update. Use \c {"org.qt-project.qt.position.sourcefactory/6.0"} in your + Qt Positioning plugins. + + Here is an example of plugin class declaration: + + \code + class MyPlugin : public QObject, public QGeoPositionInfoSourceFactory + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) + + public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; + }; + \endcode + +*/ diff --git a/src/positioning/doc/src/qtpositioning-android.qdoc b/src/positioning/doc/src/qtpositioning-android.qdoc new file mode 100644 index 0000000..4644e65 --- /dev/null +++ b/src/positioning/doc/src/qtpositioning-android.qdoc @@ -0,0 +1,58 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page qtpositioning-android.html +\inmodule QtPositioning +\title Qt Positioning on Android +\brief Notes on using Qt Positioning on Android + +\section1 Using Qt Positioning from Android Services + +Using Qt Positioning from a service requires several extra actions to be taken, +depending on the Android version. The sections below give more details on +these actions. + +\note Since Android 8 (API level 26), the OS limits how frequently an +application can retrieve the user's current location while running in the +background. The application will normally be able to receive location updates +only a few times each hour. For more information, see +\l {Background Location Limits}. + +\section2 Using Foreground Service + +Since Android 8 (API level 26), the background service can be killed by the +Android OS when the application goes to the background. This normally happens +after around a minute of running in the background. To keep the location service +running, the service should be implemented as a \l {Foreground Service}. Such +service shows a status bar notification, which cannot be dismissed until the +service is stopped or removed from the foreground. This allows the user to be +always aware of the important background activities. + +\note Since Android 9 (API level 28), foreground services require a special +\c FOREGROUND_SERVICE permission. See the Android documentation for more +details on implementing foreground services. + +\section2 Use Background Location Permission + +Since Android 10 (API level 29), the service \e must request the +\l {ACCESS_BACKGROUND_LOCATION} permission. It should be added to the +\c AndroidManifest.xml file as follows: + +\badcode + +\endcode + +\note Once the permission is added to \c {AndroidManifest.xml}, it is still +required to explicitly allow the constant access to the location services +for the application. To do it, one should navigate to \uicontrol Settings -> +\uicontrol {Apps}, select a proper application, open its permissions, and +specify the \uicontrol {Allow all the time} permission for Location +(see the screenshot below). + +\image permissions.png + +Check \l {Access Location in the Background} Android documentation for more +details. + +*/ diff --git a/src/positioning/doc/src/qtpositioning-examples.qdoc b/src/positioning/doc/src/qtpositioning-examples.qdoc new file mode 100644 index 0000000..055fcc2 --- /dev/null +++ b/src/positioning/doc/src/qtpositioning-examples.qdoc @@ -0,0 +1,14 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \group qtpositioning-examples + \title Qt Positioning Examples + \brief Examples for the Qt Positioning module + \ingroup all-examples + \ingroup qtpositioning + + The list of \l {Qt Positioning} examples demonstrating how to use + Positioning API from C++ and QML. + +*/ diff --git a/src/positioning/doc/src/qtpositioning-ios.qdoc b/src/positioning/doc/src/qtpositioning-ios.qdoc new file mode 100644 index 0000000..6c4d38b --- /dev/null +++ b/src/positioning/doc/src/qtpositioning-ios.qdoc @@ -0,0 +1,53 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page qtpositioning-ios.html +\inmodule QtPositioning +\title Qt Positioning on iOS +\brief Notes on using Qt Positioning on iOS + +\section1 Using Qt Positioning Services from an iOS App + +To enable an app to use positioning services on an iOS device, entries must +be added to the Info.plist file based on whether the positioning services +are needed when the app is in use or when the app is running in the +background. + +Once the permission is added, the user needs to grant the permission for the +positioning services to be available when the app requests the positioning +service. The user can change this by going into Settings > Privacy > +Location Services, scrolling down to find the app, and selecting an option. +The location services must be on for the positioning services to work. + +\section2 Using Foreground Location Services Permission + +If an app makes use of the positioning services when it is running, the +Info.plist file needs to have an entry with the key \c +NSLocationWhenInUseUsageDescription and a value with a text string giving the +user the reason the app makes use of it. + +\badcode +NSLocationWhenInUseUsageDescription +The reason why the app needs location services +\endcode + +\section2 Use Background Location Services Permission + +If the app makes use of location services even when it is running in the +background, there needs to be an entry with the key \c +NSLocationAlwaysAndWhenInUseUsageDescription and the reason as string value +as well as \c NSLocationWhenInUseUsageDescription. + +\badcode +NSLocationWhenInUseUsageDescription +The reason why the app needs location services +NSLocationAlwaysAndWhenInUseUsageDescription +The reason why the app needs location services +\endcode + +\note The Info.plist file is automatically generated, and changes made can be +overwritten by qmake or CMake unless measures are taken. See +\l {Platform Notes - iOS} for more information. + +*/ diff --git a/src/positioning/doc/src/qtpositioning-plugins.qdoc b/src/positioning/doc/src/qtpositioning-plugins.qdoc new file mode 100644 index 0000000..f650e3c --- /dev/null +++ b/src/positioning/doc/src/qtpositioning-plugins.qdoc @@ -0,0 +1,90 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page qtpositioning-plugins.html +\title Qt Positioning Plugins +\brief Default Plugins and Implementing Qt Positioning plugins + +Qt Positioning provides the majority of its functionality through plugins. +This document outlines how to develop a new position plugin. + +\section1 Default plugins +Some plugins already ship with Qt. These are: + +\table + \row + \li \b android + \li Wraps Android positioning subsystem. Available only on Android. + \row + \li \b corelocation + \li Wraps iOS and macOS positioning subsystems. Available only on Apple platforms supporting corelocation. + \row + \li \b geoclue2 + \li A \l {Qt Positioning GeoClue v2 plugin}{GeoClue v2} backend that + provides an interface to the GeoClue v2 D-Bus service. + \row + \li \b gypsy + \li A \l {Qt Positioning Gypsy plugin}{Gypsy} backend that provides + an interface to the Gypsy daemon. + \row + \li \b winrt + \li Wraps WinRT positioning subsystem. Available only on WinRT and Windows10. + \row + \li \b nmea + \li An \l {Qt Positioning NMEA plugin}{NMEA} backend that parses NMEA + streams from a GPS receiver to provide position updates. This plugin can + use serial port, socket or file as a source. + \row + \li \b positionpoll + \li A backend providing only area monitoring functionalities via polling on position updates. +\endtable + + +\section1 Plugin Description + +Each plugin is described by a json file. The json describes the plugins capabilities and +version. Below is an example of a json file used by the postionpoll plugin: + +\quotefile ../../../plugins/position/positionpoll/plugin.json + +The entries have the following meaning: + +\table + \header + \li Key + \li Description + \row + \li Keys + \li The unique name/key of the plugin. Each position plugin must have a unique name. + \row + \li Provider + \li The provider name of the services. Multiple plugins may have the same name. + In such cases the Version string will be used to further distinguish the plugins. + \row + \li Position + \li Set to \c true if the plugin implements a \l QGeoPositionInfoSource. + \row + \li Satellite + \li Set to \c true if the plugin implements a \l QGeoSatelliteInfoSource. + \row + \li Monitor + \li Set to \c true if the plugin implements a \l QGeoAreaMonitorSource. + \row + \li Priority + \li The plugin priority. If multiple plugins have the same provider name, the plugin + with the higest priority will be used. +\endtable + +\section1 Implementing Plugins + +A plugin implementer needs to subclass \l QGeoPositionInfoSourceFactory and override one or more of +its functions. If a plugin does not support a specific feature the function should return 0 or +utilize the default implementation. + +\list + \li \l QGeoPositionInfoSourceFactory::areaMonitor() + \li \l QGeoPositionInfoSourceFactory::positionInfoSource() + \li \l QGeoPositionInfoSourceFactory::satelliteInfoSource() +\endlist +*/ diff --git a/src/positioning/doc/src/qtpositioning-qml.qdoc b/src/positioning/doc/src/qtpositioning-qml.qdoc new file mode 100644 index 0000000..f24bccd --- /dev/null +++ b/src/positioning/doc/src/qtpositioning-qml.qdoc @@ -0,0 +1,47 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \qmlmodule QtPositioning \QtVer + \title Qt Positioning QML Types + \ingroup qmlmodules + \brief Provides QML types for position information. + + \section1 Overview + + The identifying string for this module is \e QtPositioning. To use the QML + from this module, include the following import statement in the QML file: + + \qml \QtVer + import QtPositioning \1 + \endqml + + \section2 Positioning QML Concepts + + Position information can come from a variety of sources including + satellites, Wi-Fi, text files and so on. The position is described by the + latitude, longitude, and the altitude in meters. For more information, see + the Wikipedia page on + \l {http://en.wikipedia.org/wiki/Geographic_coordinate} + {Geographic Coordinates}. + + The QML position is stored in a \l {coordinate} which contains the + latitude, longitude and altitude of the device. The \l {QtPositioning::} + {Location} contains this \l {coordinate} and adds an address, and also has + a bounding box which defines the recommended viewing region when displaying + the location. + + Now that the device has a position, with regular updates the API can + determine the speed and heading of the device. It can also define a + box-shaped or circular region that triggers notifications when the device + either leaves or enters that region. + + More detailed information on retrieving the current position can be found + under \l {Positioning (QML)}{Location Positioning via QML}. + + \section1 Basic Types + + \annotatedlist qml-QtPositioning5-basictypes + + \section1 Alphabetical Listing of All QML Types +*/ diff --git a/src/positioning/doc/src/qtpositioning.qdoc b/src/positioning/doc/src/qtpositioning.qdoc new file mode 100644 index 0000000..7963b64 --- /dev/null +++ b/src/positioning/doc/src/qtpositioning.qdoc @@ -0,0 +1,119 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \module QtPositioning + \title Qt Positioning C++ Classes + \ingroup modules + \qtcmakepackage Positioning + \qtvariable positioning + + \brief The Positioning module provides positioning information via QML and C++ interfaces. + + To load the Qt Positioning module, add the following statement to your .qml files + + \snippet doc_src_qtpositioning.qml import + + For C++ projects include the header appropriate for the current use case, + for example applications using routes may use + + \code + #include + \endcode + + \include module-use.qdocinc using qt module + + \badcode + find_package(Qt6 REQUIRED COMPONENTS Positioning) + target_link_libraries(mytarget PRIVATE Qt6::Positioning) + \endcode + + \include module-use.qdocinc building with qmake + + \badcode + QT += positioning + \endcode + + See more in the \l{Qt Positioning}{Qt Positioning Overview}. + +*/ + + + +/*! +\page qtpositioning-index.html +\title Qt Positioning +\brief The Qt Positioning API provides positioning information via QML and C++ interfaces. +\ingroup technology-apis + +The Qt Positioning API provides positioning information via QML and C++ interfaces. + +Currently, the API is supported on \l {Qt for Android}{Android}, +\l {Qt for iOS}{iOS}, \l {Qt for macOS}{\macos}, \l {Qt for Linux/X11}{Linux}, +and \l {Qt for Windows}{Windows} (with GPS receivers exposed as a serial port +providing NMEA sentences or using \c {Windows.Devices.Geolocation}). + +\section1 Overview + +The Qt Positioning API lets you to determine a position by using a variety of +possible sources, including satellite, wifi, or text files. That information can +then be used to, for example, determine a position on a map. In addition, you +can use to the API to retrieve satellite information and perform area based +monitoring. + +\section1 Using the Module + +\section2 QML API + +\include {module-use.qdocinc} {using the qml api} {QtPositioning} + +\section2 C++ API + +\include {module-use.qdocinc} {using the c++ api} + +\section3 Building with CMake + +\include {module-use.qdocinc} {building with cmake} {Positioning} + +\section3 Building with qmake + +\include {module-use.qdocinc} {building_with_qmake} {positioning} + +\section1 Articles and Guides + +\list + \li \l {Positioning (C++)} {Positioning introduction for C++} + \li \l {Positioning (QML)} {Positioning introduction for QML} + \li \l {Qt Positioning Plugins} + \li \l {Interfaces between C++ and QML Code in Qt Positioning} + \li \l {Qt Positioning on Android} + \li \l {Qt Positioning on iOS} +\endlist + +\section1 Examples + +\list + \li \l {Qt Positioning Examples} +\endlist + +\section1 Reference + +\list + \li \l {Qt Positioning C++ Classes} + \li \l {Qt Positioning QML Types} +\endlist + +\section1 Module Evolution + +\l {Changes to Qt Positioning} lists important changes in the module API and +functionality that were done for the Qt 6 series of Qt. + +\section1 Licenses + +Qt Positioning is available under commercial licenses from \l{The Qt Company}. +In addition, it is available under free software licenses. Since Qt 5.4, +these free software licenses are +\l{GNU Lesser General Public License, version 3}, or +the \l{GNU General Public License, version 2}. +See \l{Qt Licensing} for further details. +*/ diff --git a/src/positioning/qclipperutils.cpp b/src/positioning/qclipperutils.cpp new file mode 100644 index 0000000..7d36024 --- /dev/null +++ b/src/positioning/qclipperutils.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qclipperutils_p.h" +#include + +QT_BEGIN_NAMESPACE + +class QClipperUtilsPrivate +{ +public: + c2t::clip2tri m_clipper; + Path m_cachedPolygon; +}; + +static const double kClipperScaleFactor = 281474976710656.0; // 48 bits of precision +static const double kClipperScaleFactorInv = 1.0 / kClipperScaleFactor; + +static IntPoint toIntPoint(const QDoubleVector2D &p) +{ + return IntPoint(cInt(p.x() * kClipperScaleFactor), cInt(p.y() * kClipperScaleFactor)); +} + +static QDoubleVector2D toVector2D(const IntPoint &p) +{ + return QDoubleVector2D(double(p.X) * kClipperScaleFactorInv, double(p.Y) * kClipperScaleFactorInv); +} + +static QList pathToQList(const Path &path) +{ + QList res; + res.reserve(int(path.size())); + for (const IntPoint &ip: path) + res.append(toVector2D(ip)); + return res; +} + +static QList> pathsToQList(const Paths &paths) +{ + QList > res; + res.reserve(int(paths.size())); + for (const Path &p: paths) { + res.append(pathToQList(p)); + } + return res; +} + +static Path qListToPath(const QList &list) +{ + Path res; + res.reserve(list.size()); + for (const QDoubleVector2D &p: list) + res.push_back(toIntPoint(p)); + return res; +} + +QClipperUtils::QClipperUtils() : d_ptr(new QClipperUtilsPrivate) +{ +} + +QClipperUtils::QClipperUtils(const QClipperUtils &other) : d_ptr(new QClipperUtilsPrivate) +{ + d_ptr->m_cachedPolygon = other.d_ptr->m_cachedPolygon; +} + +QClipperUtils::~QClipperUtils() +{ + delete d_ptr; +} + +double QClipperUtils::clipperScaleFactor() +{ + return kClipperScaleFactor; +} + +int QClipperUtils::pointInPolygon(const QDoubleVector2D &point, const QList &polygon) +{ + if (polygon.isEmpty()) + qWarning("No vertices are specified for the polygon!"); + return c2t::clip2tri::pointInPolygon(toIntPoint(point), qListToPath(polygon)); +} + +void QClipperUtils::clearClipper() +{ + d_ptr->m_clipper.clearClipper(); +} + +void QClipperUtils::addSubjectPath(const QList &path, bool closed) +{ + d_ptr->m_clipper.addSubjectPath(qListToPath(path), closed); +} + +void QClipperUtils::addClipPolygon(const QList &path) +{ + d_ptr->m_clipper.addClipPolygon(qListToPath(path)); +} + +QList> QClipperUtils::execute(QClipperUtils::Operation op, + QClipperUtils::PolyFillType subjFillType, + QClipperUtils::PolyFillType clipFillType) +{ + auto result = d_ptr->m_clipper.execute(static_cast(op), + static_cast(subjFillType), + static_cast(clipFillType)); + return pathsToQList(result); +} + +void QClipperUtils::setPolygon(const QList &polygon) +{ + d_ptr->m_cachedPolygon = qListToPath(polygon); +} + +int QClipperUtils::pointInPolygon(const QDoubleVector2D &point) const +{ + if (d_ptr->m_cachedPolygon.empty()) + qWarning("No vertices are specified for the polygon!"); + return c2t::clip2tri::pointInPolygon(toIntPoint(point), d_ptr->m_cachedPolygon); +} + +QT_END_NAMESPACE diff --git a/src/positioning/qclipperutils_p.h b/src/positioning/qclipperutils_p.h new file mode 100644 index 0000000..fd67704 --- /dev/null +++ b/src/positioning/qclipperutils_p.h @@ -0,0 +1,85 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QCLIPPERUTILS_P_H +#define QCLIPPERUTILS_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. +// + +/* + * This file is intended to be include only in source files of + * QtPositioning/QtLocation. It is in QtPositioning to enable manipulation + * of geo polygons + */ + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/* + * This class provides a wrapper around the clip2tri library, so that + * we do not need to export any of the internal types. That is needed + * because after QtLocation and QtPositioning are moved to different + * repos, we need to use the features of the library in QtLocation without + * explicitly linking to it. +*/ + +class QClipperUtilsPrivate; +class Q_POSITIONING_PRIVATE_EXPORT QClipperUtils +{ +public: + QClipperUtils(); + QClipperUtils(const QClipperUtils &other); + ~QClipperUtils(); + + // Must be in sync with c2t::clip2tri::Operation + enum Operation { + Union, + Intersection, + Difference, + Xor + }; + + // Must be in sync with QtClipperLib::PolyFillType + enum PolyFillType { + pftEvenOdd, + pftNonZero, + pftPositive, + pftNegative + }; + + static double clipperScaleFactor(); + + static int pointInPolygon(const QDoubleVector2D &point, const QList &polygon); + + // wrap some useful non-static methods of c2t::clip2tri + void clearClipper(); + void addSubjectPath(const QList &path, bool closed); + void addClipPolygon(const QList &path); + QList> execute(Operation op, PolyFillType subjFillType = pftNonZero, + PolyFillType clipFillType = pftNonZero); + + // For optimization purposes. Set the polygon once and check for multiple + // points. Without the need to convert between Qt and clip2tri types + // every time + void setPolygon(const QList &polygon); + int pointInPolygon(const QDoubleVector2D &point) const; + +private: + QClipperUtilsPrivate *d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QCLIPPERUTILS_P_H diff --git a/src/positioning/qdoublematrix4x4.cpp b/src/positioning/qdoublematrix4x4.cpp new file mode 100644 index 0000000..f498ae1 --- /dev/null +++ b/src/positioning/qdoublematrix4x4.cpp @@ -0,0 +1,1076 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qdoublematrix4x4_p.h" +#include +//#include +#include +#include + +QT_BEGIN_NAMESPACE + +static const double inv_dist_to_plane = 1.0 / 1024.0; + +QDoubleMatrix4x4::QDoubleMatrix4x4(const double *values) +{ + for (int row = 0; row < 4; ++row) + for (int col = 0; col < 4; ++col) + m[col][row] = values[row * 4 + col]; + flagBits = General; +} + +QDoubleMatrix4x4::QDoubleMatrix4x4(const double *values, int cols, int rows) +{ + for (int col = 0; col < 4; ++col) { + for (int row = 0; row < 4; ++row) { + if (col < cols && row < rows) + m[col][row] = values[col * rows + row]; + else if (col == row) + m[col][row] = 1.0; + else + m[col][row] = 0.0; + } + } + flagBits = General; +} + +static inline double matrixDet2(const double m[4][4], int col0, int col1, int row0, int row1) +{ + return m[col0][row0] * m[col1][row1] - m[col0][row1] * m[col1][row0]; +} + +static inline double matrixDet3 + (const double m[4][4], int col0, int col1, int col2, + int row0, int row1, int row2) +{ + return m[col0][row0] * matrixDet2(m, col1, col2, row1, row2) + - m[col1][row0] * matrixDet2(m, col0, col2, row1, row2) + + m[col2][row0] * matrixDet2(m, col0, col1, row1, row2); +} + +static inline double matrixDet4(const double m[4][4]) +{ + double det; + det = m[0][0] * matrixDet3(m, 1, 2, 3, 1, 2, 3); + det -= m[1][0] * matrixDet3(m, 0, 2, 3, 1, 2, 3); + det += m[2][0] * matrixDet3(m, 0, 1, 3, 1, 2, 3); + det -= m[3][0] * matrixDet3(m, 0, 1, 2, 1, 2, 3); + return det; +} + +double QDoubleMatrix4x4::determinant() const +{ + if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) + return 1.0; + + if (flagBits < Rotation2D) + return m[0][0] * m[1][1] * m[2][2]; // Translation | Scale + if (flagBits < Perspective) + return matrixDet3(m, 0, 1, 2, 0, 1, 2); + return matrixDet4(m); +} + +QDoubleMatrix4x4 QDoubleMatrix4x4::inverted(bool *invertible) const +{ + // Handle some of the easy cases first. + if (flagBits == Identity) { + if (invertible) + *invertible = true; + return QDoubleMatrix4x4(); + } else if (flagBits == Translation) { + QDoubleMatrix4x4 inv; + inv.m[3][0] = -m[3][0]; + inv.m[3][1] = -m[3][1]; + inv.m[3][2] = -m[3][2]; + inv.flagBits = Translation; + if (invertible) + *invertible = true; + return inv; + } else if (flagBits < Rotation2D) { + // Translation | Scale + if (m[0][0] == 0 || m[1][1] == 0 || m[2][2] == 0) { + if (invertible) + *invertible = false; + return QDoubleMatrix4x4(); + } + QDoubleMatrix4x4 inv; + inv.m[0][0] = 1.0 / m[0][0]; + inv.m[1][1] = 1.0 / m[1][1]; + inv.m[2][2] = 1.0 / m[2][2]; + inv.m[3][0] = -m[3][0] * inv.m[0][0]; + inv.m[3][1] = -m[3][1] * inv.m[1][1]; + inv.m[3][2] = -m[3][2] * inv.m[2][2]; + inv.flagBits = flagBits; + + if (invertible) + *invertible = true; + return inv; + } else if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) { + if (invertible) + *invertible = true; + return orthonormalInverse(); + } else if (flagBits < Perspective) { + QDoubleMatrix4x4 inv(1); // The "1" says to not load the identity. + + double det = matrixDet3(m, 0, 1, 2, 0, 1, 2); + if (det == 0.0) { + if (invertible) + *invertible = false; + return QDoubleMatrix4x4(); + } + det = 1.0 / det; + + inv.m[0][0] = matrixDet2(m, 1, 2, 1, 2) * det; + inv.m[0][1] = -matrixDet2(m, 0, 2, 1, 2) * det; + inv.m[0][2] = matrixDet2(m, 0, 1, 1, 2) * det; + inv.m[0][3] = 0; + inv.m[1][0] = -matrixDet2(m, 1, 2, 0, 2) * det; + inv.m[1][1] = matrixDet2(m, 0, 2, 0, 2) * det; + inv.m[1][2] = -matrixDet2(m, 0, 1, 0, 2) * det; + inv.m[1][3] = 0; + inv.m[2][0] = matrixDet2(m, 1, 2, 0, 1) * det; + inv.m[2][1] = -matrixDet2(m, 0, 2, 0, 1) * det; + inv.m[2][2] = matrixDet2(m, 0, 1, 0, 1) * det; + inv.m[2][3] = 0; + inv.m[3][0] = -inv.m[0][0] * m[3][0] - inv.m[1][0] * m[3][1] - inv.m[2][0] * m[3][2]; + inv.m[3][1] = -inv.m[0][1] * m[3][0] - inv.m[1][1] * m[3][1] - inv.m[2][1] * m[3][2]; + inv.m[3][2] = -inv.m[0][2] * m[3][0] - inv.m[1][2] * m[3][1] - inv.m[2][2] * m[3][2]; + inv.m[3][3] = 1; + inv.flagBits = flagBits; + + if (invertible) + *invertible = true; + return inv; + } + + QDoubleMatrix4x4 inv(1); // The "1" says to not load the identity. + + double det = matrixDet4(m); + if (det == 0.0) { + if (invertible) + *invertible = false; + return QDoubleMatrix4x4(); + } + det = 1.0 / det; + + inv.m[0][0] = matrixDet3(m, 1, 2, 3, 1, 2, 3) * det; + inv.m[0][1] = -matrixDet3(m, 0, 2, 3, 1, 2, 3) * det; + inv.m[0][2] = matrixDet3(m, 0, 1, 3, 1, 2, 3) * det; + inv.m[0][3] = -matrixDet3(m, 0, 1, 2, 1, 2, 3) * det; + inv.m[1][0] = -matrixDet3(m, 1, 2, 3, 0, 2, 3) * det; + inv.m[1][1] = matrixDet3(m, 0, 2, 3, 0, 2, 3) * det; + inv.m[1][2] = -matrixDet3(m, 0, 1, 3, 0, 2, 3) * det; + inv.m[1][3] = matrixDet3(m, 0, 1, 2, 0, 2, 3) * det; + inv.m[2][0] = matrixDet3(m, 1, 2, 3, 0, 1, 3) * det; + inv.m[2][1] = -matrixDet3(m, 0, 2, 3, 0, 1, 3) * det; + inv.m[2][2] = matrixDet3(m, 0, 1, 3, 0, 1, 3) * det; + inv.m[2][3] = -matrixDet3(m, 0, 1, 2, 0, 1, 3) * det; + inv.m[3][0] = -matrixDet3(m, 1, 2, 3, 0, 1, 2) * det; + inv.m[3][1] = matrixDet3(m, 0, 2, 3, 0, 1, 2) * det; + inv.m[3][2] = -matrixDet3(m, 0, 1, 3, 0, 1, 2) * det; + inv.m[3][3] = matrixDet3(m, 0, 1, 2, 0, 1, 2) * det; + inv.flagBits = flagBits; + + if (invertible) + *invertible = true; + return inv; +} + +QDoubleMatrix4x4 QDoubleMatrix4x4::transposed() const +{ + QDoubleMatrix4x4 result(1); // The "1" says to not load the identity. + for (int row = 0; row < 4; ++row) { + for (int col = 0; col < 4; ++col) { + result.m[col][row] = m[row][col]; + } + } + // When a translation is transposed, it becomes a perspective transformation. + result.flagBits = (flagBits & Translation ? General : flagBits); + return result; +} + +QDoubleMatrix4x4& QDoubleMatrix4x4::operator/=(double divisor) +{ + m[0][0] /= divisor; + m[0][1] /= divisor; + m[0][2] /= divisor; + m[0][3] /= divisor; + m[1][0] /= divisor; + m[1][1] /= divisor; + m[1][2] /= divisor; + m[1][3] /= divisor; + m[2][0] /= divisor; + m[2][1] /= divisor; + m[2][2] /= divisor; + m[2][3] /= divisor; + m[3][0] /= divisor; + m[3][1] /= divisor; + m[3][2] /= divisor; + m[3][3] /= divisor; + flagBits = General; + return *this; +} + +QDoubleMatrix4x4 operator/(const QDoubleMatrix4x4& matrix, double divisor) +{ + QDoubleMatrix4x4 m(1); // The "1" says to not load the identity. + m.m[0][0] = matrix.m[0][0] / divisor; + m.m[0][1] = matrix.m[0][1] / divisor; + m.m[0][2] = matrix.m[0][2] / divisor; + m.m[0][3] = matrix.m[0][3] / divisor; + m.m[1][0] = matrix.m[1][0] / divisor; + m.m[1][1] = matrix.m[1][1] / divisor; + m.m[1][2] = matrix.m[1][2] / divisor; + m.m[1][3] = matrix.m[1][3] / divisor; + m.m[2][0] = matrix.m[2][0] / divisor; + m.m[2][1] = matrix.m[2][1] / divisor; + m.m[2][2] = matrix.m[2][2] / divisor; + m.m[2][3] = matrix.m[2][3] / divisor; + m.m[3][0] = matrix.m[3][0] / divisor; + m.m[3][1] = matrix.m[3][1] / divisor; + m.m[3][2] = matrix.m[3][2] / divisor; + m.m[3][3] = matrix.m[3][3] / divisor; + m.flagBits = QDoubleMatrix4x4::General; + return m; +} + +void QDoubleMatrix4x4::scale(const QDoubleVector3D& vector) +{ + double vx = vector.x(); + double vy = vector.y(); + double vz = vector.z(); + if (flagBits < Scale) { + m[0][0] = vx; + m[1][1] = vy; + m[2][2] = vz; + } else if (flagBits < Rotation2D) { + m[0][0] *= vx; + m[1][1] *= vy; + m[2][2] *= vz; + } else if (flagBits < Rotation) { + m[0][0] *= vx; + m[0][1] *= vx; + m[1][0] *= vy; + m[1][1] *= vy; + m[2][2] *= vz; + } else { + m[0][0] *= vx; + m[0][1] *= vx; + m[0][2] *= vx; + m[0][3] *= vx; + m[1][0] *= vy; + m[1][1] *= vy; + m[1][2] *= vy; + m[1][3] *= vy; + m[2][0] *= vz; + m[2][1] *= vz; + m[2][2] *= vz; + m[2][3] *= vz; + } + flagBits |= Scale; +} + +void QDoubleMatrix4x4::scale(double x, double y) +{ + if (flagBits < Scale) { + m[0][0] = x; + m[1][1] = y; + } else if (flagBits < Rotation2D) { + m[0][0] *= x; + m[1][1] *= y; + } else if (flagBits < Rotation) { + m[0][0] *= x; + m[0][1] *= x; + m[1][0] *= y; + m[1][1] *= y; + } else { + m[0][0] *= x; + m[0][1] *= x; + m[0][2] *= x; + m[0][3] *= x; + m[1][0] *= y; + m[1][1] *= y; + m[1][2] *= y; + m[1][3] *= y; + } + flagBits |= Scale; +} + +void QDoubleMatrix4x4::scale(double x, double y, double z) +{ + if (flagBits < Scale) { + m[0][0] = x; + m[1][1] = y; + m[2][2] = z; + } else if (flagBits < Rotation2D) { + m[0][0] *= x; + m[1][1] *= y; + m[2][2] *= z; + } else if (flagBits < Rotation) { + m[0][0] *= x; + m[0][1] *= x; + m[1][0] *= y; + m[1][1] *= y; + m[2][2] *= z; + } else { + m[0][0] *= x; + m[0][1] *= x; + m[0][2] *= x; + m[0][3] *= x; + m[1][0] *= y; + m[1][1] *= y; + m[1][2] *= y; + m[1][3] *= y; + m[2][0] *= z; + m[2][1] *= z; + m[2][2] *= z; + m[2][3] *= z; + } + flagBits |= Scale; +} + +void QDoubleMatrix4x4::scale(double factor) +{ + if (flagBits < Scale) { + m[0][0] = factor; + m[1][1] = factor; + m[2][2] = factor; + } else if (flagBits < Rotation2D) { + m[0][0] *= factor; + m[1][1] *= factor; + m[2][2] *= factor; + } else if (flagBits < Rotation) { + m[0][0] *= factor; + m[0][1] *= factor; + m[1][0] *= factor; + m[1][1] *= factor; + m[2][2] *= factor; + } else { + m[0][0] *= factor; + m[0][1] *= factor; + m[0][2] *= factor; + m[0][3] *= factor; + m[1][0] *= factor; + m[1][1] *= factor; + m[1][2] *= factor; + m[1][3] *= factor; + m[2][0] *= factor; + m[2][1] *= factor; + m[2][2] *= factor; + m[2][3] *= factor; + } + flagBits |= Scale; +} + +void QDoubleMatrix4x4::translate(const QDoubleVector3D& vector) +{ + double vx = vector.x(); + double vy = vector.y(); + double vz = vector.z(); + if (flagBits == Identity) { + m[3][0] = vx; + m[3][1] = vy; + m[3][2] = vz; + } else if (flagBits == Translation) { + m[3][0] += vx; + m[3][1] += vy; + m[3][2] += vz; + } else if (flagBits == Scale) { + m[3][0] = m[0][0] * vx; + m[3][1] = m[1][1] * vy; + m[3][2] = m[2][2] * vz; + } else if (flagBits == (Translation | Scale)) { + m[3][0] += m[0][0] * vx; + m[3][1] += m[1][1] * vy; + m[3][2] += m[2][2] * vz; + } else if (flagBits < Rotation) { + m[3][0] += m[0][0] * vx + m[1][0] * vy; + m[3][1] += m[0][1] * vx + m[1][1] * vy; + m[3][2] += m[2][2] * vz; + } else { + m[3][0] += m[0][0] * vx + m[1][0] * vy + m[2][0] * vz; + m[3][1] += m[0][1] * vx + m[1][1] * vy + m[2][1] * vz; + m[3][2] += m[0][2] * vx + m[1][2] * vy + m[2][2] * vz; + m[3][3] += m[0][3] * vx + m[1][3] * vy + m[2][3] * vz; + } + flagBits |= Translation; +} + +void QDoubleMatrix4x4::translate(double x, double y) +{ + if (flagBits == Identity) { + m[3][0] = x; + m[3][1] = y; + } else if (flagBits == Translation) { + m[3][0] += x; + m[3][1] += y; + } else if (flagBits == Scale) { + m[3][0] = m[0][0] * x; + m[3][1] = m[1][1] * y; + } else if (flagBits == (Translation | Scale)) { + m[3][0] += m[0][0] * x; + m[3][1] += m[1][1] * y; + } else if (flagBits < Rotation) { + m[3][0] += m[0][0] * x + m[1][0] * y; + m[3][1] += m[0][1] * x + m[1][1] * y; + } else { + m[3][0] += m[0][0] * x + m[1][0] * y; + m[3][1] += m[0][1] * x + m[1][1] * y; + m[3][2] += m[0][2] * x + m[1][2] * y; + m[3][3] += m[0][3] * x + m[1][3] * y; + } + flagBits |= Translation; +} + +void QDoubleMatrix4x4::translate(double x, double y, double z) +{ + if (flagBits == Identity) { + m[3][0] = x; + m[3][1] = y; + m[3][2] = z; + } else if (flagBits == Translation) { + m[3][0] += x; + m[3][1] += y; + m[3][2] += z; + } else if (flagBits == Scale) { + m[3][0] = m[0][0] * x; + m[3][1] = m[1][1] * y; + m[3][2] = m[2][2] * z; + } else if (flagBits == (Translation | Scale)) { + m[3][0] += m[0][0] * x; + m[3][1] += m[1][1] * y; + m[3][2] += m[2][2] * z; + } else if (flagBits < Rotation) { + m[3][0] += m[0][0] * x + m[1][0] * y; + m[3][1] += m[0][1] * x + m[1][1] * y; + m[3][2] += m[2][2] * z; + } else { + m[3][0] += m[0][0] * x + m[1][0] * y + m[2][0] * z; + m[3][1] += m[0][1] * x + m[1][1] * y + m[2][1] * z; + m[3][2] += m[0][2] * x + m[1][2] * y + m[2][2] * z; + m[3][3] += m[0][3] * x + m[1][3] * y + m[2][3] * z; + } + flagBits |= Translation; +} + +void QDoubleMatrix4x4::rotate(double angle, const QDoubleVector3D& vector) +{ + rotate(angle, vector.x(), vector.y(), vector.z()); +} + +void QDoubleMatrix4x4::rotate(double angle, double x, double y, double z) +{ + if (angle == 0.0) + return; + double c, s; + if (angle == 90.0 || angle == -270.0) { + s = 1.0; + c = 0.0; + } else if (angle == -90.0 || angle == 270.0) { + s = -1.0; + c = 0.0; + } else if (angle == 180.0 || angle == -180.0) { + s = 0.0; + c = -1.0; + } else { + double a = qDegreesToRadians(angle); + c = std::cos(a); + s = std::sin(a); + } + if (x == 0.0) { + if (y == 0.0) { + if (z != 0.0) { + // Rotate around the Z axis. + if (z < 0) + s = -s; + double tmp; + m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s; + m[1][0] = m[1][0] * c - tmp * s; + m[0][1] = (tmp = m[0][1]) * c + m[1][1] * s; + m[1][1] = m[1][1] * c - tmp * s; + m[0][2] = (tmp = m[0][2]) * c + m[1][2] * s; + m[1][2] = m[1][2] * c - tmp * s; + m[0][3] = (tmp = m[0][3]) * c + m[1][3] * s; + m[1][3] = m[1][3] * c - tmp * s; + + flagBits |= Rotation2D; + return; + } + } else if (z == 0.0) { + // Rotate around the Y axis. + if (y < 0) + s = -s; + double tmp; + m[2][0] = (tmp = m[2][0]) * c + m[0][0] * s; + m[0][0] = m[0][0] * c - tmp * s; + m[2][1] = (tmp = m[2][1]) * c + m[0][1] * s; + m[0][1] = m[0][1] * c - tmp * s; + m[2][2] = (tmp = m[2][2]) * c + m[0][2] * s; + m[0][2] = m[0][2] * c - tmp * s; + m[2][3] = (tmp = m[2][3]) * c + m[0][3] * s; + m[0][3] = m[0][3] * c - tmp * s; + + flagBits |= Rotation; + return; + } + } else if (y == 0.0 && z == 0.0) { + // Rotate around the X axis. + if (x < 0) + s = -s; + double tmp; + m[1][0] = (tmp = m[1][0]) * c + m[2][0] * s; + m[2][0] = m[2][0] * c - tmp * s; + m[1][1] = (tmp = m[1][1]) * c + m[2][1] * s; + m[2][1] = m[2][1] * c - tmp * s; + m[1][2] = (tmp = m[1][2]) * c + m[2][2] * s; + m[2][2] = m[2][2] * c - tmp * s; + m[1][3] = (tmp = m[1][3]) * c + m[2][3] * s; + m[2][3] = m[2][3] * c - tmp * s; + + flagBits |= Rotation; + return; + } + + double len = double(x) * double(x) + + double(y) * double(y) + + double(z) * double(z); + if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) { + len = std::sqrt(len); + x = double(double(x) / len); + y = double(double(y) / len); + z = double(double(z) / len); + } + double ic = 1.0 - c; + QDoubleMatrix4x4 rot(1); // The "1" says to not load the identity. + rot.m[0][0] = x * x * ic + c; + rot.m[1][0] = x * y * ic - z * s; + rot.m[2][0] = x * z * ic + y * s; + rot.m[3][0] = 0.0; + rot.m[0][1] = y * x * ic + z * s; + rot.m[1][1] = y * y * ic + c; + rot.m[2][1] = y * z * ic - x * s; + rot.m[3][1] = 0.0; + rot.m[0][2] = x * z * ic - y * s; + rot.m[1][2] = y * z * ic + x * s; + rot.m[2][2] = z * z * ic + c; + rot.m[3][2] = 0.0; + rot.m[0][3] = 0.0; + rot.m[1][3] = 0.0; + rot.m[2][3] = 0.0; + rot.m[3][3] = 1.0; + rot.flagBits = Rotation; + *this *= rot; +} + +void QDoubleMatrix4x4::projectedRotate(double angle, double x, double y, double z) +{ + // Used by QGraphicsRotation::applyTo() to perform a rotation + // and projection back to 2D in a single step. + if (angle == 0.0) + return; + double c, s; + if (angle == 90.0 || angle == -270.0) { + s = 1.0; + c = 0.0; + } else if (angle == -90.0 || angle == 270.0) { + s = -1.0; + c = 0.0; + } else if (angle == 180.0 || angle == -180.0) { + s = 0.0; + c = -1.0; + } else { + double a = qDegreesToRadians(angle); + c = std::cos(a); + s = std::sin(a); + } + if (x == 0.0) { + if (y == 0.0) { + if (z != 0.0) { + // Rotate around the Z axis. + if (z < 0) + s = -s; + double tmp; + m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s; + m[1][0] = m[1][0] * c - tmp * s; + m[0][1] = (tmp = m[0][1]) * c + m[1][1] * s; + m[1][1] = m[1][1] * c - tmp * s; + m[0][2] = (tmp = m[0][2]) * c + m[1][2] * s; + m[1][2] = m[1][2] * c - tmp * s; + m[0][3] = (tmp = m[0][3]) * c + m[1][3] * s; + m[1][3] = m[1][3] * c - tmp * s; + + flagBits |= Rotation2D; + return; + } + } else if (z == 0.0) { + // Rotate around the Y axis. + if (y < 0) + s = -s; + m[0][0] = m[0][0] * c + m[3][0] * s * inv_dist_to_plane; + m[0][1] = m[0][1] * c + m[3][1] * s * inv_dist_to_plane; + m[0][2] = m[0][2] * c + m[3][2] * s * inv_dist_to_plane; + m[0][3] = m[0][3] * c + m[3][3] * s * inv_dist_to_plane; + flagBits = General; + return; + } + } else if (y == 0.0 && z == 0.0) { + // Rotate around the X axis. + if (x < 0) + s = -s; + m[1][0] = m[1][0] * c - m[3][0] * s * inv_dist_to_plane; + m[1][1] = m[1][1] * c - m[3][1] * s * inv_dist_to_plane; + m[1][2] = m[1][2] * c - m[3][2] * s * inv_dist_to_plane; + m[1][3] = m[1][3] * c - m[3][3] * s * inv_dist_to_plane; + flagBits = General; + return; + } + double len = double(x) * double(x) + + double(y) * double(y) + + double(z) * double(z); + if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) { + len = std::sqrt(len); + x = double(double(x) / len); + y = double(double(y) / len); + z = double(double(z) / len); + } + double ic = 1.0 - c; + QDoubleMatrix4x4 rot(1); // The "1" says to not load the identity. + rot.m[0][0] = x * x * ic + c; + rot.m[1][0] = x * y * ic - z * s; + rot.m[2][0] = 0.0; + rot.m[3][0] = 0.0; + rot.m[0][1] = y * x * ic + z * s; + rot.m[1][1] = y * y * ic + c; + rot.m[2][1] = 0.0; + rot.m[3][1] = 0.0; + rot.m[0][2] = 0.0; + rot.m[1][2] = 0.0; + rot.m[2][2] = 1.0; + rot.m[3][2] = 0.0; + rot.m[0][3] = (x * z * ic - y * s) * -inv_dist_to_plane; + rot.m[1][3] = (y * z * ic + x * s) * -inv_dist_to_plane; + rot.m[2][3] = 0.0; + rot.m[3][3] = 1.0; + rot.flagBits = General; + *this *= rot; +} + +void QDoubleMatrix4x4::ortho(const QRect& rect) +{ + // Note: rect.right() and rect.bottom() subtract 1 in QRect, + // which gives the location of a pixel within the rectangle, + // instead of the extent of the rectangle. We want the extent. + // QRectF expresses the extent properly. + ortho(rect.x(), rect.x() + rect.width(), rect.y() + rect.height(), rect.y(), -1.0, 1.0); +} + +void QDoubleMatrix4x4::ortho(const QRectF& rect) +{ + ortho(rect.left(), rect.right(), rect.bottom(), rect.top(), -1.0, 1.0); +} + +void QDoubleMatrix4x4::ortho(double left, double right, double bottom, double top, double nearPlane, double farPlane) +{ + // Bail out if the projection volume is zero-sized. + if (left == right || bottom == top || nearPlane == farPlane) + return; + + // Construct the projection. + double width = right - left; + double invheight = top - bottom; + double clip = farPlane - nearPlane; + QDoubleMatrix4x4 m(1); + m.m[0][0] = 2.0 / width; + m.m[1][0] = 0.0; + m.m[2][0] = 0.0; + m.m[3][0] = -(left + right) / width; + m.m[0][1] = 0.0; + m.m[1][1] = 2.0 / invheight; + m.m[2][1] = 0.0; + m.m[3][1] = -(top + bottom) / invheight; + m.m[0][2] = 0.0; + m.m[1][2] = 0.0; + m.m[2][2] = -2.0 / clip; + m.m[3][2] = -(nearPlane + farPlane) / clip; + m.m[0][3] = 0.0; + m.m[1][3] = 0.0; + m.m[2][3] = 0.0; + m.m[3][3] = 1.0; + m.flagBits = Translation | Scale; + + // Apply the projection. + *this *= m; +} + +void QDoubleMatrix4x4::frustum(double left, double right, double bottom, double top, double nearPlane, double farPlane) +{ + // Bail out if the projection volume is zero-sized. + if (left == right || bottom == top || nearPlane == farPlane) + return; + + // Construct the projection. + QDoubleMatrix4x4 m(1); + double width = right - left; + double invheight = top - bottom; + double clip = farPlane - nearPlane; + m.m[0][0] = 2.0 * nearPlane / width; + m.m[1][0] = 0.0; + m.m[2][0] = (left + right) / width; + m.m[3][0] = 0.0; + m.m[0][1] = 0.0; + m.m[1][1] = 2.0 * nearPlane / invheight; + m.m[2][1] = (top + bottom) / invheight; + m.m[3][1] = 0.0; + m.m[0][2] = 0.0; + m.m[1][2] = 0.0; + m.m[2][2] = -(nearPlane + farPlane) / clip; + m.m[3][2] = -2.0 * nearPlane * farPlane / clip; + m.m[0][3] = 0.0; + m.m[1][3] = 0.0; + m.m[2][3] = -1.0; + m.m[3][3] = 0.0; + m.flagBits = General; + + // Apply the projection. + *this *= m; +} + +void QDoubleMatrix4x4::perspective(double verticalAngle, double aspectRatio, double nearPlane, double farPlane) +{ + // Bail out if the projection volume is zero-sized. + if (nearPlane == farPlane || aspectRatio == 0.0) + return; + + // Construct the projection. + QDoubleMatrix4x4 m(1); + double radians = qDegreesToRadians(verticalAngle / 2.0); + double sine = std::sin(radians); + if (sine == 0.0) + return; + double cotan = std::cos(radians) / sine; + double clip = farPlane - nearPlane; + m.m[0][0] = cotan / aspectRatio; + m.m[1][0] = 0.0; + m.m[2][0] = 0.0; + m.m[3][0] = 0.0; + m.m[0][1] = 0.0; + m.m[1][1] = cotan; + m.m[2][1] = 0.0; + m.m[3][1] = 0.0; + m.m[0][2] = 0.0; + m.m[1][2] = 0.0; + m.m[2][2] = -(nearPlane + farPlane) / clip; + m.m[3][2] = -(2.0 * nearPlane * farPlane) / clip; + m.m[0][3] = 0.0; + m.m[1][3] = 0.0; + m.m[2][3] = -1.0; + m.m[3][3] = 0.0; + m.flagBits = General; + + // Apply the projection. + *this *= m; +} + +void QDoubleMatrix4x4::lookAt(const QDoubleVector3D& eye, const QDoubleVector3D& center, const QDoubleVector3D& up) +{ + QDoubleVector3D forward = center - eye; + if (qFuzzyIsNull(forward.x()) && qFuzzyIsNull(forward.y()) && qFuzzyIsNull(forward.z())) + return; + + forward.normalize(); + QDoubleVector3D side = QDoubleVector3D::crossProduct(forward, up).normalized(); + QDoubleVector3D upVector = QDoubleVector3D::crossProduct(side, forward); + + QDoubleMatrix4x4 m(1); + m.m[0][0] = side.x(); + m.m[1][0] = side.y(); + m.m[2][0] = side.z(); + m.m[3][0] = 0.0; + m.m[0][1] = upVector.x(); + m.m[1][1] = upVector.y(); + m.m[2][1] = upVector.z(); + m.m[3][1] = 0.0; + m.m[0][2] = -forward.x(); + m.m[1][2] = -forward.y(); + m.m[2][2] = -forward.z(); + m.m[3][2] = 0.0; + m.m[0][3] = 0.0; + m.m[1][3] = 0.0; + m.m[2][3] = 0.0; + m.m[3][3] = 1.0; + m.flagBits = Rotation; + + *this *= m; + translate(-eye); +} + +void QDoubleMatrix4x4::viewport(double left, double bottom, double width, double height, double nearPlane, double farPlane) +{ + const double w2 = width / 2.0; + const double h2 = height / 2.0; + + QDoubleMatrix4x4 m(1); + m.m[0][0] = w2; + m.m[1][0] = 0.0; + m.m[2][0] = 0.0; + m.m[3][0] = left + w2; + m.m[0][1] = 0.0; + m.m[1][1] = h2; + m.m[2][1] = 0.0; + m.m[3][1] = bottom + h2; + m.m[0][2] = 0.0; + m.m[1][2] = 0.0; + m.m[2][2] = (farPlane - nearPlane) / 2.0; + m.m[3][2] = (nearPlane + farPlane) / 2.0; + m.m[0][3] = 0.0; + m.m[1][3] = 0.0; + m.m[2][3] = 0.0; + m.m[3][3] = 1.0; + m.flagBits = General; + + *this *= m; +} + +void QDoubleMatrix4x4::flipCoordinates() +{ + // Multiplying the y and z coordinates with -1 does NOT flip between right-handed and + // left-handed coordinate systems, it just rotates 180 degrees around the x axis, so + // I'm deprecating this function. + if (flagBits < Rotation2D) { + // Translation | Scale + m[1][1] = -m[1][1]; + m[2][2] = -m[2][2]; + } else { + m[1][0] = -m[1][0]; + m[1][1] = -m[1][1]; + m[1][2] = -m[1][2]; + m[1][3] = -m[1][3]; + m[2][0] = -m[2][0]; + m[2][1] = -m[2][1]; + m[2][2] = -m[2][2]; + m[2][3] = -m[2][3]; + } + flagBits |= Scale; +} + +void QDoubleMatrix4x4::copyDataTo(double *values) const +{ + for (int row = 0; row < 4; ++row) + for (int col = 0; col < 4; ++col) + values[row * 4 + col] = double(m[col][row]); +} + +QRect QDoubleMatrix4x4::mapRect(const QRect& rect) const +{ + if (flagBits < Scale) { + // Translation + return QRect(qRound(rect.x() + m[3][0]), + qRound(rect.y() + m[3][1]), + rect.width(), rect.height()); + } else if (flagBits < Rotation2D) { + // Translation | Scale + double x = rect.x() * m[0][0] + m[3][0]; + double y = rect.y() * m[1][1] + m[3][1]; + double w = rect.width() * m[0][0]; + double h = rect.height() * m[1][1]; + if (w < 0) { + w = -w; + x -= w; + } + if (h < 0) { + h = -h; + y -= h; + } + return QRect(qRound(x), qRound(y), qRound(w), qRound(h)); + } + + QPoint tl = map(rect.topLeft()); + QPoint tr = map(QPoint(rect.x() + rect.width(), rect.y())); + QPoint bl = map(QPoint(rect.x(), rect.y() + rect.height())); + QPoint br = map(QPoint(rect.x() + rect.width(), + rect.y() + rect.height())); + + int xmin = qMin(qMin(tl.x(), tr.x()), qMin(bl.x(), br.x())); + int xmax = qMax(qMax(tl.x(), tr.x()), qMax(bl.x(), br.x())); + int ymin = qMin(qMin(tl.y(), tr.y()), qMin(bl.y(), br.y())); + int ymax = qMax(qMax(tl.y(), tr.y()), qMax(bl.y(), br.y())); + + return QRect(xmin, ymin, xmax - xmin, ymax - ymin); +} + +QRectF QDoubleMatrix4x4::mapRect(const QRectF& rect) const +{ + if (flagBits < Scale) { + // Translation + return rect.translated(m[3][0], m[3][1]); + } else if (flagBits < Rotation2D) { + // Translation | Scale + double x = rect.x() * m[0][0] + m[3][0]; + double y = rect.y() * m[1][1] + m[3][1]; + double w = rect.width() * m[0][0]; + double h = rect.height() * m[1][1]; + if (w < 0) { + w = -w; + x -= w; + } + if (h < 0) { + h = -h; + y -= h; + } + return QRectF(x, y, w, h); + } + + QPointF tl = map(rect.topLeft()); QPointF tr = map(rect.topRight()); + QPointF bl = map(rect.bottomLeft()); QPointF br = map(rect.bottomRight()); + + double xmin = qMin(qMin(tl.x(), tr.x()), qMin(bl.x(), br.x())); + double xmax = qMax(qMax(tl.x(), tr.x()), qMax(bl.x(), br.x())); + double ymin = qMin(qMin(tl.y(), tr.y()), qMin(bl.y(), br.y())); + double ymax = qMax(qMax(tl.y(), tr.y()), qMax(bl.y(), br.y())); + + return QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); +} + +QDoubleMatrix4x4 QDoubleMatrix4x4::orthonormalInverse() const +{ + QDoubleMatrix4x4 result(1); // The '1' says not to load identity + + result.m[0][0] = m[0][0]; + result.m[1][0] = m[0][1]; + result.m[2][0] = m[0][2]; + + result.m[0][1] = m[1][0]; + result.m[1][1] = m[1][1]; + result.m[2][1] = m[1][2]; + + result.m[0][2] = m[2][0]; + result.m[1][2] = m[2][1]; + result.m[2][2] = m[2][2]; + + result.m[0][3] = 0.0; + result.m[1][3] = 0.0; + result.m[2][3] = 0.0; + + result.m[3][0] = -(result.m[0][0] * m[3][0] + result.m[1][0] * m[3][1] + result.m[2][0] * m[3][2]); + result.m[3][1] = -(result.m[0][1] * m[3][0] + result.m[1][1] * m[3][1] + result.m[2][1] * m[3][2]); + result.m[3][2] = -(result.m[0][2] * m[3][0] + result.m[1][2] * m[3][1] + result.m[2][2] * m[3][2]); + result.m[3][3] = 1.0; + + result.flagBits = flagBits; + + return result; +} + +void QDoubleMatrix4x4::optimize() +{ + // If the last row is not (0, 0, 0, 1), the matrix is not a special type. + flagBits = General; + if (m[0][3] != 0 || m[1][3] != 0 || m[2][3] != 0 || m[3][3] != 1) + return; + + flagBits &= ~Perspective; + + // If the last column is (0, 0, 0, 1), then there is no translation. + if (m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0) + flagBits &= ~Translation; + + // If the two first elements of row 3 and column 3 are 0, then any rotation must be about Z. + if (!m[0][2] && !m[1][2] && !m[2][0] && !m[2][1]) { + flagBits &= ~Rotation; + // If the six non-diagonal elements in the top left 3x3 matrix are 0, there is no rotation. + if (!m[0][1] && !m[1][0]) { + flagBits &= ~Rotation2D; + // Check for identity. + if (m[0][0] == 1 && m[1][1] == 1 && m[2][2] == 1) + flagBits &= ~Scale; + } else { + // If the columns are orthonormal and form a right-handed system, then there is no scale. + double det = matrixDet2(m, 0, 1, 0, 1); + double lenX = m[0][0] * m[0][0] + m[0][1] * m[0][1]; + double lenY = m[1][0] * m[1][0] + m[1][1] * m[1][1]; + double lenZ = m[2][2]; + if (qFuzzyCompare(det, 1.0) && qFuzzyCompare(lenX, 1.0) + && qFuzzyCompare(lenY, 1.0) && qFuzzyCompare(lenZ, 1.0)) + { + flagBits &= ~Scale; + } + } + } else { + // If the columns are orthonormal and form a right-handed system, then there is no scale. + double det = matrixDet3(m, 0, 1, 2, 0, 1, 2); + double lenX = m[0][0] * m[0][0] + m[0][1] * m[0][1] + m[0][2] * m[0][2]; + double lenY = m[1][0] * m[1][0] + m[1][1] * m[1][1] + m[1][2] * m[1][2]; + double lenZ = m[2][0] * m[2][0] + m[2][1] * m[2][1] + m[2][2] * m[2][2]; + if (qFuzzyCompare(det, 1.0) && qFuzzyCompare(lenX, 1.0) + && qFuzzyCompare(lenY, 1.0) && qFuzzyCompare(lenZ, 1.0)) + { + flagBits &= ~Scale; + } + } +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<(QDebug dbg, const QDoubleMatrix4x4 &m) +{ + QDebugStateSaver saver(dbg); + // Create a string that represents the matrix type. + QByteArray bits; + if (m.flagBits == QDoubleMatrix4x4::Identity) { + bits = "Identity"; + } else if (m.flagBits == QDoubleMatrix4x4::General) { + bits = "General"; + } else { + if ((m.flagBits & QDoubleMatrix4x4::Translation) != 0) + bits += "Translation,"; + if ((m.flagBits & QDoubleMatrix4x4::Scale) != 0) + bits += "Scale,"; + if ((m.flagBits & QDoubleMatrix4x4::Rotation2D) != 0) + bits += "Rotation2D,"; + if ((m.flagBits & QDoubleMatrix4x4::Rotation) != 0) + bits += "Rotation,"; + if ((m.flagBits & QDoubleMatrix4x4::Perspective) != 0) + bits += "Perspective,"; + if (!bits.isEmpty()) + bits = bits.left(bits.size() - 1); + } + + // Output in row-major order because it is more human-readable. + dbg.nospace() << "QDoubleMatrix4x4(type:" << bits.constData() << Qt::endl + << qSetFieldWidth(10) + << m(0, 0) << m(0, 1) << m(0, 2) << m(0, 3) << Qt::endl + << m(1, 0) << m(1, 1) << m(1, 2) << m(1, 3) << Qt::endl + << m(2, 0) << m(2, 1) << m(2, 2) << m(2, 3) << Qt::endl + << m(3, 0) << m(3, 1) << m(3, 2) << m(3, 3) << Qt::endl + << qSetFieldWidth(0) << ')'; + return dbg; +} + +#endif + +#ifndef QT_NO_DATASTREAM + +QDataStream &operator<<(QDataStream &stream, const QDoubleMatrix4x4 &matrix) +{ + for (int row = 0; row < 4; ++row) + for (int col = 0; col < 4; ++col) + stream << matrix(row, col); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QDoubleMatrix4x4 &matrix) +{ + double x; + for (int row = 0; row < 4; ++row) { + for (int col = 0; col < 4; ++col) { + stream >> x; + matrix(row, col) = x; + } + } + matrix.optimize(); + return stream; +} + +#endif // QT_NO_DATASTREAM + +QT_END_NAMESPACE diff --git a/src/positioning/qdoublematrix4x4_p.h b/src/positioning/qdoublematrix4x4_p.h new file mode 100644 index 0000000..d5300e3 --- /dev/null +++ b/src/positioning/qdoublematrix4x4_p.h @@ -0,0 +1,910 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QDOUBLEMATRIX4X4_H +#define QDOUBLEMATRIX4X4_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 +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/* + * This class is a copy/paste/replace of QMatrix4x4 + * No algorithm has been changed. + * Some methods have been removed. + */ + +class Q_POSITIONING_PRIVATE_EXPORT QDoubleMatrix4x4 +{ +public: + inline QDoubleMatrix4x4() { setToIdentity(); } + explicit QDoubleMatrix4x4(Qt::Initialization) : flagBits(General) {} + explicit QDoubleMatrix4x4(const double *values); + inline QDoubleMatrix4x4(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double m41, double m42, double m43, double m44); + + QDoubleMatrix4x4(const double *values, int cols, int rows); + + inline const double& operator()(int row, int column) const; + inline double& operator()(int row, int column); + + inline bool isAffine() const; + + inline bool isIdentity() const; + inline void setToIdentity(); + + inline void fill(double value); + + double determinant() const; + QDoubleMatrix4x4 inverted(bool *invertible = nullptr) const; + QDoubleMatrix4x4 transposed() const; + + inline QDoubleMatrix4x4& operator+=(const QDoubleMatrix4x4& other); + inline QDoubleMatrix4x4& operator-=(const QDoubleMatrix4x4& other); + inline QDoubleMatrix4x4& operator*=(const QDoubleMatrix4x4& other); + inline QDoubleMatrix4x4& operator*=(double factor); + QDoubleMatrix4x4& operator/=(double divisor); + inline bool operator==(const QDoubleMatrix4x4& other) const; + inline bool operator!=(const QDoubleMatrix4x4& other) const; + + friend QDoubleMatrix4x4 operator+(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2); + friend QDoubleMatrix4x4 operator-(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2); + friend QDoubleMatrix4x4 operator*(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2); + + friend QDoubleVector3D operator*(const QDoubleMatrix4x4& matrix, const QDoubleVector3D& vector); + friend QDoubleVector3D operator*(const QDoubleVector3D& vector, const QDoubleMatrix4x4& matrix); + + friend QPoint operator*(const QPoint& point, const QDoubleMatrix4x4& matrix); + friend QPointF operator*(const QPointF& point, const QDoubleMatrix4x4& matrix); + friend QDoubleMatrix4x4 operator-(const QDoubleMatrix4x4& matrix); + friend QPoint operator*(const QDoubleMatrix4x4& matrix, const QPoint& point); + friend QPointF operator*(const QDoubleMatrix4x4& matrix, const QPointF& point); + friend QDoubleMatrix4x4 operator*(double factor, const QDoubleMatrix4x4& matrix); + friend QDoubleMatrix4x4 operator*(const QDoubleMatrix4x4& matrix, double factor); + friend Q_POSITIONING_PRIVATE_EXPORT QDoubleMatrix4x4 operator/(const QDoubleMatrix4x4& matrix, double divisor); + + friend inline bool qFuzzyCompare(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2); + + + void scale(const QDoubleVector3D& vector); + void translate(const QDoubleVector3D& vector); + void rotate(double angle, const QDoubleVector3D& vector); + + void scale(double x, double y); + void scale(double x, double y, double z); + void scale(double factor); + void translate(double x, double y); + void translate(double x, double y, double z); + void rotate(double angle, double x, double y, double z = 0.0f); + + void ortho(const QRect& rect); + void ortho(const QRectF& rect); + void ortho(double left, double right, double bottom, double top, double nearPlane, double farPlane); + void frustum(double left, double right, double bottom, double top, double nearPlane, double farPlane); + void perspective(double verticalAngle, double aspectRatio, double nearPlane, double farPlane); + + void lookAt(const QDoubleVector3D& eye, const QDoubleVector3D& center, const QDoubleVector3D& up); + + void viewport(const QRectF &rect); + void viewport(double left, double bottom, double width, double height, double nearPlane = 0.0f, double farPlane = 1.0f); + void flipCoordinates(); + + void copyDataTo(double *values) const; + + QPoint map(const QPoint& point) const; + QPointF map(const QPointF& point) const; + + QDoubleVector3D map(const QDoubleVector3D& point) const; + QDoubleVector3D mapVector(const QDoubleVector3D& vector) const; + + QRect mapRect(const QRect& rect) const; + QRectF mapRect(const QRectF& rect) const; + + inline double *data(); + inline const double *data() const { return *m; } + inline const double *constData() const { return *m; } + + void optimize(); + +#ifndef QT_NO_DEBUG_STREAM + friend Q_POSITIONING_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QDoubleMatrix4x4 &m); +#endif + +private: + double m[4][4]; // Column-major order to match OpenGL. + int flagBits; // Flag bits from the enum below. + + // When matrices are multiplied, the flag bits are or-ed together. + enum { + Identity = 0x0000, // Identity matrix + Translation = 0x0001, // Contains a translation + Scale = 0x0002, // Contains a scale + Rotation2D = 0x0004, // Contains a rotation about the Z axis + Rotation = 0x0008, // Contains an arbitrary rotation + Perspective = 0x0010, // Last row is different from (0, 0, 0, 1) + General = 0x001f // General matrix, unknown contents + }; + + // Construct without initializing identity matrix. + explicit QDoubleMatrix4x4(int) { } + + QDoubleMatrix4x4 orthonormalInverse() const; + + void projectedRotate(double angle, double x, double y, double z); +}; + +Q_DECLARE_TYPEINFO(QDoubleMatrix4x4, Q_RELOCATABLE_TYPE); + +inline QDoubleMatrix4x4::QDoubleMatrix4x4 + (double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double m41, double m42, double m43, double m44) +{ + m[0][0] = m11; m[0][1] = m21; m[0][2] = m31; m[0][3] = m41; + m[1][0] = m12; m[1][1] = m22; m[1][2] = m32; m[1][3] = m42; + m[2][0] = m13; m[2][1] = m23; m[2][2] = m33; m[2][3] = m43; + m[3][0] = m14; m[3][1] = m24; m[3][2] = m34; m[3][3] = m44; + flagBits = General; +} + +inline const double& QDoubleMatrix4x4::operator()(int aRow, int aColumn) const +{ + Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4); + return m[aColumn][aRow]; +} + +inline double& QDoubleMatrix4x4::operator()(int aRow, int aColumn) +{ + Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4); + flagBits = General; + return m[aColumn][aRow]; +} + +Q_POSITIONING_PRIVATE_EXPORT QDoubleMatrix4x4 operator/(const QDoubleMatrix4x4& matrix, double divisor); + +inline bool QDoubleMatrix4x4::isAffine() const +{ + return m[0][3] == 0.0f && m[1][3] == 0.0f && m[2][3] == 0.0f && m[3][3] == 1.0f; +} + +inline bool QDoubleMatrix4x4::isIdentity() const +{ + if (flagBits == Identity) + return true; + if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f) + return false; + if (m[0][3] != 0.0f || m[1][0] != 0.0f || m[1][1] != 1.0f) + return false; + if (m[1][2] != 0.0f || m[1][3] != 0.0f || m[2][0] != 0.0f) + return false; + if (m[2][1] != 0.0f || m[2][2] != 1.0f || m[2][3] != 0.0f) + return false; + if (m[3][0] != 0.0f || m[3][1] != 0.0f || m[3][2] != 0.0f) + return false; + return (m[3][3] == 1.0f); +} + +inline void QDoubleMatrix4x4::setToIdentity() +{ + m[0][0] = 1.0f; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + m[1][0] = 0.0f; + m[1][1] = 1.0f; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 1.0f; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; + flagBits = Identity; +} + +inline void QDoubleMatrix4x4::fill(double value) +{ + m[0][0] = value; + m[0][1] = value; + m[0][2] = value; + m[0][3] = value; + m[1][0] = value; + m[1][1] = value; + m[1][2] = value; + m[1][3] = value; + m[2][0] = value; + m[2][1] = value; + m[2][2] = value; + m[2][3] = value; + m[3][0] = value; + m[3][1] = value; + m[3][2] = value; + m[3][3] = value; + flagBits = General; +} + +inline QDoubleMatrix4x4& QDoubleMatrix4x4::operator+=(const QDoubleMatrix4x4& other) +{ + m[0][0] += other.m[0][0]; + m[0][1] += other.m[0][1]; + m[0][2] += other.m[0][2]; + m[0][3] += other.m[0][3]; + m[1][0] += other.m[1][0]; + m[1][1] += other.m[1][1]; + m[1][2] += other.m[1][2]; + m[1][3] += other.m[1][3]; + m[2][0] += other.m[2][0]; + m[2][1] += other.m[2][1]; + m[2][2] += other.m[2][2]; + m[2][3] += other.m[2][3]; + m[3][0] += other.m[3][0]; + m[3][1] += other.m[3][1]; + m[3][2] += other.m[3][2]; + m[3][3] += other.m[3][3]; + flagBits = General; + return *this; +} + +inline QDoubleMatrix4x4& QDoubleMatrix4x4::operator-=(const QDoubleMatrix4x4& other) +{ + m[0][0] -= other.m[0][0]; + m[0][1] -= other.m[0][1]; + m[0][2] -= other.m[0][2]; + m[0][3] -= other.m[0][3]; + m[1][0] -= other.m[1][0]; + m[1][1] -= other.m[1][1]; + m[1][2] -= other.m[1][2]; + m[1][3] -= other.m[1][3]; + m[2][0] -= other.m[2][0]; + m[2][1] -= other.m[2][1]; + m[2][2] -= other.m[2][2]; + m[2][3] -= other.m[2][3]; + m[3][0] -= other.m[3][0]; + m[3][1] -= other.m[3][1]; + m[3][2] -= other.m[3][2]; + m[3][3] -= other.m[3][3]; + flagBits = General; + return *this; +} + +inline QDoubleMatrix4x4& QDoubleMatrix4x4::operator*=(const QDoubleMatrix4x4& other) +{ + flagBits |= other.flagBits; + + if (flagBits < Rotation2D) { + m[3][0] += m[0][0] * other.m[3][0]; + m[3][1] += m[1][1] * other.m[3][1]; + m[3][2] += m[2][2] * other.m[3][2]; + + m[0][0] *= other.m[0][0]; + m[1][1] *= other.m[1][1]; + m[2][2] *= other.m[2][2]; + return *this; + } + + double m0, m1, m2; + m0 = m[0][0] * other.m[0][0] + + m[1][0] * other.m[0][1] + + m[2][0] * other.m[0][2] + + m[3][0] * other.m[0][3]; + m1 = m[0][0] * other.m[1][0] + + m[1][0] * other.m[1][1] + + m[2][0] * other.m[1][2] + + m[3][0] * other.m[1][3]; + m2 = m[0][0] * other.m[2][0] + + m[1][0] * other.m[2][1] + + m[2][0] * other.m[2][2] + + m[3][0] * other.m[2][3]; + m[3][0] = m[0][0] * other.m[3][0] + + m[1][0] * other.m[3][1] + + m[2][0] * other.m[3][2] + + m[3][0] * other.m[3][3]; + m[0][0] = m0; + m[1][0] = m1; + m[2][0] = m2; + + m0 = m[0][1] * other.m[0][0] + + m[1][1] * other.m[0][1] + + m[2][1] * other.m[0][2] + + m[3][1] * other.m[0][3]; + m1 = m[0][1] * other.m[1][0] + + m[1][1] * other.m[1][1] + + m[2][1] * other.m[1][2] + + m[3][1] * other.m[1][3]; + m2 = m[0][1] * other.m[2][0] + + m[1][1] * other.m[2][1] + + m[2][1] * other.m[2][2] + + m[3][1] * other.m[2][3]; + m[3][1] = m[0][1] * other.m[3][0] + + m[1][1] * other.m[3][1] + + m[2][1] * other.m[3][2] + + m[3][1] * other.m[3][3]; + m[0][1] = m0; + m[1][1] = m1; + m[2][1] = m2; + + m0 = m[0][2] * other.m[0][0] + + m[1][2] * other.m[0][1] + + m[2][2] * other.m[0][2] + + m[3][2] * other.m[0][3]; + m1 = m[0][2] * other.m[1][0] + + m[1][2] * other.m[1][1] + + m[2][2] * other.m[1][2] + + m[3][2] * other.m[1][3]; + m2 = m[0][2] * other.m[2][0] + + m[1][2] * other.m[2][1] + + m[2][2] * other.m[2][2] + + m[3][2] * other.m[2][3]; + m[3][2] = m[0][2] * other.m[3][0] + + m[1][2] * other.m[3][1] + + m[2][2] * other.m[3][2] + + m[3][2] * other.m[3][3]; + m[0][2] = m0; + m[1][2] = m1; + m[2][2] = m2; + + m0 = m[0][3] * other.m[0][0] + + m[1][3] * other.m[0][1] + + m[2][3] * other.m[0][2] + + m[3][3] * other.m[0][3]; + m1 = m[0][3] * other.m[1][0] + + m[1][3] * other.m[1][1] + + m[2][3] * other.m[1][2] + + m[3][3] * other.m[1][3]; + m2 = m[0][3] * other.m[2][0] + + m[1][3] * other.m[2][1] + + m[2][3] * other.m[2][2] + + m[3][3] * other.m[2][3]; + m[3][3] = m[0][3] * other.m[3][0] + + m[1][3] * other.m[3][1] + + m[2][3] * other.m[3][2] + + m[3][3] * other.m[3][3]; + m[0][3] = m0; + m[1][3] = m1; + m[2][3] = m2; + return *this; +} + +inline QDoubleMatrix4x4& QDoubleMatrix4x4::operator*=(double factor) +{ + m[0][0] *= factor; + m[0][1] *= factor; + m[0][2] *= factor; + m[0][3] *= factor; + m[1][0] *= factor; + m[1][1] *= factor; + m[1][2] *= factor; + m[1][3] *= factor; + m[2][0] *= factor; + m[2][1] *= factor; + m[2][2] *= factor; + m[2][3] *= factor; + m[3][0] *= factor; + m[3][1] *= factor; + m[3][2] *= factor; + m[3][3] *= factor; + flagBits = General; + return *this; +} + +inline bool QDoubleMatrix4x4::operator==(const QDoubleMatrix4x4& other) const +{ + return m[0][0] == other.m[0][0] && + m[0][1] == other.m[0][1] && + m[0][2] == other.m[0][2] && + m[0][3] == other.m[0][3] && + m[1][0] == other.m[1][0] && + m[1][1] == other.m[1][1] && + m[1][2] == other.m[1][2] && + m[1][3] == other.m[1][3] && + m[2][0] == other.m[2][0] && + m[2][1] == other.m[2][1] && + m[2][2] == other.m[2][2] && + m[2][3] == other.m[2][3] && + m[3][0] == other.m[3][0] && + m[3][1] == other.m[3][1] && + m[3][2] == other.m[3][2] && + m[3][3] == other.m[3][3]; +} + +inline bool QDoubleMatrix4x4::operator!=(const QDoubleMatrix4x4& other) const +{ + return m[0][0] != other.m[0][0] || + m[0][1] != other.m[0][1] || + m[0][2] != other.m[0][2] || + m[0][3] != other.m[0][3] || + m[1][0] != other.m[1][0] || + m[1][1] != other.m[1][1] || + m[1][2] != other.m[1][2] || + m[1][3] != other.m[1][3] || + m[2][0] != other.m[2][0] || + m[2][1] != other.m[2][1] || + m[2][2] != other.m[2][2] || + m[2][3] != other.m[2][3] || + m[3][0] != other.m[3][0] || + m[3][1] != other.m[3][1] || + m[3][2] != other.m[3][2] || + m[3][3] != other.m[3][3]; +} + +inline QDoubleMatrix4x4 operator+(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2) +{ + QDoubleMatrix4x4 m(1); + m.m[0][0] = m1.m[0][0] + m2.m[0][0]; + m.m[0][1] = m1.m[0][1] + m2.m[0][1]; + m.m[0][2] = m1.m[0][2] + m2.m[0][2]; + m.m[0][3] = m1.m[0][3] + m2.m[0][3]; + m.m[1][0] = m1.m[1][0] + m2.m[1][0]; + m.m[1][1] = m1.m[1][1] + m2.m[1][1]; + m.m[1][2] = m1.m[1][2] + m2.m[1][2]; + m.m[1][3] = m1.m[1][3] + m2.m[1][3]; + m.m[2][0] = m1.m[2][0] + m2.m[2][0]; + m.m[2][1] = m1.m[2][1] + m2.m[2][1]; + m.m[2][2] = m1.m[2][2] + m2.m[2][2]; + m.m[2][3] = m1.m[2][3] + m2.m[2][3]; + m.m[3][0] = m1.m[3][0] + m2.m[3][0]; + m.m[3][1] = m1.m[3][1] + m2.m[3][1]; + m.m[3][2] = m1.m[3][2] + m2.m[3][2]; + m.m[3][3] = m1.m[3][3] + m2.m[3][3]; + m.flagBits = QDoubleMatrix4x4::General; + return m; +} + +inline QDoubleMatrix4x4 operator-(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2) +{ + QDoubleMatrix4x4 m(1); + m.m[0][0] = m1.m[0][0] - m2.m[0][0]; + m.m[0][1] = m1.m[0][1] - m2.m[0][1]; + m.m[0][2] = m1.m[0][2] - m2.m[0][2]; + m.m[0][3] = m1.m[0][3] - m2.m[0][3]; + m.m[1][0] = m1.m[1][0] - m2.m[1][0]; + m.m[1][1] = m1.m[1][1] - m2.m[1][1]; + m.m[1][2] = m1.m[1][2] - m2.m[1][2]; + m.m[1][3] = m1.m[1][3] - m2.m[1][3]; + m.m[2][0] = m1.m[2][0] - m2.m[2][0]; + m.m[2][1] = m1.m[2][1] - m2.m[2][1]; + m.m[2][2] = m1.m[2][2] - m2.m[2][2]; + m.m[2][3] = m1.m[2][3] - m2.m[2][3]; + m.m[3][0] = m1.m[3][0] - m2.m[3][0]; + m.m[3][1] = m1.m[3][1] - m2.m[3][1]; + m.m[3][2] = m1.m[3][2] - m2.m[3][2]; + m.m[3][3] = m1.m[3][3] - m2.m[3][3]; + m.flagBits = QDoubleMatrix4x4::General; + return m; +} + +inline QDoubleMatrix4x4 operator*(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2) +{ + int flagBits = m1.flagBits | m2.flagBits; + if (flagBits < QDoubleMatrix4x4::Rotation2D) { + QDoubleMatrix4x4 m = m1; + m.m[3][0] += m.m[0][0] * m2.m[3][0]; + m.m[3][1] += m.m[1][1] * m2.m[3][1]; + m.m[3][2] += m.m[2][2] * m2.m[3][2]; + + m.m[0][0] *= m2.m[0][0]; + m.m[1][1] *= m2.m[1][1]; + m.m[2][2] *= m2.m[2][2]; + m.flagBits = flagBits; + return m; + } + + QDoubleMatrix4x4 m(1); + m.m[0][0] = m1.m[0][0] * m2.m[0][0] + + m1.m[1][0] * m2.m[0][1] + + m1.m[2][0] * m2.m[0][2] + + m1.m[3][0] * m2.m[0][3]; + m.m[0][1] = m1.m[0][1] * m2.m[0][0] + + m1.m[1][1] * m2.m[0][1] + + m1.m[2][1] * m2.m[0][2] + + m1.m[3][1] * m2.m[0][3]; + m.m[0][2] = m1.m[0][2] * m2.m[0][0] + + m1.m[1][2] * m2.m[0][1] + + m1.m[2][2] * m2.m[0][2] + + m1.m[3][2] * m2.m[0][3]; + m.m[0][3] = m1.m[0][3] * m2.m[0][0] + + m1.m[1][3] * m2.m[0][1] + + m1.m[2][3] * m2.m[0][2] + + m1.m[3][3] * m2.m[0][3]; + + m.m[1][0] = m1.m[0][0] * m2.m[1][0] + + m1.m[1][0] * m2.m[1][1] + + m1.m[2][0] * m2.m[1][2] + + m1.m[3][0] * m2.m[1][3]; + m.m[1][1] = m1.m[0][1] * m2.m[1][0] + + m1.m[1][1] * m2.m[1][1] + + m1.m[2][1] * m2.m[1][2] + + m1.m[3][1] * m2.m[1][3]; + m.m[1][2] = m1.m[0][2] * m2.m[1][0] + + m1.m[1][2] * m2.m[1][1] + + m1.m[2][2] * m2.m[1][2] + + m1.m[3][2] * m2.m[1][3]; + m.m[1][3] = m1.m[0][3] * m2.m[1][0] + + m1.m[1][3] * m2.m[1][1] + + m1.m[2][3] * m2.m[1][2] + + m1.m[3][3] * m2.m[1][3]; + + m.m[2][0] = m1.m[0][0] * m2.m[2][0] + + m1.m[1][0] * m2.m[2][1] + + m1.m[2][0] * m2.m[2][2] + + m1.m[3][0] * m2.m[2][3]; + m.m[2][1] = m1.m[0][1] * m2.m[2][0] + + m1.m[1][1] * m2.m[2][1] + + m1.m[2][1] * m2.m[2][2] + + m1.m[3][1] * m2.m[2][3]; + m.m[2][2] = m1.m[0][2] * m2.m[2][0] + + m1.m[1][2] * m2.m[2][1] + + m1.m[2][2] * m2.m[2][2] + + m1.m[3][2] * m2.m[2][3]; + m.m[2][3] = m1.m[0][3] * m2.m[2][0] + + m1.m[1][3] * m2.m[2][1] + + m1.m[2][3] * m2.m[2][2] + + m1.m[3][3] * m2.m[2][3]; + + m.m[3][0] = m1.m[0][0] * m2.m[3][0] + + m1.m[1][0] * m2.m[3][1] + + m1.m[2][0] * m2.m[3][2] + + m1.m[3][0] * m2.m[3][3]; + m.m[3][1] = m1.m[0][1] * m2.m[3][0] + + m1.m[1][1] * m2.m[3][1] + + m1.m[2][1] * m2.m[3][2] + + m1.m[3][1] * m2.m[3][3]; + m.m[3][2] = m1.m[0][2] * m2.m[3][0] + + m1.m[1][2] * m2.m[3][1] + + m1.m[2][2] * m2.m[3][2] + + m1.m[3][2] * m2.m[3][3]; + m.m[3][3] = m1.m[0][3] * m2.m[3][0] + + m1.m[1][3] * m2.m[3][1] + + m1.m[2][3] * m2.m[3][2] + + m1.m[3][3] * m2.m[3][3]; + m.flagBits = flagBits; + return m; +} + +inline QDoubleVector3D operator*(const QDoubleVector3D& vector, const QDoubleMatrix4x4& matrix) +{ + double x, y, z, w; + x = vector.x() * matrix.m[0][0] + + vector.y() * matrix.m[0][1] + + vector.z() * matrix.m[0][2] + + matrix.m[0][3]; + y = vector.x() * matrix.m[1][0] + + vector.y() * matrix.m[1][1] + + vector.z() * matrix.m[1][2] + + matrix.m[1][3]; + z = vector.x() * matrix.m[2][0] + + vector.y() * matrix.m[2][1] + + vector.z() * matrix.m[2][2] + + matrix.m[2][3]; + w = vector.x() * matrix.m[3][0] + + vector.y() * matrix.m[3][1] + + vector.z() * matrix.m[3][2] + + matrix.m[3][3]; + if (w == 1.0f) + return QDoubleVector3D(x, y, z); + else + return QDoubleVector3D(x / w, y / w, z / w); +} + +inline QDoubleVector3D operator*(const QDoubleMatrix4x4& matrix, const QDoubleVector3D& vector) +{ + double x, y, z, w; + if (matrix.flagBits == QDoubleMatrix4x4::Identity) { + return vector; + } else if (matrix.flagBits < QDoubleMatrix4x4::Rotation2D) { + // Translation | Scale + return QDoubleVector3D(vector.x() * matrix.m[0][0] + matrix.m[3][0], + vector.y() * matrix.m[1][1] + matrix.m[3][1], + vector.z() * matrix.m[2][2] + matrix.m[3][2]); + } else if (matrix.flagBits < QDoubleMatrix4x4::Rotation) { + // Translation | Scale | Rotation2D + return QDoubleVector3D(vector.x() * matrix.m[0][0] + vector.y() * matrix.m[1][0] + matrix.m[3][0], + vector.x() * matrix.m[0][1] + vector.y() * matrix.m[1][1] + matrix.m[3][1], + vector.z() * matrix.m[2][2] + matrix.m[3][2]); + } else { + x = vector.x() * matrix.m[0][0] + + vector.y() * matrix.m[1][0] + + vector.z() * matrix.m[2][0] + + matrix.m[3][0]; + y = vector.x() * matrix.m[0][1] + + vector.y() * matrix.m[1][1] + + vector.z() * matrix.m[2][1] + + matrix.m[3][1]; + z = vector.x() * matrix.m[0][2] + + vector.y() * matrix.m[1][2] + + vector.z() * matrix.m[2][2] + + matrix.m[3][2]; + w = vector.x() * matrix.m[0][3] + + vector.y() * matrix.m[1][3] + + vector.z() * matrix.m[2][3] + + matrix.m[3][3]; + if (w == 1.0f) + return QDoubleVector3D(x, y, z); + else + return QDoubleVector3D(x / w, y / w, z / w); + } +} + +inline QPoint operator*(const QPoint& point, const QDoubleMatrix4x4& matrix) +{ + double xin, yin; + double x, y, w; + xin = point.x(); + yin = point.y(); + x = xin * matrix.m[0][0] + + yin * matrix.m[0][1] + + matrix.m[0][3]; + y = xin * matrix.m[1][0] + + yin * matrix.m[1][1] + + matrix.m[1][3]; + w = xin * matrix.m[3][0] + + yin * matrix.m[3][1] + + matrix.m[3][3]; + if (w == 1.0f) + return QPoint(qRound(x), qRound(y)); + else + return QPoint(qRound(x / w), qRound(y / w)); +} + +inline QPointF operator*(const QPointF& point, const QDoubleMatrix4x4& matrix) +{ + double xin, yin; + double x, y, w; + xin = point.x(); + yin = point.y(); + x = xin * matrix.m[0][0] + + yin * matrix.m[0][1] + + matrix.m[0][3]; + y = xin * matrix.m[1][0] + + yin * matrix.m[1][1] + + matrix.m[1][3]; + w = xin * matrix.m[3][0] + + yin * matrix.m[3][1] + + matrix.m[3][3]; + if (w == 1.0f) { + return QPointF(double(x), double(y)); + } else { + return QPointF(double(x / w), double(y / w)); + } +} + +inline QPoint operator*(const QDoubleMatrix4x4& matrix, const QPoint& point) +{ + double xin, yin; + double x, y, w; + xin = point.x(); + yin = point.y(); + if (matrix.flagBits == QDoubleMatrix4x4::Identity) { + return point; + } else if (matrix.flagBits < QDoubleMatrix4x4::Rotation2D) { + // Translation | Scale + return QPoint(qRound(xin * matrix.m[0][0] + matrix.m[3][0]), + qRound(yin * matrix.m[1][1] + matrix.m[3][1])); + } else if (matrix.flagBits < QDoubleMatrix4x4::Perspective) { + return QPoint(qRound(xin * matrix.m[0][0] + yin * matrix.m[1][0] + matrix.m[3][0]), + qRound(xin * matrix.m[0][1] + yin * matrix.m[1][1] + matrix.m[3][1])); + } else { + x = xin * matrix.m[0][0] + + yin * matrix.m[1][0] + + matrix.m[3][0]; + y = xin * matrix.m[0][1] + + yin * matrix.m[1][1] + + matrix.m[3][1]; + w = xin * matrix.m[0][3] + + yin * matrix.m[1][3] + + matrix.m[3][3]; + if (w == 1.0f) + return QPoint(qRound(x), qRound(y)); + else + return QPoint(qRound(x / w), qRound(y / w)); + } +} + +inline QPointF operator*(const QDoubleMatrix4x4& matrix, const QPointF& point) +{ + double xin, yin; + double x, y, w; + xin = point.x(); + yin = point.y(); + if (matrix.flagBits == QDoubleMatrix4x4::Identity) { + return point; + } else if (matrix.flagBits < QDoubleMatrix4x4::Rotation2D) { + // Translation | Scale + return QPointF(xin * matrix.m[0][0] + matrix.m[3][0], + yin * matrix.m[1][1] + matrix.m[3][1]); + } else if (matrix.flagBits < QDoubleMatrix4x4::Perspective) { + return QPointF(xin * matrix.m[0][0] + yin * matrix.m[1][0] + matrix.m[3][0], + xin * matrix.m[0][1] + yin * matrix.m[1][1] + matrix.m[3][1]); + } else { + x = xin * matrix.m[0][0] + + yin * matrix.m[1][0] + + matrix.m[3][0]; + y = xin * matrix.m[0][1] + + yin * matrix.m[1][1] + + matrix.m[3][1]; + w = xin * matrix.m[0][3] + + yin * matrix.m[1][3] + + matrix.m[3][3]; + if (w == 1.0f) { + return QPointF(double(x), double(y)); + } else { + return QPointF(double(x / w), double(y / w)); + } + } +} + +inline QDoubleMatrix4x4 operator-(const QDoubleMatrix4x4& matrix) +{ + QDoubleMatrix4x4 m(1); + m.m[0][0] = -matrix.m[0][0]; + m.m[0][1] = -matrix.m[0][1]; + m.m[0][2] = -matrix.m[0][2]; + m.m[0][3] = -matrix.m[0][3]; + m.m[1][0] = -matrix.m[1][0]; + m.m[1][1] = -matrix.m[1][1]; + m.m[1][2] = -matrix.m[1][2]; + m.m[1][3] = -matrix.m[1][3]; + m.m[2][0] = -matrix.m[2][0]; + m.m[2][1] = -matrix.m[2][1]; + m.m[2][2] = -matrix.m[2][2]; + m.m[2][3] = -matrix.m[2][3]; + m.m[3][0] = -matrix.m[3][0]; + m.m[3][1] = -matrix.m[3][1]; + m.m[3][2] = -matrix.m[3][2]; + m.m[3][3] = -matrix.m[3][3]; + m.flagBits = QDoubleMatrix4x4::General; + return m; +} + +inline QDoubleMatrix4x4 operator*(double factor, const QDoubleMatrix4x4& matrix) +{ + QDoubleMatrix4x4 m(1); + m.m[0][0] = matrix.m[0][0] * factor; + m.m[0][1] = matrix.m[0][1] * factor; + m.m[0][2] = matrix.m[0][2] * factor; + m.m[0][3] = matrix.m[0][3] * factor; + m.m[1][0] = matrix.m[1][0] * factor; + m.m[1][1] = matrix.m[1][1] * factor; + m.m[1][2] = matrix.m[1][2] * factor; + m.m[1][3] = matrix.m[1][3] * factor; + m.m[2][0] = matrix.m[2][0] * factor; + m.m[2][1] = matrix.m[2][1] * factor; + m.m[2][2] = matrix.m[2][2] * factor; + m.m[2][3] = matrix.m[2][3] * factor; + m.m[3][0] = matrix.m[3][0] * factor; + m.m[3][1] = matrix.m[3][1] * factor; + m.m[3][2] = matrix.m[3][2] * factor; + m.m[3][3] = matrix.m[3][3] * factor; + m.flagBits = QDoubleMatrix4x4::General; + return m; +} + +inline QDoubleMatrix4x4 operator*(const QDoubleMatrix4x4& matrix, double factor) +{ + QDoubleMatrix4x4 m(1); + m.m[0][0] = matrix.m[0][0] * factor; + m.m[0][1] = matrix.m[0][1] * factor; + m.m[0][2] = matrix.m[0][2] * factor; + m.m[0][3] = matrix.m[0][3] * factor; + m.m[1][0] = matrix.m[1][0] * factor; + m.m[1][1] = matrix.m[1][1] * factor; + m.m[1][2] = matrix.m[1][2] * factor; + m.m[1][3] = matrix.m[1][3] * factor; + m.m[2][0] = matrix.m[2][0] * factor; + m.m[2][1] = matrix.m[2][1] * factor; + m.m[2][2] = matrix.m[2][2] * factor; + m.m[2][3] = matrix.m[2][3] * factor; + m.m[3][0] = matrix.m[3][0] * factor; + m.m[3][1] = matrix.m[3][1] * factor; + m.m[3][2] = matrix.m[3][2] * factor; + m.m[3][3] = matrix.m[3][3] * factor; + m.flagBits = QDoubleMatrix4x4::General; + return m; +} + +inline bool qFuzzyCompare(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2) +{ + return qFuzzyCompare(m1.m[0][0], m2.m[0][0]) && + qFuzzyCompare(m1.m[0][1], m2.m[0][1]) && + qFuzzyCompare(m1.m[0][2], m2.m[0][2]) && + qFuzzyCompare(m1.m[0][3], m2.m[0][3]) && + qFuzzyCompare(m1.m[1][0], m2.m[1][0]) && + qFuzzyCompare(m1.m[1][1], m2.m[1][1]) && + qFuzzyCompare(m1.m[1][2], m2.m[1][2]) && + qFuzzyCompare(m1.m[1][3], m2.m[1][3]) && + qFuzzyCompare(m1.m[2][0], m2.m[2][0]) && + qFuzzyCompare(m1.m[2][1], m2.m[2][1]) && + qFuzzyCompare(m1.m[2][2], m2.m[2][2]) && + qFuzzyCompare(m1.m[2][3], m2.m[2][3]) && + qFuzzyCompare(m1.m[3][0], m2.m[3][0]) && + qFuzzyCompare(m1.m[3][1], m2.m[3][1]) && + qFuzzyCompare(m1.m[3][2], m2.m[3][2]) && + qFuzzyCompare(m1.m[3][3], m2.m[3][3]); +} + +inline QPoint QDoubleMatrix4x4::map(const QPoint& point) const +{ + return *this * point; +} + +inline QPointF QDoubleMatrix4x4::map(const QPointF& point) const +{ + return *this * point; +} + +inline QDoubleVector3D QDoubleMatrix4x4::map(const QDoubleVector3D& point) const +{ + return *this * point; +} + +inline QDoubleVector3D QDoubleMatrix4x4::mapVector(const QDoubleVector3D& vector) const +{ + if (flagBits < Scale) { + // Translation + return vector; + } else if (flagBits < Rotation2D) { + // Translation | Scale + return QDoubleVector3D(vector.x() * m[0][0], + vector.y() * m[1][1], + vector.z() * m[2][2]); + } else { + return QDoubleVector3D(vector.x() * m[0][0] + + vector.y() * m[1][0] + + vector.z() * m[2][0], + vector.x() * m[0][1] + + vector.y() * m[1][1] + + vector.z() * m[2][1], + vector.x() * m[0][2] + + vector.y() * m[1][2] + + vector.z() * m[2][2]); + } +} + +inline double *QDoubleMatrix4x4::data() +{ + // We have to assume that the caller will modify the matrix elements, + // so we flip it over to "General" mode. + flagBits = General; + return *m; +} + +inline void QDoubleMatrix4x4::viewport(const QRectF &rect) +{ + viewport(rect.x(), rect.y(), rect.width(), rect.height()); +} + +#ifndef QT_NO_DEBUG_STREAM +Q_POSITIONING_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QDoubleMatrix4x4 &m); +#endif + +#ifndef QT_NO_DATASTREAM +Q_POSITIONING_PRIVATE_EXPORT QDataStream &operator<<(QDataStream &, const QDoubleMatrix4x4 &); +Q_POSITIONING_PRIVATE_EXPORT QDataStream &operator>>(QDataStream &, QDoubleMatrix4x4 &); +#endif + + +QT_END_NAMESPACE + + +#endif // QDOUBLEMATRIX4X4_H diff --git a/src/positioning/qdoublevector2d.cpp b/src/positioning/qdoublevector2d.cpp new file mode 100644 index 0000000..59d3b53 --- /dev/null +++ b/src/positioning/qdoublevector2d.cpp @@ -0,0 +1,85 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QDoubleVector2D::QDoubleVector2D(const QDoubleVector3D &vector) : + xp(vector.xp), yp(vector.yp) +{ +} + +double QDoubleVector2D::length() const +{ + return qSqrt(xp * xp + yp * yp); +} + +QDoubleVector2D QDoubleVector2D::normalized() const +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp); + if (qFuzzyIsNull(len - 1.0)) + return *this; + else if (!qFuzzyIsNull(len)) + return *this / (double)qSqrt(len); + else + return QDoubleVector2D(); +} + +void QDoubleVector2D::normalize() +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp); + if (qFuzzyIsNull(len - 1.0) || qFuzzyIsNull(len)) + return; + + len = qSqrt(len); + + xp /= len; + yp /= len; +} + +QDoubleVector3D QDoubleVector2D::toVector3D() const +{ + return QDoubleVector3D(xp, yp, 0.0); +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<(QDebug dbg, const QDoubleVector2D &vector) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QDoubleVector2D(" << vector.x() << ", " << vector.y() << ')'; + return dbg; +} + +#endif + +#ifndef QT_NO_DATASTREAM + +QDataStream &operator<<(QDataStream &stream, const QDoubleVector2D &vector) +{ + stream << double(vector.x()) << double(vector.y()); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QDoubleVector2D &vector) +{ + double x, y; + stream >> x; + stream >> y; + vector.setX(double(x)); + vector.setY(double(y)); + return stream; +} + +#endif // QT_NO_DATASTREAM + +QT_END_NAMESPACE diff --git a/src/positioning/qdoublevector2d_p.h b/src/positioning/qdoublevector2d_p.h new file mode 100644 index 0000000..a01e152 --- /dev/null +++ b/src/positioning/qdoublevector2d_p.h @@ -0,0 +1,226 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QDOUBLEVECTOR2D_P_H +#define QDOUBLEVECTOR2D_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. +// + +#ifdef QT_BUILD_LOCATION_LIB +#include +#endif + +#include "qpositioningglobal_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class QDoubleVector3D; + +class Q_POSITIONING_PRIVATE_EXPORT QDoubleVector2D +{ +public: + Q_DECL_CONSTEXPR inline QDoubleVector2D(); + Q_DECL_CONSTEXPR inline QDoubleVector2D(double xpos, double ypos); + Q_DECL_CONSTEXPR explicit inline QDoubleVector2D(const QPointF &p); + explicit QDoubleVector2D(const QDoubleVector3D &vector); + + Q_DECL_CONSTEXPR inline double manhattanLength() const; + inline bool isNull() const; + inline bool isFinite() const; + + Q_DECL_CONSTEXPR inline double x() const; + Q_DECL_CONSTEXPR inline double y() const; + + inline void setX(double x); + inline void setY(double y); + + double length() const; + Q_DECL_CONSTEXPR inline double lengthSquared() const; + + QDoubleVector2D normalized() const; + void normalize(); + + inline QDoubleVector2D &operator+=(const QDoubleVector2D &vector); + inline QDoubleVector2D &operator-=(const QDoubleVector2D &vector); + inline QDoubleVector2D &operator*=(double factor); + inline QDoubleVector2D &operator*=(const QDoubleVector2D &vector); + inline QDoubleVector2D &operator/=(double divisor); + inline QDoubleVector2D &operator/=(const QDoubleVector2D &vector); + + Q_DECL_CONSTEXPR static inline double dotProduct(const QDoubleVector2D &v1, const QDoubleVector2D &v2) + { return v1.xp * v2.xp + v1.yp * v2.yp; } + + + friend Q_DECL_CONSTEXPR inline bool operator==(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend Q_DECL_CONSTEXPR inline bool operator!=(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend Q_DECL_CONSTEXPR inline const QDoubleVector2D operator+(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend Q_DECL_CONSTEXPR inline const QDoubleVector2D operator-(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend Q_DECL_CONSTEXPR inline const QDoubleVector2D operator*(double factor, const QDoubleVector2D &vector); + friend Q_DECL_CONSTEXPR inline const QDoubleVector2D operator*(const QDoubleVector2D &vector, double factor); + friend Q_DECL_CONSTEXPR inline const QDoubleVector2D operator*(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend Q_DECL_CONSTEXPR inline const QDoubleVector2D operator-(const QDoubleVector2D &vector); + friend Q_DECL_CONSTEXPR inline const QDoubleVector2D operator/(const QDoubleVector2D &vector, double divisor); + + friend Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + + QDoubleVector3D toVector3D() const; + Q_DECL_CONSTEXPR inline QPointF toPointF() const; + +private: + double xp, yp; + + friend class QDoubleVector3D; +}; + +Q_DECLARE_TYPEINFO(QDoubleVector2D, Q_RELOCATABLE_TYPE); + +Q_DECL_CONSTEXPR inline QDoubleVector2D::QDoubleVector2D() : xp(0.0), yp(0.0) {} + +Q_DECL_CONSTEXPR inline QDoubleVector2D::QDoubleVector2D(double xpos, double ypos) : xp(xpos), yp(ypos) {} + +Q_DECL_CONSTEXPR inline QDoubleVector2D::QDoubleVector2D(const QPointF &p) : xp(p.x()), yp(p.y()) { } + +Q_DECL_CONSTEXPR inline double QDoubleVector2D::manhattanLength() const +{ + return qAbs(x())+qAbs(y()); +} + +inline bool QDoubleVector2D::isNull() const +{ + return qIsNull(xp) && qIsNull(yp); +} + +inline bool QDoubleVector2D::isFinite() const +{ + return qIsFinite(xp) && qIsFinite(yp); +} + +Q_DECL_CONSTEXPR inline double QDoubleVector2D::x() const { return xp; } +Q_DECL_CONSTEXPR inline double QDoubleVector2D::y() const { return yp; } + +inline void QDoubleVector2D::setX(double aX) { xp = aX; } +inline void QDoubleVector2D::setY(double aY) { yp = aY; } + +Q_DECL_CONSTEXPR inline double QDoubleVector2D::lengthSquared() const +{ return xp * xp + yp * yp; } + +inline QDoubleVector2D &QDoubleVector2D::operator+=(const QDoubleVector2D &vector) +{ + xp += vector.xp; + yp += vector.yp; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator-=(const QDoubleVector2D &vector) +{ + xp -= vector.xp; + yp -= vector.yp; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator*=(double factor) +{ + xp *= factor; + yp *= factor; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator*=(const QDoubleVector2D &vector) +{ + xp *= vector.xp; + yp *= vector.yp; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator/=(double divisor) +{ + xp /= divisor; + yp /= divisor; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator/=(const QDoubleVector2D &vector) +{ + xp /= vector.xp; + yp /= vector.yp; + return *this; +} + +Q_DECL_CONSTEXPR inline bool operator==(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return v1.xp == v2.xp && v1.yp == v2.yp; +} + +Q_DECL_CONSTEXPR inline bool operator!=(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return v1.xp != v2.xp || v1.yp != v2.yp; +} + +Q_DECL_CONSTEXPR inline const QDoubleVector2D operator+(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return QDoubleVector2D(v1.xp + v2.xp, v1.yp + v2.yp); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector2D operator-(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return QDoubleVector2D(v1.xp - v2.xp, v1.yp - v2.yp); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector2D operator*(double factor, const QDoubleVector2D &vector) +{ + return QDoubleVector2D(vector.xp * factor, vector.yp * factor); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector2D operator*(const QDoubleVector2D &vector, double factor) +{ + return QDoubleVector2D(vector.xp * factor, vector.yp * factor); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector2D operator*(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return QDoubleVector2D(v1.xp * v2.xp, v1.yp * v2.yp); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector2D operator-(const QDoubleVector2D &vector) +{ + return QDoubleVector2D(-vector.xp, -vector.yp); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector2D operator/(const QDoubleVector2D &vector, double divisor) +{ + return QDoubleVector2D(vector.xp / divisor, vector.yp / divisor); +} + +Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return qFuzzyCompare(v1.xp, v2.xp) && qFuzzyCompare(v1.yp, v2.yp); +} + +Q_DECL_CONSTEXPR inline QPointF QDoubleVector2D::toPointF() const +{ + return QPointF(qreal(xp), qreal(yp)); +} + +#ifndef QT_NO_DEBUG_STREAM +Q_POSITIONING_EXPORT QDebug operator<<(QDebug dbg, const QDoubleVector2D &vector); +#endif + +#ifndef QT_NO_DATASTREAM +Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &, const QDoubleVector2D &); +Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &, QDoubleVector2D &); +#endif + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qdoublevector3d.cpp b/src/positioning/qdoublevector3d.cpp new file mode 100644 index 0000000..92ae8bc --- /dev/null +++ b/src/positioning/qdoublevector3d.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qdoublevector3d_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QDoubleVector3D QDoubleVector3D::normalized() const +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp) + + double(zp) * double(zp); + if (qFuzzyIsNull(len - 1.0)) + return *this; + else if (!qFuzzyIsNull(len)) + return *this / (double)qSqrt(len); + else + return QDoubleVector3D(); +} + +void QDoubleVector3D::normalize() +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp) + + double(zp) * double(zp); + if (qFuzzyIsNull(len - 1.0) || qFuzzyIsNull(len)) + return; + + len = qSqrt(len); + + xp /= len; + yp /= len; + zp /= len; +} + +QDoubleVector3D QDoubleVector3D::normal(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return crossProduct(v1, v2).normalized(); +} + +QDoubleVector3D QDoubleVector3D::normal + (const QDoubleVector3D &v1, const QDoubleVector3D &v2, const QDoubleVector3D &v3) +{ + return crossProduct((v2 - v1), (v3 - v1)).normalized(); +} + +double QDoubleVector3D::distanceToPlane + (const QDoubleVector3D &plane1, const QDoubleVector3D &plane2, const QDoubleVector3D &plane3) const +{ + QDoubleVector3D n = normal(plane2 - plane1, plane3 - plane1); + return dotProduct(*this - plane1, n); +} + +double QDoubleVector3D::distanceToLine + (const QDoubleVector3D &point, const QDoubleVector3D &direction) const +{ + if (direction.isNull()) + return (*this - point).length(); + QDoubleVector3D p = point + dotProduct(*this - point, direction) * direction; + return (*this - p).length(); +} + +double QDoubleVector3D::length() const +{ + return qSqrt(xp * xp + yp * yp + zp * zp); +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<(QDebug dbg, const QDoubleVector3D &vector) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QDoubleVector3D(" + << vector.x() << ", " << vector.y() << ", " << vector.z() << ')'; + return dbg; +} + +#endif + +#ifndef QT_NO_DATASTREAM + +QDataStream &operator<<(QDataStream &stream, const QDoubleVector3D &vector) +{ + stream << double(vector.x()) << double(vector.y()) + << double(vector.z()); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QDoubleVector3D &vector) +{ + double x, y, z; + stream >> x; + stream >> y; + stream >> z; + vector.setX(double(x)); + vector.setY(double(y)); + vector.setZ(double(z)); + return stream; +} + +#endif // QT_NO_DATASTREAM + +QT_END_NAMESPACE diff --git a/src/positioning/qdoublevector3d_p.h b/src/positioning/qdoublevector3d_p.h new file mode 100644 index 0000000..d19e236 --- /dev/null +++ b/src/positioning/qdoublevector3d_p.h @@ -0,0 +1,266 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QDOUBLEVECTOR3D_P_H +#define QDOUBLEVECTOR3D_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. +// + +#ifdef QT_BUILD_LOCATION_LIB +#include +#endif + +#include "qpositioningglobal_p.h" +#include "qdoublevector2d_p.h" +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONING_PRIVATE_EXPORT QDoubleVector3D +{ +public: + Q_DECL_CONSTEXPR inline QDoubleVector3D(); + Q_DECL_CONSTEXPR inline QDoubleVector3D(double xpos, double ypos, double zpos); + Q_DECL_CONSTEXPR inline QDoubleVector3D(const QDoubleVector2D &vector); + Q_DECL_CONSTEXPR inline QDoubleVector3D(const QDoubleVector2D &vector, double zpos); + + inline bool isNull() const; + + Q_DECL_CONSTEXPR inline double x() const; + Q_DECL_CONSTEXPR inline double y() const; + Q_DECL_CONSTEXPR inline double z() const; + + inline void setX(double x); + inline void setY(double y); + inline void setZ(double z); + + inline double get(int i) const; + inline void set(int i, double value); + + double length() const; + Q_DECL_CONSTEXPR inline double lengthSquared() const; + + QDoubleVector3D normalized() const; + void normalize(); + + inline QDoubleVector3D &operator+=(const QDoubleVector3D &vector); + inline QDoubleVector3D &operator-=(const QDoubleVector3D &vector); + inline QDoubleVector3D &operator*=(double factor); + inline QDoubleVector3D &operator*=(const QDoubleVector3D &vector); + inline QDoubleVector3D &operator/=(double divisor); + + Q_DECL_CONSTEXPR static inline double dotProduct(const QDoubleVector3D &v1, const QDoubleVector3D &v2) + { return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp; } + + Q_DECL_CONSTEXPR static inline QDoubleVector3D crossProduct(const QDoubleVector3D &v1, const QDoubleVector3D &v2) + { return QDoubleVector3D(v1.yp * v2.zp - v1.zp * v2.yp, + v1.zp * v2.xp - v1.xp * v2.zp, + v1.xp * v2.yp - v1.yp * v2.xp); } + + static QDoubleVector3D normal(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + static QDoubleVector3D normal + (const QDoubleVector3D &v1, const QDoubleVector3D &v2, const QDoubleVector3D &v3); + + double distanceToPlane(const QDoubleVector3D &plane, const QDoubleVector3D &normal) const; + double distanceToPlane(const QDoubleVector3D &plane1, const QDoubleVector3D &plane2, const QDoubleVector3D &plane3) const; + double distanceToLine(const QDoubleVector3D &point, const QDoubleVector3D &direction) const; + + friend Q_DECL_CONSTEXPR inline bool operator==(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend Q_DECL_CONSTEXPR inline bool operator!=(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend Q_DECL_CONSTEXPR inline const QDoubleVector3D operator+(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend Q_DECL_CONSTEXPR inline const QDoubleVector3D operator-(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend Q_DECL_CONSTEXPR inline const QDoubleVector3D operator*(double factor, const QDoubleVector3D &vector); + friend Q_DECL_CONSTEXPR inline const QDoubleVector3D operator*(const QDoubleVector3D &vector, double factor); + friend Q_DECL_CONSTEXPR inline const QDoubleVector3D operator*(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend Q_DECL_CONSTEXPR inline const QDoubleVector3D operator-(const QDoubleVector3D &vector); + friend Q_DECL_CONSTEXPR inline const QDoubleVector3D operator/(const QDoubleVector3D &vector, double divisor); + + friend Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + + Q_DECL_CONSTEXPR inline QDoubleVector2D toVector2D() const; + +private: + double xp, yp, zp; + + friend class QDoubleVector2D; +}; + +Q_DECLARE_TYPEINFO(QDoubleVector3D, Q_RELOCATABLE_TYPE); + +Q_DECL_CONSTEXPR inline QDoubleVector3D::QDoubleVector3D() : xp(0.0), yp(0.0), zp(0.0) {} + +Q_DECL_CONSTEXPR inline QDoubleVector3D::QDoubleVector3D(double xpos, double ypos, double zpos) : xp(xpos), yp(ypos), zp(zpos) {} + +Q_DECL_CONSTEXPR inline QDoubleVector3D::QDoubleVector3D(const QDoubleVector2D &v) + : xp(v.xp), yp(v.yp), zp(0.0) {} + +Q_DECL_CONSTEXPR inline QDoubleVector3D::QDoubleVector3D(const QDoubleVector2D &v, double zpos) + : xp(v.xp), yp(v.yp), zp(zpos) {} + +inline bool QDoubleVector3D::isNull() const +{ + return qIsNull(xp) && qIsNull(yp) && qIsNull(zp); +} + +Q_DECL_CONSTEXPR inline double QDoubleVector3D::x() const { return xp; } +Q_DECL_CONSTEXPR inline double QDoubleVector3D::y() const { return yp; } +Q_DECL_CONSTEXPR inline double QDoubleVector3D::z() const { return zp; } + +Q_DECL_CONSTEXPR inline double QDoubleVector3D::lengthSquared() const +{ return xp * xp + yp * yp + zp * zp; } + + +inline void QDoubleVector3D::setX(double aX) { xp = aX; } +inline void QDoubleVector3D::setY(double aY) { yp = aY; } +inline void QDoubleVector3D::setZ(double aZ) { zp = aZ; } + +inline double QDoubleVector3D::get(int i) const +{ + switch (i) { + case 0: + return xp; + case 1: + return yp; + case 2: + return zp; + default: + return 0.0; + } +} + +inline void QDoubleVector3D::set(int i, double value) +{ + switch (i) { + case 0: + xp = value; + break; + case 1: + yp = value; + break; + case 2: + zp = value; + break; + default: + break; + } +} + +inline QDoubleVector3D &QDoubleVector3D::operator+=(const QDoubleVector3D &vector) +{ + xp += vector.xp; + yp += vector.yp; + zp += vector.zp; + return *this; +} + +inline QDoubleVector3D &QDoubleVector3D::operator-=(const QDoubleVector3D &vector) +{ + xp -= vector.xp; + yp -= vector.yp; + zp -= vector.zp; + return *this; +} + +inline QDoubleVector3D &QDoubleVector3D::operator*=(double factor) +{ + xp *= factor; + yp *= factor; + zp *= factor; + return *this; +} + +inline QDoubleVector3D &QDoubleVector3D::operator*=(const QDoubleVector3D &vector) +{ + xp *= vector.xp; + yp *= vector.yp; + zp *= vector.zp; + return *this; +} + +inline QDoubleVector3D &QDoubleVector3D::operator/=(double divisor) +{ + xp /= divisor; + yp /= divisor; + zp /= divisor; + return *this; +} + +Q_DECL_CONSTEXPR inline bool operator==(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp; +} + +Q_DECL_CONSTEXPR inline bool operator!=(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return v1.xp != v2.xp || v1.yp != v2.yp || v1.zp != v2.zp; +} + +Q_DECL_CONSTEXPR inline const QDoubleVector3D operator+(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return QDoubleVector3D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector3D operator-(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return QDoubleVector3D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector3D operator*(double factor, const QDoubleVector3D &vector) +{ + return QDoubleVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector3D operator*(const QDoubleVector3D &vector, double factor) +{ + return QDoubleVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector3D operator*(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return QDoubleVector3D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector3D operator-(const QDoubleVector3D &vector) +{ + return QDoubleVector3D(-vector.xp, -vector.yp, -vector.zp); +} + +Q_DECL_CONSTEXPR inline const QDoubleVector3D operator/(const QDoubleVector3D &vector, double divisor) +{ + return QDoubleVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor); +} + +Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return qFuzzyCompare(v1.xp, v2.xp) && + qFuzzyCompare(v1.yp, v2.yp) && + qFuzzyCompare(v1.zp, v2.zp); +} + +Q_DECL_CONSTEXPR inline QDoubleVector2D QDoubleVector3D::toVector2D() const +{ + return QDoubleVector2D(xp, yp); +} + + +#ifndef QT_NO_DEBUG_STREAM +Q_POSITIONING_EXPORT QDebug operator<<(QDebug dbg, const QDoubleVector3D &vector); +#endif + +#ifndef QT_NO_DATASTREAM +Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &, const QDoubleVector3D &); +Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &, QDoubleVector3D &); +#endif + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qgeoaddress.cpp b/src/positioning/qgeoaddress.cpp new file mode 100644 index 0000000..ce28317 --- /dev/null +++ b/src/positioning/qgeoaddress.cpp @@ -0,0 +1,742 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeoaddress.h" +#include "qgeoaddress_p.h" + +#include + +#ifdef QGEOADDRESS_DEBUG +#include +#endif + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoAddress) + +/* + Combines a list of address parts into a single line. + + The parts parameter contains both address elements such as city, state and so on + as well as separators such as spaces and commas. + + It is expected that an element is always followed by a separator and the last + sepator is usually a new line delimeter. + + For example: Springfield, 8900 + would have four parts + ["Springfield", ", ", "8900", "
    "] + + The addressLine takes care of putting in separators appropriately or leaving + them out depending on whether the adjacent elements are present or not. + For example if city were empty in the above scenario the returned string is "8900
    " + If the postal code was empty, returned string is "Springfield
    " + If both city and postal code were empty, the returned string is "". +*/ +static QString addressLine(const QStringList &parts) +{ + QString line; + Q_ASSERT(parts.size() % 2 == 0); + + //iterate until just before the last pair + QString penultimateSeparator; + for (qsizetype i = 0; i < parts.size() - 2; i += 2) { + if (!parts.at(i).isEmpty()) { + line.append(parts.at(i) + parts.at(i + 1)); + penultimateSeparator = parts.at(i + 1); + } + } + + if (parts.at(parts.size() - 2).isEmpty()) { + line.chop(penultimateSeparator.size()); + + if (!line.isEmpty()) + line.append(parts.at(parts.size() - 1)); + } else { + line.append(parts.at(parts.size() - 2)); + line.append(parts.at(parts.size() - 1)); + } + + return line; +} + +/* + Returns a single formatted string representing the \a address. Lines of the address + are delimited by \a newLine. By default lines are delimited by
    . The \l + {QGeoAddress::countryCode} {countryCode} of the \a address determines the format of + the resultant string. +*/ +static QString formattedAddress(const QGeoAddress &address, + const QString &newLine = QLatin1String("
    ")) +{ + const QString Comma(QStringLiteral(", ")); + const QString Dash(QStringLiteral("-")); + const QString Space(QStringLiteral(" ")); + + QString text; + + // We have 2 main approaches here: + // 1. street number goes after street name + // 2. street number goes before street name + // We need to take it into account while generating the formatted address. + // Currently these pages were used to check the formats: + // https://en.wikipedia.org/wiki/Address + // https://www.grcdi.nl/gsb/world%20address%20formats.html + // We do not take into account such address extensions as apartment number, + // because this is not what you can usually get from map providers (like + // openstreetmap). + + if (address.countryCode() == QLatin1String("ALB") + || address.countryCode() == QLatin1String("MTQ")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.postalCode() << Comma + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("AND") + || address.countryCode() == QLatin1String("AUT") + || address.countryCode() == QLatin1String("GLP") + || address.countryCode() == QLatin1String("ITA") + || address.countryCode() == QLatin1String("RUS") + || address.countryCode() == QLatin1String("SMR") + || address.countryCode() == QLatin1String("VAT")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + }else if (address.countryCode() == QLatin1String("FRA") + || address.countryCode() == QLatin1String("GUF") + || address.countryCode() == QLatin1String("LUX") + || address.countryCode() == QLatin1String("MCO") + || address.countryCode() == QLatin1String("REU")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + + } else if (address.countryCode() == QLatin1String("ARE") + || address.countryCode() == QLatin1String("BHS")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.district() << Space + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("AUS")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << (address.district().isEmpty() ? address.city() : address.district()) + << Space << address.state() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("BHR")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.district() << Comma + << address.city() << Comma << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("BRA")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.district() << Space + << address.city() << Dash << address.state() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("BRN") + || address.countryCode() == QLatin1String("JOR") + || address.countryCode() == QLatin1String("LBN") + || address.countryCode() == QLatin1String("NZL")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Space + << address.city() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("CAN") + || address.countryCode() == QLatin1String("USA") + || address.countryCode() == QLatin1String("VIR")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.city() << Comma << address.state() << Space + << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("CHN")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << Comma + << address.city() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("CHL")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space + << address.district() << Comma << address.city() << Comma + << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("CYM")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.state() << Space + << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("GBR")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma + << address.city() << Comma << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("GIB")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("HKG")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.district() << newLine); + text += addressLine(QStringList() << address.city() << newLine); + } else if (address.countryCode() == QLatin1String("IND")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << Space + << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("IDN") + || address.countryCode() == QLatin1String("JEY") + || address.countryCode() == QLatin1String("LVA")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.city() << Comma << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("IRL")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("KWT")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.postalCode() << Comma + << address.district() << Comma << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("MLT") + || address.countryCode() == QLatin1String("SGP")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("UKR")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("MEX")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.district() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.city() << Comma + << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("MYS")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.city() << newLine); + text += addressLine(QStringList() << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("OMN")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << newLine); + text += addressLine(QStringList() << address.district() << Comma + << address.postalCode() << Comma + << address.city() << Comma + << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("PRI")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.district() << Comma << address.city() << Comma + << address.state() << Comma << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("QAT")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.district() << Space << address.city() << Comma + << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("SAU")) { + text += addressLine(QStringList() << address.streetNumber() << Space + << address.street() << Space + << address.district() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("TWN")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << Comma + << address.district() << Comma + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("THA")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.district() << Comma << address.city() << Space + << address.postalCode() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("TUR")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.district() << Comma + << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("VEN")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.city() << Space << address.postalCode() << Comma + << address.state() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else if (address.countryCode() == QLatin1String("ZAF")) { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.district() << Comma << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } else { + text += addressLine(QStringList() << address.street() << Space + << address.streetNumber() << newLine); + text += addressLine(QStringList() << address.postalCode() << Space << address.city() << newLine); + text += addressLine(QStringList() << address.country() << newLine); + } + + text.chop(newLine.size()); + return text; +} + +QGeoAddressPrivate::QGeoAddressPrivate() + : QSharedData(), + m_autoGeneratedText(false) +{ +} + +QGeoAddressPrivate::QGeoAddressPrivate(const QGeoAddressPrivate &other) + : QSharedData(other), + sCountry(other.sCountry), + sCountryCode(other.sCountryCode), + sState(other.sState), + sCounty(other.sCounty), + sCity(other.sCity), + sDistrict(other.sDistrict), + sStreet(other.sStreet), + sStreetNumber(other.sStreetNumber), + sPostalCode(other.sPostalCode), + sText(other.sText), + m_autoGeneratedText(false) +{ +} + +QGeoAddressPrivate::~QGeoAddressPrivate() +{ +} + +/*! + \class QGeoAddress + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \ingroup QtLocation-places-data + \ingroup QtLocation-places + \since 5.2 + + \brief The QGeoAddress class represents an address of a \l QGeoLocation. + + The address' attributes are normalized to US feature names and can be mapped + to the local feature levels (for example State matches "Bundesland" in Germany). + + The address contains a \l text() for displaying purposes and additional + properties to access the components of an address: + + \list + \li QGeoAddress::country() + \li QGeoAddress::countryCode() + \li QGeoAddress::state() + \li QGeoAddress::city() + \li QGeoAddress::district() + \li QGeoAddress::street() + \li QGeoAddress::postalCode() + \endlist +*/ + +/*! + Default constructor. +*/ +QGeoAddress::QGeoAddress() + : d(new QGeoAddressPrivate) +{ +} + +/*! + Constructs a copy of \a other. +*/ +QGeoAddress::QGeoAddress(const QGeoAddress &other) + : d(other.d) +{ +} + +/*! + \fn QGeoAddress::QGeoAddress(QGeoAddress &&other) noexcept + \since 6.2 + + Constructs a geo address object by moving from \a other. + + \note The moved-from QGeoAddress object can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + \fn QGeoAddress &QGeoAddress::operator=(QGeoAddress &other) + \since 6.2 + + Move-assigns the \a other to this address and returns a reference to this + address. + + \note The moved-from QGeoAddress object can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + Destroys this address. +*/ +QGeoAddress::~QGeoAddress() +{ +} + +QT_DEFINE_QSDP_SPECIALIZATION_DTOR(QGeoAddressPrivate) + +/*! + Assigns the given \a address to this address and + returns a reference to this address. +*/ +QGeoAddress &QGeoAddress::operator=(const QGeoAddress & address) +{ + if (this == &address) + return *this; + + d = address.d; + return *this; +} + +/*! + \fn bool QGeoAddress::operator==(const QGeoAddress &lhs, const QGeoAddress &rhs) + + Returns \c true if \a lhs address is equal to \a rhs, otherwise returns + \c false. +*/ + +/*! + \fn bool QGeoAddress::operator!=(const QGeoAddress &lhs, const QGeoAddress &rhs) + + Returns \c true if \a lhs address is not equal to \a rhs, otherwise returns + \c false. +*/ + +/*! + Returns the address as a single formatted string. It is the recommended string + to use to display the address to the user. It typically takes the format of + an address as found on an envelope, but this is not always necessarily the case. + + The address text is either automatically generated or explicitly assigned. + This can be determined by checking \l {QGeoAddress::isTextGenerated()} {isTextGenerated}. + + If an empty string is provided to setText(), then isTextGenerated() will be set + to \c true and text() will return a string which is locally formatted according to + countryCode() and based on the elements of the address such as street, city and so on. + Because the text string is generated from the address elements, a sequence + of calls such as text(), setStreet(), text() may return different strings for each + invocation of text(). + + If a non-empty string is provided to setText(), then isTextGenerated() will be + set to \c false and text() will always return the explicitly assigned string. + Calls to modify other elements such as setStreet(), setCity() and so on will not + affect the resultant string from text(). +*/ +QString QGeoAddress::text() const +{ + if (d->sText.isEmpty()) + return formattedAddress(*this); + else + return d->sText; +} + +/*! + If \a text is not empty, explicitly assigns \a text as the string to be returned by + text(). isTextGenerated() will return false. + + If \a text is empty, indicates that text() should be automatically generated + from the address elements. isTextGenerated() will return true. +*/ +void QGeoAddress::setText(const QString &text) +{ + d->sText = text; +} + +/*! + Returns the country name. +*/ +QString QGeoAddress::country() const +{ + return d->sCountry; +} + +/*! + Sets the \a country name. +*/ +void QGeoAddress::setCountry(const QString &country) +{ + d->sCountry = country; +} + +/*! + Returns the country code according to ISO 3166-1 alpha-3 +*/ +QString QGeoAddress::countryCode() const +{ + return d->sCountryCode; +} + +/*! + Sets the \a countryCode according to ISO 3166-1 alpha-3 +*/ +void QGeoAddress::setCountryCode(const QString &countryCode) +{ + d->sCountryCode = countryCode; +} + +/*! + Returns the state. The state is considered the first subdivision below country. +*/ +QString QGeoAddress::state() const +{ + return d->sState; +} + +/*! + Sets the \a state. +*/ +void QGeoAddress::setState(const QString &state) +{ + d->sState = state; +} + +/*! + Returns the county. The county is considered the second subdivision below country. +*/ +QString QGeoAddress::county() const +{ + return d->sCounty; +} + +/*! + Sets the \a county. +*/ +void QGeoAddress::setCounty(const QString &county) +{ + d->sCounty = county; +} + +/*! + Returns the city. +*/ +QString QGeoAddress::city() const +{ + return d->sCity; +} + +/*! + Sets the \a city. +*/ +void QGeoAddress::setCity(const QString &city) +{ + d->sCity = city; +} + +/*! + Returns the district. The district is considered the subdivison below city. +*/ +QString QGeoAddress::district() const +{ + return d->sDistrict; +} + +/*! + Sets the \a district. +*/ +void QGeoAddress::setDistrict(const QString &district) +{ + d->sDistrict = district; +} + +/*! + Returns the street name. + + \note Before Qt6 this could also contain things like a unit number, + a building name, or anything else that might be used to distinguish + one address from another. Use streetNumber() to obtain this data now. + + \sa streetNumber() +*/ +QString QGeoAddress::street() const +{ + return d->sStreet; +} + +/*! + Sets the street name to \a street. + + \note Before Qt6 this could also contain things like a unit number, + a building name, or anything else that might be used to distinguish + one address from another. Use setStreetNumber() to set this data now. + + \sa setStreetNumber() +*/ +void QGeoAddress::setStreet(const QString &street) +{ + d->sStreet = street; +} + +/*! + \since 6.2 + Returns the street number. + + This may also contain things like a unit number, a building name, or + anything else that might be used to distinguish one address from another. + + \note Before Qt6 this information was returned by street() method. + + \sa street() +*/ +QString QGeoAddress::streetNumber() const +{ + return d->sStreetNumber; +} + +/*! + \since 6.2 + Sets the street number to \a streetNumber. + + This may also contain things like a unit number, a building name, or + anything else that might be used to distinguish one address from another. + + \note Before Qt6 this information was set by setStreet() method. + + \sa setStreet() +*/ +void QGeoAddress::setStreetNumber(const QString &streetNumber) +{ + d->sStreetNumber = streetNumber; +} + +/*! + Returns the postal code. +*/ +QString QGeoAddress::postalCode() const +{ + return d->sPostalCode; +} + +/*! + Sets the \a postalCode. +*/ +void QGeoAddress::setPostalCode(const QString &postalCode) +{ + d->sPostalCode = postalCode; +} + +/*! + Returns whether this address is empty. An address is considered empty + if \e all of its fields are empty. +*/ +bool QGeoAddress::isEmpty() const +{ + return d->sCountry.isEmpty() && + d->sCountryCode.isEmpty() && + d->sState.isEmpty() && + d->sCounty.isEmpty() && + d->sCity.isEmpty() && + d->sDistrict.isEmpty() && + d->sStreet.isEmpty() && + d->sStreetNumber.isEmpty() && + d->sPostalCode.isEmpty() && + d->sText.isEmpty(); + +} + +/*! + Clears all of the address' data fields. +*/ +void QGeoAddress::clear() +{ + d->sCountry.clear(); + d->sCountryCode.clear(); + d->sState.clear(); + d->sCounty.clear(); + d->sCity.clear(); + d->sDistrict.clear(); + d->sStreet.clear(); + d->sStreetNumber.clear(); + d->sPostalCode.clear(); + d->sText.clear(); +} + +/*! + Returns true if QGeoAddress::text() is automatically generated from address elements, + otherwise returns false if text() has been explicitly assigned. + + \sa text(), setText() +*/ +bool QGeoAddress::isTextGenerated() const +{ + return d->sText.isEmpty(); +} + +bool QGeoAddress::equals(const QGeoAddress &lhs, const QGeoAddress &rhs) +{ +#ifdef QGEOADDRESS_DEBUG + qDebug() << "country" << (lhs.d->sCountry == rhs.d->sCountry); + qDebug() << "countryCode" << (lhs.d->sCountryCode == rhs.d->sCountryCode); + qDebug() << "state:" << (lhs.d->sState == rhs.d->sState); + qDebug() << "county:" << (lhs.d->sCounty == rhs.d->sCounty); + qDebug() << "city:" << (lhs.d->sCity == rhs.d->sCity); + qDebug() << "district:" << (lhs.d->sDistrict == rhs.d->sDistrict); + qDebug() << "street:" << (lhs.d->sStreet == rhs.d->sStreet); + qDebug() << "street number:" << (lhs.d->sStreetNumber == rhs.d->sStreetNumber); + qDebug() << "postalCode:" << (lhs.d->sPostalCode == rhs.d->sPostalCode); + qDebug() << "text:" << (lhs.text() == rhs.text()); +#endif + + return lhs.d->sCountry == rhs.d->sCountry && + lhs.d->sCountryCode == rhs.d->sCountryCode && + lhs.d->sState == rhs.d->sState && + lhs.d->sCounty == rhs.d->sCounty && + lhs.d->sCity == rhs.d->sCity && + lhs.d->sDistrict == rhs.d->sDistrict && + lhs.d->sStreet == rhs.d->sStreet && + lhs.d->sStreetNumber == rhs.d->sStreetNumber && + lhs.d->sPostalCode == rhs.d->sPostalCode && + lhs.text() == rhs.text(); +} + +/*! + \relates QGeoAddress + + Returns the hash value for the \a address, using \a seed for the + calculation. +*/ +size_t qHash(const QGeoAddress &address, size_t seed) noexcept +{ + size_t hash = qHashMulti(seed, address.country(), address.countryCode(), address.state(), + address.county(), address.city(), address.district(), + address.street(), address.streetNumber(), address.postalCode()); + + // If the text is generated from all fields, there is no need to use the + // resulting string in the hash. However, when the text is specified + // explicitly, we need to use it as well. + if (!address.isTextGenerated()) + hash = qHashMulti(seed, hash, address.text()); + return hash; +} + +QT_END_NAMESPACE diff --git a/src/positioning/qgeoaddress.h b/src/positioning/qgeoaddress.h new file mode 100644 index 0000000..ca651f7 --- /dev/null +++ b/src/positioning/qgeoaddress.h @@ -0,0 +1,87 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOADDRESS_H +#define QGEOADDRESS_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QString; +class QGeoAddressPrivate; +QT_DECLARE_QSDP_SPECIALIZATION_DTOR_WITH_EXPORT(QGeoAddressPrivate, Q_POSITIONING_EXPORT) + +class Q_POSITIONING_EXPORT QGeoAddress +{ +public: + QGeoAddress(); + QGeoAddress(const QGeoAddress &other); + QGeoAddress(QGeoAddress &&other) noexcept = default; + ~QGeoAddress(); + + QGeoAddress &operator=(const QGeoAddress &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QGeoAddress) + + void swap(QGeoAddress &other) noexcept { d.swap(other.d); } + + friend bool operator==(const QGeoAddress &lhs, const QGeoAddress &rhs) + { + return equals(lhs, rhs); + } + friend bool operator!=(const QGeoAddress &lhs, const QGeoAddress &rhs) + { + return !equals(lhs, rhs); + } + + QString text() const; + void setText(const QString &text); + + QString country() const; + void setCountry(const QString &country); + + QString countryCode() const; + void setCountryCode(const QString &countryCode); + + QString state() const; + void setState(const QString &state); + + QString county() const; + void setCounty(const QString &county); + + QString city() const; + void setCity(const QString &city); + + QString district() const; + void setDistrict(const QString &district); + + QString postalCode() const; + void setPostalCode(const QString &postalCode); + + QString street() const; + void setStreet(const QString &street); + + QString streetNumber() const; + void setStreetNumber(const QString &streetNumber); + + bool isEmpty() const; + void clear(); + + bool isTextGenerated() const; + +private: + static bool equals(const QGeoAddress &lhs, const QGeoAddress &rhs); + QSharedDataPointer d; +}; + +Q_POSITIONING_EXPORT size_t qHash(const QGeoAddress &address, size_t seed = 0) noexcept; + +Q_DECLARE_SHARED(QGeoAddress) + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoAddress, Q_POSITIONING_EXPORT) + +#endif diff --git a/src/positioning/qgeoaddress_p.h b/src/positioning/qgeoaddress_p.h new file mode 100644 index 0000000..01cfe87 --- /dev/null +++ b/src/positioning/qgeoaddress_p.h @@ -0,0 +1,50 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QLOCATION_GEOADDRESS_P_H +#define QLOCATION_GEOADDRESS_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 +#include +#include + +QT_BEGIN_NAMESPACE + +// The fields for the class are based on the nominatim openstreetmap API: +// https://nominatim.org/release-docs/latest/api/Output/#addressdetails +// It might not reflect all the address levels, but can be used to provide a +// more or less well-formed address. +class QGeoAddressPrivate : public QSharedData +{ +public: + QGeoAddressPrivate(); + QGeoAddressPrivate(const QGeoAddressPrivate &other); + ~QGeoAddressPrivate(); + + QString sCountry; //!< country field + QString sCountryCode; //!< country code field + QString sState; //!< state field + QString sCounty; //!< county field + QString sCity; //!< city field + QString sDistrict; //!< district field + QString sStreet; //!< street name field + QString sStreetNumber; //!< street number field + QString sPostalCode; //!< postal code field + QString sText; + bool m_autoGeneratedText; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qgeoareamonitorinfo.cpp b/src/positioning/qgeoareamonitorinfo.cpp new file mode 100644 index 0000000..c6e6a44 --- /dev/null +++ b/src/positioning/qgeoareamonitorinfo.cpp @@ -0,0 +1,406 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include +#include +#include +#include +#include + +#ifndef QT_NO_DEBUG_STREAM +#include +#endif + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoAreaMonitorInfo) + +/*! + \class QGeoAreaMonitorInfo + \inmodule QtPositioning + \since 5.2 + \ingroup QtPositioning-positioning + \ingroup shared + + \brief The QGeoAreaMonitorInfo class describes the parameters of an area or region + to be monitored for proximity. + + The purpose of area monitoring is to inform a user when he/she comes close to an area of + interest. In general such an area is described by a \l QGeoCircle. The circle's center + represents the place of interest and the area around it identifies the geographical region + within which notifications are sent. + + A QGeoAreaMonitorInfo object is valid if it has a non-empty name and a valid \l area(). + Such objects must be registered with a \l QGeoAreaMonitorSource to start and stop the + monitoring process. Note that extensive monitoring can be very resource consuming + because the positioning engine must remain active and has to match the current position + with each QGeoAreaMonitorInfo instance. + + To further reduce the burden on the system there are optional attributes which can + set. Each monitored area can have an expiry date which automatically removes the + to-be-monitored area from the monitoring source once the expiry date has been reached. + Another option is to adjust the persistence of a monitored area. A QGeoAreaMonitorInfo + that \l isPersistent() will remain active beyond + the current applications lifetime. If an area is entered while the monitoring + application is not running the application will be started. Note that this feature is + not available on all platforms. Its availability can be checked via + \l QGeoAreaMonitorSource::supportedAreaMonitorFeatures(). + + \sa QGeoAreaMonitorSource + + */ + +class QGeoAreaMonitorInfoPrivate : public QSharedData +{ +public: + QGeoAreaMonitorInfoPrivate() : QSharedData(), persistent(false) {} + QGeoAreaMonitorInfoPrivate(const QGeoAreaMonitorInfoPrivate &other) + : QSharedData(other) + { + uid = other.uid; + name = other.name; + shape = other.shape; + persistent = other.persistent; + notificationParameters = other.notificationParameters; + expiry = other.expiry; + } + ~QGeoAreaMonitorInfoPrivate() {} + + QUuid uid; + QString name; + QGeoShape shape; + bool persistent; + QVariantMap notificationParameters; + QDateTime expiry; +}; + +/*! + Constructs a QGeoAreaMonitorInfo object with the specified \a name. + + \sa name() + */ +QGeoAreaMonitorInfo::QGeoAreaMonitorInfo(const QString &name) +{ + d = new QGeoAreaMonitorInfoPrivate; + d->name = name; + d->uid = QUuid::createUuid(); +} + +/*! + Constructs a QGeoAreaMonitorInfo object as a copy of \a other. + */ +QGeoAreaMonitorInfo::QGeoAreaMonitorInfo(const QGeoAreaMonitorInfo &other) + : d(other.d) +{ +} + +/*! + \fn QGeoAreaMonitorInfo::QGeoAreaMonitorInfo(QGeoAreaMonitorInfo &&other) noexcept + \since 6.2 + + Constructs a QGeoAreaMonitorInfo object by moving from \a other. + + Note that a moved-from QGeoAreaMonitorInfo can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + Destructor + */ +QGeoAreaMonitorInfo::~QGeoAreaMonitorInfo() +{ +} + +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QGeoAreaMonitorInfoPrivate) + +/*! + Assigns \a other to this QGeoAreaMonitorInfo object and returns a reference + to this QGeoAreaMonitorInfo object. + */ +QGeoAreaMonitorInfo &QGeoAreaMonitorInfo::operator=(const QGeoAreaMonitorInfo &other) +{ + d = other.d; + return *this; +} + +/*! + \fn QGeoAreaMonitorInfo &QGeoAreaMonitorInfo::operator=(QGeoAreaMonitorInfo &&other) noexcept + \since 6.2 + + Move-assigns \a other to this QGeoAreaMonitorInfo object and returns a + reference to this QGeoAreaMonitorInfo object. + + Note that a moved-from QGeoAreaMonitorInfo can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + \fn bool QGeoAreaMonitorInfo::operator==(const QGeoAreaMonitorInfo &lhs, const QGeoAreaMonitorInfo &rhs) + + Returns \c true if all of the \a lhs object's values are the same as those + of \a rhs object. Otherwise returns \c false. +*/ + +/*! + \fn bool QGeoAreaMonitorInfo::operator!=(const QGeoAreaMonitorInfo &lhs, const QGeoAreaMonitorInfo &rhs) + + Returns \c true if any of the \a lhs object's values are not the same as + those of \a rhs object. Otherwise returns \c false. +*/ + +/*! + Returns the name of the QGeoAreaMonitorInfo object. The name should be used + for user-visibility purposes. + */ +QString QGeoAreaMonitorInfo::name() const +{ + return d->name; +} + +/*! + Sets the user visibile \a name. + */ +void QGeoAreaMonitorInfo::setName(const QString &name) +{ + if (d->name != name) { + d.detach(); + d->name = name; + } +} + +/*! + Returns the identifier of the QGeoAreaMonitorInfo object. + The identifier is automatically generated upon construction of a new + QGeoAreaMonitorInfo object. +*/ + +QString QGeoAreaMonitorInfo::identifier() const +{ + return d->uid.toString(); +} + +/*! + Returns true, if the monitor is valid. A valid QGeoAreaMonitorInfo has a non-empty name() + and the monitored area is not \l {QGeoShape::isEmpty()}{empty()}. + Otherwise this function returns false. + */ +bool QGeoAreaMonitorInfo::isValid() const +{ + return (!d->name.isEmpty() && !d->shape.isEmpty()); +} + +/*! + Returns the boundaries of the to-be-monitored area. This area must not be empty. + + \sa setArea() + */ +QGeoShape QGeoAreaMonitorInfo::area() const +{ + return d->shape; +} + +/*! + Sets the to-be-monitored area to \a newShape. + + \sa area() + */ +void QGeoAreaMonitorInfo::setArea(const QGeoShape &newShape) +{ + d.detach(); + d->shape = newShape; +} + +/*! + Returns the expiry date. + + After an active QGeoAreaMonitorInfo has expired the region is no longer monitored + and the QGeoAreaMonitorInfo object is removed from the list of + \l {QGeoAreaMonitorSource::activeMonitors()}{active monitors}. + + If the expiry \l QDateTime is invalid the QGeoAreaMonitorInfo object is treated as not having + an expiry date. This implies an indefinite monitoring period if the object is persistent or + until the current application closes if the object is non-persistent. + + \sa QGeoAreaMonitorSource::activeMonitors() + */ +QDateTime QGeoAreaMonitorInfo::expiration() const +{ + return d->expiry; +} + +/*! + Sets the expiry date and time to \a expiry. + */ +void QGeoAreaMonitorInfo::setExpiration(const QDateTime &expiry) +{ + d.detach(); + d->expiry = expiry; +} + +/*! + Returns true if the QGeoAreaMonitorInfo is persistent. + The default value for this property is false. + + A non-persistent QGeoAreaMonitorInfo will be removed by the system once + the application owning the monitor object stops. Persistent objects remain + active and can be retrieved once the application restarts. + + If the system triggers an event associated to a persistent QGeoAreaMonitorInfo + the relevant application will be re-started and the appropriate signal emitted. + + \sa setPersistent() + */ +bool QGeoAreaMonitorInfo::isPersistent() const +{ + return d->persistent; +} + +/*! + Sets the QGeoAreaMonitorInfo object's persistence to \a isPersistent. + + Note that setting this flag does not imply that \l QGeoAreaMonitorSource + supports persistent monitoring. + \l QGeoAreaMonitorSource::supportedAreaMonitorFeatures() can be used to + check for this feature's availability. + + \sa isPersistent() + */ +void QGeoAreaMonitorInfo::setPersistent(bool isPersistent) +{ + d.detach(); + d->persistent = isPersistent; +} + + +/*! + Returns the set of platform specific parameters used by this + QGeoAreaMonitorInfo. + + \sa setNotificationParameters() + */ +QVariantMap QGeoAreaMonitorInfo::notificationParameters() const +{ + return d->notificationParameters; +} + +/*! + Sets the set of platform specific \a parameters used by QGeoAreaMonitorInfo. + + \sa notificationParameters() + */ +void QGeoAreaMonitorInfo::setNotificationParameters(const QVariantMap ¶meters) +{ + d.detach(); + d->notificationParameters = parameters; +} + +/*! + \internal +*/ +void QGeoAreaMonitorInfo::detach() +{ + if (d) + d.detach(); + else + d = new QGeoAreaMonitorInfoPrivate; +} + +bool QGeoAreaMonitorInfo::equals(const QGeoAreaMonitorInfo &lhs, const QGeoAreaMonitorInfo &rhs) +{ + return (lhs.d->name == rhs.d->name && + lhs.d->uid == rhs.d->uid && + lhs.d->shape == rhs.d->shape && + lhs.d->persistent == rhs.d->persistent && + lhs.d->expiry == rhs.d->expiry && + lhs.d->notificationParameters == rhs.d->notificationParameters); +} + +#ifndef QT_NO_DATASTREAM + +/*! + \fn QDataStream &QGeoAreaMonitorInfo::operator<<(QDataStream &stream, const QGeoAreaMonitorInfo &monitor) + + Writes the given \a monitor to the specified \a stream. + + \sa {Serializing Qt Data Types} +*/ +QDataStream &QGeoAreaMonitorInfo::dataStreamOut(QDataStream &ds, const QGeoAreaMonitorInfo &monitor) +{ + ds << monitor.name() << monitor.d->uid << monitor.area() + << monitor.isPersistent() << monitor.notificationParameters() << monitor.expiration(); + return ds; +} + +/*! + \fn QDataStream &QGeoAreaMonitorInfo::operator>>(QDataStream &stream, QGeoAreaMonitorInfo &monitor) + + Reads a area monitoring data from the specified \a stream into the given + \a monitor. + + \sa {Serializing Qt Data Types} +*/ +QDataStream &QGeoAreaMonitorInfo::dataStreamIn(QDataStream &ds, QGeoAreaMonitorInfo &monitor) +{ + QString s; + ds >> s; + monitor = QGeoAreaMonitorInfo(s); + + QUuid id; + ds >> id; + monitor.d->uid = id; + + QGeoShape shape; + ds >> shape; + monitor.setArea(shape); + + bool persistent; + ds >> persistent; + monitor.setPersistent(persistent); + + QVariantMap map; + ds >> map; + monitor.setNotificationParameters(map); + + QDateTime dt; + ds >> dt; + monitor.setExpiration(dt); + + return ds; +} + +#endif + +#ifndef QT_NO_DEBUG_STREAM +QDebug QGeoAreaMonitorInfo::debugStreaming(QDebug dbg, const QGeoAreaMonitorInfo &monitor) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QGeoAreaMonitorInfo(\"" << qPrintable(monitor.name()) + << "\", " << monitor.area() + << ", persistent: " << monitor.isPersistent() + << ", expiry: " << monitor.expiration() << ")"; + return dbg; +} + +#endif + +size_t qHash(const QGeoAreaMonitorInfo &key, size_t seed) noexcept +{ + return qHashMulti(seed, key.d->uid); +} + +namespace QTest +{ + +char *toString(const QGeoAreaMonitorInfo &info) +{ + QString result; + QDebug dbg(&result); + dbg << info; + return qstrdup(qPrintable(result)); +} + +} // namespace QTest + +QT_END_NAMESPACE diff --git a/src/positioning/qgeoareamonitorinfo.h b/src/positioning/qgeoareamonitorinfo.h new file mode 100644 index 0000000..c0f5afc --- /dev/null +++ b/src/positioning/qgeoareamonitorinfo.h @@ -0,0 +1,103 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOAREAMONITORINFO_H +#define QGEOAREAMONITORINFO_H + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QDataStream; +class QGeoAreaMonitorInfo; + +Q_POSITIONING_EXPORT size_t qHash(const QGeoAreaMonitorInfo &key, size_t seed = 0) noexcept; +namespace QTest +{ +Q_POSITIONING_EXPORT char *toString(const QGeoAreaMonitorInfo &info); +} // namespace QTest + +class QGeoAreaMonitorInfoPrivate; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QGeoAreaMonitorInfoPrivate, Q_POSITIONING_EXPORT) + +class Q_POSITIONING_EXPORT QGeoAreaMonitorInfo +{ +public: + explicit QGeoAreaMonitorInfo(const QString &name = QString()); + QGeoAreaMonitorInfo(const QGeoAreaMonitorInfo &other); + QGeoAreaMonitorInfo(QGeoAreaMonitorInfo &&other) noexcept = default; + ~QGeoAreaMonitorInfo(); + + QGeoAreaMonitorInfo &operator=(const QGeoAreaMonitorInfo &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QGeoAreaMonitorInfo) + + void swap(QGeoAreaMonitorInfo &other) noexcept { d.swap(other.d); } + + friend bool operator==(const QGeoAreaMonitorInfo &lhs, const QGeoAreaMonitorInfo &rhs) + { + return equals(lhs, rhs); + } + friend bool operator!=(const QGeoAreaMonitorInfo &lhs, const QGeoAreaMonitorInfo &rhs) + { + return !equals(lhs, rhs); + } + + QString name() const; + void setName(const QString &name); + + QString identifier() const; + bool isValid() const; + + QGeoShape area() const; + void setArea(const QGeoShape &newShape); + + QDateTime expiration() const; + void setExpiration(const QDateTime &expiry); + + bool isPersistent() const; + void setPersistent(bool isPersistent); + + QVariantMap notificationParameters() const; + void setNotificationParameters(const QVariantMap ¶meters); + + void detach(); + +private: + static bool equals(const QGeoAreaMonitorInfo &lhs, const QGeoAreaMonitorInfo &rhs); + QExplicitlySharedDataPointer d; + friend class QGeoAreaMonitorInfoPrivate; + +#ifndef QT_NO_DATASTREAM + friend QDataStream &operator<<(QDataStream &ds, const QGeoAreaMonitorInfo &monitor) + { + return dataStreamOut(ds, monitor); + } + friend QDataStream &operator>>(QDataStream &ds, QGeoAreaMonitorInfo &monitor) + { + return dataStreamIn(ds, monitor); + } + static QDataStream &dataStreamOut(QDataStream &ds, const QGeoAreaMonitorInfo &monitor); + static QDataStream &dataStreamIn(QDataStream &ds, QGeoAreaMonitorInfo &monitor); +#endif + friend Q_POSITIONING_EXPORT size_t qHash(const QGeoAreaMonitorInfo &key, size_t seed) noexcept; + friend Q_POSITIONING_EXPORT char *QTest::toString(const QGeoAreaMonitorInfo& info); +#ifndef QT_NO_DEBUG_STREAM + friend QDebug operator<<(QDebug dbg, const QGeoAreaMonitorInfo &monitor) + { + return debugStreaming(dbg, monitor); + } + static QDebug debugStreaming(QDebug dbg, const QGeoAreaMonitorInfo &monitor); +#endif +}; + +Q_DECLARE_SHARED(QGeoAreaMonitorInfo) + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoAreaMonitorInfo, Q_POSITIONING_EXPORT) + +#endif // QGEOAREAMONITORINFO_H diff --git a/src/positioning/qgeoareamonitorsource.cpp b/src/positioning/qgeoareamonitorsource.cpp new file mode 100644 index 0000000..7606e45 --- /dev/null +++ b/src/positioning/qgeoareamonitorsource.cpp @@ -0,0 +1,398 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include +#include +#include "qgeopositioninfosourcefactory.h" +#include "qgeopositioninfosource_p.h" + +/*! + \class QGeoAreaMonitorSource + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.2 + + \brief The QGeoAreaMonitorSource class enables the detection of proximity + changes for a specified set of coordinates. + + A QGeoAreaMonitorSource emits signals when the current position is in + range, or has moved out of range, of a specified area. + Each area is specified by a \l QGeoAreaMonitorInfo object. + For example: + + \snippet cpp/cppqml.cpp BigBen + + \c QGeoAreaMonitorSource follows a singleton pattern. Each instance of + the class with the same \l sourceName() shares the same area monitoring backend. + If a new \l QGeoAreaMonitorInfo object is added via \l startMonitoring() + or \l requestUpdate() it can be retrieved by another instance of this class + (provided that they are sourced from the same area monitor provider plug-in). + The same singleton pattern applies to the \l QGeoPositionInfoSource instance + used by this class. The following code snippet emphasizes the behavior: + + \code + QGeoAreaMonitorSource *s1 = QGeoAreaMonitorSource::createSource("blah", this); + QGeoAreaMonitorSource *s2 = QGeoAreaMonitorSource::createSource("blah", this); + QVERIFY(s1->positionInfoSource() == s2->positionInfoSource); + \endcode +*/ + +QT_BEGIN_NAMESPACE + + + +class QGeoAreaMonitorSourcePrivate : public QObjectPrivate +{ +public: + QGeoPositionInfoSource *source; + QString providerName; +}; + +/*! + \enum QGeoAreaMonitorSource::Error + Defines the types of positioning methods. + + The Error enumeration represents the errors which can occur. + + \value AccessError The connection setup to the remote area monitoring backend failed because the + application lacked the required privileges. + \value InsufficientPositionInfo The area monitoring source could not retrieve a location fix or + the accuracy of the fix is not high enough to provide an effective area monitoring. + \value NoError No error has occurred. + \value UnknownSourceError An unidentified error occurred. +*/ + +/*! + \enum QGeoAreaMonitorSource::AreaMonitorFeature + Defines the types of area monitoring capabilities. + + \value PersistentAreaMonitorFeature QGeoAreaMonitorInfo instances can be made persistent. + A persistent monitor continues to be active even when the application managing the monitor is + not running. + \value AnyAreaMonitorFeature Matches all possible area monitoring features. +*/ + +/*! + \fn virtual AreaMonitoringFeatures QGeoAreaMonitorSource::supportedAreaMonitorFeatures() const = 0; + + Returns the area monitoring features available to this source. +*/ + +/*! + \fn virtual QGeoAreaMonitorSource::Error QGeoAreaMonitorSource::error() const + + Returns the type of error that last occurred. + + \note Since Qt6 the last error is always reset when calling + startMonitoring() or requestUpdate(). +*/ + +/*! + Creates a monitor source with the given \a parent. +*/ +QGeoAreaMonitorSource::QGeoAreaMonitorSource(QObject *parent) + : QObject(*new QGeoAreaMonitorSourcePrivate, parent) +{ + Q_D(QGeoAreaMonitorSource); + d->source = nullptr; +} + +/*! + Destroys the monitor source. +*/ +QGeoAreaMonitorSource::~QGeoAreaMonitorSource() +{ +} + +/*! + Creates and returns a monitor source with the given \a parent that + monitors areas using resources on the underlying system. + + Returns \c nullptr if the system has no support for position monitoring. +*/ +QGeoAreaMonitorSource *QGeoAreaMonitorSource::createDefaultSource(QObject *parent) +{ + const QList plugins = QGeoPositionInfoSourcePrivate::pluginsSorted(); + foreach (const QCborMap &obj, plugins) { + if (obj.value(QStringLiteral("Monitor")).isBool() + && obj.value(QStringLiteral("Monitor")).toBool()) + { + QGeoAreaMonitorSource *s = nullptr; + auto factory = QGeoPositionInfoSourcePrivate::loadFactory(obj); + if (factory) + s = factory->areaMonitor(parent, QVariantMap()); + if (s) + s->d_func()->providerName = obj.value(QStringLiteral("Provider")).toString(); + return s; + } + } + return nullptr; +} + +/*! + Creates and returns a monitor source with the given \a parent, + by loading the plugin named \a sourceName. + + Returns \c nullptr if the plugin cannot be found. +*/ +QGeoAreaMonitorSource *QGeoAreaMonitorSource::createSource(const QString &sourceName, QObject *parent) +{ + auto plugins = QGeoPositionInfoSourcePrivate::plugins(); + if (plugins.contains(sourceName)) { + const auto metaData = plugins.value(sourceName); + QGeoAreaMonitorSource *s = nullptr; + auto factory = QGeoPositionInfoSourcePrivate::loadFactory(metaData); + if (factory) + s = factory->areaMonitor(parent, QVariantMap()); + if (s) + s->d_func()->providerName = metaData.value(QStringLiteral("Provider")).toString(); + return s; + } + + return nullptr; +} + +/*! + Returns a list of available monitor plugins, including the default system + backend if one is available. +*/ +QStringList QGeoAreaMonitorSource::availableSources() +{ + QStringList plugins; + const auto meta = QGeoPositionInfoSourcePrivate::plugins(); + for (auto it = meta.cbegin(), end = meta.cend(); it != end; ++it) { + if (it.value().value(QStringLiteral("Monitor")).isBool() + && it.value().value(QStringLiteral("Monitor")).toBool()) { + plugins << it.key(); + } + } + + return plugins; +} + +/*! + Returns the unique name of the area monitor source implementation in use. + + This is the same name that can be passed to createSource() in order to + create a new instance of a particular area monitor source implementation. +*/ +QString QGeoAreaMonitorSource::sourceName() const +{ + Q_D(const QGeoAreaMonitorSource); + return d->providerName; +} + +/*! + \since 6.2 + + Sets the backend-specific property named \a name to \a value. + Returns \c true on success, otherwise returns \c false. + Backend-specific properties can be used to configure the area monitoring + subsystem behavior at runtime. + + \sa backendProperty() +*/ +bool QGeoAreaMonitorSource::setBackendProperty(const QString &name, const QVariant &value) +{ + Q_UNUSED(name); + Q_UNUSED(value); + return false; +} + +/*! + \since 6.2 + + Returns the value of the backend-specific property named \a name, + if present. Otherwise the returned value will be invalid. + + \sa setBackendProperty() +*/ +QVariant QGeoAreaMonitorSource::backendProperty(const QString &name) const +{ + Q_UNUSED(name); + return QVariant(); +} + +/*! + Returns the current QGeoPositionInfoSource used by this QGeoAreaMonitorSource + object. The function will return \l QGeoPositionInfoSource::createDefaultSource() + if no other object has been set. + + The function returns \c nullptr if not even a default QGeoPositionInfoSource + exists. + + Any usage of the returned \l QGeoPositionInfoSource instance should account + for the fact that it may reside in a different thread. + + \sa QGeoPositionInfoSource, setPositionInfoSource() +*/ +QGeoPositionInfoSource* QGeoAreaMonitorSource::positionInfoSource() const +{ + Q_D(const QGeoAreaMonitorSource); + return d->source; +} + +/*! + Sets the new \l QGeoPositionInfoSource to be used by this QGeoAreaMonitorSource object. + The area monitoring backend becomes the new QObject parent for \a newSource. + The previous \l QGeoPositionInfoSource object will be deleted. All QGeoAreaMonitorSource + instances based on the same \l sourceName() share the same QGeoPositionInfoSource + instance. + + This may be useful when it is desirable to manipulate the positioning system + used by the area monitoring engine. + + Note that ownership must be taken care of by subclasses of QGeoAreaMonitorSource. + Due to the singleton pattern behind this class \a newSource may be moved to a + new thread. + + \sa positionInfoSource() + */ +void QGeoAreaMonitorSource::setPositionInfoSource(QGeoPositionInfoSource *newSource) +{ + Q_D(QGeoAreaMonitorSource); + d->source = newSource; +} + + +/*! + \fn virtual bool QGeoAreaMonitorSource::startMonitoring(const QGeoAreaMonitorInfo &monitor) + + Returns \c true if the monitoring of \a monitor could be successfully started; otherwise + returns \c false. A reason for not being able to start monitoring could be the unavailability + of an appropriate default position info source while no alternative QGeoPositionInfoSource + has been set via \l setPositionInfoSource(). + + If \a monitor is already active, the existing monitor object will be replaced by the new \a monitor reference. + The identification of QGeoAreaMonitorInfo instances happens via \l QGeoAreaMonitorInfo::identifier(). + Therefore this function can also be used to update active monitors. + + If \a monitor has an expiry date that has been passed this function returns false. Calling + this function for an already via \l requestUpdate() registered single shot monitor + switches the monitor to a permanent monitoring mode. + + Requesting persistent monitoring on a QGeoAreaMonitorSource instance fails if the area monitoring + backend doesn't support \l QGeoAreaMonitorSource::PersistentAreaMonitorFeature. + + \note Since Qt6 this method always resets the last error to + \l {QGeoAreaMonitorSource::}{NoError} before starting monitoring. + + \sa stopMonitoring() +*/ + +/*! + \fn virtual bool QGeoAreaMonitorSource::requestUpdate(const QGeoAreaMonitorInfo &monitor, const char *signal) + + Enables single shot area monitoring. Area monitoring for \a monitor will be performed + until this QGeoAreaMonitorSource instance emits \a signal for the first time. Once + the signal was emitted, \a monitor is automatically removed from the list of + \l activeMonitors(). If \a monitor is invalid or has an expiry date that has + been passed, this function returns \c false. + + \code + QGeoAreaMonitor singleShotMonitor; + QGeoAreaMonitorSource * source = QGeoAreaMonitorSource::createDefaultSource(this); + //... + bool ret = source->requestUpdate(singleShotMonitor, + SIGNAL(areaExited(QGeoAreaMonitor,QGeoPositionInfo))); + \endcode + + The above \c singleShotMonitor object will cease to send updates once the \l areaExited() signal + was emitted for the first time. Until this point in time any other signal may be emitted + zero or more times depending on the area context. + + It is not possible to simultanously request updates for more than one signal of the same monitor object. + The last call to this function determines the signal upon which the updates cease to continue. + At this stage only the \l areaEntered() and \l areaExited() signals can be used to + terminate the monitoring process. + + Requesting persistent monitoring on a QGeoAreaMonitorSource instance fails if the area monitoring + backend doesn't support \l QGeoAreaMonitorSource::PersistentAreaMonitorFeature. + + If \a monitor was already registered via \l startMonitoring() it is converted to a single + shot behavior. + + \note Since Qt6 this method always resets the last error to + \l {QGeoAreaMonitorSource::}{NoError} before starting monitoring. + + \sa startMonitoring(), stopMonitoring() + */ + +/*! + \fn virtual bool QGeoAreaMonitorSource::stopMonitoring(const QGeoAreaMonitorInfo &monitor) + + Returns true if \a monitor was successfully removed from the list of \l activeMonitors(); + otherwise returns false. This behavior is independent on whether \a monitor was registered + via \l startMonitoring() or \l requestUpdate(). +*/ + +/*! + \fn virtual QList QGeoAreaMonitorSource::activeMonitors() const + + Returns the list of all active monitors known to the QGeoAreaMonitorSource object. + + An active monitor was started via startMonitoring(). For every active + monitor the source object will emit the required signals, such as + areaEntered() or areaExited(). Multiple \l QGeoAreaMonitorSource instances + within the same application share the same active monitor objects. + + Unless an active QGeoAreaMonitorInfo \l {QGeoAreaMonitorInfo::isPersistent()}{isPersistent()} an active QGeoAreaMonitorInfo + will be stopped once the current application terminates. +*/ + +/*! + \fn virtual QList QGeoAreaMonitorSource::activeMonitors(const QGeoShape &lookupArea) const + + Returns the list of all active monitors known to the QGeoAreaMonitorSource object whose + center lies within \a lookupArea. If \a lookupArea is empty the returned list will be empty. + + An active monitor was started via startMonitoring(). For every active + monitor the source object will emit the required signals, such as + areaEntered() or areaExited(). Multiple \l QGeoAreaMonitorSource instances + within the same application share the same active monitor objects. + + Unless an active QGeoAreaMonitorInfo \l {QGeoAreaMonitorInfo::isPersistent()}{isPersistent()} an active QGeoAreaMonitorInfo + will be stopped once the current application terminates. + + \sa QGeoShape +*/ + + +/*! + \fn void QGeoAreaMonitorSource::monitorExpired(const QGeoAreaMonitorInfo &monitor) + + Emitted when \a monitor has expired. An expired area monitor is automatically + removed from the list of \l activeMonitors(). + + \sa activeMonitors() +*/ + +/*! + \fn void QGeoAreaMonitorSource::areaEntered(const QGeoAreaMonitorInfo &monitor, const QGeoPositionInfo &update) + + Emitted when the current position has moved from a position outside of the active \a monitor + to a position within the monitored area. + + The \a update holds the new position. +*/ + +/*! + \fn void QGeoAreaMonitorSource::areaExited(const QGeoAreaMonitorInfo &monitor, const QGeoPositionInfo &update) + + Emitted when the current position has moved from a position within the active \a monitor + to a position outside the monitored area. + + The \a update holds the new position. +*/ + +/*! + \fn void QGeoAreaMonitorSource::errorOccurred(QGeoAreaMonitorSource::Error areaMonitoringError) + + This signal is emitted after an error occurred. The \a areaMonitoringError + parameter describes the type of error that occurred. + +*/ + +QT_END_NAMESPACE + +#include "moc_qgeoareamonitorsource.cpp" diff --git a/src/positioning/qgeoareamonitorsource.h b/src/positioning/qgeoareamonitorsource.h new file mode 100644 index 0000000..b9af93a --- /dev/null +++ b/src/positioning/qgeoareamonitorsource.h @@ -0,0 +1,75 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QGEOAREAMONITORSOURCE_H +#define QGEOAREAMONITORSOURCE_H + +#include +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfo; +class QGeoAreaMonitorSourcePrivate; +class Q_POSITIONING_EXPORT QGeoAreaMonitorSource : public QObject +{ + Q_OBJECT + +public: + enum Error { + AccessError = 0, + InsufficientPositionInfo = 1, + UnknownSourceError = 2, + NoError = 3 + }; + Q_ENUMS(Error) + + enum AreaMonitorFeature { + PersistentAreaMonitorFeature = 0x00000001, + AnyAreaMonitorFeature = 0xffffffff + }; + Q_DECLARE_FLAGS(AreaMonitorFeatures, AreaMonitorFeature) + + explicit QGeoAreaMonitorSource(QObject *parent); + virtual ~QGeoAreaMonitorSource(); + + static QGeoAreaMonitorSource *createDefaultSource(QObject *parent); + static QGeoAreaMonitorSource *createSource(const QString& sourceName, QObject *parent); + static QStringList availableSources(); + + virtual void setPositionInfoSource(QGeoPositionInfoSource *source); + virtual QGeoPositionInfoSource* positionInfoSource() const; + + QString sourceName() const; + + virtual Error error() const = 0; + virtual AreaMonitorFeatures supportedAreaMonitorFeatures() const = 0; + + virtual bool startMonitoring(const QGeoAreaMonitorInfo &monitor) = 0; + virtual bool stopMonitoring(const QGeoAreaMonitorInfo &monitor) = 0; + virtual bool requestUpdate(const QGeoAreaMonitorInfo &monitor, const char *signal) = 0; + + virtual QList activeMonitors() const = 0; + virtual QList activeMonitors(const QGeoShape &lookupArea) const = 0; + + virtual bool setBackendProperty(const QString &name, const QVariant &value); + virtual QVariant backendProperty(const QString &name) const; + +Q_SIGNALS: + void areaEntered(const QGeoAreaMonitorInfo &monitor, const QGeoPositionInfo &update); + void areaExited(const QGeoAreaMonitorInfo &monitor, const QGeoPositionInfo &update); + void monitorExpired(const QGeoAreaMonitorInfo &monitor); + void errorOccurred(QGeoAreaMonitorSource::Error error); + +private: + Q_DISABLE_COPY(QGeoAreaMonitorSource) + Q_DECLARE_PRIVATE(QGeoAreaMonitorSource) +}; + + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qgeocircle.cpp b/src/positioning/qgeocircle.cpp new file mode 100644 index 0000000..2e86256 --- /dev/null +++ b/src/positioning/qgeocircle.cpp @@ -0,0 +1,445 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeocircle.h" +#include "qgeocircle_p.h" + +#include "qgeocoordinate.h" +#include "qnumeric.h" +#include "qlocationutils_p.h" + +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" +#include +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoCircle) + +/*! + \class QGeoCircle + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.2 + + \brief The QGeoCircle class defines a circular geographic area. + + The circle is defined in terms of a QGeoCoordinate which specifies the + center of the circle and a qreal which specifies the radius of the circle + in meters. + + The circle is considered invalid if the center coordinate is invalid + or if the radius is less than zero. + + This class is a \l Q_GADGET since Qt 5.5. It can be + \l{Cpp_value_integration_positioning}{directly used from C++ and QML}. +*/ + +/*! + \property QGeoCircle::center + \brief This property holds the center coordinate for the geo circle. + + The circle is considered invalid if this property contains an invalid + coordinate. + + A default constructed QGeoCircle uses an invalid \l QGeoCoordinate + as center. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoCircle::radius + \brief This property holds the circle radius in meters. + + The circle is considered invalid if this property is negative. + + By default, the radius is initialized with \c -1. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +inline QGeoCirclePrivate *QGeoCircle::d_func() +{ + return static_cast(d_ptr.data()); +} + +inline const QGeoCirclePrivate *QGeoCircle::d_func() const +{ + return static_cast(d_ptr.constData()); +} + +struct CircleVariantConversions +{ + CircleVariantConversions() + { + QMetaType::registerConverter(); + QMetaType::registerConverter(); + } +}; + +Q_GLOBAL_STATIC(CircleVariantConversions, initCircleConversions) + +/*! + Constructs a new, invalid geo circle. +*/ +QGeoCircle::QGeoCircle() +: QGeoShape(new QGeoCirclePrivate) +{ + initCircleConversions(); +} + +/*! + Constructs a new geo circle centered at \a center and with a radius of \a radius meters. +*/ +QGeoCircle::QGeoCircle(const QGeoCoordinate ¢er, qreal radius) +{ + initCircleConversions(); + d_ptr = new QGeoCirclePrivate(center, radius); +} + +/*! + Constructs a new geo circle from the contents of \a other. +*/ +QGeoCircle::QGeoCircle(const QGeoCircle &other) +: QGeoShape(other) +{ + initCircleConversions(); +} + +/*! + Constructs a new geo circle from the contents of \a other. +*/ +QGeoCircle::QGeoCircle(const QGeoShape &other) +: QGeoShape(other) +{ + initCircleConversions(); + if (type() != QGeoShape::CircleType) + d_ptr = new QGeoCirclePrivate; +} + +/*! + Destroys this geo circle. +*/ +QGeoCircle::~QGeoCircle() {} + +/*! + Assigns \a other to this geo circle and returns a reference to this geo circle. +*/ +QGeoCircle &QGeoCircle::operator=(const QGeoCircle &other) +{ + QGeoShape::operator=(other); + return *this; +} + +bool QGeoCirclePrivate::isValid() const +{ + return m_center.isValid() && !qIsNaN(m_radius) && m_radius >= -1e-7; +} + +bool QGeoCirclePrivate::isEmpty() const +{ + return !isValid() || m_radius <= 1e-7; +} + +/*! + Sets the center coordinate of this geo circle to \a center. +*/ +void QGeoCircle::setCenter(const QGeoCoordinate ¢er) +{ + Q_D(QGeoCircle); + + d->setCenter(center); +} + +/*! + Returns the center coordinate of this geo circle. Equivalent to QGeoShape::center(). +*/ +QGeoCoordinate QGeoCircle::center() const +{ + Q_D(const QGeoCircle); + + return d->center(); +} + +/*! + Sets the radius in meters of this geo circle to \a radius. +*/ +void QGeoCircle::setRadius(qreal radius) +{ + Q_D(QGeoCircle); + + d->setRadius(radius); +} + +/*! + Returns the radius in meters of this geo circle. +*/ +qreal QGeoCircle::radius() const +{ + Q_D(const QGeoCircle); + + return d->m_radius; +} + +bool QGeoCirclePrivate::contains(const QGeoCoordinate &coordinate) const +{ + if (!isValid() || !coordinate.isValid()) + return false; + + // see QTBUG-41447 for details + qreal distance = m_center.distanceTo(coordinate); + if (qFuzzyCompare(distance, m_radius) || distance <= m_radius) + return true; + + return false; +} + +QGeoCoordinate QGeoCirclePrivate::center() const +{ + return m_center; +} + +QGeoRectangle QGeoCirclePrivate::boundingGeoRectangle() const +{ + return m_bbox; +} + +void QGeoCirclePrivate::updateBoundingBox() +{ + if (isEmpty()) { + if (m_center.isValid()) { + m_bbox.setTopLeft(m_center); + m_bbox.setBottomRight(m_center); + } + return; + } + + bool crossNorth = crossNorthPole(); + bool crossSouth = crossSouthPole(); + + if (crossNorth && crossSouth) { + // Circle crossing both poles fills the whole map + m_bbox = QGeoRectangle(QGeoCoordinate(90.0, -180.0), QGeoCoordinate(-90.0, 180.0)); + } else if (crossNorth) { + // Circle crossing one pole fills the map in the longitudinal direction + m_bbox = QGeoRectangle(QGeoCoordinate(90.0, -180.0), QGeoCoordinate(m_center.atDistanceAndAzimuth(m_radius, 180.0).latitude(), 180.0)); + } else if (crossSouth) { + m_bbox = QGeoRectangle(QGeoCoordinate(m_center.atDistanceAndAzimuth(m_radius, 0.0).latitude(), -180.0), QGeoCoordinate(-90, 180.0)); + } else { + // Regular circle not crossing anything + + // Calculate geo bounding box of the circle + // + // A circle tangential point with a meridian, together with pole and + // the circle center create a spherical triangle. + // Finding the tangential point with the spherical law of sines: + // + // * lon_delta_in_rad : delta between the circle center and a tangential + // point (absolute value). + // * r_in_rad : angular radius of the circle + // * lat_in_rad : latitude of the circle center + // * alpha_in_rad : angle between meridian and radius of the circle. + // At the tangential point, sin(alpha_in_rad) == 1. + // * lat_delta_in_rad - absolute delta of latitudes between the circle center and + // any of the two points where the great circle going through the circle + // center and the pole crosses the circle. In other words, the points + // on the circle with azimuth 0 or 180. + // + // Using: + // sin(lon_delta_in_rad)/sin(r_in_rad) = sin(alpha_in_rad)/sin(pi/2 - lat_in_rad) + + double r_in_rad = m_radius / QLocationUtils::earthMeanRadius(); // angular r + double lat_delta_in_deg = QLocationUtils::degrees(r_in_rad); + double lon_delta_in_deg = QLocationUtils::degrees(std::asin( + std::sin(r_in_rad) / + std::cos(QLocationUtils::radians(m_center.latitude())) + )); + + QGeoCoordinate topLeft; + topLeft.setLatitude(QLocationUtils::clipLat(m_center.latitude() + lat_delta_in_deg)); + topLeft.setLongitude(QLocationUtils::wrapLong(m_center.longitude() - lon_delta_in_deg)); + QGeoCoordinate bottomRight; + bottomRight.setLatitude(QLocationUtils::clipLat(m_center.latitude() - lat_delta_in_deg)); + bottomRight.setLongitude(QLocationUtils::wrapLong(m_center.longitude() + lon_delta_in_deg)); + + m_bbox = QGeoRectangle(topLeft, bottomRight); + } +} + +void QGeoCirclePrivate::setCenter(const QGeoCoordinate &c) +{ + m_center = c; + updateBoundingBox(); +} + +void QGeoCirclePrivate::setRadius(const qreal r) +{ + m_radius = r; + updateBoundingBox(); +} + +bool QGeoCirclePrivate::crossNorthPole() const +{ + const QGeoCoordinate northPole(90.0, m_center.longitude()); + qreal distanceToPole = m_center.distanceTo(northPole); + if (distanceToPole < m_radius) + return true; + return false; +} + +bool QGeoCirclePrivate::crossSouthPole() const +{ + const QGeoCoordinate southPole(-90.0, m_center.longitude()); + qreal distanceToPole = m_center.distanceTo(southPole); + if (distanceToPole < m_radius) + return true; + return false; +} + +/* + Extends the circle to include \a coordinate. +*/ +void QGeoCirclePrivate::extendCircle(const QGeoCoordinate &coordinate) +{ + if (!isValid() || !coordinate.isValid() || contains(coordinate)) + return; + + setRadius(m_center.distanceTo(coordinate)); +} + +/*! + Translates this geo circle by \a degreesLatitude northwards and \a degreesLongitude eastwards. + + Negative values of \a degreesLatitude and \a degreesLongitude correspond to + southward and westward translation respectively. +*/ +void QGeoCircle::translate(double degreesLatitude, double degreesLongitude) +{ + // TODO handle dlat, dlon larger than 360 degrees + + Q_D(QGeoCircle); + + double lat = d->m_center.latitude(); + double lon = d->m_center.longitude(); + + lat += degreesLatitude; + lon += degreesLongitude; + lon = QLocationUtils::wrapLong(lon); + + // TODO: remove this and simply clip latitude. + if (lat > 90.0) { + lat = 180.0 - lat; + if (lon < 0.0) + lon = 180.0; + else + lon -= 180; + } + + if (lat < -90.0) { + lat = 180.0 + lat; + if (lon < 0.0) + lon = 180.0; + else + lon -= 180; + } + + d->setCenter(QGeoCoordinate(lat, lon)); +} + +/*! + Returns a copy of this geo circle translated by \a degreesLatitude northwards and + \a degreesLongitude eastwards. + + Negative values of \a degreesLatitude and \a degreesLongitude correspond to + southward and westward translation respectively. + + \sa translate() +*/ +QGeoCircle QGeoCircle::translated(double degreesLatitude, double degreesLongitude) const +{ + QGeoCircle result(*this); + result.translate(degreesLatitude, degreesLongitude); + return result; +} + +/*! + Extends the geo circle to also cover the coordinate \a coordinate + + \since 5.9 +*/ +void QGeoCircle::extendCircle(const QGeoCoordinate &coordinate) +{ + Q_D(QGeoCircle); + d->extendCircle(coordinate); +} + +/*! + Returns the geo circle properties as a string. + + \since 5.5 +*/ + +QString QGeoCircle::toString() const +{ + if (type() != QGeoShape::CircleType) { + qWarning("Not a circle"); + return QStringLiteral("QGeoCircle(not a circle)"); + } + + return QStringLiteral("QGeoCircle({%1, %2}, %3)") + .arg(center().latitude()) + .arg(center().longitude()) + .arg(radius()); +} + +/******************************************************************************* +*******************************************************************************/ + +QGeoCirclePrivate::QGeoCirclePrivate() +: QGeoShapePrivate(QGeoShape::CircleType), m_radius(-1.0) +{ +} + +QGeoCirclePrivate::QGeoCirclePrivate(const QGeoCoordinate ¢er, qreal radius) +: QGeoShapePrivate(QGeoShape::CircleType), m_center(center), m_radius(radius) +{ + updateBoundingBox(); +} + +QGeoCirclePrivate::QGeoCirclePrivate(const QGeoCirclePrivate &other) +: QGeoShapePrivate(QGeoShape::CircleType), m_center(other.m_center), + m_radius(other.m_radius), m_bbox(other.m_bbox) +{ +} + +QGeoCirclePrivate::~QGeoCirclePrivate() {} + +QGeoShapePrivate *QGeoCirclePrivate::clone() const +{ + return new QGeoCirclePrivate(*this); +} + +bool QGeoCirclePrivate::operator==(const QGeoShapePrivate &other) const +{ + if (!QGeoShapePrivate::operator==(other)) + return false; + + const QGeoCirclePrivate &otherCircle = static_cast(other); + + return m_radius == otherCircle.m_radius && m_center == otherCircle.m_center; +} + +size_t QGeoCirclePrivate::hash(size_t seed) const +{ + return qHashMulti(seed, m_center, m_radius); +} + +QT_END_NAMESPACE + +#include "moc_qgeocircle.cpp" diff --git a/src/positioning/qgeocircle.h b/src/positioning/qgeocircle.h new file mode 100644 index 0000000..9b58932 --- /dev/null +++ b/src/positioning/qgeocircle.h @@ -0,0 +1,54 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOCIRCLE_H +#define QGEOCIRCLE_H + +#include + +QT_BEGIN_NAMESPACE + +class QGeoCoordinate; +class QGeoCirclePrivate; + +class Q_POSITIONING_EXPORT QGeoCircle : public QGeoShape +{ + Q_GADGET + Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter) + Q_PROPERTY(qreal radius READ radius WRITE setRadius) + +public: + QGeoCircle(); + QGeoCircle(const QGeoCoordinate ¢er, qreal radius = -1.0); + QGeoCircle(const QGeoCircle &other); + QGeoCircle(const QGeoShape &other); + + ~QGeoCircle(); + + QGeoCircle &operator=(const QGeoCircle &other); + + void setCenter(const QGeoCoordinate ¢er); + QGeoCoordinate center() const; + + void setRadius(qreal radius); + qreal radius() const; + + Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude); + Q_INVOKABLE QGeoCircle translated(double degreesLatitude, double degreesLongitude) const; + Q_INVOKABLE void extendCircle(const QGeoCoordinate &coordinate); + + Q_INVOKABLE QString toString() const; + +private: + inline QGeoCirclePrivate *d_func(); + inline const QGeoCirclePrivate *d_func() const; +}; + +Q_DECLARE_TYPEINFO(QGeoCircle, Q_RELOCATABLE_TYPE); + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoCircle, Q_POSITIONING_EXPORT) + +#endif + diff --git a/src/positioning/qgeocircle_p.h b/src/positioning/qgeocircle_p.h new file mode 100644 index 0000000..8ce01b0 --- /dev/null +++ b/src/positioning/qgeocircle_p.h @@ -0,0 +1,60 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOCIRCLE_P_H +#define QGEOCIRCLE_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 "qgeoshape_p.h" +#include "qgeocoordinate.h" + +QT_BEGIN_NAMESPACE + +class QGeoCirclePrivate : public QGeoShapePrivate +{ +public: + QGeoCirclePrivate(); + QGeoCirclePrivate(const QGeoCoordinate ¢er, qreal radius); + QGeoCirclePrivate(const QGeoCirclePrivate &other); + ~QGeoCirclePrivate(); + + bool isValid() const override; + bool isEmpty() const override; + bool contains(const QGeoCoordinate &coordinate) const override; + + QGeoCoordinate center() const override; + + QGeoRectangle boundingGeoRectangle() const override; + + bool crossNorthPole() const; + bool crossSouthPole() const; + void updateBoundingBox(); + void setCenter(const QGeoCoordinate &c); + void setRadius(const qreal r); + + void extendCircle(const QGeoCoordinate &coordinate); + + QGeoShapePrivate *clone() const override; + + bool operator==(const QGeoShapePrivate &other) const override; + + size_t hash(size_t seed) const override; + + QGeoCoordinate m_center; + qreal m_radius; + QGeoRectangle m_bbox; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qgeocoordinate.cpp b/src/positioning/qgeocoordinate.cpp new file mode 100644 index 0000000..02fb730 --- /dev/null +++ b/src/positioning/qgeocoordinate.cpp @@ -0,0 +1,759 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qgeocoordinate.h" +#include "qgeocoordinate_p.h" +#include "qlocationutils_p.h" + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoCoordinate) + +static const double qgeocoordinate_EARTH_MEAN_RADIUS = 6371.0072; + + +QGeoCoordinatePrivate::QGeoCoordinatePrivate(): + lat(qQNaN()), + lng(qQNaN()), + alt(qQNaN()) +{} + +QGeoCoordinatePrivate::QGeoCoordinatePrivate(const QGeoCoordinatePrivate &other) + : QSharedData(other), + lat(other.lat), + lng(other.lng), + alt(other.alt) +{} + +QGeoCoordinatePrivate::~QGeoCoordinatePrivate() +{} + + +QGeoMercatorCoordinatePrivate::QGeoMercatorCoordinatePrivate(): + QGeoCoordinatePrivate(), + m_mercatorX(qQNaN()), + m_mercatorY(qQNaN()) +{} + +QGeoMercatorCoordinatePrivate::QGeoMercatorCoordinatePrivate(const QGeoMercatorCoordinatePrivate &other) + : QGeoCoordinatePrivate(other), + m_mercatorX(other.m_mercatorX), + m_mercatorY(other.m_mercatorY) +{} + +QGeoMercatorCoordinatePrivate::~QGeoMercatorCoordinatePrivate() +{} + +/*! + \class QGeoCoordinate + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.2 + + \brief The QGeoCoordinate class defines a geographical position on the surface of the Earth. + + A QGeoCoordinate is defined by latitude, longitude, and optionally, altitude. + + Use type() to determine whether a coordinate is a 2D coordinate (has + latitude and longitude only) or 3D coordinate (has latitude, longitude + and altitude). Use distanceTo() and azimuthTo() to calculate the distance + and bearing between coordinates. + + The coordinate values should be specified using the WGS84 datum. For more information + on geographical terms see this article on \l {http://en.wikipedia.org/wiki/Geographic_coordinate_system}{coordinates} and + another on \l {http://en.wikipedia.org/wiki/Geodetic_system}{geodetic systems} + including WGS84. + + Azimuth in this context is equivalent to a compass bearing based on true north. + + This class is a \l Q_GADGET since Qt 5.5. It can be + \l{Cpp_value_integration_positioning}{directly used from C++ and QML}. +*/ + +/*! + \enum QGeoCoordinate::CoordinateType + Defines the types of a coordinate. + + \value InvalidCoordinate An invalid coordinate. A coordinate is invalid if its latitude or longitude values are invalid. + \value Coordinate2D A coordinate with valid latitude and longitude values. + \value Coordinate3D A coordinate with valid latitude and longitude values, and also an altitude value. +*/ + +/*! + \enum QGeoCoordinate::CoordinateFormat + Defines the possible formatting options for toString(). + + \value Degrees Returns a string representation of the coordinates in decimal degrees format. + \value DegreesWithHemisphere Returns a string representation of the coordinates in decimal degrees format, using 'N', 'S', 'E' or 'W' to indicate the hemispheres of the coordinates. + \value DegreesMinutes Returns a string representation of the coordinates in degrees-minutes format. + \value DegreesMinutesWithHemisphere Returns a string representation of the coordinates in degrees-minutes format, using 'N', 'S', 'E' or 'W' to indicate the hemispheres of the coordinates. + \value DegreesMinutesSeconds Returns a string representation of the coordinates in degrees-minutes-seconds format. + \value DegreesMinutesSecondsWithHemisphere Returns a string representation of the coordinates in degrees-minutes-seconds format, using 'N', 'S', 'E' or 'W' to indicate the hemispheres of the coordinates. + + \sa toString() +*/ + +/*! + \property QGeoCoordinate::latitude + \brief This property holds the latitude in decimal degrees. + + The property is undefined (\l {qQNaN()}) if the latitude has not been set. + A positive latitude indicates the Northern Hemisphere, and a negative + latitude indicates the Southern Hemisphere. When setting the latitude the + new value should be in the + \l {http://en.wikipedia.org/wiki/World_Geodetic_System}{WGS84} datum format. + + To be valid, the latitude must be between -90 to 90 inclusive. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoCoordinate::longitude + \brief This property holds the longitude in decimal degrees. + + The property is undefined (\l {qQNaN()}) if the longitude has not been set. + A positive longitude indicates the Eastern Hemisphere, and a negative + longitude indicates the Western Hemisphere. When setting the longitude the + new value should be in the + \l {http://en.wikipedia.org/wiki/World_Geodetic_System}{WGS84} datum format. + + To be valid, the longitude must be between -180 to 180 inclusive. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoCoordinate::altitude + \brief This property holds the altitude in meters above sea level. + + The property is undefined (\l {qQNaN()}) if the altitude has not been set. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoCoordinate::isValid + \brief This property holds the validity of this geo coordinate. + + The geo coordinate is valid if the \l [CPP]{longitude} and \l [CPP]{latitude} + properties have been set to valid values. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + Constructs a coordinate. The coordinate will be invalid until + setLatitude() and setLongitude() have been called. +*/ +QGeoCoordinate::QGeoCoordinate() + : d(new QGeoCoordinatePrivate) +{ +} + +/*! + Constructs a coordinate with the given \a latitude and \a longitude. + + If the latitude is not between -90 to 90 inclusive, or the longitude + is not between -180 to 180 inclusive, none of the values are set and + the type() will be QGeoCoordinate::InvalidCoordinate. + + \sa isValid() +*/ +QGeoCoordinate::QGeoCoordinate(double latitude, double longitude) + : d(new QGeoCoordinatePrivate) +{ + if (QLocationUtils::isValidLat(latitude) && QLocationUtils::isValidLong(longitude)) { + d->lat = latitude; + d->lng = longitude; + } +} + +/*! + Constructs a coordinate with the given \a latitude, \a longitude + and \a altitude. + + If the latitude is not between -90 to 90 inclusive, or the longitude + is not between -180 to 180 inclusive, none of the values are set and + the type() will be QGeoCoordinate::InvalidCoordinate. + + Note that \a altitude specifies the meters above sea level. + + \sa isValid() +*/ +QGeoCoordinate::QGeoCoordinate(double latitude, double longitude, double altitude) + : d(new QGeoCoordinatePrivate) +{ + if (QLocationUtils::isValidLat(latitude) && QLocationUtils::isValidLong(longitude)) { + d->lat = latitude; + d->lng = longitude; + d->alt = altitude; + } +} + +/*! + Constructs a coordinate from the contents of \a other. +*/ +QGeoCoordinate::QGeoCoordinate(const QGeoCoordinate &other) + : d(other.d) +{} + +/*! + \fn QGeoCoordinate::QGeoCoordinate(QGeoCoordinate &&other) + \since 6.2 + + Constructs a coordinate by moving from \a other. + + \note The moved-from QGeoCoordinate object can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + Assigns \a other to this coordinate and returns a reference to this coordinate. +*/ +QGeoCoordinate &QGeoCoordinate::operator=(const QGeoCoordinate &other) +{ + if (this == &other) + return *this; + + d = other.d; + return (*this); +} + +/*! + \fn QGeoCoordinate &QGeoCoordinate::operator=(QGeoCoordinate &&other) + \since 6.2 + + Move-assigns \a other to this coordinate and returns a reference to this + coordinate. + + \note The moved-from QGeoCoordinate object can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + Destroys the coordinate object. +*/ +QGeoCoordinate::~QGeoCoordinate() +{ +} + +QT_DEFINE_QSDP_SPECIALIZATION_DTOR(QGeoCoordinatePrivate) + +/*! + \fn bool QGeoCoordinate::operator==(const QGeoCoordinate &lhs, const QGeoCoordinate &rhs) + + Returns \c true if the latitude, longitude and altitude of the \a lhs + coordinate are the same as those of the \a rhs coordinate. Otherwise + returns \c false. + + The longitude will be ignored if the latitude is +/- 90 degrees. +*/ + +/*! + \fn bool QGeoCoordinate::operator!=(const QGeoCoordinate &lhs, const QGeoCoordinate &rhs) + + Returns \c true if latitude, longitude, or altitude of the \a lhs + coordinate are not identical to those of the \a rhs coordinate. Otherwise + returns \c false. +*/ + +/*! + Returns \c true if the \l longitude and \l latitude are valid. +*/ +bool QGeoCoordinate::isValid() const +{ + CoordinateType t = type(); + return t == Coordinate2D || t == Coordinate3D; +} + +/*! + Returns the type of this coordinate. +*/ +QGeoCoordinate::CoordinateType QGeoCoordinate::type() const +{ + if (QLocationUtils::isValidLat(d->lat) + && QLocationUtils::isValidLong(d->lng)) { + if (qIsNaN(d->alt)) + return Coordinate2D; + return Coordinate3D; + } + return InvalidCoordinate; +} + + +/*! + Returns the latitude, in decimal degrees. The return value is undefined + if the latitude has not been set. + + A positive latitude indicates the Northern Hemisphere, and a negative + latitude indicates the Southern Hemisphere. + + \sa setLatitude(), type() +*/ +double QGeoCoordinate::latitude() const +{ + return d->lat; +} + +/*! + Sets the latitude (in decimal degrees) to \a latitude. The value should + be in the WGS84 datum. + + To be valid, the latitude must be between -90 to 90 inclusive. + + \sa latitude() +*/ +void QGeoCoordinate::setLatitude(double latitude) +{ + d->lat = latitude; +} + +/*! + Returns the longitude, in decimal degrees. The return value is undefined + if the longitude has not been set. + + A positive longitude indicates the Eastern Hemisphere, and a negative + longitude indicates the Western Hemisphere. + + \sa setLongitude(), type() +*/ +double QGeoCoordinate::longitude() const +{ + return d->lng; +} + +/*! + Sets the longitude (in decimal degrees) to \a longitude. The value should + be in the WGS84 datum. + + To be valid, the longitude must be between -180 to 180 inclusive. + + \sa longitude() +*/ +void QGeoCoordinate::setLongitude(double longitude) +{ + d->lng = longitude; +} + +/*! + Returns the altitude (meters above sea level). + + The return value is undefined if the altitude has not been set. + + \sa setAltitude(), type() +*/ +double QGeoCoordinate::altitude() const +{ + return d->alt; +} + +/*! + Sets the altitude (meters above sea level) to \a altitude. + + \sa altitude() +*/ +void QGeoCoordinate::setAltitude(double altitude) +{ + d->alt = altitude; +} + +/*! + Returns the distance (in meters) from this coordinate to the coordinate + specified by \a other. Altitude is not used in the calculation. + + This calculation returns the great-circle distance between the two + coordinates, with an assumption that the Earth is spherical for the + purpose of this calculation. + + Returns 0 if the type of this coordinate or the type of \a other is + QGeoCoordinate::InvalidCoordinate. +*/ +qreal QGeoCoordinate::distanceTo(const QGeoCoordinate &other) const +{ + if (type() == QGeoCoordinate::InvalidCoordinate + || other.type() == QGeoCoordinate::InvalidCoordinate) { + return 0; + } + + // Haversine formula + double dlat = qDegreesToRadians(other.d->lat - d->lat); + double dlon = qDegreesToRadians(other.d->lng - d->lng); + double haversine_dlat = sin(dlat / 2.0); + haversine_dlat *= haversine_dlat; + double haversine_dlon = sin(dlon / 2.0); + haversine_dlon *= haversine_dlon; + double y = haversine_dlat + + cos(qDegreesToRadians(d->lat)) + * cos(qDegreesToRadians(other.d->lat)) + * haversine_dlon; + double x = 2 * asin(sqrt(y)); + return qreal(x * qgeocoordinate_EARTH_MEAN_RADIUS * 1000); +} + +/*! + Returns the azimuth (or bearing) in degrees from this coordinate to the + coordinate specified by \a other. Altitude is not used in the calculation. + + The bearing returned is the bearing from the origin to \a other along the + great-circle between the two coordinates. There is an assumption that the + Earth is spherical for the purpose of this calculation. + + Returns 0 if the type of this coordinate or the type of \a other is + QGeoCoordinate::InvalidCoordinate. +*/ +qreal QGeoCoordinate::azimuthTo(const QGeoCoordinate &other) const +{ + if (type() == QGeoCoordinate::InvalidCoordinate + || other.type() == QGeoCoordinate::InvalidCoordinate) { + return 0; + } + + double dlon = qDegreesToRadians(other.d->lng - d->lng); + double lat1Rad = qDegreesToRadians(d->lat); + double lat2Rad = qDegreesToRadians(other.d->lat); + + double y = sin(dlon) * cos(lat2Rad); + double x = cos(lat1Rad) * sin(lat2Rad) - sin(lat1Rad) * cos(lat2Rad) * cos(dlon); + + double azimuth = qRadiansToDegrees(atan2(y, x)) + 360.0; + double whole; + double fraction = modf(azimuth, &whole); + return qreal((int(whole + 360) % 360) + fraction); +} + +void QGeoCoordinatePrivate::atDistanceAndAzimuth(const QGeoCoordinate &coord, + qreal distance, qreal azimuth, + double *lon, double *lat) +{ + double latRad = qDegreesToRadians(coord.d->lat); + double lonRad = qDegreesToRadians(coord.d->lng); + double cosLatRad = cos(latRad); + double sinLatRad = sin(latRad); + + double azimuthRad = qDegreesToRadians(azimuth); + + double ratio = (distance / (qgeocoordinate_EARTH_MEAN_RADIUS * 1000.0)); + double cosRatio = cos(ratio); + double sinRatio = sin(ratio); + + double resultLatRad = asin(sinLatRad * cosRatio + + cosLatRad * sinRatio * cos(azimuthRad)); + double resultLonRad = lonRad + atan2(sin(azimuthRad) * sinRatio * cosLatRad, + cosRatio - sinLatRad * sin(resultLatRad)); + + *lat = qRadiansToDegrees(resultLatRad); + *lon = qRadiansToDegrees(resultLonRad); +} + +/*! + Returns the coordinate that is reached by traveling \a distance meters + from the current coordinate at \a azimuth (or bearing) along a great-circle. + There is an assumption that the Earth is spherical for the purpose of this + calculation. + + The altitude will have \a distanceUp added to it. + + Returns an invalid coordinate if this coordinate is invalid. +*/ +QGeoCoordinate QGeoCoordinate::atDistanceAndAzimuth(qreal distance, qreal azimuth, qreal distanceUp) const +{ + if (!isValid()) + return QGeoCoordinate(); + + double resultLon, resultLat; + QGeoCoordinatePrivate::atDistanceAndAzimuth(*this, distance, azimuth, + &resultLon, &resultLat); + double resultAlt = d->alt + distanceUp; + return QGeoCoordinate(resultLat, QLocationUtils::wrapLong(resultLon), resultAlt); +} + +/*! + Returns this coordinate as a string in the specified \a format. + + For example, if this coordinate has a latitude of -27.46758, a longitude + of 153.027892 and an altitude of 28.1, these are the strings + returned depending on \a format: + + \table + \header + \li \a format value + \li Returned string + \row + \li \l Degrees + \li -27.46758\unicode{0xB0}, 153.02789\unicode{0xB0}, 28.1m + \row + \li \l DegreesWithHemisphere + \li 27.46758\unicode{0xB0} S, 153.02789\unicode{0xB0} E, 28.1m + \row + \li \l DegreesMinutes + \li -27\unicode{0xB0} 28.054', 153\unicode{0xB0} 1.673', 28.1m + \row + \li \l DegreesMinutesWithHemisphere + \li 27\unicode{0xB0} 28.054 S', 153\unicode{0xB0} 1.673' E, 28.1m + \row + \li \l DegreesMinutesSeconds + \li -27\unicode{0xB0} 28' 3.2", 153\unicode{0xB0} 1' 40.4", 28.1m + \row + \li \l DegreesMinutesSecondsWithHemisphere + \li 27\unicode{0xB0} 28' 3.2" S, 153\unicode{0xB0} 1' 40.4" E, 28.1m + \endtable + + The altitude field is omitted if no altitude is set. + + If the coordinate is invalid, an empty string is returned. +*/ +QString QGeoCoordinate::toString(CoordinateFormat format) const +{ + if (type() == QGeoCoordinate::InvalidCoordinate) + return QString(); + + QString latStr; + QString longStr; + + double absLat = qAbs(d->lat); + double absLng = qAbs(d->lng); + QChar symbol(0x00B0); // degrees symbol + + switch (format) { + case Degrees: + case DegreesWithHemisphere: { + latStr = QString::number(absLat, 'f', 5) + symbol; + longStr = QString::number(absLng, 'f', 5) + symbol; + break; + } + case DegreesMinutes: + case DegreesMinutesWithHemisphere: { + double latMin = (absLat - int(absLat)) * 60; + double lngMin = (absLng - int(absLng)) * 60; + + // We use QString::number(val, 'f', 3) to represent minutes. + // It rounds up to the next integer in case the fraction > 0.9995. + // Such behavior should be handled specifically when the rounded + // value is 60, so that we overflow to degrees correctly. + // If we overflow, the minutes should unconditionally be 0.0. + if (latMin > 59.9995) { + absLat++; + latMin = 0.0f; + } + if (lngMin > 59.9995) { + absLng++; + lngMin = 0.0f; + } + + latStr = QString::fromLatin1("%1%2 %3'") + .arg(QString::number(int(absLat))) + .arg(symbol) + .arg(QString::number(latMin, 'f', 3)); + longStr = QString::fromLatin1("%1%2 %3'") + .arg(QString::number(int(absLng))) + .arg(symbol) + .arg(QString::number(lngMin, 'f', 3)); + break; + } + case DegreesMinutesSeconds: + case DegreesMinutesSecondsWithHemisphere: { + double latMin = (absLat - int(absLat)) * 60; + double lngMin = (absLng - int(absLng)) * 60; + double latSec = (latMin - int(latMin)) * 60; + double lngSec = (lngMin - int(lngMin)) * 60; + + // We use QString::number(val, 'f', 1) to represent seconds. + // It rounds up to the next integer in case the fraction >= 0.95. + // Such behavior should be handled specifically when the rounded + // value is 60, so that we overflow to minutes correctly. + // If we overflow, the seconds should unconditionally be 0.0. + if (latSec >= 59.95) { + latMin++; + latSec = 0.0f; + // We cast to int to represent minutes, so we can use qRound() + // to determine if we need to overflow to full degrees. + // If we overflow, the minutes will unconditionally be 0.0. + if (qRound(latMin) >= 60) { + absLat++; + latMin = 0.0f; + } + } + if (lngSec >= 59.95) { + lngMin++; + lngSec = 0.0f; + if (qRound(lngMin) >= 60) { + absLng++; + lngMin = 0.0f; + } + } + + latStr = QString::fromLatin1("%1%2 %3' %4\"") + .arg(QString::number(int(absLat))) + .arg(symbol) + .arg(QString::number(int(latMin))) + .arg(QString::number(latSec, 'f', 1)); + longStr = QString::fromLatin1("%1%2 %3' %4\"") + .arg(QString::number(int(absLng))) + .arg(symbol) + .arg(QString::number(int(lngMin))) + .arg(QString::number(lngSec, 'f', 1)); + break; + } + } + + // now add the "-" to the start, or append the hemisphere char + switch (format) { + case Degrees: + case DegreesMinutes: + case DegreesMinutesSeconds: { + if (d->lat < 0) + latStr.insert(0, QStringLiteral("-")); + if (d->lng < 0) + longStr.insert(0, QStringLiteral("-")); + break; + } + case DegreesWithHemisphere: + case DegreesMinutesWithHemisphere: + case DegreesMinutesSecondsWithHemisphere: { + if (d->lat < 0) + latStr.append(QString::fromLatin1(" S")); + else if (d->lat > 0) + latStr.append(QString::fromLatin1(" N")); + if (d->lng < 0) + longStr.append(QString::fromLatin1(" W")); + else if (d->lng > 0) + longStr.append(QString::fromLatin1(" E")); + break; + } + } + + if (qIsNaN(d->alt)) + return QString::fromLatin1("%1, %2").arg(latStr, longStr); + return QString::fromLatin1("%1, %2, %3m").arg(latStr, longStr, QString::number(d->alt)); +} + +bool QGeoCoordinate::equals(const QGeoCoordinate &lhs, const QGeoCoordinate &rhs) +{ + bool latEqual = (qIsNaN(lhs.d->lat) && qIsNaN(rhs.d->lat)) + || qFuzzyCompare(lhs.d->lat, rhs.d->lat); + bool lngEqual = (qIsNaN(lhs.d->lng) && qIsNaN(rhs.d->lng)) + || qFuzzyCompare(lhs.d->lng, rhs.d->lng); + bool altEqual = (qIsNaN(lhs.d->alt) && qIsNaN(rhs.d->alt)) + || qFuzzyCompare(lhs.d->alt, rhs.d->alt); + + if (!qIsNaN(lhs.d->lat) && ((lhs.d->lat == 90.0) || (lhs.d->lat == -90.0))) + lngEqual = true; + + return (latEqual && lngEqual && altEqual); +} + +QGeoCoordinate::QGeoCoordinate(QGeoCoordinatePrivate &dd): + d(&dd) +{ +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug QGeoCoordinate::debugStreaming(QDebug dbg, const QGeoCoordinate &coord) +{ + QDebugStateSaver saver(dbg); + double lat = coord.latitude(); + double lng = coord.longitude(); + + QTextStreamManipulator tsm = qSetRealNumberPrecision(11); + dbg << tsm; + dbg.nospace() << "QGeoCoordinate("; + if (qIsNaN(lat)) + dbg << '?'; + else + dbg << lat; + dbg << ", "; + if (qIsNaN(lng)) + dbg << '?'; + else + dbg << lng; + if (coord.type() == QGeoCoordinate::Coordinate3D) { + dbg << ", "; + dbg << coord.altitude(); + } + dbg << ')'; + return dbg; +} +#endif + +#ifndef QT_NO_DATASTREAM +/*! + \fn QDataStream &QGeoCoordinate::operator<<(QDataStream &stream, const QGeoCoordinate &coordinate) + + Writes the given \a coordinate to the specified \a stream. + + \sa {Serializing Qt Data Types} +*/ + +QDataStream &QGeoCoordinate::dataStreamOut(QDataStream &stream, const QGeoCoordinate &coordinate) +{ + stream << coordinate.latitude(); + stream << coordinate.longitude(); + stream << coordinate.altitude(); + return stream; +} +#endif + +#ifndef QT_NO_DATASTREAM +/*! + \fn QDataStream &QGeoCoordinate::operator>>(QDataStream &stream, QGeoCoordinate &coordinate) + + Reads a coordinate from the specified \a stream into the given + \a coordinate. + + \sa {Serializing Qt Data Types} +*/ + +QDataStream &QGeoCoordinate::dataStreamIn(QDataStream &stream, QGeoCoordinate &coordinate) +{ + double value; + stream >> value; + coordinate.setLatitude(value); + stream >> value; + coordinate.setLongitude(value); + stream >> value; + coordinate.setAltitude(value); + return stream; +} +#endif + +/*! \fn size_t qHash(const QGeoCoordinate &coordinate, size_t seed = 0) + \relates QHash + + Returns a hash value for \a coordinate, using \a seed to seed the calculation. +*/ +size_t qHash(const QGeoCoordinate &coordinate, size_t seed) +{ + QtPrivate::QHashCombine hash; + // north and south pole are geographically equivalent (no matter the longitude) + if (coordinate.latitude() != 90.0 && coordinate.latitude() != -90.0) + seed = hash(seed, coordinate.longitude()); + seed = hash(seed, coordinate.latitude()); + seed = hash(seed, coordinate.altitude()); + return seed; +} + +QT_END_NAMESPACE + +#include "moc_qgeocoordinate.cpp" diff --git a/src/positioning/qgeocoordinate.h b/src/positioning/qgeocoordinate.h new file mode 100644 index 0000000..8ff52bd --- /dev/null +++ b/src/positioning/qgeocoordinate.h @@ -0,0 +1,125 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOCOORDINATE_H +#define QGEOCOORDINATE_H + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QDebug; +class QDataStream; + +class QGeoCoordinatePrivate; +QT_DECLARE_QSDP_SPECIALIZATION_DTOR_WITH_EXPORT(QGeoCoordinatePrivate, Q_POSITIONING_EXPORT) + +class Q_POSITIONING_EXPORT QGeoCoordinate +{ + Q_GADGET + Q_ENUMS(CoordinateFormat) + + Q_PROPERTY(double latitude READ latitude WRITE setLatitude) + Q_PROPERTY(double longitude READ longitude WRITE setLongitude) + Q_PROPERTY(double altitude READ altitude WRITE setAltitude) + Q_PROPERTY(bool isValid READ isValid) + +public: + + enum CoordinateType { + InvalidCoordinate, + Coordinate2D, + Coordinate3D + }; + + enum CoordinateFormat { + Degrees, + DegreesWithHemisphere, + DegreesMinutes, + DegreesMinutesWithHemisphere, + DegreesMinutesSeconds, + DegreesMinutesSecondsWithHemisphere + }; + + QGeoCoordinate(); + QGeoCoordinate(double latitude, double longitude); + QGeoCoordinate(double latitude, double longitude, double altitude); + QGeoCoordinate(const QGeoCoordinate &other); + QGeoCoordinate(QGeoCoordinate &&other) noexcept = default; + ~QGeoCoordinate(); + + QGeoCoordinate &operator=(const QGeoCoordinate &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QGeoCoordinate) + + void swap(QGeoCoordinate &other) noexcept { d.swap(other.d); } + + friend bool operator==(const QGeoCoordinate &lhs, const QGeoCoordinate &rhs) + { + return equals(lhs, rhs); + } + friend bool operator!=(const QGeoCoordinate &lhs, const QGeoCoordinate &rhs) + { + return !equals(lhs, rhs); + } + + bool isValid() const; + CoordinateType type() const; + + void setLatitude(double latitude); + double latitude() const; + + void setLongitude(double longitude); + double longitude() const; + + void setAltitude(double altitude); + double altitude() const; + + Q_INVOKABLE qreal distanceTo(const QGeoCoordinate &other) const; + Q_INVOKABLE qreal azimuthTo(const QGeoCoordinate &other) const; + + Q_INVOKABLE QGeoCoordinate atDistanceAndAzimuth(qreal distance, qreal azimuth, qreal distanceUp = 0.0) const; + + Q_INVOKABLE QString toString(CoordinateFormat format = DegreesMinutesSecondsWithHemisphere) const; + +private: + static bool equals(const QGeoCoordinate &lhs, const QGeoCoordinate &rhs); + QGeoCoordinate(QGeoCoordinatePrivate &dd); + QSharedDataPointer d; + friend class QGeoCoordinatePrivate; + friend class QQuickGeoCoordinateAnimation; +#ifndef QT_NO_DEBUG_STREAM + friend QDebug operator<<(QDebug dbg, const QGeoCoordinate &coord) + { + return debugStreaming(dbg, coord); + } + static QDebug debugStreaming(QDebug dbg, const QGeoCoordinate &coord); +#endif +#ifndef QT_NO_DATASTREAM + friend QDataStream &operator<<(QDataStream &stream, const QGeoCoordinate &coordinate) + { + return dataStreamOut(stream, coordinate); + } + friend QDataStream &operator>>(QDataStream &stream, QGeoCoordinate &coordinate) + { + return dataStreamIn(stream, coordinate); + } + static QDataStream &dataStreamOut(QDataStream &stream, const QGeoCoordinate &coordinate); + static QDataStream &dataStreamIn(QDataStream &stream, QGeoCoordinate &coordinate); +#endif +}; + +Q_DECLARE_SHARED(QGeoCoordinate) + + +Q_POSITIONING_EXPORT size_t qHash(const QGeoCoordinate &coordinate, size_t seed = 0); + + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoCoordinate, Q_POSITIONING_EXPORT) + +#endif diff --git a/src/positioning/qgeocoordinate_p.h b/src/positioning/qgeocoordinate_p.h new file mode 100644 index 0000000..598c287 --- /dev/null +++ b/src/positioning/qgeocoordinate_p.h @@ -0,0 +1,60 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOCOORDINATE_P_H +#define QGEOCOORDINATE_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 +#include "qgeocoordinate.h" +#include "private/qglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QGeoCoordinatePrivate : public QSharedData +{ +public: + QGeoCoordinatePrivate(); + QGeoCoordinatePrivate(const QGeoCoordinatePrivate &other); + // The destructor needs to be virtual because we have a derived class + // QGeoMercatorCoordinatePrivate, which is used by + // QQuickGeoCoordinateAnimation to create QGeoCoordinate. + virtual ~QGeoCoordinatePrivate(); + + double lat; + double lng; + double alt; + + static void atDistanceAndAzimuth(const QGeoCoordinate &coord, + qreal distance, qreal azimuth, + double *lon, double *lat); + static const QGeoCoordinatePrivate *get(const QGeoCoordinate *c) { + return c->d.constData(); + } +}; + +class Q_POSITIONING_EXPORT QGeoMercatorCoordinatePrivate : public QGeoCoordinatePrivate +{ +public: + QGeoMercatorCoordinatePrivate(); + QGeoMercatorCoordinatePrivate(const QGeoMercatorCoordinatePrivate &other); + ~QGeoMercatorCoordinatePrivate(); + + double m_mercatorX; + double m_mercatorY; +}; + + +QT_END_NAMESPACE + +#endif // QGEOCOORDINATE_P_H diff --git a/src/positioning/qgeocoordinateobject.cpp b/src/positioning/qgeocoordinateobject.cpp new file mode 100644 index 0000000..b7560cf --- /dev/null +++ b/src/positioning/qgeocoordinateobject.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeocoordinateobject_p.h" + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN_TAGGED(QGeoCoordinateObject*, QGeoCoordinateObject_ptr) + +/* + + Note: This class only purpose is to enable conversion between QGeoCoordinate and QDeclarativeGeoWaypoint. + Since QGeoCoordinate lives in the QtPositioning module, this class acts as a base for QDeclarativeGeoWaypoint, + and contains the bare minimum to convert/compare to a QGeoCoordinate + +*/ + +QGeoCoordinateObject::QGeoCoordinateObject(QObject *parent) : QObject(parent) +{ +} + +QGeoCoordinateObject::QGeoCoordinateObject(const QGeoCoordinate &c, QObject *parent) : QObject(parent) +{ + setCoordinate(c); +} + +QGeoCoordinateObject::~QGeoCoordinateObject() +{ + +} + +bool QGeoCoordinateObject::operator==(const QGeoCoordinateObject &other) const +{ + return m_coordinate.value() == other.m_coordinate.value(); +} + +bool QGeoCoordinateObject::operator==(const QGeoCoordinate &other) const +{ + return m_coordinate.value() == other; +} + +QGeoCoordinate QGeoCoordinateObject::coordinate() const +{ + return m_coordinate; +} + +void QGeoCoordinateObject::setCoordinate(const QGeoCoordinate &c) +{ + m_coordinate = c; // The signal is emitted automatically if needed +} + +QBindable QGeoCoordinateObject::bindableCoordinate() +{ + return QBindable(&m_coordinate); +} + +QT_END_NAMESPACE + +#include "moc_qgeocoordinateobject_p.cpp" + diff --git a/src/positioning/qgeocoordinateobject_p.h b/src/positioning/qgeocoordinateobject_p.h new file mode 100644 index 0000000..e83ba63 --- /dev/null +++ b/src/positioning/qgeocoordinateobject_p.h @@ -0,0 +1,63 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOCOORDINATEOBJECT_P_H +#define QGEOCOORDINATEOBJECT_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 +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONING_PRIVATE_EXPORT QGeoCoordinateObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY + coordinateChanged BINDABLE bindableCoordinate) + +public: + QGeoCoordinateObject(QObject *parent = 0); + QGeoCoordinateObject(const QGeoCoordinate &c, QObject *parent = 0); + virtual ~QGeoCoordinateObject(); + + bool operator==(const QGeoCoordinate &other) const; + bool operator==(const QGeoCoordinateObject &other) const; + inline bool operator!=(const QGeoCoordinate &other) const { + return !operator==(other); + } + inline bool operator!=(const QGeoCoordinateObject &other) const { + return !operator==(other); + } + + QGeoCoordinate coordinate() const; + void setCoordinate(const QGeoCoordinate &c); + QBindable bindableCoordinate(); + +Q_SIGNALS: + void coordinateChanged(); + +protected: + Q_OBJECT_BINDABLE_PROPERTY(QGeoCoordinateObject, QGeoCoordinate, m_coordinate, + &QGeoCoordinateObject::coordinateChanged) +}; + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN_TAGGED(QGeoCoordinateObject*, QGeoCoordinateObject_ptr, + Q_POSITIONING_PRIVATE_EXPORT) + +#endif // QGEOCOORDINATEOBJECT_P_H diff --git a/src/positioning/qgeolocation.cpp b/src/positioning/qgeolocation.cpp new file mode 100644 index 0000000..feab088 --- /dev/null +++ b/src/positioning/qgeolocation.cpp @@ -0,0 +1,248 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeolocation.h" +#include "qgeolocation_p.h" + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoLocation) + +QGeoLocationPrivate::QGeoLocationPrivate() + : QSharedData() +{ +} + +QGeoLocationPrivate::QGeoLocationPrivate(const QGeoLocationPrivate &other) + : QSharedData() +{ + this->address = other.address; + this->coordinate = other.coordinate; + this->viewport = other.viewport; + this->extendedAttributes = other.extendedAttributes; +} + +QGeoLocationPrivate::~QGeoLocationPrivate() +{ +} + +bool QGeoLocationPrivate::operator==(const QGeoLocationPrivate &other) const +{ + return (this->address == other.address + && this->coordinate == other.coordinate + && this->viewport == other.viewport + && this->extendedAttributes == other.extendedAttributes); + +} + +bool QGeoLocationPrivate::isEmpty() const +{ + return (address.isEmpty() + && !coordinate.isValid() + && viewport.isEmpty() + && extendedAttributes.isEmpty()); +} + +/*! + \class QGeoLocation + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \ingroup QtLocation-places + \ingroup QtLocation-places-data + \since 5.2 + + \brief The QGeoLocation class represents basic information about a location. + + A QGeoLocation consists of a coordinate and corresponding address, along with an optional + bounding shape, which is the recommended region to be displayed when viewing the location. +*/ + +/*! + Constructs an new location object. +*/ +QGeoLocation::QGeoLocation() + : d(new QGeoLocationPrivate) +{ +} + +/*! + Constructs a copy of \a other +*/ +QGeoLocation::QGeoLocation(const QGeoLocation &other) + :d(other.d) +{ +} + +/*! + \fn QGeoLocation::QGeoLocation(QGeoLocation &&other) + \since 6.2 + + Constructs a geo location object by moving from \a other. + + \note The moved-from QGeoLocation object can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + Destroys the location object. +*/ +QGeoLocation::~QGeoLocation() +{ +} + +QT_DEFINE_QSDP_SPECIALIZATION_DTOR(QGeoLocationPrivate) + +/*! + Assigns \a other to this location and returns a reference to this location. +*/ +QGeoLocation &QGeoLocation::operator =(const QGeoLocation &other) +{ + if (this == &other) + return *this; + + d = other.d; + return *this; +} + +/*! + \fn QGeoLocation &QGeoLocation::operator=(QGeoLocation &&other) + \since 6.2 + + Move-assings \a other to this location and returns a reference to this + location. + + \note The moved-from QGeoLocation object can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + \fn bool QGeoLocation::operator==(const QGeoLocation &lhs, const QGeoLocation &rhs) + + Returns \c true if the \a lhs location is equal to \a rhs, otherwise + returns \c false. +*/ + +/*! + \fn bool QGeoLocation::operator!=(const QGeoLocation &lhs, const QGeoLocation &rhs) + + Returns \c true if the \a lhs location is not equal to \a rhs, otherwise + returns \c false. +*/ + +/*! + Returns the address of the location. +*/ +QGeoAddress QGeoLocation::address() const +{ + return d->address; +} + +/*! + Sets the \a address of the location. +*/ +void QGeoLocation::setAddress(const QGeoAddress &address) +{ + d->address = address; +} + +/*! + Returns the coordinate of the location. +*/ +QGeoCoordinate QGeoLocation::coordinate() const +{ + return d->coordinate; +} + +/*! + Sets the \a coordinate of the location. +*/ +void QGeoLocation::setCoordinate(const QGeoCoordinate &coordinate) +{ + d->coordinate = coordinate; +} + +/*! + \since 6.2 + + Returns a bounding shape which represents the recommended region + to display when viewing this location. + + For example, a building's location may have a region centered around the + building, but the region is large enough to show it's immediate surrounding + geographical context. + + \note This method was introduced in Qt6 instead of boundingBox() method. + It returns a QGeoShape instead of a QGeoRectangle. + Use \l QGeoShape::boundingGeoRectangle() to obtain a bounding QGeoRectangle + for the shape. +*/ +QGeoShape QGeoLocation::boundingShape() const +{ + return d->viewport; +} + +/*! + \since 6.2 + + Sets the \a boundingShape of the location. +*/ +void QGeoLocation::setBoundingShape(const QGeoShape &boundingShape) +{ + d->viewport = boundingShape; +} + +/*! + Returns the extended attributes associated to this location. + Extended attributes are backend-dependent and can be location-dependent. + + \since 5.13 +*/ +QVariantMap QGeoLocation::extendedAttributes() const +{ + return d->extendedAttributes; +} + +/*! + Sets the extended attributes of the location with the + parameters specified in \a data. + + \since 5.13 +*/ +void QGeoLocation::setExtendedAttributes(const QVariantMap &data) +{ + d->extendedAttributes = data; +} + +/*! + Returns \c true if the location coordinate is \l {QGeoCoordinate::isValid} + {invalid}, and all the other location fields are empty. Otherwise returns + \c false. +*/ +bool QGeoLocation::isEmpty() const +{ + return d->isEmpty(); +} + +bool QGeoLocation::equals(const QGeoLocation &lhs, const QGeoLocation &rhs) +{ + return (*(lhs.d.constData()) == *(rhs.d.constData())); +} + +/*! + \relates QGeoLocation + + Returns the hash value for the \a location, using \a seed for the + calculation. + + \note The hash does not take extended attributes into account. This means + that two geo location objects that differ only in the extended attributes + will provide similar hashes. +*/ +size_t qHash(const QGeoLocation &location, size_t seed) noexcept +{ + return qHashMulti(seed, location.coordinate(), location.boundingShape(), location.address()); +} + +QT_END_NAMESPACE diff --git a/src/positioning/qgeolocation.h b/src/positioning/qgeolocation.h new file mode 100644 index 0000000..2f08d60 --- /dev/null +++ b/src/positioning/qgeolocation.h @@ -0,0 +1,65 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOLOCATION_H +#define QGEOLOCATION_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoAddress; +class QGeoCoordinate; +class QGeoShape; +class QGeoLocationPrivate; +QT_DECLARE_QSDP_SPECIALIZATION_DTOR_WITH_EXPORT(QGeoLocationPrivate, Q_POSITIONING_EXPORT) + +class Q_POSITIONING_EXPORT QGeoLocation +{ +public: + QGeoLocation(); + QGeoLocation(const QGeoLocation &other); + QGeoLocation(QGeoLocation &&other) noexcept = default; + ~QGeoLocation(); + + QGeoLocation &operator=(const QGeoLocation &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QGeoLocation) + + void swap(QGeoLocation &other) noexcept { d.swap(other.d); } + + friend bool operator==(const QGeoLocation &lhs, const QGeoLocation &rhs) + { + return equals(lhs, rhs); + } + friend bool operator!=(const QGeoLocation &lhs, const QGeoLocation &rhs) + { + return !equals(lhs, rhs); + } + + QGeoAddress address() const; + void setAddress(const QGeoAddress &address); + QGeoCoordinate coordinate() const; + void setCoordinate(const QGeoCoordinate &position); + QGeoShape boundingShape() const; + void setBoundingShape(const QGeoShape &shape); + QVariantMap extendedAttributes() const; + void setExtendedAttributes(const QVariantMap &data); + + bool isEmpty() const; + +private: + static bool equals(const QGeoLocation &lhs, const QGeoLocation &rhs); + QSharedDataPointer d; +}; + +Q_POSITIONING_EXPORT size_t qHash(const QGeoLocation &location, size_t seed = 0) noexcept; + +Q_DECLARE_SHARED(QGeoLocation) + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoLocation, Q_POSITIONING_EXPORT) + +#endif diff --git a/src/positioning/qgeolocation_p.h b/src/positioning/qgeolocation_p.h new file mode 100644 index 0000000..4e3aa92 --- /dev/null +++ b/src/positioning/qgeolocation_p.h @@ -0,0 +1,47 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOLOCATION_P_H +#define QGEOLOCATION_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 +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoLocationPrivate : public QSharedData +{ +public: + QGeoLocationPrivate(); + QGeoLocationPrivate(const QGeoLocationPrivate &other); + + ~QGeoLocationPrivate(); + + bool operator==(const QGeoLocationPrivate &other) const; + + bool isEmpty() const; + + QGeoAddress address; + QGeoCoordinate coordinate; + QGeoShape viewport; + QVariantMap extendedAttributes; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qgeopath.cpp b/src/positioning/qgeopath.cpp new file mode 100644 index 0000000..f758335 --- /dev/null +++ b/src/positioning/qgeopath.cpp @@ -0,0 +1,742 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopath.h" +#include "qgeopolygon.h" +#include "qgeopath_p.h" + +#include "qgeocoordinate.h" +#include "qnumeric.h" +#include "qlocationutils_p.h" +#include "qwebmercator_p.h" + +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoPath) + +constexpr int kMaxInt = std::numeric_limits::max(); +constexpr auto kWarningString = u"The path has more elements than fit into an int. " + "This can cause errors while querying elements from QML"; + +/*! + \class QGeoPath + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.9 + + \brief The QGeoPath class defines a geographic path. + + The path is defined by an ordered list of \l QGeoCoordinate objects. + + Each two adjacent elements in the path are intended to be connected + together by the shortest line segment of constant bearing passing + through both elements. + This type of connection can cross the dateline in the longitudinal direction, + but never crosses the poles. + + This is relevant for the calculation of the bounding box returned by + \l QGeoShape::boundingGeoRectangle() for this shape, which will have the latitude of + the top left corner set to the maximum latitude in the path point set. + Similarly, the latitude of the bottom right corner will be the minimum latitude + in the path point set. + + This class is a \l Q_GADGET. + It can be \l{Cpp_value_integration_positioning}{directly used from C++ and QML}. + + A QGeoPath is both invalid and empty if it contains no coordinate. + + \note A default constructed QGeoPath is both invalid and empty as it does not contain any coordinates. +*/ + +/*! + \property QGeoPath::path + \brief This property holds the list of coordinates for the geo path. + + \note The coordinates cannot be processed in place. To change the value + of this property, retrieve the complete list of coordinates, process them, + and assign the new value to the property. +*/ + +inline QGeoPathPrivate *QGeoPath::d_func() +{ + return static_cast(d_ptr.data()); +} + +inline const QGeoPathPrivate *QGeoPath::d_func() const +{ + return static_cast(d_ptr.constData()); +} + +struct PathVariantConversions +{ + PathVariantConversions() + { + QMetaType::registerConverter(); + QMetaType::registerConverter(); + } +}; + +Q_GLOBAL_STATIC(PathVariantConversions, initPathConversions) + +/*! + Constructs a new, empty geo path. +*/ +QGeoPath::QGeoPath() +: QGeoShape(new QGeoPathPrivate()) +{ + initPathConversions(); +} + +/*! + Constructs a new geo path from a list of coordinates + (\a path and \a width). +*/ +QGeoPath::QGeoPath(const QList &path, const qreal &width) +: QGeoShape(new QGeoPathPrivate(path, width)) +{ + initPathConversions(); +} + +/*! + Constructs a new geo path from the contents of \a other. +*/ +QGeoPath::QGeoPath(const QGeoPath &other) +: QGeoShape(other) +{ + initPathConversions(); +} + +/*! + Constructs a new geo path from the contents of \a other. +*/ +QGeoPath::QGeoPath(const QGeoShape &other) +: QGeoShape(other) +{ + initPathConversions(); + if (type() != QGeoShape::PathType) + d_ptr = new QGeoPathPrivate(); +} + +/*! + Destroys this path. +*/ +QGeoPath::~QGeoPath() {} + +/*! + Assigns \a other to this geo path and returns a reference to this geo path. +*/ +QGeoPath &QGeoPath::operator=(const QGeoPath &other) +{ + QGeoShape::operator=(other); + return *this; +} + +/*! + Sets all the elements of the \a path. +*/ +void QGeoPath::setPath(const QList &path) +{ + Q_D(QGeoPath); + return d->setPath(path); +} + +/*! + Returns all the elements of the path. +*/ +const QList &QGeoPath::path() const +{ + Q_D(const QGeoPath); + return d->path(); +} + +/*! + Clears the path. + + \since 5.12 +*/ +void QGeoPath::clearPath() +{ + Q_D(QGeoPath); + d->clearPath(); +} + +/*! + Sets all the elements of the path. + + \internal +*/ +void QGeoPath::setVariantPath(const QVariantList &path) +{ + Q_D(QGeoPath); + QList p; + for (const auto &c: path) { + if (c.canConvert()) + p << c.value(); + } + d->setPath(p); +} +/*! + Returns all the elements of the path. + + \internal +*/ +QVariantList QGeoPath::variantPath() const +{ + Q_D(const QGeoPath); + QVariantList p; + for (const auto &c: d->path()) + p << QVariant::fromValue(c); + return p; +} + + +/*! + \property QGeoPath::width + + \brief the width of the path in meters. +*/ +void QGeoPath::setWidth(const qreal &width) +{ + Q_D(QGeoPath); + d->setWidth(width); +} + +/*! + Returns the width of the path, in meters. This information is used in the \l contains method. + The default value is 0. +*/ +qreal QGeoPath::width() const +{ + Q_D(const QGeoPath); + return d->width(); +} + +/*! + Translates this geo path by \a degreesLatitude northwards and \a degreesLongitude eastwards. + + Negative values of \a degreesLatitude and \a degreesLongitude correspond to + southward and westward translation respectively. +*/ +void QGeoPath::translate(double degreesLatitude, double degreesLongitude) +{ + Q_D(QGeoPath); + d->translate(degreesLatitude, degreesLongitude); +} + +/*! + Returns a copy of this geo path translated by \a degreesLatitude northwards and + \a degreesLongitude eastwards. + + Negative values of \a degreesLatitude and \a degreesLongitude correspond to + southward and westward translation respectively. + + \sa translate() +*/ +QGeoPath QGeoPath::translated(double degreesLatitude, double degreesLongitude) const +{ + QGeoPath result(*this); + result.translate(degreesLatitude, degreesLongitude); + return result; +} + +/*! + Returns the length of the path, in meters, from the element \a indexFrom to the element \a indexTo. + The length is intended to be the sum of the shortest distances for each pair of adjacent points. + + If \a indexTo is -1 (the default value), the length will be including the distance between last coordinate + and the first (closed loop). + To retrieve the length for the path, use 0 for \a indexFrom and \l QGeoPath::size() - 1 for \a indexTo. +*/ +double QGeoPath::length(qsizetype indexFrom, qsizetype indexTo) const +{ + Q_D(const QGeoPath); + return d->length(indexFrom, indexTo); +} + +/*! + Returns the number of elements in the path. + + \since 5.10 +*/ +qsizetype QGeoPath::size() const +{ + Q_D(const QGeoPath); + const qsizetype result = d->size(); + if (result > kMaxInt) + qWarning() << kWarningString; + return result; +} + +/*! + Appends \a coordinate to the path. +*/ +void QGeoPath::addCoordinate(const QGeoCoordinate &coordinate) +{ + Q_D(QGeoPath); + d->addCoordinate(coordinate); + if (d->size() > kMaxInt) + qWarning() << kWarningString; +} + +/*! + Inserts \a coordinate at the specified \a index. +*/ +void QGeoPath::insertCoordinate(qsizetype index, const QGeoCoordinate &coordinate) +{ + Q_D(QGeoPath); + d->insertCoordinate(index, coordinate); +} + +/*! + Replaces the path element at the specified \a index with \a coordinate. +*/ +void QGeoPath::replaceCoordinate(qsizetype index, const QGeoCoordinate &coordinate) +{ + Q_D(QGeoPath); + d->replaceCoordinate(index, coordinate); +} + +/*! + Returns the coordinate at \a index . +*/ +QGeoCoordinate QGeoPath::coordinateAt(qsizetype index) const +{ + Q_D(const QGeoPath); + return d->coordinateAt(index); +} + +/*! + Returns true if the path contains \a coordinate as one of the elements. +*/ +bool QGeoPath::containsCoordinate(const QGeoCoordinate &coordinate) const +{ + Q_D(const QGeoPath); + return d->containsCoordinate(coordinate); +} + +/*! + Removes the last occurrence of \a coordinate from the path. +*/ +void QGeoPath::removeCoordinate(const QGeoCoordinate &coordinate) +{ + Q_D(QGeoPath); + d->removeCoordinate(coordinate); +} + +/*! + Removes element at position \a index from the path. +*/ +void QGeoPath::removeCoordinate(qsizetype index) +{ + Q_D(QGeoPath); + d->removeCoordinate(index); +} + +/*! + Returns the geo path properties as a string. +*/ +QString QGeoPath::toString() const +{ + if (type() != QGeoShape::PathType) { + qWarning("Not a path"); + return QStringLiteral("QGeoPath(not a path)"); + } + + QString pathString; + for (const auto &p : path()) + pathString += p.toString() + QLatin1Char(','); + + return QStringLiteral("QGeoPath([ %1 ])").arg(pathString); +} + +/******************************************************************************* + * + * QGeoPathPrivate & friends + * +*******************************************************************************/ + +QGeoPathPrivate::QGeoPathPrivate() +: QGeoShapePrivate(QGeoShape::PathType) +{ + +} + +QGeoPathPrivate::QGeoPathPrivate(const QList &path, const qreal width) +: QGeoShapePrivate(QGeoShape::PathType) +{ + setPath(path); + setWidth(width); +} + +QGeoPathPrivate::~QGeoPathPrivate() +{ + +} + +QGeoShapePrivate *QGeoPathPrivate::clone() const +{ + return new QGeoPathPrivate(*this); +} + +bool QGeoPathPrivate::isValid() const +{ + return !isEmpty(); +} + +bool QGeoPathPrivate::isEmpty() const +{ + return path().isEmpty(); // this should perhaps return geometric emptiness, less than 2 points for line, or empty polygon for polygons +} + +QGeoCoordinate QGeoPathPrivate::center() const +{ + return boundingGeoRectangle().center(); +} + +bool QGeoPathPrivate::operator==(const QGeoShapePrivate &other) const +{ + if (!QGeoShapePrivate::operator==(other)) + return false; + + const QGeoPathPrivate &otherPath = static_cast(other); + if (m_path.size() != otherPath.m_path.size()) + return false; + return m_width == otherPath.m_width && m_path == otherPath.m_path; +} + +const QList &QGeoPathPrivate::path() const +{ + return m_path; +} + +bool QGeoPathPrivate::lineContains(const QGeoCoordinate &coordinate) const +{ + // Unoptimized approach: + // - consider each segment of the path + // - project it into mercator space (rhumb lines are straight in mercator space) + // - find closest point to coordinate + // - unproject the closest point + // - calculate coordinate to closest point distance with distanceTo() + // - if not within lineRadius, advance + // + // To keep wrapping into the equation: + // If the mercator x value of a coordinate of the line, or the coordinate parameter, is less + // than mercator(m_bbox).x, add that to the conversion. + + if (m_bboxDirty) + const_cast(*this).computeBoundingBox(); + + double lineRadius = qMax(width() * 0.5, 0.2); // minimum radius: 20cm + + if (m_path.isEmpty()) + return false; + else if (m_path.size() == 1) + return (m_path[0].distanceTo(coordinate) <= lineRadius); + + QDoubleVector2D p = QWebMercator::coordToMercator(coordinate); + if (p.x() < m_leftBoundWrapped) + p.setX(p.x() + m_leftBoundWrapped); // unwrap X + + QDoubleVector2D a; + QDoubleVector2D b; + if (!m_path.isEmpty()) { + a = QWebMercator::coordToMercator(m_path[0]); + if (a.x() < m_leftBoundWrapped) + a.setX(a.x() + m_leftBoundWrapped); // unwrap X + } + for (qsizetype i = 1; i < m_path.size(); i++) { + b = QWebMercator::coordToMercator(m_path[i]); + if (b.x() < m_leftBoundWrapped) + b.setX(b.x() + m_leftBoundWrapped); // unwrap X + if (b == a) + continue; + + double u = ((p.x() - a.x()) * (b.x() - a.x()) + (p.y() - a.y()) * (b.y() - a.y()) ) / (b - a).lengthSquared(); + QDoubleVector2D intersection(a.x() + u * (b.x() - a.x()) , a.y() + u * (b.y() - a.y()) ); + + QDoubleVector2D candidate = ( (p-a).length() < (p-b).length() ) ? a : b; + + if (u > 0 && u < 1 + && (p-intersection).length() < (p-candidate).length() ) // And it falls in the segment + candidate = intersection; + + + if (candidate.x() > 1.0) + candidate.setX(candidate.x() - m_leftBoundWrapped); // wrap X + + QGeoCoordinate closest = QWebMercator::mercatorToCoord(candidate); + + double distanceMeters = coordinate.distanceTo(closest); + if (distanceMeters <= lineRadius) + return true; + + // swap + a = b; + } + + // Last check if the coordinate is on the left of leftBoundMercator, but close enough to + // m_path[0] + return (m_path[0].distanceTo(coordinate) <= lineRadius); +} + +bool QGeoPathPrivate::contains(const QGeoCoordinate &coordinate) const +{ + return lineContains(coordinate); +} + +qreal QGeoPathPrivate::width() const +{ + return m_width; +} + +void QGeoPathPrivate::setWidth(const qreal &width) +{ + if (qIsNaN(width) || width < 0.0) + return; + m_width = width; +} + +double QGeoPathPrivate::length(qsizetype indexFrom, qsizetype indexTo) const +{ + if (path().isEmpty()) + return 0.0; + + bool wrap = indexTo == -1; + if (indexTo < 0 || indexTo >= path().size()) + indexTo = path().size() - 1; + double len = 0.0; + // TODO: consider calculating the length of the actual rhumb line segments + // instead of the shortest path from A to B. + for (qsizetype i = indexFrom; i < indexTo; i++) + len += m_path[i].distanceTo(m_path[i+1]); + if (wrap) + len += m_path.last().distanceTo(m_path.first()); + return len; +} + +qsizetype QGeoPathPrivate::size() const +{ + return m_path.size(); +} + +QGeoCoordinate QGeoPathPrivate::coordinateAt(qsizetype index) const +{ + if (index < 0 || index >= m_path.size()) + return QGeoCoordinate(); + + return m_path.at(index); +} + +bool QGeoPathPrivate::containsCoordinate(const QGeoCoordinate &coordinate) const +{ + return m_path.indexOf(coordinate) > -1; +} + +void QGeoPathPrivate::translate(double degreesLatitude, double degreesLongitude) +{ + // Need min/maxLati, so update bbox + QList m_deltaXs; + double m_minX, m_maxX, m_minLati, m_maxLati; + m_bboxDirty = false; + computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); + + if (degreesLatitude > 0.0) + degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati); + else + degreesLatitude = qMax(degreesLatitude, -90.0 - m_minLati); + for (QGeoCoordinate &p: m_path) { + p.setLatitude(p.latitude() + degreesLatitude); + p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude)); + } + m_bbox.translate(degreesLatitude, degreesLongitude); + m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x(); +} + +QGeoRectangle QGeoPathPrivate::boundingGeoRectangle() const +{ + if (m_bboxDirty) + const_cast(*this).computeBoundingBox(); + return m_bbox; +} + +size_t QGeoPathPrivate::hash(size_t seed) const +{ + const size_t res = qHashRange(m_path.cbegin(), m_path.cend(), seed); + return qHashMulti(seed, res, m_width); +} + +void QGeoPathPrivate::setPath(const QList &path) +{ + for (const QGeoCoordinate &c: path) + if (!c.isValid()) + return; + m_path = path; + markDirty(); +} + +void QGeoPathPrivate::clearPath() +{ + m_path.clear(); + markDirty(); +} + +void QGeoPathPrivate::addCoordinate(const QGeoCoordinate &coordinate) +{ + if (!coordinate.isValid()) + return; + m_path.append(coordinate); + markDirty(); +} + +void QGeoPathPrivate::insertCoordinate(qsizetype index, const QGeoCoordinate &coordinate) +{ + if (index < 0 || index > m_path.size() || !coordinate.isValid()) + return; + m_path.insert(index, coordinate); + markDirty(); +} + +void QGeoPathPrivate::replaceCoordinate(qsizetype index, const QGeoCoordinate &coordinate) +{ + if (index < 0 || index >= m_path.size() || !coordinate.isValid()) + return; + m_path[index] = coordinate; + markDirty(); +} + +void QGeoPathPrivate::removeCoordinate(const QGeoCoordinate &coordinate) +{ + qsizetype index = m_path.lastIndexOf(coordinate); + removeCoordinate(index); +} + +void QGeoPathPrivate::removeCoordinate(qsizetype index) +{ + if (index < 0 || index >= m_path.size()) + return; + m_path.removeAt(index); + markDirty(); +} + +void QGeoPathPrivate::markDirty() +{ + m_bboxDirty = true; +} + +void QGeoPathPrivate::computeBoundingBox() +{ + QList m_deltaXs; + double m_minX, m_maxX, m_minLati, m_maxLati; + m_bboxDirty = false; + computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); + m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x(); +} + +QGeoPathPrivateEager::QGeoPathPrivateEager() +: QGeoPathPrivate() +{ + m_bboxDirty = false; // never dirty on the eager version +} + +QGeoPathPrivateEager::QGeoPathPrivateEager(const QList &path, const qreal width) +: QGeoPathPrivate(path, width) +{ + m_bboxDirty = false; // never dirty on the eager version +} + +QGeoPathPrivateEager::~QGeoPathPrivateEager() +{ + +} + +QGeoShapePrivate *QGeoPathPrivateEager::clone() const +{ + return new QGeoPathPrivateEager(*this); +} + +void QGeoPathPrivateEager::markDirty() +{ + computeBoundingBox(); +} + +void QGeoPathPrivateEager::translate(double degreesLatitude, double degreesLongitude) +{ + if (degreesLatitude > 0.0) + degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati); + else + degreesLatitude = qMax(degreesLatitude, -90.0 - m_minLati); + for (QGeoCoordinate &p: m_path) { + p.setLatitude(p.latitude() + degreesLatitude); + p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude)); + } + m_bbox.translate(degreesLatitude, degreesLongitude); + m_minLati += degreesLatitude; + m_maxLati += degreesLatitude; + m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x(); +} + +void QGeoPathPrivateEager::addCoordinate(const QGeoCoordinate &coordinate) +{ + if (!coordinate.isValid()) + return; + m_path.append(coordinate); + //m_clipperDirty = true; // clipper not used in polylines + updateBoundingBox(); +} + +void QGeoPathPrivateEager::QGeoPathPrivateEager::computeBoundingBox() +{ + computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); + m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x(); +} + +void QGeoPathPrivateEager::QGeoPathPrivateEager::updateBoundingBox() +{ + updateBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); + m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x(); +} + +QGeoPathEager::QGeoPathEager() : QGeoPath() +{ + initPathConversions(); + d_ptr = new QGeoPathPrivateEager; +} + +QGeoPathEager::QGeoPathEager(const QList &path, const qreal &width) : QGeoPath() +{ + initPathConversions(); + d_ptr = new QGeoPathPrivateEager(path, width); +} + +QGeoPathEager::QGeoPathEager(const QGeoPath &other) : QGeoPath() +{ + initPathConversions(); + d_ptr = new QGeoPathPrivateEager; + setPath(other.path()); + setWidth(other.width()); +} + +QGeoPathEager::QGeoPathEager(const QGeoShape &other) : QGeoPath() +{ + initPathConversions(); + if (other.type() == QGeoShape::PathType) + *this = QGeoPathEager(QGeoPath(other)); + else + d_ptr = new QGeoPathPrivateEager; +} + +QGeoPathEager::~QGeoPathEager() {} + +QT_END_NAMESPACE + +#include "moc_qgeopath_p.cpp" +#include "moc_qgeopath.cpp" + + + + + + + diff --git a/src/positioning/qgeopath.h b/src/positioning/qgeopath.h new file mode 100644 index 0000000..462b099 --- /dev/null +++ b/src/positioning/qgeopath.h @@ -0,0 +1,65 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPATH_H +#define QGEOPATH_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoCoordinate; +class QGeoPathPrivate; + +class Q_POSITIONING_EXPORT QGeoPath : public QGeoShape +{ + Q_GADGET + Q_PROPERTY(QVariantList path READ variantPath WRITE setVariantPath) + Q_PROPERTY(qreal width READ width WRITE setWidth) + +public: + QGeoPath(); + QGeoPath(const QList &path, const qreal &width = 0.0); + QGeoPath(const QGeoPath &other); + QGeoPath(const QGeoShape &other); + + ~QGeoPath(); + + QGeoPath &operator=(const QGeoPath &other); + + void setPath(const QList &path); + const QList &path() const; + void clearPath(); + void setVariantPath(const QVariantList &path); + QVariantList variantPath() const; + + void setWidth(const qreal &width); + qreal width() const; + + Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude); + Q_INVOKABLE QGeoPath translated(double degreesLatitude, double degreesLongitude) const; + Q_INVOKABLE double length(qsizetype indexFrom = 0, qsizetype indexTo = -1) const; + Q_INVOKABLE qsizetype size() const; + Q_INVOKABLE void addCoordinate(const QGeoCoordinate &coordinate); + Q_INVOKABLE void insertCoordinate(qsizetype index, const QGeoCoordinate &coordinate); + Q_INVOKABLE void replaceCoordinate(qsizetype index, const QGeoCoordinate &coordinate); + Q_INVOKABLE QGeoCoordinate coordinateAt(qsizetype index) const; + Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate &coordinate) const; + Q_INVOKABLE void removeCoordinate(const QGeoCoordinate &coordinate); + Q_INVOKABLE void removeCoordinate(qsizetype index); + + Q_INVOKABLE QString toString() const; + +private: + inline QGeoPathPrivate *d_func(); + inline const QGeoPathPrivate *d_func() const; +}; + +Q_DECLARE_TYPEINFO(QGeoPath, Q_RELOCATABLE_TYPE); + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoPath, Q_POSITIONING_EXPORT) + +#endif // QGEOPATH_H diff --git a/src/positioning/qgeopath_p.h b/src/positioning/qgeopath_p.h new file mode 100644 index 0000000..a492a9f --- /dev/null +++ b/src/positioning/qgeopath_p.h @@ -0,0 +1,224 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPATH_P_H +#define QGEOPATH_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 +#include "qgeoshape_p.h" +#include "qgeocoordinate.h" +#include "qlocationutils_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +inline static void computeBBox(const QList &m_path, QList &m_deltaXs, + double &m_minX, double &m_maxX, double &m_minLati, double &m_maxLati, + QGeoRectangle &m_bbox) +{ + if (m_path.isEmpty()) { + m_deltaXs.clear(); + m_minX = qInf(); + m_maxX = -qInf(); + m_minLati = qInf(); + m_maxLati = -qInf(); + m_bbox = QGeoRectangle(); + return; + } + + m_minLati = m_maxLati = m_path.at(0).latitude(); + qsizetype minId = 0; + qsizetype maxId = 0; + m_deltaXs.resize(m_path.size()); + m_deltaXs[0] = m_minX = m_maxX = 0.0; + + for (qsizetype i = 1; i < m_path.size(); i++) { + const QGeoCoordinate &geoFrom = m_path.at(i-1); + const QGeoCoordinate &geoTo = m_path.at(i); + double longiFrom = geoFrom.longitude(); + double longiTo = geoTo.longitude(); + double deltaLongi = longiTo - longiFrom; + if (qAbs(deltaLongi) > 180.0) { + if (longiTo > 0.0) + longiTo -= 360.0; + else + longiTo += 360.0; + deltaLongi = longiTo - longiFrom; + } + m_deltaXs[i] = m_deltaXs[i-1] + deltaLongi; + if (m_deltaXs[i] < m_minX) { + m_minX = m_deltaXs[i]; + minId = i; + } + if (m_deltaXs[i] > m_maxX) { + m_maxX = m_deltaXs[i]; + maxId = i; + } + if (geoTo.latitude() > m_maxLati) + m_maxLati = geoTo.latitude(); + if (geoTo.latitude() < m_minLati) + m_minLati = geoTo.latitude(); + } + + m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(minId).longitude()), + QGeoCoordinate(m_minLati, m_path.at(maxId).longitude())); +} + +inline static void updateBBox(const QList &m_path, QList &m_deltaXs, + double &m_minX, double &m_maxX, double &m_minLati, double &m_maxLati, + QGeoRectangle &m_bbox) +{ + if (m_path.isEmpty()) { + m_deltaXs.clear(); + m_minX = qInf(); + m_maxX = -qInf(); + m_minLati = qInf(); + m_maxLati = -qInf(); + m_bbox = QGeoRectangle(); + return; + } else if (m_path.size() == 1) { // was 0 now is 1 + m_deltaXs.resize(1); + m_deltaXs[0] = m_minX = m_maxX = 0.0; + m_minLati = m_maxLati = m_path.at(0).latitude(); + m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(0).longitude()), + QGeoCoordinate(m_minLati, m_path.at(0).longitude())); + return; + } else if ( m_path.size() != m_deltaXs.size() + 1 ) { // this case should not happen + computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); // something went wrong + return; + } + + const QGeoCoordinate &geoFrom = m_path.at(m_path.size()-2); + const QGeoCoordinate &geoTo = m_path.last(); + double longiFrom = geoFrom.longitude(); + double longiTo = geoTo.longitude(); + double deltaLongi = longiTo - longiFrom; + if (qAbs(deltaLongi) > 180.0) { + if (longiTo > 0.0) + longiTo -= 360.0; + else + longiTo += 360.0; + deltaLongi = longiTo - longiFrom; + } + + m_deltaXs.push_back(m_deltaXs.last() + deltaLongi); + double currentMinLongi = m_bbox.topLeft().longitude(); + double currentMaxLongi = m_bbox.bottomRight().longitude(); + if (m_deltaXs.last() < m_minX) { + m_minX = m_deltaXs.last(); + currentMinLongi = geoTo.longitude(); + } + if (m_deltaXs.last() > m_maxX) { + m_maxX = m_deltaXs.last(); + currentMaxLongi = geoTo.longitude(); + } + if (geoTo.latitude() > m_maxLati) + m_maxLati = geoTo.latitude(); + if (geoTo.latitude() < m_minLati) + m_minLati = geoTo.latitude(); + m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, currentMinLongi), + QGeoCoordinate(m_minLati, currentMaxLongi)); +} + +// Lazy by default. Eager, within the module, used only in MapItems/MapObjectsQSG +class Q_POSITIONING_PRIVATE_EXPORT QGeoPathPrivate : public QGeoShapePrivate +{ +public: + QGeoPathPrivate(); + QGeoPathPrivate(const QList &path, const qreal width = 0.0); + ~QGeoPathPrivate(); + +// QGeoShape API + virtual QGeoShapePrivate *clone() const override; + virtual bool isValid() const override; + virtual bool isEmpty() const override; + virtual QGeoCoordinate center() const override; + virtual bool operator==(const QGeoShapePrivate &other) const override; + virtual bool contains(const QGeoCoordinate &coordinate) const override; + virtual QGeoRectangle boundingGeoRectangle() const override; + size_t hash(size_t seed) const override; + +// QGeoPathPrivate API + virtual const QList &path() const; + virtual bool lineContains(const QGeoCoordinate &coordinate) const; + virtual qreal width() const; + virtual double length(qsizetype indexFrom, qsizetype indexTo) const; + virtual qsizetype size() const; + virtual QGeoCoordinate coordinateAt(qsizetype index) const; + virtual bool containsCoordinate(const QGeoCoordinate &coordinate) const; + + virtual void setWidth(const qreal &width); + virtual void translate(double degreesLatitude, double degreesLongitude); + virtual void setPath(const QList &path); + virtual void clearPath(); + virtual void addCoordinate(const QGeoCoordinate &coordinate); + virtual void insertCoordinate(qsizetype index, const QGeoCoordinate &coordinate); + virtual void replaceCoordinate(qsizetype index, const QGeoCoordinate &coordinate); + virtual void removeCoordinate(const QGeoCoordinate &coordinate); + virtual void removeCoordinate(qsizetype index); + virtual void computeBoundingBox(); + virtual void markDirty(); + +// data members + QList m_path; + qreal m_width = 0; + QGeoRectangle m_bbox; // cached + double m_leftBoundWrapped; // cached + bool m_bboxDirty = false; +}; + +class Q_POSITIONING_PRIVATE_EXPORT QGeoPathPrivateEager : public QGeoPathPrivate +{ +public: + QGeoPathPrivateEager(); + QGeoPathPrivateEager(const QList &path, const qreal width = 0.0); + ~QGeoPathPrivateEager(); + +// QGeoShapePrivate API + virtual QGeoShapePrivate *clone() const override; + virtual void translate(double degreesLatitude, double degreesLongitude) override; + +// QGeoShapePrivate API + virtual void markDirty() override; + virtual void addCoordinate(const QGeoCoordinate &coordinate) override; + virtual void computeBoundingBox() override; + +// *Eager API + void updateBoundingBox(); + +// data members + QList m_deltaXs; // longitude deltas from m_path[0] + double m_minX = 0; // minimum value inside deltaXs + double m_maxX = 0; // maximum value inside deltaXs + double m_minLati = 0; // minimum latitude. paths do not wrap around through the poles + double m_maxLati = 0; // minimum latitude. paths do not wrap around through the poles +}; + +// This is a mean of creating a QGeoPathPrivateEager and injecting it into QGeoPaths via operator= +class Q_POSITIONING_PRIVATE_EXPORT QGeoPathEager : public QGeoPath +{ + Q_GADGET +public: + + QGeoPathEager(); + QGeoPathEager(const QList &path, const qreal &width = 0.0); + QGeoPathEager(const QGeoPath &other); + QGeoPathEager(const QGeoShape &other); + ~QGeoPathEager(); +}; + +QT_END_NAMESPACE + +#endif // QGEOPATH_P_H diff --git a/src/positioning/qgeopolygon.cpp b/src/positioning/qgeopolygon.cpp new file mode 100644 index 0000000..ac8974a --- /dev/null +++ b/src/positioning/qgeopolygon.cpp @@ -0,0 +1,686 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopolygon.h" +#include "qgeopolygon_p.h" +#include "qgeopath_p.h" +#include "qgeocircle.h" + +#include "qgeocoordinate.h" +#include "qnumeric.h" +#include "qlocationutils_p.h" +#include "qwebmercator_p.h" + +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" +#include "qwebmercator_p.h" + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoPolygon) + +constexpr int kMaxInt = std::numeric_limits::max(); +constexpr auto kTooManyHoles = u"The polygon has more holes than fit into an int. " + "This can cause errors while querying holes from QML"; +constexpr auto kTooManyElements = u"The polygon has more elements than fit into an int. " + "This can cause errors while querying elements from QML"; + +/*! + \class QGeoPolygon + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.10 + + \brief The QGeoPolygon class defines a geographic polygon. + + The polygon is defined by an ordered list of \l QGeoCoordinate objects + representing its perimeter. + + Each two adjacent elements in this list are intended to be connected + together by the shortest line segment of constant bearing passing + through both elements. + This type of connection can cross the date line in the longitudinal direction, + but never crosses the poles. + + This is relevant for the calculation of the bounding box returned by + \l QGeoShape::boundingGeoRectangle() for this shape, which will have the latitude of + the top left corner set to the maximum latitude in the path point set. + Similarly, the latitude of the bottom right corner will be the minimum latitude + in the path point set. + + This class is a \l Q_GADGET. + It can be \l{Cpp_value_integration_positioning}{directly used from C++ and QML}. +*/ + +/* + \property QGeoPolygon::path + \brief This property holds the list of coordinates for the geo polygon. + + The polygon is both invalid and empty if it contains no coordinate. + + A default constructed QGeoPolygon is therefore invalid. +*/ + +inline QGeoPolygonPrivate *QGeoPolygon::d_func() +{ + return static_cast(d_ptr.data()); +} + +inline const QGeoPolygonPrivate *QGeoPolygon::d_func() const +{ + return static_cast(d_ptr.constData()); +} + +struct PolygonVariantConversions +{ + PolygonVariantConversions() + { + QMetaType::registerConverter(); + QMetaType::registerConverter(); + } +}; + +Q_GLOBAL_STATIC(PolygonVariantConversions, initPolygonConversions) + +/*! + Constructs a new, empty geo polygon. +*/ +QGeoPolygon::QGeoPolygon() +: QGeoShape(new QGeoPolygonPrivate()) +{ + initPolygonConversions(); +} + +/*! + Constructs a new geo polygon from the coordinates specified + in \a path. +*/ +QGeoPolygon::QGeoPolygon(const QList &path) +: QGeoShape(new QGeoPolygonPrivate(path)) +{ + initPolygonConversions(); +} + +/*! + Constructs a new geo polygon from the contents of \a other. +*/ +QGeoPolygon::QGeoPolygon(const QGeoPolygon &other) +: QGeoShape(other) +{ + initPolygonConversions(); +} + +static void calculatePeripheralPoints(QList &path, + const QGeoCircle &circle, + int steps) +{ + const QGeoCoordinate ¢er = circle.center(); + const qreal distance = circle.radius(); + // Calculate points based on great-circle distance + // Calculation is the same as GeoCoordinate's atDistanceAndAzimuth function + // but tweaked here for computing multiple points + + // pre-calculations + steps = qMax(steps, 3); + qreal centerLon = center.longitude(); + qreal latRad = QLocationUtils::radians(center.latitude()); + qreal lonRad = QLocationUtils::radians(centerLon); + qreal cosLatRad = std::cos(latRad); + qreal sinLatRad = std::sin(latRad); + qreal ratio = (distance / QLocationUtils::earthMeanRadius()); + qreal cosRatio = std::cos(ratio); + qreal sinRatio = std::sin(ratio); + qreal sinLatRad_x_cosRatio = sinLatRad * cosRatio; + qreal cosLatRad_x_sinRatio = cosLatRad * sinRatio; + for (int i = 0; i < steps; ++i) { + qreal azimuthRad = 2 * M_PI * i / steps; + qreal resultLatRad = std::asin(sinLatRad_x_cosRatio + + cosLatRad_x_sinRatio * std::cos(azimuthRad)); + qreal resultLonRad = lonRad + std::atan2(std::sin(azimuthRad) * cosLatRad_x_sinRatio, + cosRatio - sinLatRad * std::sin(resultLatRad)); + qreal lat2 = QLocationUtils::degrees(resultLatRad); + qreal lon2 = QLocationUtils::wrapLong(QLocationUtils::degrees(resultLonRad)); + + path << QGeoCoordinate(lat2, lon2, center.altitude()); + } +} + +/*! + Constructs a new geo polygon from the contents of \a other. +*/ +QGeoPolygon::QGeoPolygon(const QGeoShape &other) +: QGeoShape(other) +{ + initPolygonConversions(); + if (type() != QGeoShape::PolygonType) { + QGeoPolygonPrivate *poly = new QGeoPolygonPrivate(); + if (type() == QGeoShape::CircleType) { + const QGeoCircle &circle = static_cast(other); + QList perimeter; + calculatePeripheralPoints(perimeter, circle, 128); + poly->setPath(perimeter); + } else if (type() == QGeoShape::RectangleType) { + const QGeoRectangle &rect = static_cast(other); + QList perimeter; + perimeter << rect.topLeft() << rect.topRight() + << rect.bottomRight() << rect.bottomLeft(); + poly->setPath(perimeter); + } + d_ptr = poly; + } +} + +/*! + Destroys this polygon. +*/ +QGeoPolygon::~QGeoPolygon() {} + +/*! + Assigns \a other to this geo polygon and returns a reference to this geo polygon. +*/ +QGeoPolygon &QGeoPolygon::operator=(const QGeoPolygon &other) +{ + QGeoShape::operator=(other); + return *this; +} + +/*! + Sets the perimeter of the polygon based on a list of coordinates \a path. + + \since QtPositioning 5.12 +*/ +void QGeoPolygon::setPerimeter(const QList &path) +{ + Q_D(QGeoPolygon); + return d->setPath(path); +} + +/*! + Returns all the elements of the polygon's perimeter. + + \since QtPositioning 5.12 +*/ +const QList &QGeoPolygon::perimeter() const +{ + Q_D(const QGeoPolygon); + return d->path(); +} + +/*! + Translates this geo polygon by \a degreesLatitude northwards and \a degreesLongitude eastwards. + + Negative values of \a degreesLatitude and \a degreesLongitude correspond to + southward and westward translation respectively. +*/ +void QGeoPolygon::translate(double degreesLatitude, double degreesLongitude) +{ + Q_D(QGeoPolygon); + d->translate(degreesLatitude, degreesLongitude); +} + +/*! + Returns a copy of this geo polygon translated by \a degreesLatitude northwards and + \a degreesLongitude eastwards. + + Negative values of \a degreesLatitude and \a degreesLongitude correspond to + southward and westward translation respectively. + + \sa translate() +*/ +QGeoPolygon QGeoPolygon::translated(double degreesLatitude, double degreesLongitude) const +{ + QGeoPolygon result(*this); + result.translate(degreesLatitude, degreesLongitude); + return result; +} + +/*! + Returns the length of the polygon's perimeter, in meters, from the element \a indexFrom to the element \a indexTo. + The length is intended to be the sum of the shortest distances for each pair of adjacent points. +*/ +double QGeoPolygon::length(qsizetype indexFrom, qsizetype indexTo) const +{ + Q_D(const QGeoPolygon); + return d->length(indexFrom, indexTo); +} + +/*! + Returns the number of elements in the polygon. + + \since 5.10 +*/ +qsizetype QGeoPolygon::size() const +{ + Q_D(const QGeoPolygon); + const qsizetype result = d->size(); + if (result > kMaxInt) + qWarning() << kTooManyElements; + return result; +} + +/*! + Appends \a coordinate to the polygon. +*/ +void QGeoPolygon::addCoordinate(const QGeoCoordinate &coordinate) +{ + Q_D(QGeoPolygon); + d->addCoordinate(coordinate); + if (d->size() > kMaxInt) + qWarning() << kTooManyElements; +} + +/*! + Inserts \a coordinate at the specified \a index. +*/ +void QGeoPolygon::insertCoordinate(qsizetype index, const QGeoCoordinate &coordinate) +{ + Q_D(QGeoPolygon); + d->insertCoordinate(index, coordinate); +} + +/*! + Replaces the path element at the specified \a index with \a coordinate. +*/ +void QGeoPolygon::replaceCoordinate(qsizetype index, const QGeoCoordinate &coordinate) +{ + Q_D(QGeoPolygon); + d->replaceCoordinate(index, coordinate); +} + +/*! + Returns the coordinate at \a index . +*/ +QGeoCoordinate QGeoPolygon::coordinateAt(qsizetype index) const +{ + Q_D(const QGeoPolygon); + return d->coordinateAt(index); +} + +/*! + Returns true if the polygon's perimeter contains \a coordinate as one of the elements. +*/ +bool QGeoPolygon::containsCoordinate(const QGeoCoordinate &coordinate) const +{ + Q_D(const QGeoPolygon); + return d->containsCoordinate(coordinate); +} + +/*! + Removes the last occurrence of \a coordinate from the polygon. +*/ +void QGeoPolygon::removeCoordinate(const QGeoCoordinate &coordinate) +{ + Q_D(QGeoPolygon); + d->removeCoordinate(coordinate); +} + +/*! + Removes element at position \a index from the polygon. +*/ +void QGeoPolygon::removeCoordinate(qsizetype index) +{ + Q_D(QGeoPolygon); + d->removeCoordinate(index); +} + +/*! + Returns the geo polygon properties as a string. +*/ +QString QGeoPolygon::toString() const +{ + if (type() != QGeoShape::PolygonType) { + qWarning("Not a polygon"); + return QStringLiteral("QGeoPolygon(not a polygon)"); + } + + QString pathString; + for (const auto &p : perimeter()) + pathString += p.toString() + QLatin1Char(','); + + return QStringLiteral("QGeoPolygon([ %1 ])").arg(pathString); +} + +/*! + Sets the \a holePath for a hole inside the polygon. The hole is a + QVariant containing a QList. + + \since 5.12 +*/ +void QGeoPolygon::addHole(const QVariant &holePath) +{ + QList qgcHolePath; + if (holePath.canConvert()) { + const QVariantList qvlHolePath = holePath.toList(); + for (const QVariant &vertex : qvlHolePath) { + if (vertex.canConvert()) + qgcHolePath << vertex.value(); + } + } + //ToDo: add QGeoShape support + addHole(qgcHolePath); +} + +/*! + Overloaded method. Sets the \a holePath for a hole inside the polygon. The hole is a QList. + + \since 5.12 +*/ +void QGeoPolygon::addHole(const QList &holePath) +{ + Q_D(QGeoPolygon); + d->addHole(holePath); + if (d->holesCount() > kMaxInt) + qDebug() << kTooManyHoles; +} + +/*! + Returns a QVariant containing a QList + which represents the hole at \a index. + + \since 5.12 +*/ +const QVariantList QGeoPolygon::hole(qsizetype index) const +{ + Q_D(const QGeoPolygon); + QVariantList holeCoordinates; + for (const QGeoCoordinate &coords: d->holePath(index)) + holeCoordinates << QVariant::fromValue(coords); + return holeCoordinates; +} + +/*! + Returns a QList which represents the hole at \a index. + + \since 5.12 +*/ +const QList QGeoPolygon::holePath(qsizetype index) const +{ + Q_D(const QGeoPolygon); + return d->holePath(index); +} + +/*! + Removes element at position \a index from the list of holes. + + \since 5.12 +*/ +void QGeoPolygon::removeHole(qsizetype index) +{ + Q_D(QGeoPolygon); + return d->removeHole(index); +} + +/*! + Returns the number of holes. + + \since 5.12 +*/ +qsizetype QGeoPolygon::holesCount() const +{ + Q_D(const QGeoPolygon); + const qsizetype result = d->holesCount(); + if (result > kMaxInt) + qWarning() << kTooManyHoles; + return result; +} + +/******************************************************************************* + * + * QGeoPathPrivate & friends + * +*******************************************************************************/ + +QGeoPolygonPrivate::QGeoPolygonPrivate() +: QGeoPathPrivate() +{ + type = QGeoShape::PolygonType; +} + +QGeoPolygonPrivate::QGeoPolygonPrivate(const QList &path) +: QGeoPathPrivate(path) +{ + type = QGeoShape::PolygonType; +} + +QGeoPolygonPrivate::~QGeoPolygonPrivate() {} + +QGeoShapePrivate *QGeoPolygonPrivate::clone() const +{ + return new QGeoPolygonPrivate(*this); +} + +bool QGeoPolygonPrivate::isValid() const +{ + return path().size() > 2; +} + +bool QGeoPolygonPrivate::contains(const QGeoCoordinate &coordinate) const +{ + return polygonContains(coordinate); +} + +inline static void translatePoly( QList &m_path, + QList> &m_holesList, + QGeoRectangle &m_bbox, + double degreesLatitude, + double degreesLongitude, + double m_maxLati, + double m_minLati) +{ + if (degreesLatitude > 0.0) + degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati); + else + degreesLatitude = qMax(degreesLatitude, -90.0 - m_minLati); + for (QGeoCoordinate &p: m_path) { + p.setLatitude(p.latitude() + degreesLatitude); + p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude)); + } + if (!m_holesList.isEmpty()){ + for (QList &hole: m_holesList){ + for (QGeoCoordinate &holeVertex: hole){ + holeVertex.setLatitude(holeVertex.latitude() + degreesLatitude); + holeVertex.setLongitude(QLocationUtils::wrapLong(holeVertex.longitude() + degreesLongitude)); + } + } + } + m_bbox.translate(degreesLatitude, degreesLongitude); +} + +void QGeoPolygonPrivate::translate(double degreesLatitude, double degreesLongitude) +{ + // Need min/maxLati, so update bbox + QList m_deltaXs; + double m_minX, m_maxX, m_minLati, m_maxLati; + m_bboxDirty = false; // Updated in translatePoly + computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); + translatePoly(m_path, m_holesList, m_bbox, degreesLatitude, degreesLongitude, m_maxLati, m_minLati); + m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x(); + m_clipperDirty = true; +} + +bool QGeoPolygonPrivate::operator==(const QGeoShapePrivate &other) const +{ + if (!QGeoShapePrivate::operator==(other)) // checks type + return false; + + const QGeoPolygonPrivate &otherPath = static_cast(other); + if (m_path.size() != otherPath.m_path.size() + || m_holesList.size() != otherPath.m_holesList.size()) + return false; + return m_path == otherPath.m_path && m_holesList == otherPath.m_holesList; +} + +size_t QGeoPolygonPrivate::hash(size_t seed) const +{ + const size_t pointsHash = qHashRange(m_path.cbegin(), m_path.cend(), seed); + const size_t holesHash = qHashRange(m_holesList.cbegin(), m_holesList.cend(), seed); + return qHashMulti(seed, pointsHash, holesHash); +} + +void QGeoPolygonPrivate::addHole(const QList &holePath) +{ + for (const QGeoCoordinate &holeVertex: holePath) + if (!holeVertex.isValid()) + return; + + m_holesList << holePath; + // ToDo: mark clipper dirty when hole caching gets added +} + +const QList QGeoPolygonPrivate::holePath(qsizetype index) const +{ + return m_holesList.at(index); +} + +void QGeoPolygonPrivate::removeHole(qsizetype index) +{ + if (index < 0 || index >= m_holesList.size()) + return; + + m_holesList.removeAt(index); + // ToDo: mark clipper dirty when hole caching gets added +} + +qsizetype QGeoPolygonPrivate::holesCount() const +{ + return m_holesList.size(); +} + +bool QGeoPolygonPrivate::polygonContains(const QGeoCoordinate &coordinate) const +{ + if (m_clipperDirty) + const_cast(this)->updateClipperPath(); // this one updates bbox too if needed + + QDoubleVector2D coord = QWebMercator::coordToMercator(coordinate); + + if (coord.x() < m_leftBoundWrapped) + coord.setX(coord.x() + 1.0); + + if (!m_clipperWrapper.pointInPolygon(coord)) + return false; + + // else iterates the holes List checking whether the point is contained inside the holes + for (const QList &holePath : std::as_const(m_holesList)) { + // ToDo: cache these + QGeoPolygon holePolygon; + holePolygon.setPerimeter(holePath); + if (holePolygon.contains(coordinate)) + return false; + } + return true; +} + +void QGeoPolygonPrivate::markDirty() +{ + m_bboxDirty = m_clipperDirty = true; +} + +void QGeoPolygonPrivate::updateClipperPath() +{ + if (m_bboxDirty) + computeBoundingBox(); + m_clipperDirty = false; + + QList preservedPath; + for (const QGeoCoordinate &c : m_path) { + QDoubleVector2D crd = QWebMercator::coordToMercator(c); + if (crd.x() < m_leftBoundWrapped) + crd.setX(crd.x() + 1.0); + preservedPath << crd; + } + m_clipperWrapper.setPolygon(preservedPath); +} + +QGeoPolygonPrivateEager::QGeoPolygonPrivateEager() : QGeoPolygonPrivate() +{ + m_bboxDirty = false; // never dirty on the eager version +} + +QGeoPolygonPrivateEager::QGeoPolygonPrivateEager(const QList &path) : QGeoPolygonPrivate(path) +{ + m_bboxDirty = false; // never dirty on the eager version +} + +QGeoPolygonPrivateEager::~QGeoPolygonPrivateEager() +{ + +} + +QGeoShapePrivate *QGeoPolygonPrivateEager::clone() const +{ + return new QGeoPolygonPrivate(*this); +} + +void QGeoPolygonPrivateEager::translate(double degreesLatitude, double degreesLongitude) +{ + translatePoly(m_path, m_holesList, m_bbox, degreesLatitude, degreesLongitude, m_maxLati, m_minLati); + m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x(); + m_clipperDirty = true; +} + +void QGeoPolygonPrivateEager::markDirty() +{ + m_clipperDirty = true; + computeBoundingBox(); +} + +void QGeoPolygonPrivateEager::addCoordinate(const QGeoCoordinate &coordinate) +{ + if (!coordinate.isValid()) + return; + m_path.append(coordinate); + m_clipperDirty = true; + updateBoundingBox(); // do not markDirty as it uses computeBoundingBox instead +} + +void QGeoPolygonPrivateEager::computeBoundingBox() +{ + computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); + m_leftBoundWrapped = QWebMercator::coordToMercator(m_bbox.topLeft()).x(); +} + +void QGeoPolygonPrivateEager::updateBoundingBox() +{ + updateBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); +} + +QGeoPolygonEager::QGeoPolygonEager() : QGeoPolygon() +{ + initPolygonConversions(); + d_ptr = new QGeoPolygonPrivateEager; +} + +QGeoPolygonEager::QGeoPolygonEager(const QList &path) : QGeoPolygon() +{ + initPolygonConversions(); + d_ptr = new QGeoPolygonPrivateEager(path); +} + +QGeoPolygonEager::QGeoPolygonEager(const QGeoPolygon &other) : QGeoPolygon() +{ + initPolygonConversions(); + // without being able to dynamic_cast the d_ptr, only way to be sure is to reconstruct a new QGeoPolygonPrivateEager + d_ptr = new QGeoPolygonPrivateEager; + setPerimeter(other.perimeter()); + for (qsizetype i = 0; i < other.holesCount(); i++) + addHole(other.holePath(i)); +} + +QGeoPolygonEager::QGeoPolygonEager(const QGeoShape &other) : QGeoPolygon() +{ + initPolygonConversions(); + if (other.type() == QGeoShape::PolygonType) + *this = QGeoPolygonEager(QGeoPolygon(other)); + else + d_ptr = new QGeoPolygonPrivateEager; +} + +QGeoPolygonEager::~QGeoPolygonEager() +{ + +} + +QT_END_NAMESPACE + +#include "moc_qgeopolygon_p.cpp" +#include "moc_qgeopolygon.cpp" diff --git a/src/positioning/qgeopolygon.h b/src/positioning/qgeopolygon.h new file mode 100644 index 0000000..2fbb9a4 --- /dev/null +++ b/src/positioning/qgeopolygon.h @@ -0,0 +1,64 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOLYGON_H +#define QGEOPOLYGON_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoCoordinate; +class QGeoPolygonPrivate; + +class Q_POSITIONING_EXPORT QGeoPolygon : public QGeoShape +{ + Q_GADGET + Q_PROPERTY(QList perimeter READ perimeter WRITE setPerimeter REVISION(5, 12)) + +public: + QGeoPolygon(); + QGeoPolygon(const QList &path); + QGeoPolygon(const QGeoPolygon &other); + QGeoPolygon(const QGeoShape &other); + + ~QGeoPolygon(); + + QGeoPolygon &operator=(const QGeoPolygon &other); + + void setPerimeter(const QList &path); + const QList &perimeter() const; + + Q_INVOKABLE void addHole(const QVariant &holePath); + void addHole(const QList &holePath); + Q_INVOKABLE const QVariantList hole(qsizetype index) const; + const QList holePath(qsizetype index) const; + Q_INVOKABLE void removeHole(qsizetype index); + Q_INVOKABLE qsizetype holesCount() const; + Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude); + Q_INVOKABLE QGeoPolygon translated(double degreesLatitude, double degreesLongitude) const; + Q_INVOKABLE double length(qsizetype indexFrom = 0, qsizetype indexTo = -1) const; + Q_INVOKABLE qsizetype size() const; + Q_INVOKABLE void addCoordinate(const QGeoCoordinate &coordinate); + Q_INVOKABLE void insertCoordinate(qsizetype index, const QGeoCoordinate &coordinate); + Q_INVOKABLE void replaceCoordinate(qsizetype index, const QGeoCoordinate &coordinate); + Q_INVOKABLE QGeoCoordinate coordinateAt(qsizetype index) const; + Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate &coordinate) const; + Q_INVOKABLE void removeCoordinate(const QGeoCoordinate &coordinate); + Q_INVOKABLE void removeCoordinate(qsizetype index); + + Q_INVOKABLE QString toString() const; + +private: + inline QGeoPolygonPrivate *d_func(); + inline const QGeoPolygonPrivate *d_func() const; +}; + +Q_DECLARE_TYPEINFO(QGeoPolygon, Q_RELOCATABLE_TYPE); + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoPolygon, Q_POSITIONING_EXPORT) + +#endif // QGEOPOLYGON_H diff --git a/src/positioning/qgeopolygon_p.h b/src/positioning/qgeopolygon_p.h new file mode 100644 index 0000000..c99d318 --- /dev/null +++ b/src/positioning/qgeopolygon_p.h @@ -0,0 +1,101 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOLYGON_P_H +#define QGEOPOLYGON_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 +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONING_PRIVATE_EXPORT QGeoPolygonPrivate : public QGeoPathPrivate +{ +public: + QGeoPolygonPrivate(); + QGeoPolygonPrivate(const QList &path); + ~QGeoPolygonPrivate(); + +// QGeoShape API + virtual QGeoShapePrivate *clone() const override; + virtual bool isValid() const override; + virtual bool contains(const QGeoCoordinate &coordinate) const override; + virtual void translate(double degreesLatitude, double degreesLongitude) override; + virtual bool operator==(const QGeoShapePrivate &other) const override; + size_t hash(size_t seed) const override; + +// QGeoPath API + virtual void markDirty() override; + +// QGeoPolygonPrivate API + qsizetype holesCount() const; + bool polygonContains(const QGeoCoordinate &coordinate) const; + const QList holePath(qsizetype index) const; + + virtual void addHole(const QList &holePath); + virtual void removeHole(qsizetype index); + virtual void updateClipperPath(); + +// data members + bool m_clipperDirty = true; + QList> m_holesList; + QClipperUtils m_clipperWrapper; +}; + +class Q_POSITIONING_PRIVATE_EXPORT QGeoPolygonPrivateEager : public QGeoPolygonPrivate +{ +public: + QGeoPolygonPrivateEager(); + QGeoPolygonPrivateEager(const QList &path); + ~QGeoPolygonPrivateEager(); + +// QGeoShape API + virtual QGeoShapePrivate *clone() const override; + virtual void translate(double degreesLatitude, double degreesLongitude) override; + +// QGeoPath API + virtual void markDirty() override; + virtual void addCoordinate(const QGeoCoordinate &coordinate) override; + virtual void computeBoundingBox() override; + +// QGeoPolygonPrivate API + +// *Eager API + void updateBoundingBox(); + +// data members + QList m_deltaXs; // longitude deltas from m_path[0] + double m_minX = 0; // minimum value inside deltaXs + double m_maxX = 0; // maximum value inside deltaXs + double m_minLati = 0; // minimum latitude. paths do not wrap around through the poles + double m_maxLati = 0; // minimum latitude. paths do not wrap around through the poles +}; + +// This is a mean of creating a QGeoPolygonPrivateEager and injecting it into QGeoPolygons via operator= +class Q_POSITIONING_PRIVATE_EXPORT QGeoPolygonEager : public QGeoPolygon +{ + Q_GADGET +public: + + QGeoPolygonEager(); + QGeoPolygonEager(const QList &path); + QGeoPolygonEager(const QGeoPolygon &other); + QGeoPolygonEager(const QGeoShape &other); + ~QGeoPolygonEager(); +}; + +QT_END_NAMESPACE + +#endif // QGEOPOLYGON_P_H diff --git a/src/positioning/qgeopositioninfo.cpp b/src/positioning/qgeopositioninfo.cpp new file mode 100644 index 0000000..a1f6ec0 --- /dev/null +++ b/src/positioning/qgeopositioninfo.cpp @@ -0,0 +1,418 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qgeopositioninfo.h" +#include "private/qgeopositioninfo_p.h" +#include +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoPositionInfo) + +/*! + \class QGeoPositionInfo + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \ingroup shared + \since 5.2 + + \brief The QGeoPositionInfo class contains information gathered on a global position, direction and velocity at a particular point in time. + + A QGeoPositionInfo contains, at a minimum, a geographical coordinate and + a timestamp. It may also have heading and speed measurements as well as + estimates of the accuracy of the provided data. + + \sa QGeoPositionInfoSource +*/ + +/*! + \enum QGeoPositionInfo::Attribute + Defines the attributes for positional information. + + \value Direction The bearing measured in degrees clockwise from true north to the direction of travel. + \value GroundSpeed The ground speed, in meters/sec. + \value VerticalSpeed The vertical speed, in meters/sec. + \value MagneticVariation The angle between the horizontal component of the magnetic field and true north, in degrees. Also known as magnetic declination. A positive value indicates a clockwise direction from true north and a negative value indicates a counter-clockwise direction. + \value HorizontalAccuracy The accuracy of the provided latitude-longitude value, in meters. + \value VerticalAccuracy The accuracy of the provided altitude value, in meters. + \value DirectionAccuracy The accuracy of the provided bearing, in degrees. + This attribute is available only on Android (API level 26 or above) and + macOS/iOS. See corresponding \l {Android getBearingAccuracyDegrees} + {Android} and \l {iOS courseAccuracy}{Apple} documentation for more details. + + NMEA protocol also suggests another type of accuracy - PositionAccuracy, + which is a 3D accuracy value. Qt does not provide a separate attribute for + it. If you need this value, you can calculate it based on the following + formula: + + \c {PositionAccuracy} \sup 2 \c {= HorizontalAccuracy} \sup 2 \c { + + VerticalAccuracy} \sup 2 +*/ + +/*! + Creates an invalid QGeoPositionInfo object. + + \sa isValid() +*/ +QGeoPositionInfo::QGeoPositionInfo() + : d(new QGeoPositionInfoPrivate) +{ +} + +/*! + Creates a QGeoPositionInfo for the given \a coordinate and \a timestamp. +*/ +QGeoPositionInfo::QGeoPositionInfo(const QGeoCoordinate &coordinate, const QDateTime ×tamp) + : d(new QGeoPositionInfoPrivate) +{ + d->timestamp = timestamp; + d->coord = coordinate; +} + +/*! + Creates a QGeoPositionInfo with the values of \a other. +*/ +QGeoPositionInfo::QGeoPositionInfo(const QGeoPositionInfo &other) + : d(other.d) +{ +} + +/*! + \fn QGeoPositionInfo::QGeoPositionInfo(QGeoPositionInfo &&other) noexcept + \since 6.2 + + Creates a QGeoPositionInfo object by moving from \a other. + + Note that a moved-from QGeoPositionInfo can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +QGeoPositionInfo::QGeoPositionInfo(QGeoPositionInfoPrivate &dd) : d(&dd) +{ +} + +/*! + Destroys a QGeoPositionInfo object. +*/ +QGeoPositionInfo::~QGeoPositionInfo() +{ +} + +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QGeoPositionInfoPrivate) + +/*! + Assigns the values from \a other to this QGeoPositionInfo. +*/ +QGeoPositionInfo &QGeoPositionInfo::operator=(const QGeoPositionInfo & other) +{ + if (this == &other) + return *this; + + d = other.d; + return *this; +} + +/*! + \fn QGeoPositionInfo &QGeoPositionInfo::operator=(QGeoPositionInfo &&other) noexcept + \since 6.2 + + Move-assigns the values from \a other to this object. + + Note that a moved-from QGeoPositionInfo can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + \fn bool QGeoPositionInfo::operator==(const QGeoPositionInfo &lhs, const QGeoPositionInfo &rhs) + + Returns \c true if all of the \a lhs object's values are the same as those + of \a rhs. Otherwise returns \c false. +*/ + +/*! + \fn bool QGeoPositionInfo::operator!=(const QGeoPositionInfo &lhs, const QGeoPositionInfo &rhs) + + Returns \c true if any of the \a lhs object's values are not the same as + those of \a rhs. Otherwise returns \c false. +*/ + +/*! + Returns true if the timestamp() and coordinate() values are both valid. + + \sa QGeoCoordinate::isValid(), QDateTime::isValid() +*/ +bool QGeoPositionInfo::isValid() const +{ + return d->timestamp.isValid() && d->coord.isValid(); +} + +/*! + Sets the date and time at which this position was reported to \a timestamp. + + The \a timestamp must be in UTC time. + + \sa timestamp() +*/ +void QGeoPositionInfo::setTimestamp(const QDateTime ×tamp) +{ + d.detach(); + d->timestamp = timestamp; +} + +/*! + Returns the date and time at which this position was reported, in UTC time. + + Returns an invalid QDateTime if no date/time value has been set. + + \sa setTimestamp() +*/ +QDateTime QGeoPositionInfo::timestamp() const +{ + return d->timestamp; +} + +/*! + Sets the coordinate for this position to \a coordinate. + + \sa coordinate() +*/ +void QGeoPositionInfo::setCoordinate(const QGeoCoordinate &coordinate) +{ + d.detach(); + d->coord = coordinate; +} + +/*! + Returns the coordinate for this position. + + Returns an invalid coordinate if no coordinate has been set. + + \sa setCoordinate() +*/ +QGeoCoordinate QGeoPositionInfo::coordinate() const +{ + return d->coord; +} + +/*! + Sets the value for \a attribute to \a value. + + \sa attribute() +*/ +void QGeoPositionInfo::setAttribute(Attribute attribute, qreal value) +{ + d.detach(); + d->doubleAttribs[attribute] = value; +} + +/*! + Returns the value of the specified \a attribute as a qreal value. + + Returns NaN if the value has not been set. + + The function hasAttribute() should be used to determine whether or + not a value has been set for an attribute. + + \sa hasAttribute(), setAttribute() +*/ +qreal QGeoPositionInfo::attribute(Attribute attribute) const +{ + if (d->doubleAttribs.contains(attribute)) + return d->doubleAttribs[attribute]; + return qQNaN(); +} + +/*! + Removes the specified \a attribute and its value. +*/ +void QGeoPositionInfo::removeAttribute(Attribute attribute) +{ + d.detach(); + d->doubleAttribs.remove(attribute); +} + +/*! + Returns true if the specified \a attribute is present for this + QGeoPositionInfo object. +*/ +bool QGeoPositionInfo::hasAttribute(Attribute attribute) const +{ + return d->doubleAttribs.contains(attribute); +} + +/*! + \internal +*/ +void QGeoPositionInfo::detach() +{ + if (d) + d.detach(); + else + d = new QGeoPositionInfoPrivate; +} + +bool QGeoPositionInfo::equals(const QGeoPositionInfo &lhs, const QGeoPositionInfo &rhs) +{ + return *lhs.d == *rhs.d; +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug QGeoPositionInfo::debugStreaming(QDebug dbg, const QGeoPositionInfo &info) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QGeoPositionInfo(" << info.d->timestamp; + dbg.nospace() << ", "; // timestamp force dbg.space() -> reverting here + dbg << info.d->coord; + + QList attribs = info.d->doubleAttribs.keys(); + std::stable_sort(attribs.begin(), attribs.end()); // Output a sorted list from an unsorted hash. + for (int i = 0; i < attribs.size(); ++i) { + dbg << ", "; + switch (attribs[i]) { + case QGeoPositionInfo::Direction: + dbg << "Direction="; + break; + case QGeoPositionInfo::GroundSpeed: + dbg << "GroundSpeed="; + break; + case QGeoPositionInfo::VerticalSpeed: + dbg << "VerticalSpeed="; + break; + case QGeoPositionInfo::MagneticVariation: + dbg << "MagneticVariation="; + break; + case QGeoPositionInfo::HorizontalAccuracy: + dbg << "HorizontalAccuracy="; + break; + case QGeoPositionInfo::VerticalAccuracy: + dbg << "VerticalAccuracy="; + break; + case QGeoPositionInfo::DirectionAccuracy: + dbg << "DirectionAccuracy="; + break; + } + dbg << info.d->doubleAttribs[attribs[i]]; + } + dbg << ')'; + return dbg; +} +#endif + + +#ifndef QT_NO_DATASTREAM +/*! + \fn QDataStream &QGeoPositionInfo::operator<<(QDataStream &stream, QGeoPositionInfo::Attribute attr) + + Writes the given \a attr enumeration to the specified \a stream. + + \sa {Serializing Qt Data Types} +*/ +QDataStream &QGeoPositionInfo::dataStreamOut(QDataStream &stream, QGeoPositionInfo::Attribute attr) +{ + return stream << qint32(attr); +} + +/*! + \fn QDataStream &QGeoPositionInfo::operator>>(QDataStream &stream, QGeoPositionInfo::Attribute &attr) + + Reads an attribute enumeration from the specified \a stream info the given \a attr. + + \sa {Serializing Qt Data Types} +*/ +QDataStream &QGeoPositionInfo::dataStreamIn(QDataStream &stream, QGeoPositionInfo::Attribute &attr) +{ + qint32 a; + stream >> a; + attr = static_cast(a); + return stream; +} + +/*! + \fn QDataStream &QGeoPositionInfo::operator<<(QDataStream &stream, const QGeoPositionInfo &info) + + Writes the given \a info to the specified \a stream. + + \sa {Serializing Qt Data Types} +*/ + +QDataStream &QGeoPositionInfo::dataStreamOut(QDataStream &stream, const QGeoPositionInfo &info) +{ + stream << info.d->timestamp; + stream << info.d->coord; + stream << info.d->doubleAttribs; + return stream; +} + +/*! + \fn QDataStream &QGeoPositionInfo::operator>>(QDataStream &stream, QGeoPositionInfo &info) + + Reads a coordinate from the specified \a stream into the given + \a info. + + \sa {Serializing Qt Data Types} +*/ + +QDataStream &QGeoPositionInfo::dataStreamIn(QDataStream &stream, QGeoPositionInfo &info) +{ + stream >> info.d->timestamp; + stream >> info.d->coord; + stream >> info.d->doubleAttribs; + return stream; +} +#endif + +QGeoPositionInfoPrivate::QGeoPositionInfoPrivate() : QSharedData() +{ +} + +QGeoPositionInfoPrivate::QGeoPositionInfoPrivate(const QGeoPositionInfoPrivate &other) + : QSharedData(other), + timestamp(other.timestamp), + coord(other.coord), + doubleAttribs(other.doubleAttribs) +{ +} + +QGeoPositionInfoPrivate::~QGeoPositionInfoPrivate() +{ + +} + +bool QGeoPositionInfoPrivate::operator==(const QGeoPositionInfoPrivate &other) const +{ + return timestamp == other.timestamp + && coord == other.coord + && doubleAttribs == other.doubleAttribs; +} + +QGeoPositionInfoPrivate *QGeoPositionInfoPrivate::get(const QGeoPositionInfo &info) +{ + return info.d.data(); +} + +size_t qHash(const QGeoPositionInfo &key, size_t seed) noexcept +{ + return qHashMulti(seed, key.d->coord); +} + +namespace QTest +{ + +char *toString(const QGeoPositionInfo &info) +{ + QString result; + QDebug dbg(&result); + dbg << info; + + return qstrdup(qPrintable(result)); +} + +} // namespace QTest + +QT_END_NAMESPACE diff --git a/src/positioning/qgeopositioninfo.h b/src/positioning/qgeopositioninfo.h new file mode 100644 index 0000000..c37fc33 --- /dev/null +++ b/src/positioning/qgeopositioninfo.h @@ -0,0 +1,122 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QGEOPOSITIONINFO_H +#define QGEOPOSITIONINFO_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QDebug; +class QDataStream; + +class QGeoPositionInfo; +Q_POSITIONING_EXPORT size_t qHash(const QGeoPositionInfo &key, size_t seed = 0) noexcept; +namespace QTest +{ + +Q_POSITIONING_EXPORT char *toString(const QGeoPositionInfo &info); + +} // namespace QTest + +class QGeoPositionInfoPrivate; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QGeoPositionInfoPrivate, Q_POSITIONING_EXPORT) + +class Q_POSITIONING_EXPORT QGeoPositionInfo +{ +public: + enum Attribute { + Direction, + GroundSpeed, + VerticalSpeed, + MagneticVariation, + HorizontalAccuracy, + VerticalAccuracy, + DirectionAccuracy + }; + + QGeoPositionInfo(); + QGeoPositionInfo(const QGeoCoordinate &coordinate, const QDateTime &updateTime); + QGeoPositionInfo(const QGeoPositionInfo &other); + QGeoPositionInfo(QGeoPositionInfo &&other) noexcept = default; + QGeoPositionInfo(QGeoPositionInfoPrivate &dd); + ~QGeoPositionInfo(); + + QGeoPositionInfo &operator=(const QGeoPositionInfo &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QGeoPositionInfo) + + void swap(QGeoPositionInfo &other) noexcept { d.swap(other.d); } + + friend bool operator==(const QGeoPositionInfo &lhs, const QGeoPositionInfo &rhs) + { + return equals(lhs, rhs); + } + friend bool operator!=(const QGeoPositionInfo &lhs, const QGeoPositionInfo &rhs) + { + return !equals(lhs, rhs); + } + + bool isValid() const; + + void setTimestamp(const QDateTime ×tamp); + QDateTime timestamp() const; + + void setCoordinate(const QGeoCoordinate &coordinate); + QGeoCoordinate coordinate() const; + + void setAttribute(Attribute attribute, qreal value); + qreal attribute(Attribute attribute) const; + void removeAttribute(Attribute attribute); + bool hasAttribute(Attribute attribute) const; + + void detach(); + +private: + static bool equals(const QGeoPositionInfo &lhs, const QGeoPositionInfo &rhs); +#ifndef QT_NO_DEBUG_STREAM + friend QDebug operator<<(QDebug dbg, const QGeoPositionInfo &info) + { + return debugStreaming(dbg, info); + } + static QDebug debugStreaming(QDebug dbg, const QGeoPositionInfo &info); +#endif +#ifndef QT_NO_DATASTREAM + friend QDataStream &operator<<(QDataStream &stream, const QGeoPositionInfo &info) + { + return dataStreamOut(stream, info); + } + friend QDataStream &operator>>(QDataStream &stream, QGeoPositionInfo &info) + { + return dataStreamIn(stream, info); + } + static QDataStream &dataStreamOut(QDataStream &stream, const QGeoPositionInfo &info); + static QDataStream &dataStreamIn(QDataStream &stream, QGeoPositionInfo &info); + + friend QDataStream &operator<<(QDataStream &stream, QGeoPositionInfo::Attribute attr) + { + return dataStreamOut(stream, attr); + } + friend QDataStream &operator>>(QDataStream &stream, QGeoPositionInfo::Attribute &attr) + { + return dataStreamIn(stream, attr); + } + static QDataStream &dataStreamOut(QDataStream &stream, QGeoPositionInfo::Attribute attr); + static QDataStream &dataStreamIn(QDataStream &stream, QGeoPositionInfo::Attribute &attr); +#endif + QExplicitlySharedDataPointer d; + friend class QGeoPositionInfoPrivate; + + friend Q_POSITIONING_EXPORT size_t qHash(const QGeoPositionInfo &key, size_t seed) noexcept; + friend Q_POSITIONING_EXPORT char *QTest::toString(const QGeoPositionInfo &info); +}; + +Q_DECLARE_SHARED(QGeoPositionInfo) + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoPositionInfo, Q_POSITIONING_EXPORT) + +#endif // QGEOPOSITIONINFO_H diff --git a/src/positioning/qgeopositioninfo_p.h b/src/positioning/qgeopositioninfo_p.h new file mode 100644 index 0000000..e5ef4bd --- /dev/null +++ b/src/positioning/qgeopositioninfo_p.h @@ -0,0 +1,42 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QGEOPOSITIONINFO_P_H +#define QGEOPOSITIONINFO_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 +#include "qgeopositioninfo.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfoPrivate : public QSharedData +{ +public: + QGeoPositionInfoPrivate(); + QGeoPositionInfoPrivate(const QGeoPositionInfoPrivate &other); + virtual ~QGeoPositionInfoPrivate(); + bool operator==(const QGeoPositionInfoPrivate &other) const; + + QDateTime timestamp; + QGeoCoordinate coord; + QHash doubleAttribs; + + static QGeoPositionInfoPrivate *get(const QGeoPositionInfo &info); +}; + +QT_END_NAMESPACE + +#endif // QGEOPOSITIONINFO_P_H diff --git a/src/positioning/qgeopositioninfosource.cpp b/src/positioning/qgeopositioninfosource.cpp new file mode 100644 index 0000000..87de692 --- /dev/null +++ b/src/positioning/qgeopositioninfosource.cpp @@ -0,0 +1,605 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include +#include "qgeopositioninfosource_p.h" +#include "qgeopositioninfosourcefactory.h" + +#include +#include +#include +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + ("org.qt-project.qt.position.sourcefactory/6.0", + QLatin1String("/position"))) + +/*! + \class QGeoPositionInfoSource + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.2 + + \brief The QGeoPositionInfoSource class is an abstract base class for the distribution of positional updates. + + The static function QGeoPositionInfoSource::createDefaultSource() creates a default + position source that is appropriate for the platform, if one is available. + Otherwise, QGeoPositionInfoSource will check for available plugins that + implement the QGeoPositionInfoSourceFactory interface. + + Users of a QGeoPositionInfoSource subclass can request the current position using + requestUpdate(), or start and stop regular position updates using + startUpdates() and stopUpdates(). When an update is available, + positionUpdated() is emitted. The last known position can be accessed with + lastKnownPosition(). + + If regular position updates are required, setUpdateInterval() can be used + to specify how often these updates should be emitted. If no interval is + specified, updates are simply provided whenever they are available. + For example: + + \code + // Emit updates every 10 seconds if available + QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(0); + if (source) + source->setUpdateInterval(10000); + \endcode + + To remove an update interval that was previously set, call + setUpdateInterval() with a value of 0. + + \note The position source may have a minimum value requirement for + update intervals, as returned by minimumUpdateInterval(). + + \note To use this class from Android service, see + \l {Qt Positioning on Android}. +*/ + +/*! + \enum QGeoPositionInfoSource::PositioningMethod + Defines the types of positioning methods. + + \value NoPositioningMethods None of the positioning methods. + \value SatellitePositioningMethods Satellite-based positioning methods such as GPS or GLONASS. + \value NonSatellitePositioningMethods Other positioning methods such as 3GPP cell identifier or WiFi based positioning. + \value AllPositioningMethods Satellite-based positioning methods as soon as available. Otherwise non-satellite based methods. +*/ + +QGeoPositionInfoSourcePrivate::~QGeoPositionInfoSourcePrivate() +{ + +} + +QGeoPositionInfoSourceFactory *QGeoPositionInfoSourcePrivate::loadFactory(const QCborMap &meta) +{ + const int idx = static_cast(meta.value(QStringLiteral("index")).toDouble()); + if (idx < 0) + return nullptr; + QObject *instance = loader()->instance(idx); + if (!instance) + return nullptr; + return qobject_cast(instance); +} + +QMultiHash QGeoPositionInfoSourcePrivate::plugins(bool reload) +{ + static QMultiHash plugins; + static bool alreadyDiscovered = false; + + if (reload == true) + alreadyDiscovered = false; + + if (!alreadyDiscovered) { + loadPluginMetadata(plugins); + alreadyDiscovered = true; + } + return plugins; +} + +static bool pluginComparator(const QCborMap &p1, const QCborMap &p2) +{ + const QString prio = QStringLiteral("Priority"); + if (p1.contains(prio) && !p2.contains(prio)) + return true; + if (!p1.contains(prio) && p2.contains(prio)) + return false; + if (p1.value(prio).isDouble() && !p2.value(prio).isDouble()) + return true; + if (!p1.value(prio).isDouble() && p2.value(prio).isDouble()) + return false; + return (p1.value(prio).toDouble() > p2.value(prio).toDouble()); +} + +QList QGeoPositionInfoSourcePrivate::pluginsSorted() +{ + QList list = plugins().values(); + std::stable_sort(list.begin(), list.end(), pluginComparator); + return list; +} + +void QGeoPositionInfoSourcePrivate::loadPluginMetadata(QMultiHash &plugins) +{ + QFactoryLoader *l = loader(); + QList meta = l->metaData(); + for (qsizetype i = 0; i < meta.size(); ++i) { + QCborMap obj = meta.at(i).value(QtPluginMetaDataKeys::MetaData).toMap(); + const QLatin1String testableKey("Testable"); + if (!obj.value(testableKey).toBool(true)) { + static bool inTest = qEnvironmentVariableIsSet("QT_QTESTLIB_RUNNING"); + if (inTest) + continue; + } + obj.insert(QLatin1String("index"), static_cast(i)); + plugins.insert(obj.value(QStringLiteral("Provider")).toString(), obj); + } +} + +/*! + Creates a position source with the specified \a parent. +*/ + +QGeoPositionInfoSource::QGeoPositionInfoSource(QObject *parent) + : QObject(*new QGeoPositionInfoSourcePrivate, parent) +{ + qRegisterMetaType(); +} + +/*! + Destroys the position source. +*/ +QGeoPositionInfoSource::~QGeoPositionInfoSource() +{ +} + +/*! + \property QGeoPositionInfoSource::sourceName + \brief This property holds the unique name of the position source + implementation in use. + + This is the same name that can be passed to createSource() in order to + create a new instance of a particular position source implementation. +*/ +QString QGeoPositionInfoSource::sourceName() const +{ + Q_D(const QGeoPositionInfoSource); + return d->sourceName; +} + +/*! + Sets the backend-specific property named \a name to \a value. + Returns \c true on success, \c false otherwise. + Backend-specific properties can be used to configure the positioning subsystem behavior + at runtime. + Supported backend-specific properties are listed and described in + \l {Qt Positioning plugins#Default plugins}. + + \sa backendProperty + \since Qt 5.14 +*/ +bool QGeoPositionInfoSource::setBackendProperty(const QString &name, const QVariant &value) +{ + Q_UNUSED(name) + Q_UNUSED(value) + return false; +} + +/*! + Returns the value of the backend-specific property named \a name, if present. + Otherwise, the returned value will be invalid. + Supported backend-specific properties are listed and described in + \l {Qt Positioning plugins#Default plugins}. + + \sa setBackendProperty + \since Qt 5.14 +*/ +QVariant QGeoPositionInfoSource::backendProperty(const QString &name) const +{ + Q_UNUSED(name) + return QVariant(); +} + +/*! + \property QGeoPositionInfoSource::updateInterval + \brief This property holds the requested interval in milliseconds between each update. + + If the update interval is not set (or is set to 0) the + source will provide updates as often as necessary. + + If the update interval is set, the source will provide updates at an + interval as close to the requested interval as possible. If the requested + interval is less than the minimumUpdateInterval(), + the minimum interval is used instead. + + Changes to the update interval will happen as soon as is practical, however the + time the change takes may vary between implementations. Whether or not the elapsed + time from the previous interval is counted as part of the new interval is also + implementation dependent. + + The default value for this property is 0. + + \note Subclass implementations must call the base implementation of + \c {setUpdateInterval()} so that \c {updateInterval()} returns the correct + value. + + \note This property can't be used to tune update frequency on iOS and macOS, + because their APIs do not provide such possibility. On these systems this + parameter is only used to set \l UpdateTimeoutError and trigger an + \l errorOccurred signal if the update is not received within the desired + interval. +*/ +void QGeoPositionInfoSource::setUpdateInterval(int msec) +{ + Q_D(QGeoPositionInfoSource); + d->interval = msec; +} + +int QGeoPositionInfoSource::updateInterval() const +{ + Q_D(const QGeoPositionInfoSource); + return d->interval.value(); +} + +QBindable QGeoPositionInfoSource::bindableUpdateInterval() +{ + Q_D(QGeoPositionInfoSource); + return QBindable(&d->interval); +} + +/*! + \property QGeoPositionInfoSource::preferredPositioningMethods + + \brief Sets the preferred positioning methods for this source. + + If new methods include a method that is not supported by the source, the + unsupported method will be ignored. + + If new methods do not include a single method available/supported by the + source, the preferred methods will be set to the set of methods which the + source has available. If the source has no method availabe (e.g. because its + Location service is turned off or it does not offer a Location service), + the passed methods are accepted as they are. + + The default value for this property is \l {QGeoPositionInfoSource::} + {NoPositioningMethods}. + + \note Subclass implementations must call the base implementation of + \c {setPreferredPositioningMethods()} to ensure + \c {preferredPositioningMethods()} returns the correct value. + + \sa supportedPositioningMethods() +*/ +void QGeoPositionInfoSource::setPreferredPositioningMethods(PositioningMethods methods) +{ + Q_D(QGeoPositionInfoSource); + d->methods.removeBindingUnlessInWrapper(); + // The supported positioning methods can change during the calls to this + // method, so we can't have a simple check like: + // if (currentMethods == methods) return; + // Instead we need to save the current value and compare it afterwards + const auto prevMethods = d->methods.value(); + + if (supportedPositioningMethods() != QGeoPositionInfoSource::NoPositioningMethods) { + d->methods.setValueBypassingBindings(methods & supportedPositioningMethods()); + if (d->methods.value() == 0) { + d->methods.setValueBypassingBindings(supportedPositioningMethods()); + } + } else { // avoid that turned of Location service blocks any changes to d->methods + d->methods.setValueBypassingBindings(methods); + } + if (prevMethods != d->methods.value()) + d->methods.notify(); +} + +QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSource::preferredPositioningMethods() const +{ + Q_D(const QGeoPositionInfoSource); + return d->methods.value(); +} + +QBindable +QGeoPositionInfoSource::bindablePreferredPositioningMethods() +{ + Q_D(QGeoPositionInfoSource); + return QBindable(&d->methods); +} + +QGeoPositionInfoSource *QGeoPositionInfoSourcePrivate::createSourceReal(const QCborMap &meta, const QVariantMap ¶meters, QObject *parent) +{ + QGeoPositionInfoSource *s = nullptr; + auto factory = QGeoPositionInfoSourcePrivate::loadFactory(meta); + if (factory) + s = factory->positionInfoSource(parent, parameters); + if (s) + s->d_func()->sourceName = meta.value(QStringLiteral("Provider")).toString(); + + return s; +} + +/*! + Creates and returns a position source with the given \a parent that + reads from the system's default sources of location data, or the plugin + with the highest available priority. + + Returns \c nullptr if the system has no default position source, no valid + plugins could be found or the user does not have the permission to access + the current position. +*/ +QGeoPositionInfoSource *QGeoPositionInfoSource::createDefaultSource(QObject *parent) +{ + return createDefaultSource(QVariantMap(), parent); +} + +/*! + Creates and returns a position source with the given \a parent that + reads from the system's default sources of location data, or the plugin + with the highest available priority. + + Returns \c nullptr if the system has no default position source, no valid plugins + could be found or the user does not have the permission to access the current position. + + This method passes \a parameters to the factory to configure the source. + + \since Qt 5.14 +*/ +QGeoPositionInfoSource *QGeoPositionInfoSource::createDefaultSource(const QVariantMap ¶meters, QObject *parent) +{ + const QList plugins = QGeoPositionInfoSourcePrivate::pluginsSorted(); + foreach (const QCborMap &obj, plugins) { + if (obj.value(QStringLiteral("Position")).isBool() + && obj.value(QStringLiteral("Position")).toBool()) { + QGeoPositionInfoSource *source = QGeoPositionInfoSourcePrivate::createSourceReal(obj, parameters, parent); + if (source) + return source; + } + } + return nullptr; +} + +/*! + Creates and returns a position source with the given \a parent, + by loading the plugin named \a sourceName. + + Returns \c nullptr if the plugin cannot be found. +*/ +QGeoPositionInfoSource *QGeoPositionInfoSource::createSource(const QString &sourceName, QObject *parent) +{ + return createSource(sourceName, QVariantMap(), parent); +} + +/*! + Creates and returns a position source with the given \a parent, + by loading the plugin named \a sourceName. + + Returns \c nullptr if the plugin cannot be found. + + This method passes \a parameters to the factory to configure the source. + + \since Qt 5.14 +*/ +QGeoPositionInfoSource *QGeoPositionInfoSource::createSource(const QString &sourceName, const QVariantMap ¶meters, QObject *parent) +{ + auto plugins = QGeoPositionInfoSourcePrivate::plugins(); + if (plugins.contains(sourceName)) + return QGeoPositionInfoSourcePrivate::createSourceReal(plugins.value(sourceName), parameters, parent); + return nullptr; +} + +/*! + Returns a list of available source plugins. This includes any default backend + plugin for the current platform. +*/ +QStringList QGeoPositionInfoSource::availableSources() +{ + QStringList plugins; + const auto meta = QGeoPositionInfoSourcePrivate::plugins(); + for (auto it = meta.cbegin(), end = meta.cend(); it != end; ++it) { + if (it.value().value(QStringLiteral("Position")).isBool() + && it.value().value(QStringLiteral("Position")).toBool()) { + plugins << it.key(); + } + } + + return plugins; +} + +QGeoPositionInfoSource::QGeoPositionInfoSource(QGeoPositionInfoSourcePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + qRegisterMetaType(); + Q_D(QGeoPositionInfoSource); + d->interval.setValueBypassingBindings(0); + d->methods.setValueBypassingBindings(NoPositioningMethods); +} + +/*! + \fn QGeoPositionInfo QGeoPositionInfoSource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const = 0; + + Returns an update containing the last known position, or a null update + if none is available. + + If \a fromSatellitePositioningMethodsOnly is true, this returns the last + known position received from a satellite positioning method; if none + is available, a null update is returned. +*/ + +/*! + \fn virtual PositioningMethods QGeoPositionInfoSource::supportedPositioningMethods() const = 0; + + Returns the positioning methods available to this source. Availability is defined as being usable + at the time of calling this function. Therefore user settings like turned off location service or + limitations to Satellite-based position providers are reflected by this function. Runtime notifications + when the status changes can be obtained via \l supportedPositioningMethodsChanged(). + + Not all platforms distinguish the different positioning methods or communicate the current user + configuration of the device. The following table provides an overview of the current platform situation: + + \table + \header + \li Platform + \li Brief Description + \row + \li Android + \li Individual provider status and general Location service state are known and communicated + when location service is active. + \row + \li GeoClue + \li Hardcoced to always return AllPositioningMethods. + \row + \li GeoClue2 + \li Individual providers are not distinguishable but disabled Location services reflected. + \row + \li iOS/tvOS + \li Hardcoced to always return AllPositioningMethods. + \row + \li macOS + \li Hardcoced to always return AllPositioningMethods. + \row + \li Windows (UWP) + \li Individual providers are not distinguishable but disabled Location services reflected. + \endtable + + \sa supportedPositioningMethodsChanged(), setPreferredPositioningMethods() +*/ + + +/*! + \property QGeoPositionInfoSource::minimumUpdateInterval + \brief This property holds the minimum time (in milliseconds) required to retrieve a position update. + + This is the minimum value accepted by setUpdateInterval() and + requestUpdate(). +*/ + + +/*! + \fn virtual void QGeoPositionInfoSource::startUpdates() = 0; + + Starts emitting updates at regular intervals as specified by setUpdateInterval(). + + If setUpdateInterval() has not been called, the source will emit updates + as soon as they become available. + + An errorOccurred() signal with the \l {QGeoPositionInfoSource::} + {UpdateTimeoutError} will be emitted if this QGeoPositionInfoSource subclass + determines that it will not be able to provide regular updates. This could + happen if a satellite fix is lost or if a hardware error is detected. + Position updates will recommence if the data becomes available later on. + The \l {QGeoPositionInfoSource::}{UpdateTimeoutError} error will not + be emitted again until after the periodic updates resume. + + \note Since Qt6 this method always resets the last error to + \l {QGeoPositionInfoSource::}{NoError} before starting the updates. + + \note To understand how to use this method from an Android service, see + \l {Qt Positioning on Android}. + + On iOS, starting from version 8, Core Location framework requires additional + entries in the application's Info.plist with keys NSLocationAlwaysUsageDescription or + NSLocationWhenInUseUsageDescription and a string to be displayed in the authorization prompt. + The key NSLocationWhenInUseUsageDescription is used when requesting permission + to use location services while the app is in the foreground. + The key NSLocationAlwaysUsageDescription is used when requesting permission + to use location services whenever the app is running (both the foreground and the background). + If both entries are defined, NSLocationWhenInUseUsageDescription has a priority in the + foreground mode. +*/ + +/*! + \fn virtual void QGeoPositionInfoSource::stopUpdates() = 0; + + Stops emitting updates at regular intervals. +*/ + +/*! + \fn virtual void QGeoPositionInfoSource::requestUpdate(int timeout = 0); + + Attempts to get the current position and emit positionUpdated() with + this information. If the current position cannot be found within the given \a timeout + (in milliseconds) or if \a timeout is less than the value returned by + minimumUpdateInterval(), an errorOccurred() signal with the + \l {QGeoPositionInfoSource::}{UpdateTimeoutError} is emitted. + + If the timeout is zero, the timeout defaults to a reasonable timeout + period as appropriate for the source. + + This does nothing if another update request is in progress. However + it can be called even if startUpdates() has already been called and + regular updates are in progress. + + If the source uses multiple positioning methods, it tries to get the + current position from the most accurate positioning method within the + given timeout. + + \note Since Qt6 this method always resets the last error to + \l {QGeoPositionInfoSource::}{NoError} before requesting + the position. + + \note To understand how to use this method from an Android service, see + \l {Qt Positioning on Android}. +*/ + +/*! + \fn virtual QGeoPositionInfoSource::Error QGeoPositionInfoSource::error() const; + + Returns the type of error that last occurred. + + \note Since Qt6 the last error is always reset when calling startUpdates() + or requestUpdate(). +*/ + +/*! + \fn void QGeoPositionInfoSource::positionUpdated(const QGeoPositionInfo &update); + + If startUpdates() or requestUpdate() is called, this signal is emitted + when an update becomes available. + + The \a update value holds the value of the new update. +*/ + +/*! + \fn void QGeoPositionInfoSource::errorOccurred(QGeoPositionInfoSource::Error positioningError) + + This signal is emitted after an error occurred. The \a positioningError + parameter describes the type of error that occurred. +*/ + +/*! + \enum QGeoPositionInfoSource::Error + + The Error enumeration represents the errors which can occur. + + \value AccessError The connection setup to the remote positioning backend failed because the + application lacked the required privileges. + \value ClosedError The remote positioning backend closed the connection, which happens for example in case + the user is switching location services to off. As soon as the location service is re-enabled + regular updates will resume. + \value NoError No error has occurred. + \value UnknownSourceError An unidentified error occurred. + \value [since 6.2] UpdateTimeoutError If requestUpdate() was called, this + error indicates that the current position could not be retrieved within + the specified timeout. If startUpdates() was called, this error + indicates that this QGeoPositionInfoSource subclass determined that it + will not be able to provide further regular updates. In the latter case + the error would not be emitted again until after the regular updates + resume. + */ + +/*! + \fn void QGeoPositionInfoSource::supportedPositioningMethodsChanged() + + This signal is emitted when the supported positioning methods changed. The cause for a change could be + a user turning Location services on/off or restricting Location services to certain types (e.g. GPS only). + Note that changes to the supported positioning methods cannot be detected on all platforms. + \l supportedPositioningMethods() provides an overview of the current platform support. + + \since Qt 5.12 +*/ + +QT_END_NAMESPACE + +#include "moc_qgeopositioninfosource.cpp" diff --git a/src/positioning/qgeopositioninfosource.h b/src/positioning/qgeopositioninfosource.h new file mode 100644 index 0000000..df49301 --- /dev/null +++ b/src/positioning/qgeopositioninfosource.h @@ -0,0 +1,93 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCE_H +#define QGEOPOSITIONINFOSOURCE_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfoSourcePrivate; +class Q_POSITIONING_EXPORT QGeoPositionInfoSource : public QObject +{ + Q_OBJECT + Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval BINDABLE + bindableUpdateInterval) + Q_PROPERTY(int minimumUpdateInterval READ minimumUpdateInterval) + Q_PROPERTY(QString sourceName READ sourceName) + Q_PROPERTY(PositioningMethods preferredPositioningMethods READ preferredPositioningMethods WRITE + setPreferredPositioningMethods BINDABLE bindablePreferredPositioningMethods) + +public: + enum Error { + AccessError = 0, + ClosedError = 1, + UnknownSourceError = 2, + NoError = 3, + UpdateTimeoutError = 4 + }; + Q_ENUM(Error) + + enum PositioningMethod { + NoPositioningMethods = 0x00000000, + SatellitePositioningMethods = 0x000000ff, + NonSatellitePositioningMethods = 0xffffff00, + AllPositioningMethods = 0xffffffff + }; + Q_DECLARE_FLAGS(PositioningMethods, PositioningMethod) + + explicit QGeoPositionInfoSource(QObject *parent); + virtual ~QGeoPositionInfoSource(); + + virtual void setUpdateInterval(int msec); + int updateInterval() const; + QBindable bindableUpdateInterval(); + + virtual void setPreferredPositioningMethods(PositioningMethods methods); + PositioningMethods preferredPositioningMethods() const; + QBindable bindablePreferredPositioningMethods(); + + virtual QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const = 0; + + virtual PositioningMethods supportedPositioningMethods() const = 0; + virtual int minimumUpdateInterval() const = 0; + + QString sourceName() const; + + virtual bool setBackendProperty(const QString &name, const QVariant &value); + virtual QVariant backendProperty(const QString &name) const; + + static QGeoPositionInfoSource *createDefaultSource(QObject *parent); + static QGeoPositionInfoSource *createDefaultSource(const QVariantMap ¶meters, QObject *parent); + static QGeoPositionInfoSource *createSource(const QString &sourceName, QObject *parent); + static QGeoPositionInfoSource *createSource(const QString &sourceName, const QVariantMap ¶meters, QObject *parent); + static QStringList availableSources(); + virtual Error error() const = 0; + +public Q_SLOTS: + virtual void startUpdates() = 0; + virtual void stopUpdates() = 0; + + virtual void requestUpdate(int timeout = 0) = 0; + +Q_SIGNALS: + void positionUpdated(const QGeoPositionInfo &update); + void errorOccurred(QGeoPositionInfoSource::Error); + void supportedPositioningMethodsChanged(); + +protected: + explicit QGeoPositionInfoSource(QGeoPositionInfoSourcePrivate &dd, QObject *parent); + +private: + Q_DISABLE_COPY(QGeoPositionInfoSource) + Q_DECLARE_PRIVATE(QGeoPositionInfoSource) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QGeoPositionInfoSource::PositioningMethods) + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qgeopositioninfosource_p.h b/src/positioning/qgeopositioninfosource_p.h new file mode 100644 index 0000000..39fdbbd --- /dev/null +++ b/src/positioning/qgeopositioninfosource_p.h @@ -0,0 +1,60 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCE_P_H +#define QGEOPOSITIONINFOSOURCE_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 +#include +#include +#include "qgeopositioninfosource.h" +#include "qgeopositioninfosourcefactory.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoPositionInfoSourcePrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGeoPositionInfoSource) +public: + virtual ~QGeoPositionInfoSourcePrivate(); + + static QGeoPositionInfoSourceFactory *loadFactory(const QCborMap &meta); + static QGeoPositionInfoSource *createSourceReal(const QCborMap &meta, + const QVariantMap ¶meters, + QObject *parent); + + void setPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods) + { + q_func()->setPreferredPositioningMethods(methods); + } + + Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QGeoPositionInfoSourcePrivate, int, interval, 0) + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QGeoPositionInfoSourcePrivate, + QGeoPositionInfoSource::PositioningMethods, methods, + &QGeoPositionInfoSourcePrivate::setPositioningMethods, + QGeoPositionInfoSource::NoPositioningMethods) + QString sourceName; + + static QMultiHash plugins(bool reload = false); + static void loadPluginMetadata(QMultiHash &list); + static QList pluginsSorted(); +}; + +QT_END_NAMESPACE + +#endif // QGEOPOSITIONINFOSOURCE_P_H diff --git a/src/positioning/qgeopositioninfosourcefactory.cpp b/src/positioning/qgeopositioninfosourcefactory.cpp new file mode 100644 index 0000000..2cfba01 --- /dev/null +++ b/src/positioning/qgeopositioninfosourcefactory.cpp @@ -0,0 +1,54 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeopositioninfosourcefactory.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QGeoPositionInfoSourceFactory + \inmodule QtPositioning + \since 5.2 + + \brief The QGeoPositionInfoSourceFactory class is a factory class used + as the plugin interface for external providers of positioning data. + + Each factory method takes a parameters argument, which allows to configure + the created source. +*/ + +/*! + \fn QGeoPositionInfoSource *QGeoPositionInfoSourceFactory::positionInfoSource(QObject *parent, const QVariantMap ¶meters) + + Returns a new QGeoPositionInfoSource associated with this plugin + with parent \a parent, and using \a parameters as configuration parameters. + Can also return 0, in which case the plugin loader will use the factory with + the next highest priority. +*/ + +/*! + \fn QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactory::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) + + Returns a new QGeoSatelliteInfoSource associated with this plugin + with parent \a parent, and using \a parameters as configuration parameters. + Can also return 0, in which case the plugin loader will use the factory with + the next highest priority. +*/ + +/*! + \fn QGeoAreaMonitorSource *QGeoPositionInfoSourceFactory::areaMonitor(QObject *parent, const QVariantMap ¶meters); + + Returns a new QGeoAreaMonitorSource associated with this plugin with parent + \a parent, and using \a parameters as configuration parameters. + Can also return 0, in which case the plugin loader will use the factory with + the next highest priority. +*/ + +/*! + Destroys the position info source factory. +*/ +QGeoPositionInfoSourceFactory::~QGeoPositionInfoSourceFactory() +{} + +QT_END_NAMESPACE + diff --git a/src/positioning/qgeopositioninfosourcefactory.h b/src/positioning/qgeopositioninfosourcefactory.h new file mode 100644 index 0000000..94465a6 --- /dev/null +++ b/src/positioning/qgeopositioninfosourcefactory.h @@ -0,0 +1,30 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOPOSITIONINFOSOURCEFACTORY_H +#define QGEOPOSITIONINFOSOURCEFACTORY_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONING_EXPORT QGeoPositionInfoSourceFactory +{ +public: + virtual ~QGeoPositionInfoSourceFactory(); + + virtual QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) = 0; + virtual QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) = 0; + virtual QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) = 0; +}; + +#define QT_POSITION_SOURCE_INTERFACE +Q_DECLARE_INTERFACE(QGeoPositionInfoSourceFactory, + "org.qt-project.qt.position.sourcefactory/6.0") + +QT_END_NAMESPACE + +#endif // QGEOPOSITIONINFOSOURCEFACTORY_H diff --git a/src/positioning/qgeorectangle.cpp b/src/positioning/qgeorectangle.cpp new file mode 100644 index 0000000..5cbfa01 --- /dev/null +++ b/src/positioning/qgeorectangle.cpp @@ -0,0 +1,935 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeorectangle.h" +#include "qgeorectangle_p.h" + +#include "qwebmercator_p.h" +#include "qdoublevector2d_p.h" +#include "qgeocoordinate.h" +#include "qnumeric.h" +#include "qlocationutils_p.h" +#include +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoRectangle) + +/*! + \class QGeoRectangle + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.2 + + \brief The QGeoRectangle class defines a rectangular geographic area. + + The rectangle is defined in terms of a QGeoCoordinate which specifies the + top left coordinate of the rectangle and a QGeoCoordinate which specifies + the bottom right coordinate of the rectangle. + + A geo rectangle is considered invalid if the top left or bottom right + coordinates are invalid or if the top left coordinate is south of the + bottom right coordinate. + + Geo rectangles can never cross the poles. + + Several methods behave as though the geo rectangle is defined in terms of a + center coordinate, the width of the geo rectangle in degrees and the height + of the geo rectangle in degrees. + + If the height or center of a geo rectangle is adjusted such that it would + cross one of the poles the height is modified such that the geo rectangle + touches but does not cross the pole and that the center coordinate is still + in the center of the geo rectangle. + + This class is a \l Q_GADGET since Qt 5.5. It can be + \l{Cpp_value_integration_positioning}{directly used from C++ and QML}. +*/ + +/*! + \property QGeoRectangle::bottomLeft + \brief This property holds the bottom left coorindate of this geo rectangle. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoRectangle::bottomRight + \brief This property holds the bottom right coordinate of this geo rectangle. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoRectangle::topLeft + \brief This property holds the top left coordinate of this geo rectangle. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoRectangle::topRight + \brief This property holds the top right coordinate of this geo rectangle. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoRectangle::center + \brief This property holds the center of this geo rectangle. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \sa QGeoShape::center + + \since 5.5 +*/ + +/*! + \property QGeoRectangle::width + \brief This property holds the width of this geo rectangle in degrees. + + The property value is undefined if this geo rectangle is invalid. + + If the new width is less than 0.0 or if this geo rectangle is invalid, this + function does nothing. To set up the values of an invalid + geo rectangle based on the center, width, and height, you should use + \l setCenter() first to make the geo rectangle valid. + + 360.0 is the width used only if the new width is equal or greater than 360. + In such cases the leftmost longitude of the geo rectangle is set to -180.0 + degrees and the rightmost longitude of the geo rectangle is set to 180.0 + degrees. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoRectangle::height + \brief This property holds the height of this geo rectangle in degrees. + + The property value is undefined if this geo rectangle is invalid. + + If the new height is less than 0.0 or if this geo rectangle is invalid, + the property is not changed. To set up the values of an invalid + geo rectangle based on the center, width, and height, you should use + \l setCenter() first to make the geo rectangle valid. + + If the change in height would cause the geo rectangle to cross a pole, + the height is adjusted such that the geo rectangle only touches the pole. + + This change is done such that the center coordinate is still at the + center of the geo rectangle, which may result in a geo rectangle with + a smaller height than expected. + + 180.0 is the height used only if the new height is greater or equal than 180. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +inline QGeoRectanglePrivate *QGeoRectangle::d_func() +{ + return static_cast(d_ptr.data()); +} + +inline const QGeoRectanglePrivate *QGeoRectangle::d_func() const +{ + return static_cast(d_ptr.constData()); +} + +struct RectangleVariantConversions +{ + RectangleVariantConversions() + { + QMetaType::registerConverter(); + QMetaType::registerConverter(); + } +}; + + +Q_GLOBAL_STATIC(RectangleVariantConversions, initRectangleConversions) + +/*! + Constructs a new, invalid geo rectangle. +*/ +QGeoRectangle::QGeoRectangle() +: QGeoShape(new QGeoRectanglePrivate) +{ + initRectangleConversions(); +} + +/*! + Constructs a new geo rectangle centered at \a center with a + width in degrees of \a degreesWidth and a height in degrees of \a degreesHeight. + + If \a degreesHeight would take the geo rectangle beyond one of the poles, + the height of the geo rectangle will be truncated such that the geo rectangle + only extends up to the pole. The center of the geo rectangle will be + unchanged, and the height will be adjusted such that the center point is at + the center of the truncated geo rectangle. +*/ +QGeoRectangle::QGeoRectangle(const QGeoCoordinate ¢er, double degreesWidth, double degreesHeight) +{ + initRectangleConversions(); + d_ptr = new QGeoRectanglePrivate(center, center); + setWidth(degreesWidth); + setHeight(degreesHeight); +} + +/*! + Constructs a new geo rectangle with a top left coordinate \a topLeft and a bottom right + coordinate \a bottomRight. +*/ +QGeoRectangle::QGeoRectangle(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight) +{ + initRectangleConversions(); + d_ptr = new QGeoRectanglePrivate(topLeft, bottomRight); +} + +/*! + Constructs a new geo rectangle, of minimum size, containing all of the \a coordinates. +*/ +QGeoRectangle::QGeoRectangle(const QList &coordinates) +{ + initRectangleConversions(); + if (coordinates.isEmpty()) { + d_ptr = new QGeoRectanglePrivate; + } else { + const QGeoCoordinate &startCoordinate = coordinates.first(); + d_ptr = new QGeoRectanglePrivate(startCoordinate, startCoordinate); + + foreach (const QGeoCoordinate &coordinate, coordinates) { + d_func()->extendRectangle(coordinate); + } + } +} + +/*! + Constructs a geo rectangle from the contents of \a other. +*/ +QGeoRectangle::QGeoRectangle(const QGeoRectangle &other) +: QGeoShape(other) +{ + initRectangleConversions(); +} + +/*! + Constructs a geo rectangle from the contents of \a other. +*/ +QGeoRectangle::QGeoRectangle(const QGeoShape &other) +: QGeoShape(other) +{ + initRectangleConversions(); + if (type() != QGeoShape::RectangleType) + d_ptr = new QGeoRectanglePrivate; +} + +/*! + Destroys this geo rectangle. +*/ +QGeoRectangle::~QGeoRectangle() +{ +} + +/*! + Assigns \a other to this geo rectangle and returns a reference to this geo rectangle. +*/ +QGeoRectangle &QGeoRectangle::operator=(const QGeoRectangle &other) +{ + QGeoShape::operator=(other); + return *this; +} + +bool QGeoRectanglePrivate::isValid() const +{ + return topLeft.isValid() && bottomRight.isValid() && + topLeft.latitude() >= bottomRight.latitude(); +} + +bool QGeoRectanglePrivate::isEmpty() const +{ + if (!isValid()) + return true; + + return topLeft.latitude() == bottomRight.latitude() || + topLeft.longitude() == bottomRight.longitude(); +} + +/*! + Sets the top left coordinate of this geo rectangle to \a topLeft. +*/ +void QGeoRectangle::setTopLeft(const QGeoCoordinate &topLeft) +{ + Q_D(QGeoRectangle); + + d->topLeft = topLeft; +} + +/*! + Returns the top left coordinate of this geo rectangle. +*/ +QGeoCoordinate QGeoRectangle::topLeft() const +{ + Q_D(const QGeoRectangle); + + return d->topLeft; +} + +/*! + Sets the top right coordinate of this geo rectangle to \a topRight. +*/ +void QGeoRectangle::setTopRight(const QGeoCoordinate &topRight) +{ + Q_D(QGeoRectangle); + + d->topLeft.setLatitude(topRight.latitude()); + d->bottomRight.setLongitude(topRight.longitude()); +} + +/*! + Returns the top right coordinate of this geo rectangle. +*/ +QGeoCoordinate QGeoRectangle::topRight() const +{ + // TODO remove? + if (!isValid()) + return QGeoCoordinate(); + + Q_D(const QGeoRectangle); + + return QGeoCoordinate(d->topLeft.latitude(), d->bottomRight.longitude()); +} + +/*! + Sets the bottom left coordinate of this geo rectangle to \a bottomLeft. +*/ +void QGeoRectangle::setBottomLeft(const QGeoCoordinate &bottomLeft) +{ + Q_D(QGeoRectangle); + + d->bottomRight.setLatitude(bottomLeft.latitude()); + d->topLeft.setLongitude(bottomLeft.longitude()); +} + +/*! + Returns the bottom left coordinate of this geo rectangle. +*/ +QGeoCoordinate QGeoRectangle::bottomLeft() const +{ + // TODO remove? + if (!isValid()) + return QGeoCoordinate(); + + Q_D(const QGeoRectangle); + + return QGeoCoordinate(d->bottomRight.latitude(), d->topLeft.longitude()); +} + +/*! + Sets the bottom right coordinate of this geo rectangle to \a bottomRight. +*/ +void QGeoRectangle::setBottomRight(const QGeoCoordinate &bottomRight) +{ + Q_D(QGeoRectangle); + + d->bottomRight = bottomRight; +} + +/*! + Returns the bottom right coordinate of this geo rectangle. +*/ +QGeoCoordinate QGeoRectangle::bottomRight() const +{ + Q_D(const QGeoRectangle); + + return d->bottomRight; +} + +/*! + Sets the center of this geo rectangle to \a center. + + If this causes the geo rectangle to cross on of the poles the height of the + geo rectangle will be truncated such that the geo rectangle only extends up + to the pole. The center of the geo rectangle will be unchanged, and the + height will be adjusted such that the center point is at the center of the + truncated geo rectangle. + +*/ +void QGeoRectangle::setCenter(const QGeoCoordinate ¢er) +{ + Q_D(QGeoRectangle); + + if (!isValid()) { + d->topLeft = center; + d->bottomRight = center; + return; + } + double width = this->width(); + double height = this->height(); + + double tlLat = center.latitude() + height / 2.0; + double tlLon = center.longitude() - width / 2.0; + double brLat = center.latitude() - height / 2.0; + double brLon = center.longitude() + width / 2.0; + tlLon = QLocationUtils::wrapLong(tlLon); + brLon = QLocationUtils::wrapLong(brLon); + + if (tlLat > 90.0) { + brLat = 2 * center.latitude() - 90.0; + tlLat = 90.0; + } + + if (tlLat < -90.0) { + brLat = -90.0; + tlLat = -90.0; + } + + if (brLat > 90.0) { + tlLat = 90.0; + brLat = 90.0; + } + + if (brLat < -90.0) { + tlLat = 2 * center.latitude() + 90.0; + brLat = -90.0; + } + + if (width == 360.0) { + tlLon = -180.0; + brLon = 180.0; + } + + d->topLeft = QGeoCoordinate(tlLat, tlLon); + d->bottomRight = QGeoCoordinate(brLat, brLon); +} + +/*! + Returns the center of this geo rectangle. Equivalent to QGeoShape::center(). +*/ +QGeoCoordinate QGeoRectangle::center() const +{ + Q_D(const QGeoRectangle); + + return d->center(); +} + +/*! + Sets the width of this geo rectangle in degrees to \a degreesWidth. +*/ +void QGeoRectangle::setWidth(double degreesWidth) +{ + if (!isValid()) + return; + + if (degreesWidth < 0.0) + return; + + Q_D(QGeoRectangle); + + if (degreesWidth >= 360.0) { + d->topLeft.setLongitude(-180.0); + d->bottomRight.setLongitude(180.0); + return; + } + + double tlLat = d->topLeft.latitude(); + double brLat = d->bottomRight.latitude(); + + QGeoCoordinate c = center(); + + double tlLon = c.longitude() - degreesWidth / 2.0; + tlLon = QLocationUtils::wrapLong(tlLon); + + double brLon = c.longitude() + degreesWidth / 2.0; + brLon = QLocationUtils::wrapLong(brLon); + + d->topLeft = QGeoCoordinate(tlLat, tlLon); + d->bottomRight = QGeoCoordinate(brLat, brLon); +} + +/*! + Returns the width of this geo rectangle in degrees. + + The return value is undefined if this geo rectangle is invalid. +*/ +double QGeoRectangle::width() const +{ + if (!isValid()) + return qQNaN(); + + Q_D(const QGeoRectangle); + + double result = d->bottomRight.longitude() - d->topLeft.longitude(); + if (result < 0.0) + result += 360.0; + if (result > 360.0) + result -= 360.0; + + return result; +} + +/*! + Sets the height of this geo rectangle in degrees to \a degreesHeight. +*/ +void QGeoRectangle::setHeight(double degreesHeight) +{ + if (!isValid()) + return; + + if (degreesHeight < 0.0) + return; + + if (degreesHeight >= 180.0) { + degreesHeight = 180.0; + } + + Q_D(QGeoRectangle); + + double tlLon = d->topLeft.longitude(); + double brLon = d->bottomRight.longitude(); + + QGeoCoordinate c = center(); + + double tlLat = c.latitude() + degreesHeight / 2.0; + double brLat = c.latitude() - degreesHeight / 2.0; + + if (tlLat > 90.0) { + brLat = 2* c.latitude() - 90.0; + tlLat = 90.0; + } + + if (tlLat < -90.0) { + brLat = -90.0; + tlLat = -90.0; + } + + if (brLat > 90.0) { + tlLat = 90.0; + brLat = 90.0; + } + + if (brLat < -90.0) { + tlLat = 2 * c.latitude() + 90.0; + brLat = -90.0; + } + + d->topLeft = QGeoCoordinate(tlLat, tlLon); + d->bottomRight = QGeoCoordinate(brLat, brLon); +} + +/*! + Returns the height of this geo rectangle in degrees. + + The return value is undefined if this geo rectangle is invalid. +*/ +double QGeoRectangle::height() const +{ + if (!isValid()) + return qQNaN(); + + Q_D(const QGeoRectangle); + + return d->topLeft.latitude() - d->bottomRight.latitude(); +} + +bool QGeoRectanglePrivate::contains(const QGeoCoordinate &coordinate) const +{ + if (!isValid() || !coordinate.isValid()) + return false; + + double left = topLeft.longitude(); + double right = bottomRight.longitude(); + double top = topLeft.latitude(); + double bottom = bottomRight.latitude(); + + double lon = coordinate.longitude(); + double lat = coordinate.latitude(); + + if (lat > top) + return false; + if (lat < bottom) + return false; + + if ((lat == 90.0) && (top == 90.0)) + return true; + + if ((lat == -90.0) && (bottom == -90.0)) + return true; + + if (left <= right) { + if ((lon < left) || (lon > right)) + return false; + } else { + if ((lon < left) && (lon > right)) + return false; + } + + return true; +} + +QGeoCoordinate QGeoRectanglePrivate::center() const +{ + if (!isValid()) + return QGeoCoordinate(); + + double cLat = (topLeft.latitude() + bottomRight.latitude()) / 2.0; + double cLon = (bottomRight.longitude() + topLeft.longitude()) / 2.0; + + if (topLeft.longitude() > bottomRight.longitude()) + cLon = cLon - 180.0; + + cLon = QLocationUtils::wrapLong(cLon); + return QGeoCoordinate(cLat, cLon); +} + +QGeoRectangle QGeoRectanglePrivate::boundingGeoRectangle() const +{ + return QGeoRectangle(topLeft, bottomRight); +} + +/*! + Returns whether the geo rectangle \a rectangle is contained within this + geo rectangle. +*/ +bool QGeoRectangle::contains(const QGeoRectangle &rectangle) const +{ + Q_D(const QGeoRectangle); + + return (d->contains(rectangle.topLeft()) + && d->contains(rectangle.topRight()) + && d->contains(rectangle.bottomLeft()) + && d->contains(rectangle.bottomRight())); +} + +/*! + Returns whether the geo rectangle \a rectangle intersects this geo rectangle. + + If the top or bottom edges of both geo rectangles are at one of the poles + the geo rectangles are considered to be intersecting, since the longitude + is irrelevant when the edges are at the pole. +*/ +bool QGeoRectangle::intersects(const QGeoRectangle &rectangle) const +{ + Q_D(const QGeoRectangle); + + double left1 = d->topLeft.longitude(); + double right1 = d->bottomRight.longitude(); + double top1 = d->topLeft.latitude(); + double bottom1 = d->bottomRight.latitude(); + + double left2 = rectangle.d_func()->topLeft.longitude(); + double right2 = rectangle.d_func()->bottomRight.longitude(); + double top2 = rectangle.d_func()->topLeft.latitude(); + double bottom2 = rectangle.d_func()->bottomRight.latitude(); + + if (top1 < bottom2) + return false; + + if (bottom1 > top2) + return false; + + if ((top1 == 90.0) && (top1 == top2)) + return true; + + if ((bottom1 == -90.0) && (bottom1 == bottom2)) + return true; + + if (left1 < right1) { + if (left2 < right2) { + if ((left1 > right2) || (right1 < left2)) + return false; + } else { + if ((left1 > right2) && (right1 < left2)) + return false; + } + } else { + if (left2 < right2) { + if ((left2 > right1) && (right2 < left1)) + return false; + } else { + // if both wrap then they have to intersect + } + } + + return true; +} + +/*! + Translates this geo rectangle by \a degreesLatitude northwards and \a + degreesLongitude eastwards. + + Negative values of \a degreesLatitude and \a degreesLongitude correspond to + southward and westward translation respectively. + + If the translation would have caused the geo rectangle to cross a pole the + geo rectangle will be translated until the top or bottom edge of the geo rectangle + touches the pole but not further. +*/ +void QGeoRectangle::translate(double degreesLatitude, double degreesLongitude) +{ + // TODO handle dlat, dlon larger than 360 degrees + + Q_D(QGeoRectangle); + + double tlLat = d->topLeft.latitude(); + double tlLon = d->topLeft.longitude(); + double brLat = d->bottomRight.latitude(); + double brLon = d->bottomRight.longitude(); + + if (degreesLatitude >= 0.0) + degreesLatitude = qMin(degreesLatitude, 90.0 - tlLat); + else + degreesLatitude = qMax(degreesLatitude, -90.0 - brLat); + + if ( (tlLon != -180.0) || (brLon != 180.0) ) { + tlLon = QLocationUtils::wrapLong(tlLon + degreesLongitude); + brLon = QLocationUtils::wrapLong(brLon + degreesLongitude); + } + + tlLat += degreesLatitude; + brLat += degreesLatitude; + + d->topLeft = QGeoCoordinate(tlLat, tlLon); + d->bottomRight = QGeoCoordinate(brLat, brLon); +} + +/*! + Returns a copy of this geo rectangle translated by \a degreesLatitude northwards and \a + degreesLongitude eastwards. + + Negative values of \a degreesLatitude and \a degreesLongitude correspond to + southward and westward translation respectively. + + \sa translate() +*/ +QGeoRectangle QGeoRectangle::translated(double degreesLatitude, double degreesLongitude) const +{ + QGeoRectangle result(*this); + result.translate(degreesLatitude, degreesLongitude); + return result; +} + +/*! + Extends the geo rectangle to also cover the coordinate \a coordinate + + \since 5.9 +*/ +void QGeoRectangle::extendRectangle(const QGeoCoordinate &coordinate) +{ + Q_D(QGeoRectangle); + d->extendRectangle(coordinate); +} + +/*! + Returns the smallest geo rectangle which contains both this geo rectangle and \a rectangle. + + If the centers of the two geo rectangles are separated by exactly 180.0 degrees then the + width is set to 360.0 degrees with the leftmost longitude set to -180.0 degrees and the + rightmost longitude set to 180.0 degrees. This is done to ensure that the result is + independent of the order of the operands. + +*/ +QGeoRectangle QGeoRectangle::united(const QGeoRectangle &rectangle) const +{ + QGeoRectangle result(*this); + if (rectangle.isValid()) + result |= rectangle; + return result; +} + +/*! + Extends the rectangle in the smallest possible way to include \a coordinate in + the shape. + + Both the rectangle and coordinate needs to be valid. If the rectangle already covers + the coordinate noting happens. + +*/ +void QGeoRectanglePrivate::extendRectangle(const QGeoCoordinate &coordinate) +{ + if (!isValid() || !coordinate.isValid() || contains(coordinate)) + return; + + double left = topLeft.longitude(); + double right = bottomRight.longitude(); + double top = topLeft.latitude(); + double bottom = bottomRight.latitude(); + + double inputLat = coordinate.latitude(); + double inputLon = coordinate.longitude(); + + top = qMax(top, inputLat); + bottom = qMin(bottom, inputLat); + + bool wrap = left > right; + + if (wrap && inputLon > right && inputLon < left) { + if (qAbs(left - inputLon) < qAbs(right - inputLon)) + left = inputLon; + else + right = inputLon; + } else if (!wrap) { + if (inputLon < left) { + if (360 - (right - inputLon) < left - inputLon) + right = inputLon; + else + left = inputLon; + } else if (inputLon > right) { + if (360 - (inputLon - left) < inputLon - right) + left = inputLon; + else + right = inputLon; + } + } + topLeft = QGeoCoordinate(top, left); + bottomRight = QGeoCoordinate(bottom, right); +} + +/*! + \fn QGeoRectangle QGeoRectangle::operator|(const QGeoRectangle &rectangle) const + + Returns the smallest geo rectangle which contains both this geo rectangle and \a rectangle. + + If the centers of the two geo rectangles are separated by exactly 180.0 degrees then the + width is set to 360.0 degrees with the leftmost longitude set to -180.0 degrees and the + rightmost longitude set to 180.0 degrees. This is done to ensure that the result is + independent of the order of the operands. + +*/ + +/*! + Returns the smallest geo rectangle which contains both this geo rectangle and \a rectangle. + + If the centers of the two geo rectangles are separated by exactly 180.0 degrees then the + width is set to 360.0 degrees with the leftmost longitude set to -180.0 degrees and the + rightmost longitude set to 180.0 degrees. This is done to ensure that the result is + independent of the order of the operands. + +*/ +QGeoRectangle &QGeoRectangle::operator|=(const QGeoRectangle &rectangle) +{ + // If non-intersecting goes for most narrow box + + Q_D(QGeoRectangle); + + double top = qMax(d->topLeft.latitude(), rectangle.d_func()->topLeft.latitude()); + double bottom = qMin(d->bottomRight.latitude(), rectangle.d_func()->bottomRight.latitude()); + + QGeoRectangle candidate( + {top, d->topLeft.longitude()}, + {bottom, rectangle.d_func()->bottomRight.longitude()} + ); + QGeoRectangle otherCandidate( + {top, rectangle.d_func()->topLeft.longitude()}, + {bottom, d->bottomRight.longitude()} + ); + double unwrappedWidth = (candidate.width() < rectangle.width() ? 360 : 0) + candidate.width(); + double otherUnwrappedWidth = (otherCandidate.width() < width() ? 360 : 0) + otherCandidate.width(); + if (otherUnwrappedWidth < unwrappedWidth) { + candidate = otherCandidate; + unwrappedWidth = otherUnwrappedWidth; + } + if (360 <= unwrappedWidth) { + candidate.d_func()->topLeft.setLongitude(-180.0); + candidate.d_func()->bottomRight.setLongitude(180.0); + } + + candidate = (candidate.width() < width() ? *this : candidate); + candidate = (candidate.width() < rectangle.width() ? rectangle : candidate); + + double middle1 = center().longitude(); + double middle2 = rectangle.center().longitude(); + if ((middle1 <= middle2 ? 0 : 360) + middle2 - middle1 == 180) { + candidate.d_func()->topLeft.setLongitude(-180.0); + candidate.d_func()->bottomRight.setLongitude(180.0); + } + + *this = candidate; + this->d_func()->topLeft.setLatitude(top); + this->d_func()->bottomRight.setLatitude(bottom); + + return *this; +} + +/*! + Returns the geo rectangle properties as a string. + + \since 5.5 +*/ +QString QGeoRectangle::toString() const +{ + if (type() != QGeoShape::RectangleType) { + qWarning("Not a rectangle a %d\n", type()); + return QStringLiteral("QGeoRectangle(not a rectangle)"); + } + + return QStringLiteral("QGeoRectangle({%1, %2}, {%3, %4})") + .arg(topLeft().latitude()) + .arg(topLeft().longitude()) + .arg(bottomRight().latitude()) + .arg(bottomRight().longitude()); +} + +/******************************************************************************* +*******************************************************************************/ + +QGeoRectanglePrivate::QGeoRectanglePrivate() +: QGeoShapePrivate(QGeoShape::RectangleType) +{ +} + +QGeoRectanglePrivate::QGeoRectanglePrivate(const QGeoCoordinate &topLeft, + const QGeoCoordinate &bottomRight) +: QGeoShapePrivate(QGeoShape::RectangleType), topLeft(topLeft), bottomRight(bottomRight) +{ +} + +QGeoRectanglePrivate::QGeoRectanglePrivate(const QGeoRectanglePrivate &other) +: QGeoShapePrivate(QGeoShape::RectangleType), topLeft(other.topLeft), + bottomRight(other.bottomRight) +{ +} + +QGeoRectanglePrivate::~QGeoRectanglePrivate() {} + +QGeoShapePrivate *QGeoRectanglePrivate::clone() const +{ + return new QGeoRectanglePrivate(*this); +} + +bool QGeoRectanglePrivate::operator==(const QGeoShapePrivate &other) const +{ + if (!QGeoShapePrivate::operator==(other)) + return false; + + const QGeoRectanglePrivate &otherBox = static_cast(other); + + return topLeft == otherBox.topLeft && bottomRight == otherBox.bottomRight; +} + +size_t QGeoRectanglePrivate::hash(size_t seed) const +{ + return qHashMulti(seed, topLeft, bottomRight); +} + +QT_END_NAMESPACE + +#include "moc_qgeorectangle.cpp" diff --git a/src/positioning/qgeorectangle.h b/src/positioning/qgeorectangle.h new file mode 100644 index 0000000..a6f64d4 --- /dev/null +++ b/src/positioning/qgeorectangle.h @@ -0,0 +1,87 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEORECTANGLE_H +#define QGEORECTANGLE_H + +#include + +QT_BEGIN_NAMESPACE + +class QGeoRectanglePrivate; + +class Q_POSITIONING_EXPORT QGeoRectangle : public QGeoShape +{ + Q_GADGET + Q_PROPERTY(QGeoCoordinate bottomLeft READ bottomLeft WRITE setBottomLeft) + Q_PROPERTY(QGeoCoordinate bottomRight READ bottomRight WRITE setBottomRight) + Q_PROPERTY(QGeoCoordinate topLeft READ topLeft WRITE setTopLeft) + Q_PROPERTY(QGeoCoordinate topRight READ topRight WRITE setTopRight) + Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter) + Q_PROPERTY(double height READ height WRITE setHeight) + Q_PROPERTY(double width READ width WRITE setWidth) + +public: + QGeoRectangle(); + QGeoRectangle(const QGeoCoordinate ¢er, double degreesWidth, double degreesHeight); + QGeoRectangle(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight); + QGeoRectangle(const QList &coordinates); + QGeoRectangle(const QGeoRectangle &other); + QGeoRectangle(const QGeoShape &other); + + ~QGeoRectangle(); + + QGeoRectangle &operator=(const QGeoRectangle &other); + + void setTopLeft(const QGeoCoordinate &topLeft); + QGeoCoordinate topLeft() const; + + void setTopRight(const QGeoCoordinate &topRight); + QGeoCoordinate topRight() const; + + void setBottomLeft(const QGeoCoordinate &bottomLeft); + QGeoCoordinate bottomLeft() const; + + void setBottomRight(const QGeoCoordinate &bottomRight); + QGeoCoordinate bottomRight() const; + + void setCenter(const QGeoCoordinate ¢er); + QGeoCoordinate center() const; + + void setWidth(double degreesWidth); + double width() const; + + void setHeight(double degreesHeight); + double height() const; + + using QGeoShape::contains; + bool contains(const QGeoRectangle &rectangle) const; + Q_INVOKABLE bool intersects(const QGeoRectangle &rectangle) const; + + Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude); + Q_INVOKABLE QGeoRectangle translated(double degreesLatitude, double degreesLongitude) const; + Q_INVOKABLE void extendRectangle(const QGeoCoordinate &coordinate); + + Q_INVOKABLE QGeoRectangle united(const QGeoRectangle &rectangle) const; + QGeoRectangle operator|(const QGeoRectangle &rectangle) const; + QGeoRectangle &operator|=(const QGeoRectangle &rectangle); + + Q_INVOKABLE QString toString() const; + +private: + inline QGeoRectanglePrivate *d_func(); + inline const QGeoRectanglePrivate *d_func() const; +}; + +Q_DECLARE_TYPEINFO(QGeoRectangle, Q_RELOCATABLE_TYPE); + +inline QGeoRectangle QGeoRectangle::operator|(const QGeoRectangle &rectangle) const +{ + return united(rectangle); +} + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoRectangle, Q_POSITIONING_EXPORT) + +#endif diff --git a/src/positioning/qgeorectangle_p.h b/src/positioning/qgeorectangle_p.h new file mode 100644 index 0000000..c4e4fe3 --- /dev/null +++ b/src/positioning/qgeorectangle_p.h @@ -0,0 +1,53 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEORECTANGLE_P_H +#define QGEORECTANGLE_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 "qgeoshape_p.h" +#include "qgeocoordinate.h" + +QT_BEGIN_NAMESPACE + +class QGeoRectanglePrivate : public QGeoShapePrivate +{ +public: + QGeoRectanglePrivate(); + QGeoRectanglePrivate(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight); + QGeoRectanglePrivate(const QGeoRectanglePrivate &other); + ~QGeoRectanglePrivate(); + + bool isValid() const override; + bool isEmpty() const override; + bool contains(const QGeoCoordinate &coordinate) const override; + + QGeoCoordinate center() const override; + + QGeoRectangle boundingGeoRectangle() const override; + + void extendRectangle(const QGeoCoordinate &coordinate); + + QGeoShapePrivate *clone() const override; + + bool operator==(const QGeoShapePrivate &other) const override; + + size_t hash(size_t seed) const override; + + QGeoCoordinate topLeft; + QGeoCoordinate bottomRight; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qgeosatelliteinfo.cpp b/src/positioning/qgeosatelliteinfo.cpp new file mode 100644 index 0000000..6965074 --- /dev/null +++ b/src/positioning/qgeosatelliteinfo.cpp @@ -0,0 +1,401 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qgeosatelliteinfo.h" +#include "private/qgeosatelliteinfo_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoSatelliteInfo) + +/*! + \class QGeoSatelliteInfo + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \ingroup shared + \since 5.2 + + \brief The QGeoSatelliteInfo class contains basic information about a satellite. + + \sa QGeoSatelliteInfoSource +*/ + +/*! + \enum QGeoSatelliteInfo::Attribute + Defines the attributes for the satellite information. + \value Elevation The elevation of the satellite, in degrees. + \value Azimuth The azimuth to true north, in degrees. +*/ + +/*! + \enum QGeoSatelliteInfo::SatelliteSystem + Defines the GNSS system of the satellite. + \value Undefined Not defined. + \value GPS Global Positioning System (USA). + \value GLONASS Global Positioning System (Russia). + \value GALILEO Global navigation satellite system (EU). + \value BEIDOU BeiDou navigation satellite system (China). + \value QZSS Quasi-Zenith Satellite System (Japan). + \value Multiple This type normally indicates that the information is + received from a device that supports multiple satellite systems, and + the satellite system is not explicitly specified. Depending on the + data source, you might use other information to determine the actual + system type. One example of the usage of this type is an NMEA $GNGSA + message, which contains the IDs of the satellites being used, but + does not explicitly mention their system types. + \value CustomType The first type that can be used for user purposes. For + example when reimplementing NMEA data parsing in + \l QNmeaSatelliteInfoSource. User can add more types using + \c {CustomType + 1}, \c {CustomType + 2} and so on. +*/ + +/*! + Creates a satellite information object. +*/ +QGeoSatelliteInfo::QGeoSatelliteInfo() + : d(new QGeoSatelliteInfoPrivate) +{ + d->signal = -1; + d->satId = -1; + d->system = QGeoSatelliteInfo::Undefined; +} + +/*! + Creates a satellite information object with the values of \a other. +*/ + +QGeoSatelliteInfo::QGeoSatelliteInfo(const QGeoSatelliteInfo &other) + : d(other.d) +{ +} + +QGeoSatelliteInfo::QGeoSatelliteInfo(QGeoSatelliteInfoPrivate &dd) : d(&dd) +{ +} + +/*! + \fn QGeoSatelliteInfo::QGeoSatelliteInfo(QGeoSatelliteInfo &&other) noexcept + \since 6.2 + + Creates a satellite information object by moving from \a other. + + Note that a moved-from QGeoSatelliteInfo can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + Destroys a satellite information object. +*/ +QGeoSatelliteInfo::~QGeoSatelliteInfo() +{ +} + +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QGeoSatelliteInfoPrivate) + +/*! + Assigns the values from \a other to this object. +*/ +QGeoSatelliteInfo &QGeoSatelliteInfo::operator=(const QGeoSatelliteInfo & other) +{ + if (this == &other) + return *this; + + d = other.d; + return *this; +} + +/*! + \fn QGeoSatelliteInfo &QGeoSatelliteInfo::operator=(QGeoSatelliteInfo &&other) noexcept + \since 6.2 + + Move-assigns the value from \a other to this object + + Note that a moved-from QGeoSatelliteInfo can only be destroyed or + assigned to. The effect of calling other functions than the destructor + or one of the assignment operators is undefined. +*/ + +/*! + \fn bool QGeoSatelliteInfo::operator==(const QGeoSatelliteInfo &lhs, const QGeoSatelliteInfo &rhs) + + Returns \c true if all the parameters of the \a lhs satellite are the same + as those of \a rhs. Otherwise returns \c false. +*/ + +/*! + \fn bool QGeoSatelliteInfo::operator!=(const QGeoSatelliteInfo &lhs, const QGeoSatelliteInfo &rhs) + + Returns \c true if any of the parameters of the \a lhs satellite are not + the same as those of \a rhs. Otherwise returns \c false. +*/ + +/*! + Sets the Satellite System (GPS, GLONASS, ...) to \a system. +*/ +void QGeoSatelliteInfo::setSatelliteSystem(SatelliteSystem system) +{ + d.detach(); + d->system = system; +} + +/*! + Returns the Satellite System (GPS, GLONASS, ...) + + \note This value can be used together with \l satelliteIdentifier() + to uniquely identify a satellite. + + \sa satelliteIdentifier() +*/ +QGeoSatelliteInfo::SatelliteSystem QGeoSatelliteInfo::satelliteSystem() const +{ + return d->system; +} + +/*! + Sets the satellite identifier number to \a satId. + + The satellite identifier number can be used to identify a satellite within + the satellite system. + + The actual value may vary, depending on the platform and the selected + backend. + + For example, if \e nmea plugin is used, the satellite identifier for GPS + satellite system represents the PRN (Pseudo-random noise) number, and the + satellite identifier for GLONASS satellite system represents the slot + number. +*/ +void QGeoSatelliteInfo::setSatelliteIdentifier(int satId) +{ + d.detach(); + d->satId = satId; +} + +/*! + Returns the satellite identifier number. + + The satellite identifier number can be used to identify a satellite within + the satellite system. + + The actual value may vary, depending on the platform and the selected + backend. + + For example, if \e nmea plugin is used, the satellite identifier for GPS + satellite system represents the PRN (Pseudo-random noise) number, and the + satellite identifier for GLONASS satellite system represents the slot + number. + + For NMEA-based backends the satellite identifier can be used to determine + the satellite system type if it is not available from other sources. + You can refer to \l {https://gpsd.gitlab.io/gpsd/NMEA.html#_satellite_ids} + {satellite IDs list} to check the ID ranges for different satellite systems. + + \note Depending on the platform and the selected backend, the satellite + identifier ranges for different satellite systems may intersect. To uniquely + identify a satellite, a combination of satelliteIndetifier() and + \l satelliteSystem() must be used. + + \sa satelliteSystem() +*/ +int QGeoSatelliteInfo::satelliteIdentifier() const +{ + return d->satId; +} + +/*! + Sets the signal strength to \a signalStrength, in decibels. +*/ +void QGeoSatelliteInfo::setSignalStrength(int signalStrength) +{ + d.detach(); + d->signal = signalStrength; +} + +/*! + Returns the signal strength, or -1 if the value has not been set. +*/ +int QGeoSatelliteInfo::signalStrength() const +{ + return d->signal; +} + +/*! + Sets the value for \a attribute to \a value. +*/ +void QGeoSatelliteInfo::setAttribute(Attribute attribute, qreal value) +{ + d.detach(); + d->doubleAttribs[int(attribute)] = value; +} + +/*! + Returns the value of the specified \a attribute as a qreal value. + + Returns -1 if the value has not been set. + + \sa hasAttribute(), setAttribute() +*/ +qreal QGeoSatelliteInfo::attribute(Attribute attribute) const +{ + if (d->doubleAttribs.contains(int(attribute))) + return d->doubleAttribs[int(attribute)]; + return -1; +} + +/*! + Removes the specified \a attribute and its value. +*/ +void QGeoSatelliteInfo::removeAttribute(Attribute attribute) +{ + d.detach(); + d->doubleAttribs.remove(int(attribute)); +} + +/*! + Returns true if the specified \a attribute is present in this update. +*/ +bool QGeoSatelliteInfo::hasAttribute(Attribute attribute) const +{ + return d->doubleAttribs.contains(int(attribute)); +} + +/*! + \internal +*/ +void QGeoSatelliteInfo::detach() +{ + if (d) + d.detach(); + else + d = new QGeoSatelliteInfoPrivate; +} + +bool QGeoSatelliteInfo::equals(const QGeoSatelliteInfo &lhs, const QGeoSatelliteInfo &rhs) +{ + return *lhs.d == *rhs.d; +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug QGeoSatelliteInfo::debugStreaming(QDebug dbg, const QGeoSatelliteInfo &info) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QGeoSatelliteInfo(system=" << info.d->system; + dbg << ", satId=" << info.d->satId; + dbg << ", signal-strength=" << info.d->signal; + + + QList attribs = info.d->doubleAttribs.keys(); + for (int i = 0; i < attribs.size(); ++i) { + dbg << ", "; + switch (attribs[i]) { + case QGeoSatelliteInfo::Elevation: + dbg << "Elevation="; + break; + case QGeoSatelliteInfo::Azimuth: + dbg << "Azimuth="; + break; + } + dbg << info.d->doubleAttribs[attribs[i]]; + } + dbg << ')'; + return dbg; +} +#endif // QT_NO_DEBUG_STREAM + +#ifndef QT_NO_DATASTREAM +/*! + \fn QDataStream &QGeoSatelliteInfo::operator<<(QDataStream &stream, const QGeoSatelliteInfo &info) + + Writes the given \a info to the specified \a stream. + + \sa {Serializing Qt Data Types} + +*/ + +QDataStream &QGeoSatelliteInfo::dataStreamOut(QDataStream &stream, const QGeoSatelliteInfo &info) +{ + stream << info.d->signal; + stream << info.d->doubleAttribs; + stream << info.d->satId; + stream << int(info.d->system); + return stream; +} +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DATASTREAM +/*! + \fn QDataStream &QGeoSatelliteInfo::operator>>(QDataStream &stream, QGeoSatelliteInfo &info) + + Reads satellite information from the specified \a stream into the given + \a info. + + \sa {Serializing Qt Data Types} +*/ + +QDataStream &QGeoSatelliteInfo::dataStreamIn(QDataStream &stream, QGeoSatelliteInfo &info) +{ + int system; + stream >> info.d->signal; + stream >> info.d->doubleAttribs; + stream >> info.d->satId; + stream >> system; + info.d->system = (QGeoSatelliteInfo::SatelliteSystem)system; + return stream; +} +#endif // QT_NO_DATASTREAM + +QGeoSatelliteInfoPrivate::QGeoSatelliteInfoPrivate() : QSharedData() +{ + +} + +QGeoSatelliteInfoPrivate::QGeoSatelliteInfoPrivate(const QGeoSatelliteInfoPrivate &other) + : QSharedData(other) +{ + signal = other.signal; + satId = other.satId; + system = other.system; + doubleAttribs = other.doubleAttribs; +} + +QGeoSatelliteInfoPrivate::~QGeoSatelliteInfoPrivate() {} + +bool QGeoSatelliteInfoPrivate::operator==(const QGeoSatelliteInfoPrivate &other) const +{ + return signal == other.signal + && satId == other.satId + && system == other.system + && doubleAttribs == other.doubleAttribs; +} + +QGeoSatelliteInfoPrivate *QGeoSatelliteInfoPrivate::get(const QGeoSatelliteInfo &info) +{ + return info.d.data(); +} + +size_t qHash(const QGeoSatelliteInfo &key, size_t seed) noexcept +{ + // Other properties and attributes might change + return qHashMulti(seed, key.d->satId, key.d->system); +} + +namespace QTest +{ + +char *toString(const QGeoSatelliteInfo &info) +{ + QString result; + QDebug dbg(&result); + dbg << info; + + return qstrdup(qPrintable(result)); +} + +} + + +QT_END_NAMESPACE diff --git a/src/positioning/qgeosatelliteinfo.h b/src/positioning/qgeosatelliteinfo.h new file mode 100644 index 0000000..5ab0faf --- /dev/null +++ b/src/positioning/qgeosatelliteinfo.h @@ -0,0 +1,118 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QGEOSATELLITEINFO_H +#define QGEOSATELLITEINFO_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QDebug; +class QDataStream; + +class QGeoSatelliteInfo; +Q_POSITIONING_EXPORT size_t qHash(const QGeoSatelliteInfo &key, size_t seed = 0) noexcept; +namespace QTest +{ + +Q_POSITIONING_EXPORT char *toString(const QGeoSatelliteInfo &info); + +} // namespace QTest + +class QGeoSatelliteInfoPrivate; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QGeoSatelliteInfoPrivate, Q_POSITIONING_EXPORT) + +class Q_POSITIONING_EXPORT QGeoSatelliteInfo +{ +public: + enum Attribute { + Elevation, + Azimuth + }; + + enum SatelliteSystem { + Undefined = 0x00, + GPS = 0x01, + GLONASS = 0x02, + GALILEO = 0x03, + BEIDOU = 0x04, + QZSS = 0x05, + Multiple = 0xFF, + CustomType = 0x100 + }; + + QGeoSatelliteInfo(); + QGeoSatelliteInfo(const QGeoSatelliteInfo &other); + QGeoSatelliteInfo(QGeoSatelliteInfoPrivate &dd); + QGeoSatelliteInfo(QGeoSatelliteInfo &&other) noexcept = default; + ~QGeoSatelliteInfo(); + + QGeoSatelliteInfo &operator=(const QGeoSatelliteInfo &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QGeoSatelliteInfo) + + void swap(QGeoSatelliteInfo &other) noexcept { d.swap(other.d); } + + friend bool operator==(const QGeoSatelliteInfo &lhs, const QGeoSatelliteInfo &rhs) + { + return equals(lhs, rhs); + } + friend bool operator!=(const QGeoSatelliteInfo &lhs, const QGeoSatelliteInfo &rhs) + { + return !equals(lhs, rhs); + } + + void setSatelliteSystem(SatelliteSystem system); + SatelliteSystem satelliteSystem() const; + + void setSatelliteIdentifier(int satId); + int satelliteIdentifier() const; + + void setSignalStrength(int signalStrength); + int signalStrength() const; + + void setAttribute(Attribute attribute, qreal value); + qreal attribute(Attribute attribute) const; + void removeAttribute(Attribute attribute); + + bool hasAttribute(Attribute attribute) const; + + void detach(); + +private: + static bool equals(const QGeoSatelliteInfo &lhs, const QGeoSatelliteInfo &rhs); +#ifndef QT_NO_DEBUG_STREAM + friend QDebug operator<<(QDebug dbg, const QGeoSatelliteInfo &info) + { + return debugStreaming(dbg, info); + } + static QDebug debugStreaming(QDebug dbg, const QGeoSatelliteInfo &info); +#endif +#ifndef QT_NO_DATASTREAM + friend QDataStream &operator<<(QDataStream &stream, const QGeoSatelliteInfo &info) + { + return dataStreamOut(stream, info); + } + friend QDataStream &operator>>(QDataStream &stream, QGeoSatelliteInfo &info) + { + return dataStreamIn(stream, info); + } + static QDataStream &dataStreamOut(QDataStream &stream, const QGeoSatelliteInfo &info); + static QDataStream &dataStreamIn(QDataStream &stream, QGeoSatelliteInfo &info); +#endif + QExplicitlySharedDataPointer d; + friend class QGeoSatelliteInfoPrivate; + + friend Q_POSITIONING_EXPORT size_t qHash(const QGeoSatelliteInfo &key, size_t seed) noexcept; + friend Q_POSITIONING_EXPORT char *QTest::toString(const QGeoSatelliteInfo &info); +}; + +Q_DECLARE_SHARED(QGeoSatelliteInfo) + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoSatelliteInfo, Q_POSITIONING_EXPORT) + +#endif diff --git a/src/positioning/qgeosatelliteinfo_p.h b/src/positioning/qgeosatelliteinfo_p.h new file mode 100644 index 0000000..ebb75ec --- /dev/null +++ b/src/positioning/qgeosatelliteinfo_p.h @@ -0,0 +1,41 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOSATELLITEINFO_P_H +#define QGEOSATELLITEINFO_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 +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoSatelliteInfoPrivate : public QSharedData +{ +public: + QGeoSatelliteInfoPrivate(); + QGeoSatelliteInfoPrivate(const QGeoSatelliteInfoPrivate &other); + virtual ~QGeoSatelliteInfoPrivate(); + bool operator==(const QGeoSatelliteInfoPrivate &other) const; + static QGeoSatelliteInfoPrivate *get(const QGeoSatelliteInfo &info); + + int signal; + int satId; + QGeoSatelliteInfo::SatelliteSystem system; + QHash doubleAttribs; +}; + +QT_END_NAMESPACE + +#endif // QGEOSATELLITEINFO_P_H diff --git a/src/positioning/qgeosatelliteinfosource.cpp b/src/positioning/qgeosatelliteinfosource.cpp new file mode 100644 index 0000000..6347532 --- /dev/null +++ b/src/positioning/qgeosatelliteinfosource.cpp @@ -0,0 +1,390 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include +#include +#include "qgeopositioninfosourcefactory.h" +#include "qgeopositioninfosource_p.h" +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QGeoSatelliteInfoSource + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.2 + + \brief The QGeoSatelliteInfoSource class is an abstract base class for the distribution of satellite information updates. + + The static function QGeoSatelliteInfoSource::createDefaultSource() creates a default + satellite data source that is appropriate for the platform, if one is + available. Otherwise, available QGeoPositionInfoSourceFactory plugins will + be checked for one that has a satellite data source available. + + Call startUpdates() and stopUpdates() to start and stop regular updates, + or requestUpdate() to request a single update. + When an update is available, satellitesInViewUpdated() and/or + satellitesInUseUpdated() will be emitted. + + If regular satellite updates are required, setUpdateInterval() can be used + to specify how often these updates should be emitted. If no interval is + specified, updates are simply provided whenever they are available. + For example: + + \code + // Emit updates every 10 seconds if available + QGeoSatelliteInfoSource *source = QGeoSatelliteInfoSource::createDefaultSource(0); + if (source) + source->setUpdateInterval(10000); + \endcode + + To remove an update interval that was previously set, call + setUpdateInterval() with a value of 0. + + \note The satellite source may have a minimum value requirement for + update intervals, as returned by minimumUpdateInterval(). + + \note To use this class from Android service, see + \l {Qt Positioning on Android}. +*/ + +/*! + Creates a satellite source with the specified \a parent. +*/ + +QGeoSatelliteInfoSourcePrivate::~QGeoSatelliteInfoSourcePrivate() +{ + +} + +QGeoSatelliteInfoSource::QGeoSatelliteInfoSource(QObject *parent) + : QObject(*new QGeoSatelliteInfoSourcePrivate, parent) +{ +} + +QGeoSatelliteInfoSource::QGeoSatelliteInfoSource(QGeoSatelliteInfoSourcePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + +} + +/*! + Destroys the satellite source. +*/ +QGeoSatelliteInfoSource::~QGeoSatelliteInfoSource() +{ +} + +/*! + Returns the unique name of the satellite source implementation in use. + + This is the same name that can be passed to createSource() in order to + create a new instance of a particular satellite source implementation. +*/ +QString QGeoSatelliteInfoSource::sourceName() const +{ + Q_D(const QGeoSatelliteInfoSource); + return d->providerName; +} + + +/*! + \property QGeoSatelliteInfoSource::updateInterval + \brief This property holds the requested interval in milliseconds between each update. + + If the update interval is not set (or is set to 0) the + source will provide updates as often as necessary. + + If the update interval is set, the source will provide updates at an + interval as close to the requested interval as possible. If the requested + interval is less than the minimumUpdateInterval(), + the minimum interval is used instead. + + Changes to the update interval will happen as soon as is practical, however the + time the change takes may vary between implementations. Whether or not the elapsed + time from the previous interval is counted as part of the new interval is also + implementation dependent. + + The default value for this property is 0. + + \note Subclass implementations must call the base implementation of + setUpdateInterval() so that updateInterval() returns the correct value. +*/ +void QGeoSatelliteInfoSource::setUpdateInterval(int msec) +{ + Q_D(QGeoSatelliteInfoSource); + d->interval = msec; +} + +int QGeoSatelliteInfoSource::updateInterval() const +{ + Q_D(const QGeoSatelliteInfoSource); + return d->interval.value(); +} + +QBindable QGeoSatelliteInfoSource::bindableUpdateInterval() +{ + Q_D(QGeoSatelliteInfoSource); + return QBindable(&d->interval); +} + +/*! + \since 6.2 + Sets the backend-specific property named \a name to \a value. + Returns \c true on success, \c false otherwise. + Backend-specific properties can be used to configure the satellite info + subsystem behavior at runtime. + + \sa backendProperty +*/ +bool QGeoSatelliteInfoSource::setBackendProperty(const QString &name, const QVariant &value) +{ + Q_UNUSED(name) + Q_UNUSED(value) + return false; +} + +/*! + \since 6.2 + Returns the value of the backend-specific property named \a name, + if present. Otherwise the returned value will be invalid. + + \sa setBackendProperty +*/ +QVariant QGeoSatelliteInfoSource::backendProperty(const QString &name) const +{ + Q_UNUSED(name) + return QVariant(); +} + +QGeoSatelliteInfoSource *QGeoSatelliteInfoSourcePrivate::createSourceReal(const QCborMap &meta, const QVariantMap ¶meters, QObject *parent) +{ + QGeoSatelliteInfoSource *s = nullptr; + auto factory = QGeoPositionInfoSourcePrivate::loadFactory(meta); + if (factory) + s = factory->satelliteInfoSource(parent, parameters); + if (s) + s->d_func()->providerName = meta.value(QStringLiteral("Provider")).toString(); + + return s; +} + +/*! + Creates and returns a source with the specified \a parent that reads + from the system's default source of satellite update information, or the + highest priority available plugin. + + Returns \c nullptr if the system has no default satellite source, no valid + plugins could be found or the user does not have the permission to access + the satellite data. +*/ +QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createDefaultSource(QObject *parent) +{ + return createDefaultSource(QVariantMap(), parent); +} + +/*! + Creates and returns a source with the given \a parent, + by loading the plugin named \a sourceName. + + Returns \c nullptr if the plugin cannot be found. +*/ +QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createSource(const QString &sourceName, QObject *parent) +{ + return createSource(sourceName, QVariantMap(), parent); +} + +/*! + Creates and returns a satellite source with the given \a parent that + reads from the system's default sources of satellite data, or the plugin + with the highest available priority. + + Returns \c nullptr if the system has no default satellite source, no valid + plugins could be found or the user does not have the permission to access + the satellite information. + + This method passes \a parameters to the factory to configure the source. + + \since Qt 5.14 +*/ +QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createDefaultSource(const QVariantMap ¶meters, QObject *parent) +{ + const QList plugins = QGeoPositionInfoSourcePrivate::pluginsSorted(); + foreach (const QCborMap &obj, plugins) { + if (obj.value(QStringLiteral("Satellite")).isBool() + && obj.value(QStringLiteral("Satellite")).toBool()) + { + const QString testableKey = QStringLiteral("Testable"); + if (obj.contains(testableKey) && !obj.value(testableKey).toBool()) { + static bool inTest = qEnvironmentVariableIsSet("QT_QTESTLIB_RUNNING"); + if (inTest) + continue; + } + return QGeoSatelliteInfoSourcePrivate::createSourceReal(obj, parameters, parent); + } + } + + return nullptr; +} + +/*! + Creates and returns a satellite source with the given \a parent, + by loading the plugin named \a sourceName. + + Returns \c nullptr if the plugin cannot be found. + + This method passes \a parameters to the factory to configure the source. + + \since Qt 5.14 +*/ +QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createSource(const QString &sourceName, const QVariantMap ¶meters, QObject *parent) +{ + auto plugins = QGeoPositionInfoSourcePrivate::plugins(); + if (plugins.contains(sourceName)) + return QGeoSatelliteInfoSourcePrivate::createSourceReal(plugins.value(sourceName), parameters, parent); + return nullptr; +} + +/*! + Returns a list of available source plugins, including the default system + backend if one is available. +*/ +QStringList QGeoSatelliteInfoSource::availableSources() +{ + QStringList plugins; + const auto meta = QGeoPositionInfoSourcePrivate::plugins(); + for (auto it = meta.cbegin(), end = meta.cend(); it != end; ++it) { + if (it.value().value(QStringLiteral("Satellite")).isBool() + && it.value().value(QStringLiteral("Satellite")).toBool()) { + plugins << it.key(); + } + } + + return plugins; +} + +/*! + \fn void QGeoSatelliteInfoSource::satellitesInViewUpdated(const QList &satellites); + + If startUpdates() or requestUpdate() is called, this signal is emitted + when an update is available on the satellites that are + currently in view. + + The \a satellites parameter holds the satellites currently in view. +*/ + +/*! + \fn void QGeoSatelliteInfoSource::satellitesInUseUpdated(const QList &satellites); + + If startUpdates() or requestUpdate() is called, this signal is emitted + when an update is available on the number of satellites that are + currently in use. + + These are the satellites that are used to get a "fix" - that + is, those used to determine the current position. + + The \a satellites parameter holds the satellites currently in use. +*/ + +/*! + \property QGeoSatelliteInfoSource::minimumUpdateInterval + \brief This property holds the minimum time (in milliseconds) required to retrieve a satellite update. + + This is the minimum value accepted by setUpdateInterval() and + requestUpdate(). +*/ + + +/*! + \fn virtual void QGeoSatelliteInfoSource::startUpdates() = 0; + + Starts emitting updates at regular intervals. The updates will be + provided whenever new satellite information becomes available. + + If satellite information cannot be retrieved or some other + form of timeout has occurred the satellitesInViewUpdated() + and satellitesInUseUpdated() signals may be emitted with + empty parameter lists. + + \note Since Qt6 this method always resets the last error to + \l {QGeoSatelliteInfoSource::}{NoError} before starting + the updates. + + \note To understand how to use this method from an Android service, see + \l {Qt Positioning on Android}. + + \sa satellitesInViewUpdated(), satellitesInUseUpdated() +*/ + +/*! + \fn virtual void QGeoSatelliteInfoSource::stopUpdates() = 0; + + Stops emitting updates at regular intervals. +*/ + +/*! + \fn virtual void QGeoSatelliteInfoSource::requestUpdate(int timeout = 0); + + Attempts to get the current satellite information and emit + satellitesInViewUpdated() and satellitesInUseUpdated() with this + information. If the current satellite information cannot be found + within the given \a timeout (in milliseconds) or if \a timeout is less than + the value returned by minimumUpdateInterval(), an errorOccurred() signal + with \l {QGeoSatelliteInfoSource::UpdateTimeoutError} + {UpdateTimeoutError} is emitted. + + If the timeout is zero, the timeout defaults to a reasonable timeout + period as appropriate for the source. + + This does nothing if another update request is in progress. However + it can be called even if startUpdates() has already been called and + regular updates are in progress. + + \note Since Qt6 this method always resets the last error to + \l {QGeoSatelliteInfoSource::}{NoError} before requesting + the satellite information. + + \note To understand how to use this method from an Android service, see + \l {Qt Positioning on Android}. +*/ + +/*! + \fn QGeoSatelliteInfoSource::Error QGeoSatelliteInfoSource::error() const = 0 + + Returns the last error that occurred. + + \note Since Qt6 the last error is always reset when calling startUpdates() + or requestUpdate(). +*/ + +/*! + \fn void QGeoSatelliteInfoSource::errorOccurred(QGeoSatelliteInfoSource::Error satelliteError) + + This signal is emitted after an error occurred. The \a satelliteError + parameter describes the type of error that occurred. +*/ + +/*! + \enum QGeoSatelliteInfoSource::Error + + The Error enumeration represents the errors which can occur. + + \value AccessError The connection setup to the satellite backend failed because the + application lacked the required privileges. + \value ClosedError The satellite backend closed the connection, which happens for example in case + the user is switching location services to off. This object becomes invalid and should be deleted. + A new satellite source can be created by calling createDefaultSource() later on. + \value NoError No error has occurred. + \value UnknownSourceError An unidentified error occurred. + \value UpdateTimeoutError The current satellite information could not be + retrieved within the specified timeout. + */ + + +QT_END_NAMESPACE + +#include "moc_qgeosatelliteinfosource.cpp" diff --git a/src/positioning/qgeosatelliteinfosource.h b/src/positioning/qgeosatelliteinfosource.h new file mode 100644 index 0000000..76a9621 --- /dev/null +++ b/src/positioning/qgeosatelliteinfosource.h @@ -0,0 +1,73 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QGEOSATELLITEINFOSOURCE_H +#define QGEOSATELLITEINFOSOURCE_H + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoSatelliteInfoSourcePrivate; +class Q_POSITIONING_EXPORT QGeoSatelliteInfoSource : public QObject +{ + Q_OBJECT + Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval BINDABLE + bindableUpdateInterval) + Q_PROPERTY(int minimumUpdateInterval READ minimumUpdateInterval) + +public: + enum Error { + AccessError = 0, + ClosedError = 1, + NoError = 2, + UnknownSourceError = -1, + UpdateTimeoutError = 3, + }; + Q_ENUM(Error) + + explicit QGeoSatelliteInfoSource(QObject *parent); + virtual ~QGeoSatelliteInfoSource(); + + static QGeoSatelliteInfoSource *createDefaultSource(QObject *parent); + static QGeoSatelliteInfoSource *createSource(const QString &sourceName, QObject *parent); + static QGeoSatelliteInfoSource *createDefaultSource(const QVariantMap ¶meters, QObject *parent); + static QGeoSatelliteInfoSource *createSource(const QString &sourceName, const QVariantMap ¶meters, QObject *parent); + static QStringList availableSources(); + + QString sourceName() const; + + virtual void setUpdateInterval(int msec); + int updateInterval() const; + QBindable bindableUpdateInterval(); + + virtual int minimumUpdateInterval() const = 0; + virtual Error error() const = 0; + + virtual bool setBackendProperty(const QString &name, const QVariant &value); + virtual QVariant backendProperty(const QString &name) const; + +public Q_SLOTS: + virtual void startUpdates() = 0; + virtual void stopUpdates() = 0; + + virtual void requestUpdate(int timeout = 0) = 0; + +Q_SIGNALS: + void satellitesInViewUpdated(const QList &satellites); + void satellitesInUseUpdated(const QList &satellites); + void errorOccurred(QGeoSatelliteInfoSource::Error); + +protected: + explicit QGeoSatelliteInfoSource(QGeoSatelliteInfoSourcePrivate &dd, QObject *parent); + +private: + Q_DISABLE_COPY(QGeoSatelliteInfoSource) + Q_DECLARE_PRIVATE(QGeoSatelliteInfoSource) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qgeosatelliteinfosource_p.h b/src/positioning/qgeosatelliteinfosource_p.h new file mode 100644 index 0000000..bd02bc4 --- /dev/null +++ b/src/positioning/qgeosatelliteinfosource_p.h @@ -0,0 +1,37 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOSATELLITEINFOSOURCE_P_H +#define QGEOSATELLITEINFOSOURCE_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 +#include +#include + +QT_BEGIN_NAMESPACE +class QGeoSatelliteInfoSource; +class QGeoSatelliteInfoSourcePrivate : public QObjectPrivate +{ +public: + virtual ~QGeoSatelliteInfoSourcePrivate(); + static QGeoSatelliteInfoSource *createSourceReal(const QCborMap &meta, + const QVariantMap ¶meters, + QObject *parent); + Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QGeoSatelliteInfoSourcePrivate, int, interval, 0) + QString providerName; +}; + +QT_END_NAMESPACE + +#endif // QGEOSATELLITEINFOSOURCE_P_H diff --git a/src/positioning/qgeoshape.cpp b/src/positioning/qgeoshape.cpp new file mode 100644 index 0000000..2463e90 --- /dev/null +++ b/src/positioning/qgeoshape.cpp @@ -0,0 +1,415 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qgeoshape.h" +#include "qgeoshape_p.h" +#include "qgeorectangle.h" +#include "qgeocircle.h" +#include "qgeopath.h" +#include "qgeopolygon.h" + + +#ifndef QT_NO_DEBUG_STREAM +#include +#endif + +#ifndef QT_NO_DATASTREAM +#include +#endif + +QT_BEGIN_NAMESPACE + +QT_IMPL_METATYPE_EXTERN(QGeoShape) + +QGeoShapePrivate::QGeoShapePrivate(QGeoShape::ShapeType type) +: type(type) +{ +} + +QGeoShapePrivate::~QGeoShapePrivate() +{ +} + +bool QGeoShapePrivate::operator==(const QGeoShapePrivate &other) const +{ + return type == other.type; +} + +/*! + \class QGeoShape + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.2 + + \brief The QGeoShape class defines a geographic area. + + This class is the base class for classes which specify a geographic + area. + + For the sake of consistency, subclasses should describe the specific + details of the associated areas in terms of QGeoCoordinate instances + and distances in meters. + + This class is a \l Q_GADGET since Qt 5.5. It can be + \l{Cpp_value_integration_positioning}{directly used from C++ and QML}. +*/ + +/*! + \enum QGeoShape::ShapeType + + Describes the type of the shape. + + \value UnknownType A shape of unknown type + \value RectangleType A rectangular shape + \value CircleType A circular shape + \value PathType A path type + \value PolygonType A polygon type +*/ + +/*! + \property QGeoShape::type + \brief This property holds the type of this geo shape. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoShape::isValid + \brief This property holds the validity of the geo shape. + + A geo shape is considered to be invalid if some of the data that is required to + unambiguously describe the geo shape has not been set or has been set to an + unsuitable value depending on the subclass of this object. The default constructed + objects of this type are invalid. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ + +/*! + \property QGeoShape::isEmpty + \brief This property defines whether this geo shape is empty. + + An empty geo shape is a region which has a geometrical area of 0. + + While this property is introduced in Qt 5.5, the related accessor functions + exist since the first version of this class. + + \since 5.5 +*/ +inline QGeoShapePrivate *QGeoShape::d_func() +{ + return static_cast(d_ptr.data()); +} + +inline const QGeoShapePrivate *QGeoShape::d_func() const +{ + return static_cast(d_ptr.constData()); +} + +/*! + Constructs a new invalid geo shape of \l UnknownType. +*/ +QGeoShape::QGeoShape() +{ +} + +/*! + Constructs a new geo shape which is a copy of \a other. +*/ +QGeoShape::QGeoShape(const QGeoShape &other) +: d_ptr(other.d_ptr) +{ +} + +/*! + \internal +*/ +QGeoShape::QGeoShape(QGeoShapePrivate *d) +: d_ptr(d) +{ +} + +bool QGeoShape::equals(const QGeoShape &lhs, const QGeoShape &rhs) +{ + if (lhs.d_func() == rhs.d_func()) + return true; + + if (!lhs.d_func() || !rhs.d_func()) + return false; + + return *lhs.d_func() == *rhs.d_func(); +} + +/*! + Destroys this geo shape. +*/ +QGeoShape::~QGeoShape() +{ +} + +/*! + Returns the type of this geo shape. +*/ +QGeoShape::ShapeType QGeoShape::type() const +{ + Q_D(const QGeoShape); + + if (d) + return d->type; + else + return UnknownType; +} + +/*! + Returns whether this geo shape is valid. + +*/ +bool QGeoShape::isValid() const +{ + Q_D(const QGeoShape); + + if (d) + return d->isValid(); + else + return false; +} + +/*! + Returns whether this geo shape is empty. + + An empty geo shape is a region which has a geometrical area of 0. +*/ +bool QGeoShape::isEmpty() const +{ + Q_D(const QGeoShape); + + if (d) + return d->isEmpty(); + else + return true; +} + +/*! + Returns whether the coordinate \a coordinate is contained within this geo shape. +*/ +bool QGeoShape::contains(const QGeoCoordinate &coordinate) const +{ + Q_D(const QGeoShape); + + if (d) + return d->contains(coordinate); + else + return false; +} + +/*! + Returns a QGeoRectangle representing the geographical bounding rectangle of the + geo shape, that defines the latitudinal/longitudinal bounds of the geo shape. + + \since 5.9 +*/ +QGeoRectangle QGeoShape::boundingGeoRectangle() const +{ + Q_D(const QGeoShape); + + if (d) + return d->boundingGeoRectangle(); + else + return QGeoRectangle(); +} + +/*! + Returns the coordinate located at the geometric center of the geo shape. + + \since 5.5 +*/ +QGeoCoordinate QGeoShape::center() const +{ + Q_D(const QGeoShape); + + if (d) + return d->center(); + else + return QGeoCoordinate(); +} + +/*! + \fn bool QGeoShape::operator==(const QGeoShape &lhs, const QGeoShape &rhs) + + Returns \c true if the \a lhs geo shape is equivalent to the \a rhs geo + shape, otherwise returns \c false. +*/ + +/*! + \fn bool QGeoShape::operator!=(const QGeoShape &lhs, const QGeoShape &rhs) + + Returns \c true if the \a lhs geo shape is not equivalent to the \a rhs geo + shape, otherwise returns \c false. +*/ + +/*! + Assigns \a other to this geo shape and returns a reference to this geo shape. +*/ +QGeoShape &QGeoShape::operator=(const QGeoShape &other) +{ + if (this == &other) + return *this; + + d_ptr = other.d_ptr; + return *this; +} + +/*! + Returns a string representation of this geo shape. + + \since 5.5 +*/ +QString QGeoShape::toString() const +{ + return QStringLiteral("QGeoShape(%1)").arg(type()); +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug QGeoShape::debugStreaming(QDebug dbg, const QGeoShape &shape) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QGeoShape("; + switch (shape.type()) { + case QGeoShape::UnknownType: + dbg << "Unknown"; + break; + case QGeoShape::RectangleType: + dbg << "Rectangle"; + break; + case QGeoShape::PathType: + dbg << "Path"; + break; + case QGeoShape::PolygonType: + dbg << "Polygon"; + break; + case QGeoShape::CircleType: + dbg << "Circle"; + } + + dbg << ')'; + + return dbg; +} +#endif + +#ifndef QT_NO_DATASTREAM +QDataStream &QGeoShape::dataStreamOut(QDataStream &stream, const QGeoShape &shape) +{ + stream << quint32(shape.type()); + switch (shape.type()) { + case QGeoShape::UnknownType: + break; + case QGeoShape::RectangleType: { + QGeoRectangle r = shape; + stream << r.topLeft() << r.bottomRight(); + break; + } + case QGeoShape::CircleType: { + QGeoCircle c = shape; + stream << c.center() << c.radius(); + break; + } + case QGeoShape::PathType: { + QGeoPath p = shape; + stream << p.width(); + stream << p.path().size(); + for (const auto &c: p.path()) + stream << c; + break; + } + case QGeoShape::PolygonType: { + QGeoPolygon p = shape; + stream << p.perimeter().size(); + for (const auto &c: p.perimeter()) + stream << c; + break; + } + } + + return stream; +} + +QDataStream &QGeoShape::dataStreamIn(QDataStream &stream, QGeoShape &shape) +{ + quint32 type; + stream >> type; + + switch (type) { + case QGeoShape::UnknownType: + shape = QGeoShape(); + break; + case QGeoShape::RectangleType: { + QGeoCoordinate tl; + QGeoCoordinate br; + stream >> tl >> br; + shape = QGeoRectangle(tl, br); + break; + } + case QGeoShape::CircleType: { + QGeoCoordinate c; + qreal r; + stream >> c >> r; + shape = QGeoCircle(c, r); + break; + } + case QGeoShape::PathType: { + QList l; + QGeoCoordinate c; + qreal width; + stream >> width; + qsizetype sz; + stream >> sz; + for (qsizetype i = 0; i < sz; i++) { + stream >> c; + l.append(c); + } + shape = QGeoPath(l, width); + break; + } + case QGeoShape::PolygonType: { + QList l; + QGeoCoordinate c; + qsizetype sz; + stream >> sz; + for (qsizetype i = 0; i < sz; i++) { + stream >> c; + l.append(c); + } + shape = QGeoPolygon(l); + break; + } + } + + return stream; +} +#endif + +/*! + \relates QGeoShape + + Returns the hash value for the \a shape, using \a seed for the + calculation. +*/ +size_t qHash(const QGeoShape &shape, size_t seed) noexcept +{ + if (shape.d_ptr) + return shape.d_ptr->hash(seed); + else + return qHashMulti(seed, shape.type()); +} + +QT_END_NAMESPACE + +#include "moc_qgeoshape.cpp" + diff --git a/src/positioning/qgeoshape.h b/src/positioning/qgeoshape.h new file mode 100644 index 0000000..a4046da --- /dev/null +++ b/src/positioning/qgeoshape.h @@ -0,0 +1,97 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOSHAPE_H +#define QGEOSHAPE_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QDebug; +class QGeoShapePrivate; +class QGeoRectangle; + +class Q_POSITIONING_EXPORT QGeoShape +{ + Q_GADGET + Q_PROPERTY(ShapeType type READ type) + Q_PROPERTY(bool isValid READ isValid) + Q_PROPERTY(bool isEmpty READ isEmpty) + Q_PROPERTY(QGeoCoordinate center READ center) + Q_ENUMS(ShapeType) + +public: + QGeoShape(); + QGeoShape(const QGeoShape &other); + ~QGeoShape(); + + enum ShapeType { + UnknownType, + RectangleType, + CircleType, + PathType, + PolygonType + }; + + ShapeType type() const; + + bool isValid() const; + bool isEmpty() const; + Q_INVOKABLE bool contains(const QGeoCoordinate &coordinate) const; + Q_INVOKABLE QGeoRectangle boundingGeoRectangle() const; + QGeoCoordinate center() const; + + friend bool operator==(const QGeoShape &lhs, const QGeoShape &rhs) + { + return equals(lhs, rhs); + } + friend bool operator!=(const QGeoShape &lhs, const QGeoShape &rhs) + { + return !equals(lhs, rhs); + } + + QGeoShape &operator=(const QGeoShape &other); + + Q_INVOKABLE QString toString() const; +protected: + QGeoShape(QGeoShapePrivate *d); + + QSharedDataPointer d_ptr; + +private: + static bool equals(const QGeoShape &lhs, const QGeoShape &rhs); + inline QGeoShapePrivate *d_func(); + inline const QGeoShapePrivate *d_func() const; +#ifndef QT_NO_DEBUG_STREAM + friend QDebug operator<<(QDebug dbg, const QGeoShape &shape) + { + return debugStreaming(dbg, shape); + } + static QDebug debugStreaming(QDebug dbg, const QGeoShape &shape); +#endif +#ifndef QT_NO_DATASTREAM + friend QDataStream &operator<<(QDataStream &stream, const QGeoShape &shape) + { + return dataStreamOut(stream, shape); + } + friend QDataStream &operator>>(QDataStream &stream, QGeoShape &shape) + { + return dataStreamIn(stream, shape); + } + static QDataStream &dataStreamOut(QDataStream &stream, const QGeoShape &shape); + static QDataStream &dataStreamIn(QDataStream &stream, QGeoShape &shape); +#endif + friend Q_POSITIONING_EXPORT size_t qHash(const QGeoShape &key, size_t seed) noexcept; +}; + +Q_POSITIONING_EXPORT size_t qHash(const QGeoShape &shape, size_t seed = 0) noexcept; + +Q_DECLARE_TYPEINFO(QGeoShape, Q_RELOCATABLE_TYPE); + +QT_END_NAMESPACE + +QT_DECL_METATYPE_EXTERN(QGeoShape, Q_POSITIONING_EXPORT) + +#endif diff --git a/src/positioning/qgeoshape_p.h b/src/positioning/qgeoshape_p.h new file mode 100644 index 0000000..4151f38 --- /dev/null +++ b/src/positioning/qgeoshape_p.h @@ -0,0 +1,58 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QGEOSHAPE_P_H +#define QGEOSHAPE_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 + +#include "qgeorectangle.h" +#include "private/qglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QGeoShapePrivate : public QSharedData +{ +public: + explicit QGeoShapePrivate(QGeoShape::ShapeType type); + virtual ~QGeoShapePrivate(); + + virtual bool isValid() const = 0; + virtual bool isEmpty() const = 0; + virtual bool contains(const QGeoCoordinate &coordinate) const = 0; + + virtual QGeoCoordinate center() const = 0; + + virtual QGeoRectangle boundingGeoRectangle() const = 0; + + virtual QGeoShapePrivate *clone() const = 0; + + virtual bool operator==(const QGeoShapePrivate &other) const; + + virtual size_t hash(size_t seed) const = 0; + + QGeoShape::ShapeType type; +}; + +// don't use the copy constructor when detaching from a QSharedDataPointer, use virtual clone() +// call instead. +template <> +Q_INLINE_TEMPLATE QGeoShapePrivate *QSharedDataPointer::clone() +{ + return d->clone(); +} + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qlocationutils.cpp b/src/positioning/qlocationutils.cpp new file mode 100644 index 0000000..b21fb45 --- /dev/null +++ b/src/positioning/qlocationutils.cpp @@ -0,0 +1,602 @@ +// Copyright (C) 2016 Jolla Ltd. +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qlocationutils_p.h" +#include "qgeopositioninfo.h" +#include "qgeosatelliteinfo.h" + +#include +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +// converts e.g. 15306.0235 from NMEA sentence to 153.100392 +static double qlocationutils_nmeaDegreesToDecimal(double nmeaDegrees) +{ + double deg; + double min = 100.0 * modf(nmeaDegrees / 100.0, °); + return deg + (min / 60.0); +} + +static void qlocationutils_readGga(const char *data, int size, QGeoPositionInfo *info, double uere, + bool *hasFix) +{ + QByteArray sentence(data, size); + QList parts = sentence.split(','); + QGeoCoordinate coord; + + if (hasFix && parts.size() > 6 && !parts[6].isEmpty()) + *hasFix = parts[6].toInt() > 0; + + if (parts.size() > 1 && !parts[1].isEmpty()) { + QTime time; + if (QLocationUtils::getNmeaTime(parts[1], &time)) + info->setTimestamp(QDateTime(QDate(), time, Qt::UTC)); + } + + if (parts.size() > 5 && parts[3].size() == 1 && parts[5].size() == 1) { + double lat; + double lng; + if (QLocationUtils::getNmeaLatLong(parts[2], parts[3][0], parts[4], parts[5][0], &lat, &lng)) { + coord.setLatitude(lat); + coord.setLongitude(lng); + } + } + + if (parts.size() > 8 && !parts[8].isEmpty()) { + bool hasHdop = false; + double hdop = parts[8].toDouble(&hasHdop); + if (hasHdop) + info->setAttribute(QGeoPositionInfo::HorizontalAccuracy, 2 * hdop * uere); + } + + if (parts.size() > 9 && !parts[9].isEmpty()) { + bool hasAlt = false; + double alt = parts[9].toDouble(&hasAlt); + if (hasAlt) + coord.setAltitude(alt); + } + + if (coord.type() != QGeoCoordinate::InvalidCoordinate) + info->setCoordinate(coord); +} + +static void qlocationutils_readGsa(const char *data, int size, QGeoPositionInfo *info, double uere, + bool *hasFix) +{ + QList parts = QByteArray::fromRawData(data, size).split(','); + + if (hasFix && parts.size() > 2 && !parts[2].isEmpty()) + *hasFix = parts[2].toInt() > 0; + + if (parts.size() > 16 && !parts[16].isEmpty()) { + bool hasHdop = false; + double hdop = parts[16].toDouble(&hasHdop); + if (hasHdop) + info->setAttribute(QGeoPositionInfo::HorizontalAccuracy, 2 * hdop * uere); + } + + if (parts.size() > 17 && !parts[17].isEmpty()) { + bool hasVdop = false; + double vdop = parts[17].toDouble(&hasVdop); + if (hasVdop) + info->setAttribute(QGeoPositionInfo::VerticalAccuracy, 2 * vdop * uere); + } +} + +static void qlocationutils_readGsa(const char *data, + int size, + QList &pnrsInUse) +{ + QList parts = QByteArray::fromRawData(data, size).split(','); + pnrsInUse.clear(); + if (parts.size() <= 2) + return; + bool ok; + for (qsizetype i = 3; i < qMin(15, parts.size()); ++i) { + const QByteArray &pnrString = parts.at(i); + if (pnrString.isEmpty()) + continue; + int pnr = pnrString.toInt(&ok); + if (ok) + pnrsInUse.append(pnr); + } +} + +static void qlocationutils_readGll(const char *data, int size, QGeoPositionInfo *info, bool *hasFix) +{ + QByteArray sentence(data, size); + QList parts = sentence.split(','); + QGeoCoordinate coord; + + if (hasFix && parts.size() > 6 && !parts[6].isEmpty()) + *hasFix = (parts[6][0] == 'A'); + + if (parts.size() > 5 && !parts[5].isEmpty()) { + QTime time; + if (QLocationUtils::getNmeaTime(parts[5], &time)) + info->setTimestamp(QDateTime(QDate(), time, Qt::UTC)); + } + + if (parts.size() > 4 && parts[2].size() == 1 && parts[4].size() == 1) { + double lat; + double lng; + if (QLocationUtils::getNmeaLatLong(parts[1], parts[2][0], parts[3], parts[4][0], &lat, &lng)) { + coord.setLatitude(lat); + coord.setLongitude(lng); + } + } + + if (coord.type() != QGeoCoordinate::InvalidCoordinate) + info->setCoordinate(coord); +} + +static void qlocationutils_readRmc(const char *data, int size, QGeoPositionInfo *info, bool *hasFix) +{ + QByteArray sentence(data, size); + QList parts = sentence.split(','); + QGeoCoordinate coord; + QDate date; + QTime time; + + if (hasFix && parts.size() > 2 && !parts[2].isEmpty()) + *hasFix = (parts[2][0] == 'A'); + + if (parts.size() > 9 && parts[9].size() == 6) { + date = QDate::fromString(QString::fromLatin1(parts[9]), QStringLiteral("ddMMyy")); + if (date.isValid()) + date = date.addYears(100); // otherwise starts from 1900 + else + date = QDate(); + } + + if (parts.size() > 1 && !parts[1].isEmpty()) + QLocationUtils::getNmeaTime(parts[1], &time); + + if (parts.size() > 6 && parts[4].size() == 1 && parts[6].size() == 1) { + double lat; + double lng; + if (QLocationUtils::getNmeaLatLong(parts[3], parts[4][0], parts[5], parts[6][0], &lat, &lng)) { + coord.setLatitude(lat); + coord.setLongitude(lng); + } + } + + bool parsed = false; + double value = 0.0; + if (parts.size() > 7 && !parts[7].isEmpty()) { + value = parts[7].toDouble(&parsed); + if (parsed) + info->setAttribute(QGeoPositionInfo::GroundSpeed, qreal(value * 1.852 / 3.6)); // knots -> m/s + } + if (parts.size() > 8 && !parts[8].isEmpty()) { + value = parts[8].toDouble(&parsed); + if (parsed) + info->setAttribute(QGeoPositionInfo::Direction, qreal(value)); + } + if (parts.size() > 11 && parts[11].size() == 1 + && (parts[11][0] == 'E' || parts[11][0] == 'W')) { + value = parts[10].toDouble(&parsed); + if (parsed) { + if (parts[11][0] == 'W') + value *= -1; + info->setAttribute(QGeoPositionInfo::MagneticVariation, qreal(value)); + } + } + + if (coord.type() != QGeoCoordinate::InvalidCoordinate) + info->setCoordinate(coord); + + info->setTimestamp(QDateTime(date, time, Qt::UTC)); +} + +static void qlocationutils_readVtg(const char *data, int size, QGeoPositionInfo *info, bool *hasFix) +{ + if (hasFix) + *hasFix = false; + + QByteArray sentence(data, size); + QList parts = sentence.split(','); + + bool parsed = false; + double value = 0.0; + if (parts.size() > 1 && !parts[1].isEmpty()) { + value = parts[1].toDouble(&parsed); + if (parsed) + info->setAttribute(QGeoPositionInfo::Direction, qreal(value)); + } + if (parts.size() > 7 && !parts[7].isEmpty()) { + value = parts[7].toDouble(&parsed); + if (parsed) + info->setAttribute(QGeoPositionInfo::GroundSpeed, qreal(value / 3.6)); // km/h -> m/s + } +} + +static void qlocationutils_readZda(const char *data, int size, QGeoPositionInfo *info, bool *hasFix) +{ + if (hasFix) + *hasFix = false; + + QByteArray sentence(data, size); + QList parts = sentence.split(','); + QDate date; + QTime time; + + if (parts.size() > 1 && !parts[1].isEmpty()) + QLocationUtils::getNmeaTime(parts[1], &time); + + if (parts.size() > 4 && !parts[2].isEmpty() && !parts[3].isEmpty() + && parts[4].size() == 4) { // must be full 4-digit year + int day = parts[2].toInt(); + int month = parts[3].toInt(); + int year = parts[4].toInt(); + if (day > 0 && month > 0 && year > 0) + date.setDate(year, month, day); + } + + info->setTimestamp(QDateTime(date, time, Qt::UTC)); +} + +QLocationUtils::NmeaSentence QLocationUtils::getNmeaSentenceType(const char *data, int size) +{ + if (size < 6 || data[0] != '$' || !hasValidNmeaChecksum(data, size)) + return NmeaSentenceInvalid; + + if (data[3] == 'G' && data[4] == 'G' && data[5] == 'A') + return NmeaSentenceGGA; + + if (data[3] == 'G' && data[4] == 'S' && data[5] == 'A') + return NmeaSentenceGSA; + + if (data[3] == 'G' && data[4] == 'S' && data[5] == 'V') + return NmeaSentenceGSV; + + if (data[3] == 'G' && data[4] == 'L' && data[5] == 'L') + return NmeaSentenceGLL; + + if (data[3] == 'R' && data[4] == 'M' && data[5] == 'C') + return NmeaSentenceRMC; + + if (data[3] == 'V' && data[4] == 'T' && data[5] == 'G') + return NmeaSentenceVTG; + + if (data[3] == 'Z' && data[4] == 'D' && data[5] == 'A') + return NmeaSentenceZDA; + + return NmeaSentenceInvalid; +} + +QGeoSatelliteInfo::SatelliteSystem QLocationUtils::getSatelliteSystem(const char *data, int size) +{ + if (size < 6 || data[0] != '$' || !hasValidNmeaChecksum(data, size)) + return QGeoSatelliteInfo::Undefined; + + // GPS: GP + if (data[1] == 'G' && data[2] == 'P') + return QGeoSatelliteInfo::GPS; + + // GLONASS: GL + if (data[1] == 'G' && data[2] == 'L') + return QGeoSatelliteInfo::GLONASS; + + // GALILEO: GA + if (data[1] == 'G' && data[2] == 'A') + return QGeoSatelliteInfo::GALILEO; + + // BeiDou: BD or GB + if ((data[1] == 'B' && data[2] == 'D') || (data[1] == 'G' && data[2] == 'B')) + return QGeoSatelliteInfo::BEIDOU; + + // QZSS: GQ, PQ, QZ + if ((data[1] == 'G' && data[2] == 'Q') || (data[1] == 'P' && data[2] == 'Q') + || (data[1] == 'Q' && data[2] == 'Z')) { + return QGeoSatelliteInfo::QZSS; + } + + // Multiple: GN + if (data[1] == 'G' && data[2] == 'N') + return QGeoSatelliteInfo::Multiple; + + return QGeoSatelliteInfo::Undefined; +} + +QGeoSatelliteInfo::SatelliteSystem QLocationUtils::getSatelliteSystemBySatelliteId(int satId) +{ + if (satId >= 1 && satId <= 32) + return QGeoSatelliteInfo::GPS; + + if (satId >= 65 && satId <= 96) // including future extensions + return QGeoSatelliteInfo::GLONASS; + + if (satId >= 193 && satId <= 200) // including future extensions + return QGeoSatelliteInfo::QZSS; + + if ((satId >= 201 && satId <= 235) || (satId >= 401 && satId <= 437)) + return QGeoSatelliteInfo::BEIDOU; + + if (satId >= 301 && satId <= 336) + return QGeoSatelliteInfo::GALILEO; + + return QGeoSatelliteInfo::Undefined; +} + +bool QLocationUtils::getPosInfoFromNmea(const char *data, int size, QGeoPositionInfo *info, + double uere, bool *hasFix) +{ + if (!info) + return false; + + if (hasFix) + *hasFix = false; + + NmeaSentence nmeaType = getNmeaSentenceType(data, size); + if (nmeaType == NmeaSentenceInvalid) + return false; + + // Adjust size so that * and following characters are not parsed by the following functions. + for (int i = 0; i < size; ++i) { + if (data[i] == '*') { + size = i; + break; + } + } + + switch (nmeaType) { + case NmeaSentenceGGA: + qlocationutils_readGga(data, size, info, uere, hasFix); + return true; + case NmeaSentenceGSA: + qlocationutils_readGsa(data, size, info, uere, hasFix); + return true; + case NmeaSentenceGLL: + qlocationutils_readGll(data, size, info, hasFix); + return true; + case NmeaSentenceRMC: + qlocationutils_readRmc(data, size, info, hasFix); + return true; + case NmeaSentenceVTG: + qlocationutils_readVtg(data, size, info, hasFix); + return true; + case NmeaSentenceZDA: + qlocationutils_readZda(data, size, info, hasFix); + return true; + default: + return false; + } +} + +QNmeaSatelliteInfoSource::SatelliteInfoParseStatus +QLocationUtils::getSatInfoFromNmea(const char *data, int size, QList &infos, QGeoSatelliteInfo::SatelliteSystem &system) +{ + if (!data || !size) + return QNmeaSatelliteInfoSource::NotParsed; + + NmeaSentence nmeaType = getNmeaSentenceType(data, size); + if (nmeaType != NmeaSentenceGSV) + return QNmeaSatelliteInfoSource::NotParsed; + + // Standard forbids using $GN talker id for GSV messages, so the system + // type here will be uniquely identified. + system = getSatelliteSystem(data, size); + + // Adjust size so that * and following characters are not parsed by the + // following code. + for (int i = 0; i < size; ++i) { + if (data[i] == '*') { + size = i; + break; + } + } + + QList parts = QByteArray::fromRawData(data, size).split(','); + + if (parts.size() <= 3) { + infos.clear(); + return QNmeaSatelliteInfoSource::FullyParsed; // Malformed sentence. + } + bool ok; + const int totalSentences = parts.at(1).toInt(&ok); + if (!ok) { + infos.clear(); + return QNmeaSatelliteInfoSource::FullyParsed; // Malformed sentence. + } + + const int sentence = parts.at(2).toInt(&ok); + if (!ok) { + infos.clear(); + return QNmeaSatelliteInfoSource::FullyParsed; // Malformed sentence. + } + + const int totalSats = parts.at(3).toInt(&ok); + if (!ok) { + infos.clear(); + return QNmeaSatelliteInfoSource::FullyParsed; // Malformed sentence. + } + + if (sentence == 1) + infos.clear(); + + const int numSatInSentence = qMin(sentence * 4, totalSats) - (sentence - 1) * 4; + if (parts.size() < (4 + numSatInSentence * 4)) { + infos.clear(); + return QNmeaSatelliteInfoSource::FullyParsed; // Malformed sentence. + } + + int field = 4; + for (int i = 0; i < numSatInSentence; ++i) { + QGeoSatelliteInfo info; + info.setSatelliteSystem(system); + int prn = parts.at(field++).toInt(&ok); + // Quote from: https://gpsd.gitlab.io/gpsd/NMEA.html#_satellite_ids + // GLONASS satellite numbers come in two flavors. If a sentence has a GL + // talker ID, expect the skyviews to be GLONASS-only and in the range + // 1-32; you must add 64 to get a globally-unique NMEA ID. If the + // sentence has a GN talker ID, the device emits a multi-constellation + // skyview with GLONASS IDs already in the 65-96 range. + // + // However I don't observe such behavior with my device. So implementing + // a safe scenario. + if (ok && (system == QGeoSatelliteInfo::GLONASS)) { + if (prn <= 64) + prn += 64; + } + info.setSatelliteIdentifier((ok) ? prn : 0); + const int elevation = parts.at(field++).toInt(&ok); + info.setAttribute(QGeoSatelliteInfo::Elevation, (ok) ? elevation : 0); + const int azimuth = parts.at(field++).toInt(&ok); + info.setAttribute(QGeoSatelliteInfo::Azimuth, (ok) ? azimuth : 0); + const int snr = parts.at(field++).toInt(&ok); + info.setSignalStrength((ok) ? snr : -1); + infos.append(info); + } + + if (sentence == totalSentences) + return QNmeaSatelliteInfoSource::FullyParsed; + + return QNmeaSatelliteInfoSource::PartiallyParsed; +} + +QGeoSatelliteInfo::SatelliteSystem QLocationUtils::getSatInUseFromNmea(const char *data, int size, + QList &pnrsInUse) +{ + if (!data || !size) + return QGeoSatelliteInfo::Undefined; + + NmeaSentence nmeaType = getNmeaSentenceType(data, size); + if (nmeaType != NmeaSentenceGSA) + return QGeoSatelliteInfo::Undefined; + + auto systemType = getSatelliteSystem(data, size); + if (systemType == QGeoSatelliteInfo::Undefined) + return systemType; + + // The documentation states that we do not modify pnrsInUse if we could not + // parse the data + pnrsInUse.clear(); + + // Adjust size so that * and following characters are not parsed by the following functions. + for (int i = 0; i < size; ++i) { + if (data[i] == '*') { + size = i; + break; + } + } + qlocationutils_readGsa(data, size, pnrsInUse); + + // Quote from: https://gpsd.gitlab.io/gpsd/NMEA.html#_satellite_ids + // GLONASS satellite numbers come in two flavors. If a sentence has a GL + // talker ID, expect the skyviews to be GLONASS-only and in the range 1-32; + // you must add 64 to get a globally-unique NMEA ID. If the sentence has a + // GN talker ID, the device emits a multi-constellation skyview with + // GLONASS IDs already in the 65-96 range. + // + // However I don't observe such behavior with my device. So implementing a + // safe scenario. + if (systemType == QGeoSatelliteInfo::GLONASS) { + std::for_each(pnrsInUse.begin(), pnrsInUse.end(), [](int &id) { + if (id <= 64) + id += 64; + }); + } + + if ((systemType == QGeoSatelliteInfo::Multiple) && !pnrsInUse.isEmpty()) { + // Standard claims that in case of multiple system types we will receive + // several GSA messages, each containing data from only one satellite + // system, so we can pick the first id to determine the system type. + auto tempSystemType = getSatelliteSystemBySatelliteId(pnrsInUse.front()); + if (tempSystemType != QGeoSatelliteInfo::Undefined) + systemType = tempSystemType; + } + + return systemType; +} + +bool QLocationUtils::hasValidNmeaChecksum(const char *data, int size) +{ + int asteriskIndex = -1; + for (int i = 0; i < size; ++i) { + if (data[i] == '*') { + asteriskIndex = i; + break; + } + } + + constexpr qsizetype CSUM_LEN = 2; + if (asteriskIndex < 0 || asteriskIndex >= size - CSUM_LEN) + return false; + + // XOR byte value of all characters between '$' and '*' + int result = 0; + for (int i = 1; i < asteriskIndex; ++i) + result ^= data[i]; + /* + char calc[CSUM_LEN + 1]; + ::snprintf(calc, CSUM_LEN + 1, "%02x", result); + return ::strncmp(calc, &data[asteriskIndex+1], 2) == 0; + */ + + QByteArray checkSumBytes(&data[asteriskIndex + 1], 2); + bool ok = false; + int checksum = checkSumBytes.toInt(&ok,16); + return ok && checksum == result; +} + +bool QLocationUtils::getNmeaTime(const QByteArray &bytes, QTime *time) +{ + int dotIndex = bytes.indexOf('.'); + QTime tempTime; + + if (dotIndex < 0) { + tempTime = QTime::fromString(QString::fromLatin1(bytes.constData()), + QStringLiteral("hhmmss")); + } else { + tempTime = QTime::fromString(QString::fromLatin1(bytes.mid(0, dotIndex)), + QStringLiteral("hhmmss")); + bool hasMsecs = false; + int midLen = qMin(3, bytes.size() - dotIndex - 1); + int msecs = bytes.mid(dotIndex + 1, midLen).toUInt(&hasMsecs); + if (hasMsecs) + tempTime = tempTime.addMSecs(msecs*(midLen == 3 ? 1 : midLen == 2 ? 10 : 100)); + } + + if (tempTime.isValid()) { + *time = tempTime; + return true; + } + return false; +} + +bool QLocationUtils::getNmeaLatLong(const QByteArray &latString, char latDirection, const QByteArray &lngString, char lngDirection, double *lat, double *lng) +{ + if ((latDirection != 'N' && latDirection != 'S') + || (lngDirection != 'E' && lngDirection != 'W')) { + return false; + } + + bool hasLat = false; + bool hasLong = false; + double tempLat = latString.toDouble(&hasLat); + double tempLng = lngString.toDouble(&hasLong); + if (hasLat && hasLong) { + tempLat = qlocationutils_nmeaDegreesToDecimal(tempLat); + if (latDirection == 'S') + tempLat *= -1; + tempLng = qlocationutils_nmeaDegreesToDecimal(tempLng); + if (lngDirection == 'W') + tempLng *= -1; + + if (isValidLat(tempLat) && isValidLong(tempLng)) { + *lat = tempLat; + *lng = tempLng; + return true; + } + } + return false; +} + +QT_END_NAMESPACE + diff --git a/src/positioning/qlocationutils_p.h b/src/positioning/qlocationutils_p.h new file mode 100644 index 0000000..eba8964 --- /dev/null +++ b/src/positioning/qlocationutils_p.h @@ -0,0 +1,314 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QLOCATIONUTILS_P_H +#define QLOCATIONUTILS_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 +#include // needed for non-std:: versions of functions +#include +#include +#include +#include + +static const double offsetEpsilon = 1e-12; // = 0.000000000001 +static const double leftOffset = -180.0 + offsetEpsilon; +static const double rightOffset = 180.0 - offsetEpsilon; + +QT_BEGIN_NAMESPACE +class QTime; +class QByteArray; + +class QGeoPositionInfo; +class QGeoSatelliteInfo; +class Q_POSITIONING_PRIVATE_EXPORT QLocationUtils +{ +public: + enum CardinalDirection { + CardinalN, + CardinalE, + CardinalS, + CardinalW, + CardinalNE, + CardinalSE, + CardinalSW, + CardinalNW, + CardinalNNE, + CardinalENE, + CardinalESE, + CardinalSSE, + CardinalSSW, + CardinalWSW, + CardinalWNW, + CardinalNNW + }; + + enum NmeaSentence { + NmeaSentenceInvalid, + NmeaSentenceGGA, // Fix information + NmeaSentenceGSA, // Overall Satellite data, such as HDOP and VDOP + NmeaSentenceGLL, // Lat/Lon data + NmeaSentenceRMC, // Recommended minimum data for gps + NmeaSentenceVTG, // Vector track an Speed over the Ground + NmeaSentenceZDA, // Date and Time + NmeaSentenceGSV // Per-Satellite Info + }; + + inline static bool isValidLat(double lat) { + return lat >= -90.0 && lat <= 90.0; + } + inline static bool isValidLong(double lng) { + return lng >= -180.0 && lng <= 180.0; + } + + inline static double clipLat(double lat, double clipValue = 90.0) { + if (lat > clipValue) + lat = clipValue; + else if (lat < -clipValue) + lat = -clipValue; + return lat; + } + + inline static double wrapLong(double lng) { + if (lng > 180.0) + lng -= 360.0; + else if (lng < -180.0) + lng += 360.0; + return lng; + } + + inline static CardinalDirection azimuthToCardinalDirection4(double azimuth) + { + azimuth = fmod(azimuth, 360.0); + if (azimuth < 45.0 || azimuth > 315.0 ) + return CardinalN; + else if (azimuth < 135.0) + return CardinalE; + else if (azimuth < 225.0) + return CardinalS; + else + return CardinalW; + } + + inline static CardinalDirection azimuthToCardinalDirection8(double azimuth) + { + azimuth = fmod(azimuth, 360.0); + if (azimuth < 22.5 || azimuth > 337.5 ) + return CardinalN; + else if (azimuth < 67.5) + return CardinalNE; + else if (azimuth < 112.5) + return CardinalE; + else if (azimuth < 157.5) + return CardinalSE; + else if (azimuth < 202.5) + return CardinalS; + + else if (azimuth < 247.5) + return CardinalSW; + else if (azimuth < 292.5) + return CardinalW; + else + return CardinalNW; + } + + inline static CardinalDirection azimuthToCardinalDirection16(double azimuth) + { + azimuth = fmod(azimuth, 360.0); + if (azimuth < 11.5 || azimuth > 348.75 ) + return CardinalN; + else if (azimuth < 33.75) + return CardinalNNE; + else if (azimuth < 56.25) + return CardinalNE; + else if (azimuth < 78.75) + return CardinalENE; + else if (azimuth < 101.25) + return CardinalE; + else if (azimuth < 123.75) + return CardinalESE; + else if (azimuth < 146.25) + return CardinalSE; + else if (azimuth < 168.75) + return CardinalSSE; + else if (azimuth < 191.25) + return CardinalS; + + else if (azimuth < 213.75) + return CardinalSSW; + else if (azimuth < 236.25) + return CardinalSW; + else if (azimuth < 258.75) + return CardinalWSW; + else if (azimuth < 281.25) + return CardinalW; + else if (azimuth < 303.75) + return CardinalWNW; + else if (azimuth < 326.25) + return CardinalNW; + else + return CardinalNNW; + } + + // For values exceeding +- 720.0 + inline static double wrapLongExt(double lng) { + double remainder = fmod(lng + 180.0, 360.0); + return fmod(remainder + 360.0, 360.0) - 180.0; + } + + // Mirrors the azimuth against the X axis. Azimuth assumed to be in [0,360[ + inline static double mirrorAzimuthX(double azimuth) { + if (azimuth <= 90.0) + return 180.0 - azimuth; + else + return 180.0 + (360.0 - azimuth); + } + + // Mirrors the azimuth against the Y axis. Azimuth assumed to be in [0,360[ + inline static double mirrorAzimuthY(double azimuth) { + if (azimuth == 0.0) + return 0.0; + return 360.0 - azimuth; + } + + inline static double radians(double degrees) + { + return qDegreesToRadians(degrees); + } + + inline static double degrees(double radians) + { + return qRadiansToDegrees(radians); + } + + inline static double earthMeanRadius() + { + return 6371007.2; + } + + inline static double earthMeanCircumference() + { + return earthMeanRadius() * 2.0 * M_PI; + } + + inline static double mercatorMaxLatitude() + { + return 85.05113; + } + + inline static QGeoCoordinate antipodalPoint(const QGeoCoordinate &p) + { + return QGeoCoordinate(-p.latitude(), wrapLong(p.longitude() + 180.0)); + } + + // Leftmost longitude before wrapping kicks in + inline static double mapLeftLongitude(double centerLongitude) + { + return wrapLong(centerLongitude + leftOffset); + } + + // Rightmost longitude before wrapping kicks in + inline static double mapRightLongitude(double centerLongitude) + { + return wrapLong(centerLongitude - leftOffset); + } + + inline static void split_double(double input, float *hipart, float *lopart) + { + *hipart = (float) input; + double delta = input - ((double) *hipart); + *lopart = (float) delta; + } + + static qreal metersPerPixel(qreal zoomLevel, const QGeoCoordinate &coordinate) + { + const qreal metersPerTile = earthMeanCircumference() * std::cos(radians(coordinate.latitude())) / std::pow(2, zoomLevel); + return metersPerTile / 256.0; + } + + /* + returns the NMEA sentence type. + */ + static NmeaSentence getNmeaSentenceType(const char *data, int size); + + /* + Returns the satellite system type based on the message type. + See https://gpsd.gitlab.io/gpsd/NMEA.html#_talker_ids for reference + */ + static QGeoSatelliteInfo::SatelliteSystem getSatelliteSystem(const char *data, int size); + + /* + Returns the satellite system type based on the satellite id. + See https://gpsd.gitlab.io/gpsd/NMEA.html#_satellite_ids for reference + */ + static QGeoSatelliteInfo::SatelliteSystem getSatelliteSystemBySatelliteId(int satId); + + /* + Creates a QGeoPositionInfo from a GGA, GLL, RMC, VTG or ZDA sentence. + + Note: + - GGA and GLL sentences have time but not date so the update's + QDateTime object will have an invalid date. + - RMC reports date with a two-digit year so in this case the year + is assumed to be after the year 2000. + */ + static bool getPosInfoFromNmea(const char *data, + int size, + QGeoPositionInfo *info, double uere, + bool *hasFix = nullptr); + + /* + Retruns a list of QGeoSatelliteInfo in the view. + + Note: this function has to be called repeatedly until it returns + QNmeaSatelliteInfoSource::FullyParsed. + Reason being that GSV sentences can be split into multiple samples, so + getting the full data requires parsing multiple sentences. + */ + static QNmeaSatelliteInfoSource::SatelliteInfoParseStatus + getSatInfoFromNmea(const char *data, int size, QList &infos, QGeoSatelliteInfo::SatelliteSystem &system); + + /* + Parses GSA for satellites in use. + + Returns satellite system type or QGeoSatelliteInfo::Undefined if parsing + failed + */ + static QGeoSatelliteInfo::SatelliteSystem getSatInUseFromNmea(const char *data, int size, + QList &pnrsInUse); + + /* + Returns true if the given NMEA sentence has a valid checksum. + */ + static bool hasValidNmeaChecksum(const char *data, int size); + + /* + Returns time from a string in hhmmss or hhmmss.z+ format. + */ + static bool getNmeaTime(const QByteArray &bytes, QTime *time); + + /* + Accepts for example ("2734.7964", 'S', "15306.0124", 'E') and returns the + lat-long values. Fails if lat or long fail isValidLat() or isValidLong(). + */ + static bool getNmeaLatLong(const QByteArray &latString, + char latDirection, + const QByteArray &lngString, + char lngDirection, + double *lat, + double *lon); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qnmeapositioninfosource.cpp b/src/positioning/qnmeapositioninfosource.cpp new file mode 100644 index 0000000..b78e2dc --- /dev/null +++ b/src/positioning/qnmeapositioninfosource.cpp @@ -0,0 +1,931 @@ +// Copyright (C) 2016 Jolla Ltd. +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qnmeapositioninfosource_p.h" +#include "qgeopositioninfo_p.h" +#include "qlocationutils_p.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +#define USE_NMEA_PIMPL 0 + +#if USE_NMEA_PIMPL +class QGeoPositionInfoPrivateNmea : public QGeoPositionInfoPrivate +{ +public: + virtual ~QGeoPositionInfoPrivateNmea(); + + QList nmeaSentences; +}; + + +QGeoPositionInfoPrivateNmea::~QGeoPositionInfoPrivateNmea() +{ + +} +#else +typedef QGeoPositionInfoPrivate QGeoPositionInfoPrivateNmea; +#endif + +static bool propagateCoordinate(QGeoPositionInfo &dst, const QGeoPositionInfo &src, bool force = true) +{ + bool updated = false; + QGeoCoordinate c = dst.coordinate(); + const QGeoCoordinate & srcCoordinate = src.coordinate(); + if (qIsFinite(src.coordinate().latitude()) + && (!qIsFinite(dst.coordinate().latitude()) || force)) { + updated |= (c.latitude() != srcCoordinate.latitude()); + c.setLatitude(src.coordinate().latitude()); + } + if (qIsFinite(src.coordinate().longitude()) + && (!qIsFinite(dst.coordinate().longitude()) || force)) { + updated |= (c.longitude() != srcCoordinate.longitude()); + c.setLongitude(src.coordinate().longitude()); + } + if (qIsFinite(src.coordinate().altitude()) + && (!qIsFinite(dst.coordinate().altitude()) || force)) { + updated |= (c.altitude() != srcCoordinate.altitude()); + c.setAltitude(src.coordinate().altitude()); + } + dst.setCoordinate(c); + return updated; +} + +static bool propagateDate(QGeoPositionInfo &dst, const QGeoPositionInfo &src) +{ + if (!dst.timestamp().date().isValid() && src.timestamp().isValid()) { // time was supposed to be set/the same already. Date can be overwritten. + dst.setTimestamp(src.timestamp()); + return true; + } + return false; +} + +static bool propagateAttributes(QGeoPositionInfo &dst, const QGeoPositionInfo &src, bool force = true) +{ + bool updated = false; + static Q_DECL_CONSTEXPR std::array attrs { + { QGeoPositionInfo::GroundSpeed + ,QGeoPositionInfo::HorizontalAccuracy + ,QGeoPositionInfo::VerticalAccuracy + ,QGeoPositionInfo::Direction + ,QGeoPositionInfo::VerticalSpeed + ,QGeoPositionInfo::MagneticVariation} }; + for (const auto a: attrs) { + if (src.hasAttribute(a) && (!dst.hasAttribute(a) || force)) { + updated |= (dst.attribute(a) != src.attribute(a)); + dst.setAttribute(a, src.attribute(a)); + } + } + + return updated; +} + +// returns false if src does not contain any additional or different data than dst, +// true otherwise. +static bool mergePositions(QGeoPositionInfo &dst, const QGeoPositionInfo &src, QByteArray nmeaSentence) +{ + bool updated = false; + + updated |= propagateCoordinate(dst, src); + updated |= propagateDate(dst, src); + updated |= propagateAttributes(dst, src); + +#if USE_NMEA_PIMPL + QGeoPositionInfoPrivateNmea *dstPimpl = static_cast(QGeoPositionInfoPrivate::get(dst)); + dstPimpl->nmeaSentences.append(nmeaSentence); +#else + Q_UNUSED(nmeaSentence); +#endif + return updated; +} + +static qint64 msecsTo(const QDateTime &from, const QDateTime &to) +{ + if (!from.time().isValid() || !to.time().isValid()) + return 0; + + if (!from.date().isValid() || !to.date().isValid()) // use only time + return from.time().msecsTo(to.time()); + + return from.msecsTo(to); +} + +QNmeaRealTimeReader::QNmeaRealTimeReader(QNmeaPositionInfoSourcePrivate *sourcePrivate) + : QNmeaReader(sourcePrivate), m_update(*new QGeoPositionInfoPrivateNmea) +{ + // An env var controlling the number of milliseconds to use to withold + // an update and wait for additional data to combine. + // The update will be pushed earlier than this if a newer update will be received. + // The update will be withold longer than this amount of time if additional + // valid data will keep arriving within this time frame. + bool ok = false; + int pushDelay = qEnvironmentVariableIntValue("QT_NMEA_PUSH_DELAY", &ok); + if (ok) + pushDelay = std::clamp(pushDelay, -1, 1000); + else + pushDelay = 20; + + if (pushDelay >= 0) { + m_timer.setSingleShot(true); + m_timer.setInterval(pushDelay); + m_timer.connect(&m_timer, &QTimer::timeout, [this]() { + this->notifyNewUpdate(); + }); + } + m_pushDelay = pushDelay; +} + +void QNmeaRealTimeReader::readAvailableData() +{ + while (m_proxy->m_device->canReadLine()) { + const QTime infoTime = m_update.timestamp().time(); // if update has been set, time must be valid. + const QDate infoDate = m_update.timestamp().date(); // this one might not be valid, as some sentences do not contain it + + QGeoPositionInfoPrivateNmea *pimpl = new QGeoPositionInfoPrivateNmea; + QGeoPositionInfo pos(*pimpl); + + char buf[1024]; + qint64 size = m_proxy->m_device->readLine(buf, sizeof(buf)); + const bool oldFix = m_hasFix; + bool hasFix; + const bool parsed = m_proxy->parsePosInfoFromNmeaData(buf, size, &pos, &hasFix); + + if (!parsed) { + // got garbage, don't stop the timer + continue; + } + + m_hasFix |= hasFix; + m_updateParsed = true; + + // Date may or may not be valid, as some packets do not have date. + // If date isn't valid, match is performed on time only. + // Hence, make sure that packet blocks are generated with + // the sentences containing the full timestamp (e.g., GPRMC) *first* ! + if (infoTime.isValid()) { + if (pos.timestamp().time().isValid()) { + const bool newerTime = infoTime < pos.timestamp().time(); + const bool newerDate = (infoDate.isValid() // if time is valid but one date or both are not, + && pos.timestamp().date().isValid() + && infoDate < pos.timestamp().date()); + if (newerTime || newerDate) { + // Effectively read data for different update, that is also newer, + // so flush retained update, and copy the new pos into m_update + const QDate updateDate = m_update.timestamp().date(); + const QDate lastPushedDate = m_lastPushedTS.date(); + const bool newerTimestampSinceLastPushed = m_update.timestamp() > m_lastPushedTS; + const bool invalidDate = !(updateDate.isValid() && lastPushedDate.isValid()); + const bool newerTimeSinceLastPushed = m_update.timestamp().time() > m_lastPushedTS.time(); + if ( newerTimestampSinceLastPushed || (invalidDate && newerTimeSinceLastPushed)) { + m_proxy->notifyNewUpdate(&m_update, oldFix); + m_lastPushedTS = m_update.timestamp(); + } + m_timer.stop(); + // next update data + propagateAttributes(pos, m_update, false); + m_update = pos; + m_hasFix = hasFix; + } else { + if (infoTime == pos.timestamp().time()) + // timestamps match -- merge into m_update + if (mergePositions(m_update, pos, QByteArray(buf, size))) { + // Reset the timer only if new info has been received. + // Else the source might be keep repeating outdated info until + // new info become available. + m_timer.stop(); + } + // else discard out of order outdated info. + } + } else { + // no timestamp available in parsed update-- merge into m_update + if (mergePositions(m_update, pos, QByteArray(buf, size))) + m_timer.stop(); + } + } else { + // there was no info with valid TS. Overwrite with whatever is parsed. +#if USE_NMEA_PIMPL + pimpl->nmeaSentences.append(QByteArray(buf, size)); +#endif + propagateAttributes(pos, m_update); + m_update = pos; + m_timer.stop(); + } + } + + if (m_updateParsed) { + if (m_pushDelay < 0) + notifyNewUpdate(); + else + m_timer.start(); + } +} + +void QNmeaRealTimeReader::notifyNewUpdate() +{ + const bool newerTime = m_update.timestamp().time() > m_lastPushedTS.time(); + const bool newerDate = (m_update.timestamp().date().isValid() + && m_lastPushedTS.date().isValid() + && m_update.timestamp().date() > m_lastPushedTS.date()); + if (newerTime || newerDate) { + m_proxy->notifyNewUpdate(&m_update, m_hasFix); + m_lastPushedTS = m_update.timestamp(); + } + m_timer.stop(); +} + + +//============================================================ + +QNmeaSimulatedReader::QNmeaSimulatedReader(QNmeaPositionInfoSourcePrivate *sourcePrivate) + : QNmeaReader(sourcePrivate), + m_currTimerId(-1), + m_hasValidDateTime(false) +{ +} + +QNmeaSimulatedReader::~QNmeaSimulatedReader() +{ + if (m_currTimerId > 0) + killTimer(m_currTimerId); +} + +void QNmeaSimulatedReader::readAvailableData() +{ + if (m_currTimerId > 0) // we are already reading + return; + + if (!m_hasValidDateTime) { // first update + Q_ASSERT(m_proxy->m_device && (m_proxy->m_device->openMode() & QIODevice::ReadOnly)); + + if (!setFirstDateTime()) { + //m_proxy->notifyReachedEndOfFile(); + qWarning("QNmeaPositionInfoSource: cannot find NMEA sentence with valid date & time"); + return; + } + + m_hasValidDateTime = true; + simulatePendingUpdate(); + + } else { + // previously read to EOF, but now new data has arrived + processNextSentence(); + } +} + +static int processSentence(QGeoPositionInfo &info, + QByteArray &m_nextLine, + QNmeaPositionInfoSourcePrivate *m_proxy, + QQueue &m_pendingUpdates, + bool &hasFix) +{ + int timeToNextUpdate = -1; + QDateTime prevTs; + if (!m_pendingUpdates.isEmpty()) + prevTs = m_pendingUpdates.head().info.timestamp(); + + // find the next update with a valid time (as long as the time is valid, + // we can calculate when the update should be emitted) + while (!m_nextLine.isEmpty() || (m_proxy->m_device && m_proxy->m_device->bytesAvailable() > 0)) { + char static_buf[1024]; + char *buf = static_buf; + QByteArray nextLine; + qint64 size = 0; + if (!m_nextLine.isEmpty()) { + // Read something in the previous call, but TS was later. + size = m_nextLine.size(); + nextLine = m_nextLine; + m_nextLine.clear(); + buf = nextLine.data(); + } else { + size = m_proxy->m_device->readLine(buf, sizeof(static_buf)); + } + + if (size <= 0) + continue; + + const QTime infoTime = info.timestamp().time(); // if info has been set, time must be valid. + const QDate infoDate = info.timestamp().date(); // this one might not be valid, as some sentences do not contain it + + /* + Packets containing time information are GGA, RMC, ZDA, GLL: + + GGA : GPS fix data - only time + GLL : geographic latitude and longitude - only time + RMC : recommended minimum FPOS/transit data - date and time + ZDA : only timestamp - date and time + + QLocationUtils is currently also capable of parsing VTG and GSA sentences: + + VTG: containing Track made good and ground speed + GSA: overall satellite data, w. accuracies (ends up into PositionInfo) + + Since these sentences contain no timestamp, their content will be merged with the content + from any prior sentence that had timestamp info, if any is available. + */ + + QGeoPositionInfoPrivateNmea *pimpl = new QGeoPositionInfoPrivateNmea; + QGeoPositionInfo pos(*pimpl); + if (m_proxy->parsePosInfoFromNmeaData(buf, size, &pos, &hasFix)) { + // Date may or may not be valid, as some packets do not have date. + // If date isn't valid, match is performed on time only. + // Hence, make sure that packet blocks are generated with + // the sentences containing the full timestamp (e.g., GPRMC) *first* ! + if (infoTime.isValid()) { + if (pos.timestamp().time().isValid()) { + const bool newerTime = infoTime < pos.timestamp().time(); + const bool newerDate = (infoDate.isValid() // if time is valid but one date or both are not, + && pos.timestamp().date().isValid() + && infoDate < pos.timestamp().date()); + if (newerTime || newerDate) { + // Effectively read data for different update, that is also newer, so copy buf into m_nextLine + m_nextLine = QByteArray(buf, size); + break; + } else { + if (infoTime == pos.timestamp().time()) + // timestamps match -- merge into info + mergePositions(info, pos, QByteArray(buf, size)); + // else discard out of order outdated info. + } + } else { + // no timestamp available -- merge into info + mergePositions(info, pos, QByteArray(buf, size)); + } + } else { + // there was no info with valid TS. Overwrite with whatever is parsed. +#if USE_NMEA_PIMPL + pimpl->nmeaSentences.append(QByteArray(buf, size)); +#endif + info = pos; + } + + if (prevTs.time().isValid()) { + timeToNextUpdate = msecsTo(prevTs, info.timestamp()); + if (timeToNextUpdate < 0) // Somehow parsing expired packets, reset info + info = QGeoPositionInfo(*new QGeoPositionInfoPrivateNmea); + } + } + } + + return timeToNextUpdate; +} + +bool QNmeaSimulatedReader::setFirstDateTime() +{ + // find the first update with valid date and time + QGeoPositionInfo info(*new QGeoPositionInfoPrivateNmea); + bool hasFix = false; + processSentence(info, m_nextLine, m_proxy, m_pendingUpdates, hasFix); + + if (info.timestamp().time().isValid()) { // NMEA may have sentences with only time and no date. These would generate invalid positions + QPendingGeoPositionInfo pending; + pending.info = info; + pending.hasFix = hasFix; + m_pendingUpdates.enqueue(pending); + return true; + } + return false; +} + +void QNmeaSimulatedReader::simulatePendingUpdate() +{ + if (!m_pendingUpdates.isEmpty()) { + // will be dequeued in processNextSentence() + QPendingGeoPositionInfo &pending = m_pendingUpdates.head(); + m_proxy->notifyNewUpdate(&pending.info, pending.hasFix); + } + + processNextSentence(); +} + +void QNmeaSimulatedReader::timerEvent(QTimerEvent *event) +{ + killTimer(event->timerId()); + m_currTimerId = -1; + simulatePendingUpdate(); +} + +void QNmeaSimulatedReader::processNextSentence() +{ + QGeoPositionInfo info(*new QGeoPositionInfoPrivateNmea); + bool hasFix = false; + + int timeToNextUpdate = processSentence(info, m_nextLine, m_proxy, m_pendingUpdates, hasFix); + if (timeToNextUpdate < 0) + return; + + m_pendingUpdates.dequeue(); + + QPendingGeoPositionInfo pending; + pending.info = info; + pending.hasFix = hasFix; + m_pendingUpdates.enqueue(pending); + m_currTimerId = startTimer(timeToNextUpdate); +} + + +//============================================================ + + +QNmeaPositionInfoSourcePrivate::QNmeaPositionInfoSourcePrivate(QNmeaPositionInfoSource *parent, QNmeaPositionInfoSource::UpdateMode updateMode) + : QObject(parent), + m_updateMode(updateMode), + m_device(0), + m_invokedStart(false), + m_positionError(QGeoPositionInfoSource::UnknownSourceError), + m_userEquivalentRangeError(qQNaN()), + m_source(parent), + m_nmeaReader(0), + m_updateTimer(0), + m_requestTimer(0), + m_horizontalAccuracy(qQNaN()), + m_verticalAccuracy(qQNaN()), + m_noUpdateLastInterval(false), + m_updateTimeoutSent(false), + m_connectedReadyRead(false) +{ +} + +QNmeaPositionInfoSourcePrivate::~QNmeaPositionInfoSourcePrivate() +{ + delete m_nmeaReader; + delete m_updateTimer; +} + +bool QNmeaPositionInfoSourcePrivate::openSourceDevice() +{ + if (!m_device) { + qWarning("QNmeaPositionInfoSource: no QIODevice data source, call setDevice() first"); + return false; + } + + if (!m_device->isOpen() && !m_device->open(QIODevice::ReadOnly)) { + qWarning("QNmeaPositionInfoSource: cannot open QIODevice data source"); + return false; + } + + connect(m_device, SIGNAL(aboutToClose()), SLOT(sourceDataClosed())); + connect(m_device, SIGNAL(readChannelFinished()), SLOT(sourceDataClosed())); + connect(m_device, SIGNAL(destroyed()), SLOT(sourceDataClosed())); + + return true; +} + +void QNmeaPositionInfoSourcePrivate::sourceDataClosed() +{ + if (m_nmeaReader && m_device && m_device->bytesAvailable()) + m_nmeaReader->readAvailableData(); +} + +void QNmeaPositionInfoSourcePrivate::readyRead() +{ + if (m_nmeaReader) + m_nmeaReader->readAvailableData(); +} + +bool QNmeaPositionInfoSourcePrivate::initialize() +{ + if (m_nmeaReader) + return true; + + if (!openSourceDevice()) + return false; + + if (m_updateMode == QNmeaPositionInfoSource::RealTimeMode) + m_nmeaReader = new QNmeaRealTimeReader(this); + else + m_nmeaReader = new QNmeaSimulatedReader(this); + + return true; +} + +void QNmeaPositionInfoSourcePrivate::prepareSourceDevice() +{ + // some data may already be available + if (m_updateMode == QNmeaPositionInfoSource::SimulationMode) { + if (m_nmeaReader && m_device->bytesAvailable()) + m_nmeaReader->readAvailableData(); + } + + if (!m_connectedReadyRead) { + connect(m_device, SIGNAL(readyRead()), SLOT(readyRead())); + m_connectedReadyRead = true; + } +} + +bool QNmeaPositionInfoSourcePrivate::parsePosInfoFromNmeaData(const char *data, int size, + QGeoPositionInfo *posInfo, bool *hasFix) +{ + return m_source->parsePosInfoFromNmeaData(data, size, posInfo, hasFix); +} + +void QNmeaPositionInfoSourcePrivate::startUpdates() +{ + if (m_invokedStart) + return; + + m_positionError = QGeoPositionInfoSource::NoError; + + m_invokedStart = true; + m_pendingUpdate = QGeoPositionInfo(); + m_noUpdateLastInterval = false; + + bool initialized = initialize(); + if (!initialized) { + m_source->setError(QGeoPositionInfoSource::AccessError); + return; + } + + if (m_updateMode == QNmeaPositionInfoSource::RealTimeMode) { + // skip over any buffered data - we only want the newest data. + // Don't do this in requestUpdate. In that case bufferedData is good to have/use. + if (m_device->bytesAvailable()) { + if (m_device->isSequential()) + m_device->readAll(); + else + m_device->seek(m_device->bytesAvailable()); + } + } + + if (m_updateTimer) + m_updateTimer->stop(); + + if (m_source->updateInterval() > 0) { + if (!m_updateTimer) + m_updateTimer = new QBasicTimer; + m_updateTimer->start(m_source->updateInterval(), this); + } + + if (initialized) + prepareSourceDevice(); +} + +void QNmeaPositionInfoSourcePrivate::stopUpdates() +{ + m_invokedStart = false; + if (m_updateTimer) + m_updateTimer->stop(); + m_pendingUpdate = QGeoPositionInfo(); + m_noUpdateLastInterval = false; +} + +void QNmeaPositionInfoSourcePrivate::requestUpdate(int msec) +{ + if (m_requestTimer && m_requestTimer->isActive()) + return; + + m_positionError = QGeoPositionInfoSource::NoError; + + if (msec <= 0 || msec < m_source->minimumUpdateInterval()) { + m_source->setError(QGeoPositionInfoSource::UpdateTimeoutError); + return; + } + + if (!m_requestTimer) { + m_requestTimer = new QTimer(this); + connect(m_requestTimer, SIGNAL(timeout()), SLOT(updateRequestTimeout())); + } + + bool initialized = initialize(); + if (!initialized) { + m_source->setError(QGeoPositionInfoSource::UpdateTimeoutError); + return; + } + + m_requestTimer->start(msec); + prepareSourceDevice(); +} + +void QNmeaPositionInfoSourcePrivate::updateRequestTimeout() +{ + m_requestTimer->stop(); + m_source->setError(QGeoPositionInfoSource::UpdateTimeoutError); +} + +void QNmeaPositionInfoSourcePrivate::notifyNewUpdate(QGeoPositionInfo *update, bool hasFix) +{ + // include before uncommenting + //qDebug() << "QNmeaPositionInfoSourcePrivate::notifyNewUpdate()" << update->timestamp() << hasFix << m_invokedStart << (m_requestTimer && m_requestTimer->isActive()); + + QDate date = update->timestamp().date(); + if (date.isValid()) { + m_currentDate = date; + } else { + // some sentence have time but no date + QTime time = update->timestamp().time(); + if (time.isValid() && m_currentDate.isValid()) + update->setTimestamp(QDateTime(m_currentDate, time, Qt::UTC)); + } + + // Some attributes are sent in separate NMEA sentences. Save and restore the accuracy + // measurements. + if (update->hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) + m_horizontalAccuracy = update->attribute(QGeoPositionInfo::HorizontalAccuracy); + else if (!qIsNaN(m_horizontalAccuracy)) + update->setAttribute(QGeoPositionInfo::HorizontalAccuracy, m_horizontalAccuracy); + + if (update->hasAttribute(QGeoPositionInfo::VerticalAccuracy)) + m_verticalAccuracy = update->attribute(QGeoPositionInfo::VerticalAccuracy); + else if (!qIsNaN(m_verticalAccuracy)) + update->setAttribute(QGeoPositionInfo::VerticalAccuracy, m_verticalAccuracy); + + if (hasFix && update->isValid()) { + if (m_requestTimer && m_requestTimer->isActive()) { // User called requestUpdate() + m_requestTimer->stop(); + emitUpdated(*update); + } else if (m_invokedStart) { // user called startUpdates() + if (m_updateTimer && m_updateTimer->isActive()) { // update interval > 0 + // for periodic updates, only want the most recent update + m_pendingUpdate = *update; // Set what to send in timerEvent() + if (m_noUpdateLastInterval) { + // if the update was invalid when timerEvent was last called, a valid update + // should be sent ASAP + emitPendingUpdate(); + m_noUpdateLastInterval = false; + } + } else { // update interval <= 0 + emitUpdated(*update); + } + } + m_lastUpdate = *update; // Set in any case, if update is valid. Used in lastKnownPosition(). + } +} + +void QNmeaPositionInfoSourcePrivate::timerEvent(QTimerEvent *) +{ + emitPendingUpdate(); +} + +void QNmeaPositionInfoSourcePrivate::emitPendingUpdate() +{ + if (m_pendingUpdate.isValid()) { + m_updateTimeoutSent = false; + m_noUpdateLastInterval = false; + emitUpdated(m_pendingUpdate); + m_pendingUpdate = QGeoPositionInfo(); + } else { // invalid update + if (m_noUpdateLastInterval && !m_updateTimeoutSent) { + m_updateTimeoutSent = true; + m_pendingUpdate = QGeoPositionInfo(); // Invalid already, but clear just in case. + m_source->setError(QGeoPositionInfoSource::UpdateTimeoutError); + } + m_noUpdateLastInterval = true; + } +} + +void QNmeaPositionInfoSourcePrivate::emitUpdated(const QGeoPositionInfo &update) +{ + // check for duplication already done in QNmeaRealTimeReader::notifyNewUpdate + // and QNmeaRealTimeReader::readAvailableData + m_lastUpdate = update; + emit m_source->positionUpdated(update); +} + +//========================================================= + +/*! + \class QNmeaPositionInfoSource + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 5.2 + + \brief The QNmeaPositionInfoSource class provides positional information using a NMEA data source. + + NMEA is a commonly used protocol for the specification of one's global + position at a certain point in time. The QNmeaPositionInfoSource class reads NMEA + data and uses it to provide positional data in the form of + QGeoPositionInfo objects. + + A QNmeaPositionInfoSource instance operates in either \l {RealTimeMode} or + \l {SimulationMode}. These modes allow NMEA data to be read from either a + live source of positional data, or replayed for simulation purposes from + previously recorded NMEA data. + + The source of NMEA data is set with setDevice(). + + Use startUpdates() to start receiving regular position updates and stopUpdates() to stop these + updates. If you only require updates occasionally, you can call requestUpdate() to request a + single update. + + In both cases the position information is received via the positionUpdated() signal and the + last known position can be accessed with lastKnownPosition(). + + QNmeaPositionInfoSource supports reporting the accuracy of the horizontal and vertical position. + To enable position accuracy reporting an estimate of the User Equivalent Range Error associated + with the NMEA source must be set with setUserEquivalentRangeError(). +*/ + + +/*! + \enum QNmeaPositionInfoSource::UpdateMode + Defines the available update modes. + + \value RealTimeMode Positional data is read and distributed from the data source as it becomes available. Use this mode if you are using a live source of positional data (for example, a GPS hardware device). + \value SimulationMode The data and time information in the NMEA source data is used to provide positional updates at the rate at which the data was originally recorded. Use this mode if the data source contains previously recorded NMEA data and you want to replay the data for simulation purposes. +*/ + + +/*! + Constructs a QNmeaPositionInfoSource instance with the given \a parent + and \a updateMode. +*/ +QNmeaPositionInfoSource::QNmeaPositionInfoSource(UpdateMode updateMode, QObject *parent) + : QGeoPositionInfoSource(parent), + d(new QNmeaPositionInfoSourcePrivate(this, updateMode)) +{ +} + +/*! + Destroys the position source. +*/ +QNmeaPositionInfoSource::~QNmeaPositionInfoSource() +{ + delete d; +} + +/*! + Sets the User Equivalent Range Error (UERE) to \a uere. The UERE is used in calculating an + estimate of the accuracy of the position information reported by the position info source. The + UERE should be set to a value appropriate for the GPS device which generated the NMEA stream. + + The true UERE value is calculated from multiple error sources including errors introduced by + the satellites and signal propogation delays through the atmosphere as well as errors + introduced by the receiving GPS equipment. For details on GPS accuracy see + \l {https://web.archive.org/web/20161212144906if_/http://edu-observatory.org/gps/gps_accuracy.html} {Sam J. Wormley, GPS Errors & Estimating Your Reveiver's Accuracy}. + + A typical value for UERE is approximately 5.1. + + \since 5.3 + + \sa userEquivalentRangeError() +*/ +void QNmeaPositionInfoSource::setUserEquivalentRangeError(double uere) +{ + d->m_userEquivalentRangeError = uere; +} + +/*! + Returns the current User Equivalent Range Error (UERE). The UERE is used in calculating an + estimate of the accuracy of the position information reported by the position info source. The + default value is NaN which means no accuracy information will be provided. + + \since 5.3 + + \sa setUserEquivalentRangeError() +*/ +double QNmeaPositionInfoSource::userEquivalentRangeError() const +{ + return d->m_userEquivalentRangeError; +} + +/*! + Parses an NMEA sentence string into a QGeoPositionInfo. + + The default implementation will parse standard NMEA sentences. + This method should be reimplemented in a subclass whenever the need to deal with non-standard + NMEA sentences arises. + + The parser reads \a size bytes from \a data and uses that information to setup \a posInfo and + \a hasFix. If \a hasFix is set to false then \a posInfo may contain only the time or the date + and the time. + + Returns true if the sentence was successfully parsed, otherwise returns false and should not + modifiy \a posInfo or \a hasFix. +*/ +bool QNmeaPositionInfoSource::parsePosInfoFromNmeaData(const char *data, int size, + QGeoPositionInfo *posInfo, bool *hasFix) +{ + return QLocationUtils::getPosInfoFromNmea(data, size, posInfo, d->m_userEquivalentRangeError, + hasFix); +} + +/*! + Returns the update mode. +*/ +QNmeaPositionInfoSource::UpdateMode QNmeaPositionInfoSource::updateMode() const +{ + return d->m_updateMode; +} + +/*! + Sets the NMEA data source to \a device. If the device is not open, it + will be opened in QIODevice::ReadOnly mode. + + The source device can only be set once and must be set before calling + startUpdates() or requestUpdate(). + + \b {Note:} The \a device must emit QIODevice::readyRead() for the + source to be notified when data is available for reading. + QNmeaPositionInfoSource does not assume the ownership of the device, + and hence does not deallocate it upon destruction. +*/ +void QNmeaPositionInfoSource::setDevice(QIODevice *device) +{ + if (device != d->m_device) { + if (!d->m_device) + d->m_device = device; + else + qWarning("QNmeaPositionInfoSource: source device has already been set"); + } +} + +/*! + Returns the NMEA data source. +*/ +QIODevice *QNmeaPositionInfoSource::device() const +{ + return d->m_device; +} + +/*! + \reimp +*/ +void QNmeaPositionInfoSource::setUpdateInterval(int msec) +{ + int interval = msec; + if (interval != 0) + interval = qMax(msec, minimumUpdateInterval()); + QGeoPositionInfoSource::setUpdateInterval(interval); + if (d->m_invokedStart) { + d->stopUpdates(); + d->startUpdates(); + } +} + +/*! + \reimp +*/ +void QNmeaPositionInfoSource::startUpdates() +{ + d->startUpdates(); +} + +/*! + \reimp +*/ +void QNmeaPositionInfoSource::stopUpdates() +{ + d->stopUpdates(); +} + +/*! + \reimp +*/ +void QNmeaPositionInfoSource::requestUpdate(int msec) +{ + d->requestUpdate(msec == 0 ? 60000 * 5 : msec); // 5min default timeout +} + +/*! + \reimp +*/ +QGeoPositionInfo QNmeaPositionInfoSource::lastKnownPosition(bool) const +{ + // the bool value does not matter since we only use satellite positioning + return d->m_lastUpdate; +} + +/*! + \reimp +*/ +QGeoPositionInfoSource::PositioningMethods QNmeaPositionInfoSource::supportedPositioningMethods() const +{ + return SatellitePositioningMethods; +} + +/*! + \reimp +*/ +int QNmeaPositionInfoSource::minimumUpdateInterval() const +{ + return 2; // Some chips are capable of over 100 updates per seconds. +} + +/*! + \reimp +*/ +QGeoPositionInfoSource::Error QNmeaPositionInfoSource::error() const +{ + return d->m_positionError; +} + +void QNmeaPositionInfoSource::setError(QGeoPositionInfoSource::Error positionError) +{ + d->m_positionError = positionError; + if (d->m_positionError != QGeoPositionInfoSource::NoError) + emit QGeoPositionInfoSource::errorOccurred(positionError); +} + +QT_END_NAMESPACE + +#include "moc_qnmeapositioninfosource_p.cpp" +#include "moc_qnmeapositioninfosource.cpp" diff --git a/src/positioning/qnmeapositioninfosource.h b/src/positioning/qnmeapositioninfosource.h new file mode 100644 index 0000000..b8d73e3 --- /dev/null +++ b/src/positioning/qnmeapositioninfosource.h @@ -0,0 +1,61 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QNMEAPOSITIONINFOSOURCE_H +#define QNMEAPOSITIONINFOSOURCE_H + +#include + +QT_BEGIN_NAMESPACE + +class QIODevice; + +class QNmeaPositionInfoSourcePrivate; +class Q_POSITIONING_EXPORT QNmeaPositionInfoSource : public QGeoPositionInfoSource +{ + Q_OBJECT +public: + enum UpdateMode { + RealTimeMode = 1, + SimulationMode + }; + + explicit QNmeaPositionInfoSource(UpdateMode updateMode, QObject *parent = nullptr); + ~QNmeaPositionInfoSource(); + + void setUserEquivalentRangeError(double uere); + double userEquivalentRangeError() const; + + UpdateMode updateMode() const; + + void setDevice(QIODevice *source); + QIODevice *device() const; + + void setUpdateInterval(int msec) override; + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override; + PositioningMethods supportedPositioningMethods() const override; + int minimumUpdateInterval() const override; + Error error() const override; + + +public Q_SLOTS: + void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 0) override; + +protected: + virtual bool parsePosInfoFromNmeaData(const char *data, + int size, + QGeoPositionInfo *posInfo, + bool *hasFix); + void setError(QGeoPositionInfoSource::Error positionError); + +private: + Q_DISABLE_COPY(QNmeaPositionInfoSource) + friend class QNmeaPositionInfoSourcePrivate; + QNmeaPositionInfoSourcePrivate *d; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qnmeapositioninfosource_p.h b/src/positioning/qnmeapositioninfosource_p.h new file mode 100644 index 0000000..fdade7b --- /dev/null +++ b/src/positioning/qnmeapositioninfosource_p.h @@ -0,0 +1,153 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QNMEAPOSITIONINFOSOURCE_P_H +#define QNMEAPOSITIONINFOSOURCE_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 "qnmeapositioninfosource.h" +#include "qgeopositioninfo.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QBasicTimer; +class QTimerEvent; +class QTimer; + +class QNmeaReader; +struct QPendingGeoPositionInfo +{ + QGeoPositionInfo info; + bool hasFix; +}; + + +class QNmeaPositionInfoSourcePrivate : public QObject +{ + Q_OBJECT +public: + QNmeaPositionInfoSourcePrivate(QNmeaPositionInfoSource *parent, QNmeaPositionInfoSource::UpdateMode updateMode); + ~QNmeaPositionInfoSourcePrivate(); + + void startUpdates(); + void stopUpdates(); + void requestUpdate(int msec); + + bool parsePosInfoFromNmeaData(const char *data, + int size, + QGeoPositionInfo *posInfo, + bool *hasFix); + + void notifyNewUpdate(QGeoPositionInfo *update, bool fixStatus); + + QNmeaPositionInfoSource::UpdateMode m_updateMode; + QPointer m_device; + QGeoPositionInfo m_lastUpdate; + bool m_invokedStart; + QGeoPositionInfoSource::Error m_positionError; + double m_userEquivalentRangeError; + +public Q_SLOTS: + void readyRead(); + +protected: + void timerEvent(QTimerEvent *event) override; + +private Q_SLOTS: + void emitPendingUpdate(); + void sourceDataClosed(); + void updateRequestTimeout(); + +private: + bool openSourceDevice(); + bool initialize(); + void prepareSourceDevice(); + void emitUpdated(const QGeoPositionInfo &update); + + QNmeaPositionInfoSource *m_source; + QNmeaReader *m_nmeaReader; + QGeoPositionInfo m_pendingUpdate; + QDate m_currentDate; + QBasicTimer *m_updateTimer; // the timer used in startUpdates() + QTimer *m_requestTimer; // the timer used in requestUpdate() + qreal m_horizontalAccuracy; + qreal m_verticalAccuracy; + bool m_noUpdateLastInterval; + bool m_updateTimeoutSent; + bool m_connectedReadyRead; +}; + + +class QNmeaReader +{ +public: + explicit QNmeaReader(QNmeaPositionInfoSourcePrivate *sourcePrivate) + : m_proxy(sourcePrivate) {} + virtual ~QNmeaReader() {} + + virtual void readAvailableData() = 0; + +protected: + QNmeaPositionInfoSourcePrivate *m_proxy; +}; + + +class QNmeaRealTimeReader : public QNmeaReader +{ +public: + explicit QNmeaRealTimeReader(QNmeaPositionInfoSourcePrivate *sourcePrivate); + void readAvailableData() override; + void notifyNewUpdate(); + + // Data members + QGeoPositionInfo m_update; + QDateTime m_lastPushedTS; + bool m_updateParsed = false; + bool m_hasFix = false; + QTimer m_timer; + int m_pushDelay = -1; +}; + + +class QNmeaSimulatedReader : public QObject, public QNmeaReader +{ + Q_OBJECT +public: + explicit QNmeaSimulatedReader(QNmeaPositionInfoSourcePrivate *sourcePrivate); + ~QNmeaSimulatedReader(); + void readAvailableData() override; + +protected: + void timerEvent(QTimerEvent *event) override; + +private Q_SLOTS: + void simulatePendingUpdate(); + +private: + bool setFirstDateTime(); + void processNextSentence(); + + QQueue m_pendingUpdates; + QByteArray m_nextLine; + int m_currTimerId; + bool m_hasValidDateTime; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qnmeasatelliteinfosource.cpp b/src/positioning/qnmeasatelliteinfosource.cpp new file mode 100644 index 0000000..82e101f --- /dev/null +++ b/src/positioning/qnmeasatelliteinfosource.cpp @@ -0,0 +1,876 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qnmeasatelliteinfosource.h" +#include "private/qnmeasatelliteinfosource_p.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#if USE_NMEA_PIMPL +class QGeoSatelliteInfoPrivateNmea : public QGeoSatelliteInfoPrivate +{ +public: + QGeoSatelliteInfoPrivateNmea(const QGeoSatelliteInfoPrivate &other); + QGeoSatelliteInfoPrivateNmea(const QGeoSatelliteInfoPrivateNmea &other); + virtual ~QGeoSatelliteInfoPrivateNmea(); + + QList nmeaSentences; +}; + +QGeoSatelliteInfoPrivateNmea::QGeoSatelliteInfoPrivateNmea(const QGeoSatelliteInfoPrivate &other) + : QGeoSatelliteInfoPrivate(other) +{ +} + +QGeoSatelliteInfoPrivateNmea::QGeoSatelliteInfoPrivateNmea(const QGeoSatelliteInfoPrivateNmea &other) + : QGeoSatelliteInfoPrivate(other) +{ + nmeaSentences = other.nmeaSentences; +} + +QGeoSatelliteInfoPrivateNmea::~QGeoSatelliteInfoPrivateNmea() {} +#else +typedef QGeoSatelliteInfoPrivate QGeoSatelliteInfoPrivateNmea; +#endif + +QNmeaSatelliteInfoSourcePrivate::QNmeaSatelliteInfoSourcePrivate(QNmeaSatelliteInfoSource *parent, QNmeaSatelliteInfoSource::UpdateMode updateMode) + : m_source(parent), + m_updateMode(updateMode) +{ +} + +void QNmeaSatelliteInfoSourcePrivate::notifyNewUpdate() +{ + if (m_pendingUpdate.isValid() && m_pendingUpdate.isFresh()) { + if (m_requestTimer && m_requestTimer->isActive()) { // User called requestUpdate() + m_requestTimer->stop(); + emitUpdated(m_pendingUpdate, true); + } else if (m_invokedStart) { // user called startUpdates() + if (m_updateTimer && m_updateTimer->isActive()) { // update interval > 0 + // for periodic updates, only want the most recent update + if (m_noUpdateLastInterval) { + // if the update was invalid when timerEvent was last called, a valid update + // should be sent ASAP + emitPendingUpdate(); // m_noUpdateLastInterval handled in there. + } + } else { // update interval <= 0, send anything new ASAP + m_noUpdateLastInterval = !emitUpdated(m_pendingUpdate, false); + } + } + } +} + +void QNmeaSatelliteInfoSourcePrivate::processNmeaData(QNmeaSatelliteInfoUpdate &updateInfo) +{ + char buf[1024]; + qint64 size = m_device->readLine(buf, sizeof(buf)); + QList satInUse; + const auto satSystemType = m_source->parseSatellitesInUseFromNmea(buf, size, satInUse); + if (satSystemType != QGeoSatelliteInfo::Undefined) { + const bool res = updateInfo.setSatellitesInUse(satSystemType, satInUse); +#if USE_NMEA_PIMPL + if (res) { + updateInfo.gsa = QByteArray(buf, size); + auto &info = updateInfo.m_satellites[satSystemType]; + if (!info.satellitesInUse.isEmpty()) { + for (auto &s : info.satellitesInUse) { + static_cast(QGeoSatelliteInfoPrivate::get(s)) + ->nmeaSentences.append(updateInfo.gsa); + } + for (auto &s : info.satellitesInView) { + static_cast(QGeoSatelliteInfoPrivate::get(s)) + ->nmeaSentences.append(updateInfo.gsa); + } + } + } +#else + Q_UNUSED(res) +#endif // USE_NMEA_PIMPL + } else { + // Here we have the assumption that multiple parts of GSV sentence + // come one after another. At least this is how it should be. + auto systemType = QGeoSatelliteInfo::Undefined; + const auto parserStatus = m_source->parseSatelliteInfoFromNmea( + buf, size, updateInfo.m_satellitesInViewParsed, systemType); + if (parserStatus == QNmeaSatelliteInfoSource::PartiallyParsed) { + updateInfo.m_satellites[systemType].updatingGSV = true; +#if USE_NMEA_PIMPL + updateInfo.gsv.append(QByteArray(buf, size)); +#endif + } else if (parserStatus == QNmeaSatelliteInfoSource::FullyParsed) { +#if USE_NMEA_PIMPL + updateInfo.gsv.append(QByteArray(buf, size)); + for (int i = 0; i < updateInfo.m_satellitesInViewParsed.size(); i++) { + const QGeoSatelliteInfo &s = updateInfo.m_satellitesInViewParsed.at(i); + QGeoSatelliteInfoPrivateNmea *pimpl = + new QGeoSatelliteInfoPrivateNmea(*QGeoSatelliteInfoPrivate::get(s)); + pimpl->nmeaSentences.append(updateInfo.gsa); + pimpl->nmeaSentences.append(updateInfo.gsv); + updateInfo.m_satellitesInViewParsed.replace(i, QGeoSatelliteInfo(*pimpl)); + } + updateInfo.gsv.clear(); +#endif + updateInfo.setSatellitesInView(systemType, updateInfo.m_satellitesInViewParsed); + } + } +} + +QNmeaSatelliteInfoSourcePrivate::~QNmeaSatelliteInfoSourcePrivate() +{ + delete m_updateTimer; +} + +void QNmeaSatelliteInfoSourcePrivate::startUpdates() +{ + if (m_invokedStart) + return; + + m_satelliteError = QGeoSatelliteInfoSource::NoError; + + m_invokedStart = true; + m_pendingUpdate.clear(); + m_noUpdateLastInterval = false; + + bool initialized = initialize(); + if (!initialized) + return; + + if (m_updateMode == QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode) { + // skip over any buffered data - we only want the newest data. + // Don't do this in requestUpdate. In that case bufferedData is good to have/use. + if (m_device->bytesAvailable()) { + if (m_device->isSequential()) + m_device->readAll(); + else + m_device->seek(m_device->bytesAvailable()); + } + } + + if (m_updateTimer) + m_updateTimer->stop(); + + if (m_source->updateInterval() > 0) { + if (!m_updateTimer) + m_updateTimer = new QBasicTimer; + m_updateTimer->start(m_source->updateInterval(), this); + } + + if (initialized) + prepareSourceDevice(); +} + +void QNmeaSatelliteInfoSourcePrivate::stopUpdates() +{ + m_invokedStart = false; + if (m_updateTimer) + m_updateTimer->stop(); + m_pendingUpdate.clear(); + m_noUpdateLastInterval = false; +} + +void QNmeaSatelliteInfoSourcePrivate::requestUpdate(int msec) +{ + if (m_requestTimer && m_requestTimer->isActive()) + return; + + m_satelliteError = QGeoSatelliteInfoSource::NoError; + + if (msec <= 0 || msec < m_source->minimumUpdateInterval()) { + m_source->setError(QGeoSatelliteInfoSource::UpdateTimeoutError); + return; + } + + if (!m_requestTimer) { + m_requestTimer = new QTimer(this); + connect(m_requestTimer, SIGNAL(timeout()), SLOT(updateRequestTimeout())); + } + + bool initialized = initialize(); + if (!initialized) { + m_source->setError(QGeoSatelliteInfoSource::UpdateTimeoutError); + return; + } + + m_requestTimer->start(msec); + prepareSourceDevice(); +} + +void QNmeaSatelliteInfoSourcePrivate::readyRead() +{ + if (m_nmeaReader) + m_nmeaReader->readAvailableData(); +} + +void QNmeaSatelliteInfoSourcePrivate::emitPendingUpdate() +{ + if (m_pendingUpdate.isValid() && m_pendingUpdate.isFresh()) { + m_updateTimeoutSent = false; + m_noUpdateLastInterval = false; + if (!emitUpdated(m_pendingUpdate, false)) + m_noUpdateLastInterval = true; + // m_pendingUpdate.clear(); // Do not clear, it will be incrementally updated + } else { // invalid or not fresh update + if (m_noUpdateLastInterval && !m_updateTimeoutSent) { + m_updateTimeoutSent = true; + m_source->setError(QGeoSatelliteInfoSource::UpdateTimeoutError); + } + m_noUpdateLastInterval = true; + } +} + +void QNmeaSatelliteInfoSourcePrivate::sourceDataClosed() +{ + if (m_nmeaReader && m_device && m_device->bytesAvailable()) + m_nmeaReader->readAvailableData(); +} + +void QNmeaSatelliteInfoSourcePrivate::updateRequestTimeout() +{ + m_requestTimer->stop(); + m_source->setError(QGeoSatelliteInfoSource::UpdateTimeoutError); +} + +bool QNmeaSatelliteInfoSourcePrivate::openSourceDevice() +{ + if (!m_device) { + qWarning("QNmeaSatelliteInfoSource: no QIODevice data source, call setDevice() first"); + return false; + } + + if (!m_device->isOpen() && !m_device->open(QIODevice::ReadOnly)) { + qWarning("QNmeaSatelliteInfoSource: cannot open QIODevice data source"); + return false; + } + + connect(m_device, SIGNAL(aboutToClose()), SLOT(sourceDataClosed())); + connect(m_device, SIGNAL(readChannelFinished()), SLOT(sourceDataClosed())); + connect(m_device, SIGNAL(destroyed()), SLOT(sourceDataClosed())); + + return true; +} + +bool QNmeaSatelliteInfoSourcePrivate::initialize() +{ + if (m_nmeaReader) + return true; + + if (!openSourceDevice()) + return false; + + if (m_updateMode == QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode) + m_nmeaReader.reset(new QNmeaSatelliteRealTimeReader(this)); + else + m_nmeaReader.reset(new QNmeaSatelliteSimulationReader(this)); + + return true; +} + +void QNmeaSatelliteInfoSourcePrivate::prepareSourceDevice() +{ + // some data may already be available + if (m_updateMode == QNmeaSatelliteInfoSource::UpdateMode::SimulationMode) { + if (m_nmeaReader && m_device->bytesAvailable()) + m_nmeaReader->readAvailableData(); + } + + if (!m_connectedReadyRead) { + connect(m_device, SIGNAL(readyRead()), SLOT(readyRead())); + m_connectedReadyRead = true; + } +} + +bool QNmeaSatelliteInfoSourcePrivate::emitUpdated(QNmeaSatelliteInfoUpdate &update, + bool fromRequestUpdate) +{ + bool emitted = false; + if (!update.isFresh()) + return emitted; + + update.consume(); + bool inUseUpdated = false; + bool inViewUpdated = false; + if (!fromRequestUpdate) { + // we need to send update if information from at least one satellite + // systems has changed + for (auto it = update.m_satellites.cbegin(); it != update.m_satellites.cend(); ++it) { + inUseUpdated |= + it->satellitesInUse != m_lastUpdate.m_satellites[it.key()].satellitesInUse; + inViewUpdated |= + it->satellitesInView != m_lastUpdate.m_satellites[it.key()].satellitesInView; + } + } else { + // if we come here from requestUpdate(), we need to emit, even if the data + // didn't really change + inUseUpdated = true; + inViewUpdated = true; + } + + m_lastUpdate = update; + if (update.m_validInUse && inUseUpdated) { + emit m_source->satellitesInUseUpdated(update.allSatellitesInUse()); + emitted = true; + } + if (update.m_validInView && inViewUpdated) { + emit m_source->satellitesInViewUpdated(update.allSatellitesInView()); + emitted = true; + } + return emitted; +} + +void QNmeaSatelliteInfoSourcePrivate::timerEvent(QTimerEvent * /*event*/) +{ + emitPendingUpdate(); +} + +/*! + \class QNmeaSatelliteInfoSource + \inmodule QtPositioning + \ingroup QtPositioning-positioning + \since 6.2 + + \brief The \l QNmeaSatelliteInfoSource class provides satellite information + using an NMEA data source. + + NMEA is a commonly used protocol for the specification of one's global + position at a certain point in time. The \l QNmeaSatelliteInfoSource class + reads NMEA data and uses it to provide information about satellites in view + and satellites in use in form of lists of \l QGeoSatelliteInfo objects. + + A \l QNmeaSatelliteInfoSource instance operates in either \l {RealTimeMode} + or \l {SimulationMode}. These modes allow NMEA data to be read from either a + live source of data, or replayed for simulation purposes from previously + recorded NMEA data. + + The source of NMEA data is set via \l setDevice(). + + Use \l startUpdates() to start receiving regular satellite information + updates and \l stopUpdates() to stop these updates. If you only require + updates occasionally, you can call \l requestUpdate() to request a single + update of both satellites in view and satellites in use. + + The information about satellites in view is received via the + \l satellitesInViewUpdated() signal. + + The information about satellites in use is received via the + \l satellitesInUseUpdated() signal. +*/ + +/*! + \enum QNmeaSatelliteInfoSource::UpdateMode + Defines the available update modes. + + \value RealTimeMode Satellite information is read and distributed from the + data source as it becomes available. Use this mode if you are using + a live source of NMEA data (for example a GPS hardware device). + \value SimulationMode Satellite information is read and distributed from the + data source at the given rate. The rate is determined by the + \l {QNmeaSatelliteInfoSource::}{SimulationUpdateInterval} parameter. + Use this mode if the data source contains previously recorded NMEA + data and you want to replay the data for simulation purposes. +*/ + +/*! + \variable QNmeaSatelliteInfoSource::SimulationUpdateInterval + \brief The backend property name for data read rate in the + \l SimulationMode. The value for this property is the integer number + representing the amount of milliseconds between the subsequent reads. + Use this parameter in the \l {QNmeaSatelliteInfoSource::} + {setBackendProperty()} and \l {QNmeaSatelliteInfoSource::}{backendProperty()} + methods. + + \note This property is different from the interval that can be set via + \l {setUpdateInterval()}. The value set via \l {setUpdateInterval()} + denotes an interval for the user notification, while this parameter + specifies the internal frequency of reading the data from source file. It + means that one can have multiple (or none) reads during the + \l {updateInterval()} period. +*/ +QString QNmeaSatelliteInfoSource::SimulationUpdateInterval = + QStringLiteral("nmea.satellite_info_simulation_interval"); + +/*! + Constructs a \l QNmeaSatelliteInfoSource instance with the given \a parent + and \a mode. +*/ +QNmeaSatelliteInfoSource::QNmeaSatelliteInfoSource(UpdateMode mode, QObject *parent) + : QGeoSatelliteInfoSource(parent), + d(new QNmeaSatelliteInfoSourcePrivate(this, mode)) +{ +} + +/*! + Destroys the satellite information source. +*/ +QNmeaSatelliteInfoSource::~QNmeaSatelliteInfoSource() +{ + delete d; +} + +/*! + Returns the update mode. +*/ +QNmeaSatelliteInfoSource::UpdateMode QNmeaSatelliteInfoSource::updateMode() const +{ + return d->m_updateMode; +} + +/*! + Sets the NMEA data source to \a device. If the device is not open, it + will be opened in QIODevice::ReadOnly mode. + + The source device can only be set once and must be set before calling + \l startUpdates() or \l requestUpdate(). + + \note The \a device must emit \l {QIODevice::readyRead()} for the + source to be notified when data is available for reading. + \l QNmeaSatelliteInfoSource does not assume the ownership of the device, + and hence does not deallocate it upon destruction. +*/ +void QNmeaSatelliteInfoSource::setDevice(QIODevice *device) +{ + if (device != d->m_device) { + if (!d->m_device) + d->m_device = device; + else + qWarning("QNmeaSatelliteInfoSource: source device has already been set"); + } +} + +/*! + Returns the NMEA data source. +*/ +QIODevice *QNmeaSatelliteInfoSource::device() const +{ + return d->m_device; +} + +/*! + \reimp +*/ +void QNmeaSatelliteInfoSource::setUpdateInterval(int msec) +{ + int interval = msec; + if (interval != 0) + interval = qMax(msec, minimumUpdateInterval()); + QGeoSatelliteInfoSource::setUpdateInterval(interval); + if (d->m_invokedStart) { + d->stopUpdates(); + d->startUpdates(); + } +} + +/*! + \reimp +*/ +int QNmeaSatelliteInfoSource::minimumUpdateInterval() const +{ + return 2; // Some chips are capable of over 100 updates per seconds. +} + +/*! + \reimp +*/ +QGeoSatelliteInfoSource::Error QNmeaSatelliteInfoSource::error() const +{ + return d->m_satelliteError; +} + +/*! + \reimp +*/ +bool QNmeaSatelliteInfoSource::setBackendProperty(const QString &name, const QVariant &value) +{ + if (name == SimulationUpdateInterval && d->m_updateMode == UpdateMode::SimulationMode) { + bool ok = false; + const int interval = value.toInt(&ok); + if (ok) { + auto *reader = dynamic_cast(d->m_nmeaReader.get()); + if (reader) { + reader->setUpdateInterval(interval); + } else { + // d->m_nmeaReader will use it in constructor + d->m_simulationUpdateInterval = interval; + } + return true; + } + } + return false; +} + +/*! + \reimp +*/ +QVariant QNmeaSatelliteInfoSource::backendProperty(const QString &name) const +{ + if (name == SimulationUpdateInterval && d->m_updateMode == UpdateMode::SimulationMode) { + auto *reader = dynamic_cast(d->m_nmeaReader.get()); + if (reader) + return reader->updateInterval(); + else + return d->m_simulationUpdateInterval; + } + return QVariant(); +} + +/*! + \reimp +*/ +void QNmeaSatelliteInfoSource::startUpdates() +{ + d->startUpdates(); +} + +/*! + \reimp +*/ +void QNmeaSatelliteInfoSource::stopUpdates() +{ + d->stopUpdates(); +} + +/*! + \reimp +*/ +void QNmeaSatelliteInfoSource::requestUpdate(int msec) +{ + d->requestUpdate(msec == 0 ? 60000 * 5 : msec); // 5min default timeout +} + +/*! + Parses an NMEA sentence string to extract the IDs of satelites in use. + + The default implementation will parse standard NMEA $GPGSA sentences. + This method should be reimplemented in a subclass whenever the need to deal + with non-standard NMEA sentences arises. + + The parser reads \a size bytes from \a data and uses that information to + fill \a pnrsInUse list. + + Returns system type if the sentence was successfully parsed, otherwise + returns \l QGeoSatelliteInfo::Undefined and should not modifiy \a pnrsInUse. +*/ +QGeoSatelliteInfo::SatelliteSystem +QNmeaSatelliteInfoSource::parseSatellitesInUseFromNmea(const char *data, int size, + QList &pnrsInUse) +{ + return QLocationUtils::getSatInUseFromNmea(data, size, pnrsInUse); +} + +/*! + \enum QNmeaSatelliteInfoSource::SatelliteInfoParseStatus + Defines the parse status of satellite information. The satellite information + can be split into multiple sentences, and we need to parse all of them. + \value NotParsed The data does not contain information about satellites. + \value PartiallyParsed A valid satellite information is received and parsed, + but it's not complete, so we need to wait for another NMEA sentence. + \value FullyParsed Satellite information was fully collected and parsed. +*/ + +/*! + Parses an NMEA sentence string to extract the information about satellites + in view. + + The default implementation will parse standard NMEA $GPGSV sentences. + This method should be reimplemented in a subclass whenever the need to deal + with non-standard NMEA sentences arises. + + The parser reads \a size bytes from \a data and uses that information to + fill \a infos list. + + Returns \l SatelliteInfoParseStatus with parse result. + Modifies \a infos list in case \l {QNmeaSatelliteInfoSource::} + {PartiallyParsed} or \l {QNmeaSatelliteInfoSource::}{FullyParsed} is + returned. + Also sets the \a system to correct satellite system type. This is required + to determine the system type in case there are no satellites in view. +*/ +QNmeaSatelliteInfoSource::SatelliteInfoParseStatus +QNmeaSatelliteInfoSource::parseSatelliteInfoFromNmea(const char *data, int size, + QList &infos, + QGeoSatelliteInfo::SatelliteSystem &system) +{ + return static_cast( + QLocationUtils::getSatInfoFromNmea(data, size, infos, system)); +} + +void QNmeaSatelliteInfoSource::setError(QGeoSatelliteInfoSource::Error satelliteError) +{ + d->m_satelliteError = satelliteError; + if (d->m_satelliteError != QGeoSatelliteInfoSource::NoError) + emit QGeoSatelliteInfoSource::errorOccurred(satelliteError); +} + +QList QNmeaSatelliteInfoUpdate::allSatellitesInUse() const +{ + QList result; + for (const auto &s : m_satellites) + result.append(s.satellitesInUse); + return result; +} + +QList QNmeaSatelliteInfoUpdate::allSatellitesInView() const +{ + QList result; + for (const auto &s : m_satellites) + result.append(s.satellitesInView); + return result; +} + +void QNmeaSatelliteInfoUpdate::setSatellitesInView(QGeoSatelliteInfo::SatelliteSystem system, + const QList &inView) +{ + auto &info = m_satellites[system]; + info.updatingGSV = false; + + info.satellitesInView = inView; + info.validInView = true; + + if (!info.satellitesInUseReceived) { + // Normally a GSA message should come after a GSV message. If this flag + // is not set, we have received 2 consecutive GSV messages for this + // system without a GSA in between. + // This means that we could actually receive a $GNGSA empty message for + // this specific type. As it had no ids and GN talker id, we could not + // determine system type. This most probably means that we have no + // satellites in use for this system type. + // Clear satellites in use, if any. + info.satellitesInUse.clear(); + info.inUseIds.clear(); + info.validInUse = true; + } + info.satellitesInUseReceived = false; + + if (info.satellitesInView.isEmpty()) { + // If we received an empty list of satellites in view, then the list of + // satellites in use will also be empty, so we would not be able to + // match it with correct system type in case of $GNGSA message. Clear + // the list in advance. + info.satellitesInUse.clear(); + info.inUseIds.clear(); + info.validInUse = true; + } else if (!info.inUseIds.isEmpty()) { + // We have some satellites in use cached. Check if we have received the + // proper GSV for them. + info.satellitesInUse.clear(); + info.validInUse = false; + bool corrupt = false; + for (const auto id : info.inUseIds) { + bool found = false; + for (const auto &s : info.satellitesInView) { + if (s.satelliteIdentifier() == id) { + info.satellitesInUse.append(s); + found = true; + break; + } + } + if (!found) { + // The previoulsy received GSA is incorrect or not related to + // this GSV + info.satellitesInUse.clear(); + corrupt = true; + break; + } + } + info.validInUse = !corrupt; + info.inUseIds.clear(); + } + + m_validInUse = calculateValidInUse(); + m_validInView = calculateValidInView(); + m_fresh = true; +} + +bool QNmeaSatelliteInfoUpdate::setSatellitesInUse(QGeoSatelliteInfo::SatelliteSystem system, + const QList &inUse) +{ + if (system == QGeoSatelliteInfo::Undefined || system == QGeoSatelliteInfo::Multiple) + return false; // No way to determine satellite system + + SatelliteInfo &info = m_satellites[system]; + info.satellitesInUse.clear(); + + info.satellitesInUseReceived = true; + info.inUseIds = inUse; + + if (info.updatingGSV) { + info.validInView = false; + m_validInView = false; + return false; + } + + for (const auto id : inUse) { + bool found = false; + for (const auto &s : info.satellitesInView) { + if (s.satelliteIdentifier() == id) { + info.satellitesInUse.append(s); + found = true; + break; + } + } + if (!found) { + // satellites in use are not in view -> related GSV is not yet received + info.satellitesInView.clear(); + info.validInView = false; + m_validInView = false; + return false; + } + } + + info.inUseIds.clear(); // make sure we remove all obsolete cache + + info.validInUse = true; + m_fresh = true; + m_validInUse = calculateValidInUse(); + + return true; +} + +void QNmeaSatelliteInfoUpdate::consume() +{ + m_fresh = false; +} + +bool QNmeaSatelliteInfoUpdate::isFresh() const +{ + return m_fresh; +} + +void QNmeaSatelliteInfoUpdate::clear() +{ + m_satellites.clear(); + m_satellitesInViewParsed.clear(); + m_validInView = false; + m_validInUse = false; + m_fresh = false; +#if USE_NMEA_PIMPL + gsa.clear(); + gsv.clear(); +#endif +} + +bool QNmeaSatelliteInfoUpdate::isValid() const +{ + // GSV without GSA is valid. GSA with outdated but still matching GSV also valid. + return m_validInView || m_validInUse; +} + +bool QNmeaSatelliteInfoUpdate::calculateValidInUse() const +{ + for (const auto &s : m_satellites) { + if (!s.validInUse) + return false; + } + return true; +} + +bool QNmeaSatelliteInfoUpdate::calculateValidInView() const +{ + for (const auto &s : m_satellites) { + if (!s.validInView) + return false; + } + return true; +} + +QNmeaSatelliteReader::QNmeaSatelliteReader(QNmeaSatelliteInfoSourcePrivate *sourcePrivate) + : m_proxy(sourcePrivate) +{ +} + +QNmeaSatelliteReader::~QNmeaSatelliteReader() +{ +} + +QNmeaSatelliteRealTimeReader::QNmeaSatelliteRealTimeReader(QNmeaSatelliteInfoSourcePrivate *sourcePrivate) + : QNmeaSatelliteReader(sourcePrivate) +{ +} + +void QNmeaSatelliteRealTimeReader::readAvailableData() +{ + while (m_proxy->m_device->canReadLine()) + m_proxy->processNmeaData(m_proxy->m_pendingUpdate); + m_proxy->notifyNewUpdate(); +} + +QNmeaSatelliteSimulationReader::QNmeaSatelliteSimulationReader(QNmeaSatelliteInfoSourcePrivate *sourcePrivate) + : QNmeaSatelliteReader(sourcePrivate) +{ + m_timer.reset(new QTimer); + QObject::connect(m_timer.get(), &QTimer::timeout, [this]() { + readAvailableData(); + }); + m_updateInterval = + qMax(m_proxy->m_simulationUpdateInterval, m_proxy->m_source->minimumUpdateInterval()); +} + +void QNmeaSatelliteSimulationReader::readAvailableData() +{ + if (!m_timer->isActive()) { + // At the very first start we just start a timer to simulate a short + // delay for overlapping requestUpdate() calls. + // See TestQGeoSatelliteInfoSource::requestUpdate_overlappingCalls and + // TestQGeoSatelliteInfoSource::requestUpdate_overlappingCallsWithTimeout + m_timer->start(m_updateInterval); + } else { + // Here we try to get both satellites in view and satellites in use. + // We behave like that because according to the QGeoSatelliteInfoSource + // tests each call to requestUpdate() should return both satellites in + // view and satellites in use. Same is expected on each interval for + // startUpdates(). + // However user-provided NMEA logs might not contain some of the + // messages, so we will try not to get stuck here infinitely. + int numSatInUseMsgs = 0; + int numSatInViewMsgs = 0; + while (!numSatInUseMsgs || !numSatInViewMsgs) { + m_proxy->processNmeaData(m_proxy->m_pendingUpdate); + if (m_proxy->m_pendingUpdate.m_validInUse) + numSatInUseMsgs++; + if (m_proxy->m_pendingUpdate.m_validInView) + numSatInViewMsgs++; + // if we got the second message for one of them, but still didn't + // receive any for the other - break. + // We use 2 in the comparison, because, as soon as the m_validIn* + // flag is set, it will stay true until we receive invalid message. + if (numSatInUseMsgs > 2 || numSatInViewMsgs > 2) { + const QString msgType = (numSatInUseMsgs > numSatInViewMsgs) + ? QStringLiteral("GSA") + : QStringLiteral("GSV"); + qWarning() << "nmea simulation reader: possibly incorrect message order. Got too " + "many consecutive" + << msgType << "messages"; + break; + } + } + m_proxy->notifyNewUpdate(); + } +} + +void QNmeaSatelliteSimulationReader::setUpdateInterval(int msec) +{ + // restart the timer with new interval + m_updateInterval = qMax(msec, m_proxy->m_source->minimumUpdateInterval()); + if (m_timer->isActive()) + m_timer->start(m_updateInterval); +} + +int QNmeaSatelliteSimulationReader::updateInterval() const +{ + return m_updateInterval; +} + +QT_END_NAMESPACE + +#include "moc_qnmeasatelliteinfosource_p.cpp" +#include "moc_qnmeasatelliteinfosource.cpp" diff --git a/src/positioning/qnmeasatelliteinfosource.h b/src/positioning/qnmeasatelliteinfosource.h new file mode 100644 index 0000000..de42332 --- /dev/null +++ b/src/positioning/qnmeasatelliteinfosource.h @@ -0,0 +1,68 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QNMEASATELLITEINFOSOURCE_H +#define QNMEASATELLITEINFOSOURCE_H + +#include + +QT_BEGIN_NAMESPACE + +class QIODevice; + +class QNmeaSatelliteInfoSourcePrivate; +class Q_POSITIONING_EXPORT QNmeaSatelliteInfoSource : public QGeoSatelliteInfoSource +{ + Q_OBJECT +public: + enum class UpdateMode { + RealTimeMode = 1, + SimulationMode + }; + + static QString SimulationUpdateInterval; + + explicit QNmeaSatelliteInfoSource(UpdateMode mode, QObject *parent = nullptr); + ~QNmeaSatelliteInfoSource() override; + + UpdateMode updateMode() const; + + void setDevice(QIODevice *source); + QIODevice *device() const; + + void setUpdateInterval(int msec) override; + int minimumUpdateInterval() const override; + Error error() const override; + + bool setBackendProperty(const QString &name, const QVariant &value) override; + QVariant backendProperty(const QString &name) const override; + +public Q_SLOTS: + void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 0) override; + +protected: + virtual QGeoSatelliteInfo::SatelliteSystem + parseSatellitesInUseFromNmea(const char *data, int size, QList &pnrsInUse); + enum SatelliteInfoParseStatus { + NotParsed = 0, + PartiallyParsed, + FullyParsed + }; + virtual SatelliteInfoParseStatus parseSatelliteInfoFromNmea(const char *data, int size, + QList &infos, + QGeoSatelliteInfo::SatelliteSystem &system); + + QNmeaSatelliteInfoSourcePrivate *d; + void setError(QGeoSatelliteInfoSource::Error satelliteError); + + friend class QNmeaSatelliteInfoSourcePrivate; + Q_DISABLE_COPY(QNmeaSatelliteInfoSource) + + // for using the SatelliteInfoParseStatus enum + friend class QLocationUtils; +}; + +QT_END_NAMESPACE + +#endif // QNMEASATELLITEINFOSOURCE_H diff --git a/src/positioning/qnmeasatelliteinfosource_p.h b/src/positioning/qnmeasatelliteinfosource_p.h new file mode 100644 index 0000000..0914b84 --- /dev/null +++ b/src/positioning/qnmeasatelliteinfosource_p.h @@ -0,0 +1,146 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QNMESATELLITEINFOSOURCE_P_H +#define QNMESATELLITEINFOSOURCE_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 "qnmeasatelliteinfosource.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#define USE_NMEA_PIMPL 1 + +struct SatelliteInfo +{ + QList satellitesInView; + QList satellitesInUse; + QList inUseIds; // temp buffer for GSA received before GSV + bool satellitesInUseReceived = false; + bool updatingGSV = false; + bool validInView = false; + bool validInUse = false; +}; + +struct QNmeaSatelliteInfoUpdate +{ + QMap m_satellites; + QList m_satellitesInViewParsed; + bool m_validInView = false; // global state for all satellite systems + bool m_validInUse = false; // global state for all satellite systems + bool m_fresh = false; +#if USE_NMEA_PIMPL + QByteArray gsa; + QList gsv; +#endif + QList allSatellitesInUse() const; + QList allSatellitesInView() const; + void setSatellitesInView(QGeoSatelliteInfo::SatelliteSystem system, + const QList &inView); + bool setSatellitesInUse(QGeoSatelliteInfo::SatelliteSystem system, const QList &inUse); + void consume(); + bool isFresh() const; + void clear(); + bool isValid() const; + bool calculateValidInUse() const; + bool calculateValidInView() const; +}; + +class QNmeaSatelliteReader; +class QNmeaSatelliteInfoSourcePrivate : public QObject +{ + Q_OBJECT +public: + QNmeaSatelliteInfoSourcePrivate(QNmeaSatelliteInfoSource *parent, QNmeaSatelliteInfoSource::UpdateMode updateMode); + ~QNmeaSatelliteInfoSourcePrivate(); + + void startUpdates(); + void stopUpdates(); + void requestUpdate(int msec); + void notifyNewUpdate(); + void processNmeaData(QNmeaSatelliteInfoUpdate &updateInfo); + +public slots: + void readyRead(); + void emitPendingUpdate(); + void sourceDataClosed(); + void updateRequestTimeout(); + +public: + QNmeaSatelliteInfoSource *m_source = nullptr; + QGeoSatelliteInfoSource::Error m_satelliteError = QGeoSatelliteInfoSource::NoError; + QPointer m_device; + QNmeaSatelliteInfoUpdate m_pendingUpdate; + QNmeaSatelliteInfoUpdate m_lastUpdate; + bool m_invokedStart = false; + bool m_noUpdateLastInterval = false; + bool m_updateTimeoutSent = false; + bool m_connectedReadyRead = false; + QBasicTimer *m_updateTimer = nullptr; // the timer used in startUpdates() + QTimer *m_requestTimer = nullptr; // the timer used in requestUpdate() + QScopedPointer m_nmeaReader; + QNmeaSatelliteInfoSource::UpdateMode m_updateMode; + int m_simulationUpdateInterval = 100; + +protected: + bool openSourceDevice(); + bool initialize(); + void prepareSourceDevice(); + bool emitUpdated(QNmeaSatelliteInfoUpdate &update, bool fromRequestUpdate); + void timerEvent(QTimerEvent *event) override; +}; + +class QNmeaSatelliteReader +{ +public: + QNmeaSatelliteReader(QNmeaSatelliteInfoSourcePrivate *sourcePrivate); + virtual ~QNmeaSatelliteReader(); + + virtual void readAvailableData() = 0; + +protected: + QNmeaSatelliteInfoSourcePrivate *m_proxy; +}; + +class QNmeaSatelliteRealTimeReader : public QNmeaSatelliteReader +{ +public: + QNmeaSatelliteRealTimeReader(QNmeaSatelliteInfoSourcePrivate *sourcePrivate); + void readAvailableData() override; +}; + +class QNmeaSatelliteSimulationReader : public QNmeaSatelliteReader +{ +public: + QNmeaSatelliteSimulationReader(QNmeaSatelliteInfoSourcePrivate *sourcePrivate); + void readAvailableData() override; + void setUpdateInterval(int msec); + int updateInterval() const; + +private: + QScopedPointer m_timer; + int m_updateInterval; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/positioning/qpositioningglobal.h b/src/positioning/qpositioningglobal.h new file mode 100644 index 0000000..316e0ee --- /dev/null +++ b/src/positioning/qpositioningglobal.h @@ -0,0 +1,10 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QPOSITIONINGGLOBAL_H +#define QPOSITIONINGGLOBAL_H + +#include +#include + +#endif // QPOSITIONINGGLOBAL_H + diff --git a/src/positioning/qpositioningglobal_p.h b/src/positioning/qpositioningglobal_p.h new file mode 100644 index 0000000..1b0e018 --- /dev/null +++ b/src/positioning/qpositioningglobal_p.h @@ -0,0 +1,21 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QPOSITIONINGGLOBAL_P_H +#define QPOSITIONINGGLOBAL_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 "qpositioningglobal.h" +#include + +#endif // QPOSITIONINGGLOBAL_P_H + diff --git a/src/positioning/qwebmercator.cpp b/src/positioning/qwebmercator.cpp new file mode 100644 index 0000000..ce7cc64 --- /dev/null +++ b/src/positioning/qwebmercator.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qwebmercator_p.h" + +#include "qgeocoordinate.h" + +#include +#include + +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" + +QT_BEGIN_NAMESPACE + +QDoubleVector2D QWebMercator::coordToMercator(const QGeoCoordinate &coord) +{ + const double pi = M_PI; + + double lon = coord.longitude() / 360.0 + 0.5; + + double lat = coord.latitude(); + lat = 0.5 - (std::log(std::tan((pi / 4.0) + (pi / 2.0) * lat / 180.0)) / pi) / 2.0; + lat = qBound(0.0, lat, 1.0); + + return QDoubleVector2D(lon, lat); +} + +double QWebMercator::realmod(const double a, const double b) +{ + quint64 div = static_cast(a / b); + return a - static_cast(div) * b; +} + +QGeoCoordinate QWebMercator::mercatorToCoord(const QDoubleVector2D &mercator) +{ + const double pi = M_PI; + + double fx = mercator.x(); + double fy = mercator.y(); + + if (fy < 0.0) + fy = 0.0; + else if (fy > 1.0) + fy = 1.0; + + double lat; + + if (fy == 0.0) + lat = 90.0; + else if (fy == 1.0) + lat = -90.0; + else + lat = (180.0 / pi) * (2.0 * std::atan(std::exp(pi * (1.0 - 2.0 * fy))) - (pi / 2.0)); + + double lng; + if (fx >= 0) { + lng = realmod(fx, 1.0); + } else { + lng = realmod(1.0 - realmod(-1.0 * fx, 1.0), 1.0); + } + + lng = lng * 360.0 - 180.0; + + return QGeoCoordinate(lat, lng, 0.0); +} + +QGeoCoordinate QWebMercator::coordinateInterpolation(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress) +{ + QDoubleVector2D s = QWebMercator::coordToMercator(from); + QDoubleVector2D e = QWebMercator::coordToMercator(to); + + double x; + + if (0.5 < qAbs(e.x() - s.x())) { + // handle dateline crossing + double ex = e.x(); + double sx = s.x(); + if (ex < sx) + sx -= 1.0; + else if (sx < ex) + ex -= 1.0; + + x = (1.0 - progress) * sx + progress * ex; + + if (!qFuzzyIsNull(x) && (x < 0.0)) + x += 1.0; + + } else { + x = (1.0 - progress) * s.x() + progress * e.x(); + } + + double y = (1.0 - progress) * s.y() + progress * e.y(); + + QGeoCoordinate result = QWebMercator::mercatorToCoord(QDoubleVector2D(x, y)); + result.setAltitude((1.0 - progress) * from.altitude() + progress * to.altitude()); + + return result; +} + +QT_END_NAMESPACE diff --git a/src/positioning/qwebmercator_p.h b/src/positioning/qwebmercator_p.h new file mode 100644 index 0000000..a7d318d --- /dev/null +++ b/src/positioning/qwebmercator_p.h @@ -0,0 +1,39 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QWEBMERCATOR_P_H +#define QWEBMERCATOR_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 +#include +#include "qpositioningglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QGeoCoordinate; +class QDoubleVector2D; + +class Q_POSITIONING_PRIVATE_EXPORT QWebMercator +{ +public: + static QDoubleVector2D coordToMercator(const QGeoCoordinate &coord); + static QGeoCoordinate mercatorToCoord(const QDoubleVector2D &mercator); + static QGeoCoordinate coordinateInterpolation(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress); + +private: + static double realmod(const double a, const double b); +}; + +QT_END_NAMESPACE + +#endif // QWEBMERCATOR_P_H diff --git a/src/positioningquick/CMakeLists.txt b/src/positioningquick/CMakeLists.txt new file mode 100644 index 0000000..051f128 --- /dev/null +++ b/src/positioningquick/CMakeLists.txt @@ -0,0 +1,50 @@ +# Generated from positioningquick.pro. + +##################################################################### +## PositioningQuick Module: +##################################################################### + +qt_internal_add_qml_module(PositioningQuick + URI QtPositioning + VERSION ${CMAKE_PROJECT_VERSION} + PLUGIN_TARGET positioningquickplugin + NO_GENERATE_PLUGIN_SOURCE + NO_PLUGIN_OPTIONAL + CLASS_NAME QtPositioningDeclarativeModule + DEPENDENCIES + QtQuick/auto + SOURCES + qdeclarativegeoaddress_p.h qdeclarativegeoaddress.cpp + qdeclarativegeolocation_p.h qdeclarativegeolocation.cpp + qdeclarativepluginparameter_p.h qdeclarativepluginparameter.cpp + qdeclarativeposition_p.h qdeclarativeposition.cpp + qdeclarativepositionsource_p.h qdeclarativepositionsource.cpp + qquickgeocoordinateanimation_p.h qquickgeocoordinateanimation.cpp + locationsingleton_p.h locationsingleton.cpp + qquickgeocoordinateanimation_p_p.h + qpositioningquickglobal.h + qpositioningquickglobal_p.h + qpositioningquickmodule_p.h qpositioningquickmodule.cpp + LIBRARIES + Qt::PositioningPrivate + Qt::QuickPrivate + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning + Qt::Qml + Qt::Quick + PRIVATE_MODULE_INTERFACE + Qt::PositioningPrivate + Qt::QuickPrivate + GENERATE_CPP_EXPORTS + GENERATE_PRIVATE_CPP_EXPORTS +) + +qt_internal_extend_target(positioningquickplugin + SOURCES + positioningplugin.cpp + LIBRARIES + Qt::PositioningQuickPrivate + Qt::Quick +) + diff --git a/src/positioningquick/locationsingleton.cpp b/src/positioningquick/locationsingleton.cpp new file mode 100644 index 0000000..41745e0 --- /dev/null +++ b/src/positioningquick/locationsingleton.cpp @@ -0,0 +1,359 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "locationsingleton_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +static QGeoCoordinate parseCoordinate(const QJSValue &value, bool *ok) +{ + QGeoCoordinate c; + + if (value.isObject()) { + if (value.hasProperty(QStringLiteral("latitude"))) + c.setLatitude(value.property(QStringLiteral("latitude")).toNumber()); + if (value.hasProperty(QStringLiteral("longitude"))) + c.setLongitude(value.property(QStringLiteral("longitude")).toNumber()); + if (value.hasProperty(QStringLiteral("altitude"))) + c.setAltitude(value.property(QStringLiteral("altitude")).toNumber()); + + if (ok) + *ok = true; + } else if (ok) { + *ok = false; + } + + return c; +} + + +/*! + \qmltype QtPositioning + \inqmlmodule QtPositioning + \since 5.2 + + \brief The QtPositioning global object provides useful functions for working with location-based + types in QML. + + \qml + import QtPositioning + + Item { + property var coordinate: QtPositioning.coordinate(-27.5, 153.1) + } + \endqml +*/ + +LocationSingleton::LocationSingleton(QObject *parent) +: QObject(parent) +{ +} + +/*! + \qmlmethod coordinate ::QtPositioning::coordinate() + + Constructs an invalid coordinate. + +*/ +QGeoCoordinate LocationSingleton::coordinate() const +{ + return QGeoCoordinate(); +} + +/*! + \qmlmethod coordinate QtPositioning::coordinate(real latitude, real longitude, real altitude) const + + Constructs a coordinate with the specified \a latitude, \a longitude and optional \a altitude. + Both \a latitude and \a longitude must be valid, otherwise an invalid coordinate is returned. + + \sa {coordinate} +*/ +QGeoCoordinate LocationSingleton::coordinate(double latitude, double longitude, double altitude) const +{ + return QGeoCoordinate(latitude, longitude, altitude); +} + +/*! + \qmlmethod geoshape QtPositioning::shape() const + + Constructs an invalid geoshape. + + \sa {geoshape} +*/ +QGeoShape LocationSingleton::shape() const +{ + return QGeoShape(); +} + +/*! + \qmlmethod georectangle QtPositioning::rectangle() const + + Constructs an invalid georectangle. + + \sa {georectangle} +*/ +QGeoRectangle LocationSingleton::rectangle() const +{ + return QGeoRectangle(); +} + +/*! + \qmlmethod georectangle QtPositioning::rectangle(coordinate center, real width, real height) const + + Constructs a georectangle centered at \a center with a width of \a width degrees and a hight of + \a height degrees. + + \sa {georectangle} +*/ +QGeoRectangle LocationSingleton::rectangle(const QGeoCoordinate ¢er, + double width, double height) const +{ + return QGeoRectangle(center, width, height); +} + +/*! + \qmlmethod georectangle QtPositioning::rectangle(coordinate topLeft, coordinate bottomRight) const + + Constructs a georectangle with its top left corner positioned at \a topLeft and its bottom + right corner positioned at \a {bottomRight}. + + \sa {georectangle} +*/ +QGeoRectangle LocationSingleton::rectangle(const QGeoCoordinate &topLeft, + const QGeoCoordinate &bottomRight) const +{ + return QGeoRectangle(topLeft, bottomRight); +} + +/*! + \qmlmethod georectangle QtLocation5::QtLocation::rectangle(list coordinates) const + + Constructs a georectangle from the list of coordinates, the returned list is the smallest possible + containing all the coordinates. + + \sa {georectangle} +*/ +QGeoRectangle LocationSingleton::rectangle(const QVariantList &coordinates) const +{ + QList internalCoordinates; + for (const auto &coordinate : coordinates) { + if (coordinate.canConvert()) + internalCoordinates << coordinate.value(); + } + + return QGeoRectangle(internalCoordinates); +} + +/*! + \qmlmethod geocircle QtPositioning::circle() const + + Constructs an invalid geocircle. + + \sa {geocircle} +*/ +QGeoCircle LocationSingleton::circle() const +{ + return QGeoCircle(); +} + +/*! + \qmlmethod geocircle QtPositioning::circle(coordinate center, real radius) const + + Constructs a geocircle centered at \a center with a radius of \a radius meters. +*/ +QGeoCircle LocationSingleton::circle(const QGeoCoordinate ¢er, qreal radius) const +{ + return QGeoCircle(center, radius); +} + +/*! + \qmlmethod geopath QtPositioning::path() const + + Constructs an empty geopath. + + \sa {geopath} + \since 5.9 +*/ +QGeoPath LocationSingleton::path() const +{ + return QGeoPath(); +} + +/*! + \qmlmethod geopath QtPositioning::path(list coordinates, real width) const + + Constructs a geopath from coordinates and width. + + \sa {geopath} + \since 5.9 +*/ +QGeoPath LocationSingleton::path(const QJSValue &value, qreal width) const +{ + QList pathList; + + if (value.isArray()) { + quint32 length = value.property(QStringLiteral("length")).toUInt(); + for (quint32 i = 0; i < length; ++i) { + bool ok = false; + QGeoCoordinate c = parseCoordinate(value.property(i), &ok); + + if (!ok || !c.isValid()) { + pathList.clear(); // aborting + break; + } + + pathList.append(c); + } + } + + return QGeoPath(pathList, width); +} + +/*! + \qmlmethod geopolygon QtPositioning::polygon() const + + Constructs an empty polygon. + + \sa {geopolygon} + \since 5.10 +*/ +QGeoPolygon LocationSingleton::polygon() const +{ + return QGeoPolygon(); +} + +/*! + \qmlmethod geopolygon QtPositioning::polygon(list coordinates) const + + Constructs a polygon from coordinates. + + \sa {geopolygon} + \since 5.10 +*/ +QGeoPolygon LocationSingleton::polygon(const QVariantList &coordinates) const +{ + QList internalCoordinates; + for (const auto &coordinate : coordinates) { + if (coordinate.canConvert()) + internalCoordinates << coordinate.value(); + } + + return QGeoPolygon(internalCoordinates); +} + +/*! + \qmlmethod geopolygon QtPositioning::polygon(list perimeter, list> holes) const + + Constructs a polygon from coordinates for perimeter and inner holes. + + \sa {geopolygon} + \since 5.12 +*/ +QGeoPolygon LocationSingleton::polygon(const QVariantList &perimeter, const QVariantList &holes) const +{ + QList internalCoordinates; + for (const auto &coordinate : perimeter) { + if (coordinate.canConvert()) + internalCoordinates << coordinate.value(); + } + QGeoPolygon poly(internalCoordinates); + + for (const auto &h : holes) { + if (h.metaType().id() == QMetaType::QVariantList) { + QList hole; + const QVariantList &holeData = h.toList(); + for (const auto &coord : holeData) { + if (coord.canConvert()) + hole << coord.value(); + } + if (!hole.isEmpty()) + poly.addHole(hole); + } + } + + return poly; +} + +/*! + \qmlmethod geocircle QtPositioning::shapeToCircle(geoshape shape) const + + Converts \a shape to a geocircle. + + \sa {geocircle} + \since 5.5 +*/ +QGeoCircle LocationSingleton::shapeToCircle(const QGeoShape &shape) const +{ + return QGeoCircle(shape); +} + +/*! + \qmlmethod georectangle QtPositioning::shapeToRectangle(geoshape shape) const + + Converts \a shape to a georectangle. + + \sa {georectangle} + \since 5.5 +*/ +QGeoRectangle LocationSingleton::shapeToRectangle(const QGeoShape &shape) const +{ + return QGeoRectangle(shape); +} + +/*! + \qmlmethod geopath QtPositioning::shapeToPath(geoshape shape) const + + Converts \a shape to a geopath. + + \sa {geopath} + \since 5.9 +*/ +QGeoPath LocationSingleton::shapeToPath(const QGeoShape &shape) const +{ + return QGeoPath(shape); +} + +/*! + \qmlmethod geopolygon QtPositioning::shapeToPolygon(geoshape shape) const + + Converts \a shape to a polygon. + + \sa {geopolygon} + \since 5.10 +*/ +QGeoPolygon LocationSingleton::shapeToPolygon(const QGeoShape &shape) const +{ + return QGeoPolygon(shape); +} + +/*! + \qmlmethod coordinate QtPositioning::mercatorToCoord(point mercator) const + + Converts a \a mercator coordinate into a latitude-longitude coordinate. + + \sa {coordToMercator} + \since 5.12 +*/ +QGeoCoordinate LocationSingleton::mercatorToCoord(const QPointF &mercator) const +{ + return QWebMercator::mercatorToCoord(QDoubleVector2D(mercator.x(), mercator.y())); +} + +/*! + \qmlmethod point QtPositioning::coordToMercator(coordinate coord) const + + Converts a coordinate \a coord into a mercator coordinate and returns it. + \sa {mercatorToCoord} + \since 5.12 +*/ +QPointF LocationSingleton::coordToMercator(const QGeoCoordinate &coord) const +{ + return QWebMercator::coordToMercator(coord).toPointF(); +} + +QT_END_NAMESPACE + +#include "moc_locationsingleton_p.cpp" diff --git a/src/positioningquick/locationsingleton_p.h b/src/positioningquick/locationsingleton_p.h new file mode 100644 index 0000000..42c055b --- /dev/null +++ b/src/positioningquick/locationsingleton_p.h @@ -0,0 +1,78 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef LOCATIONSINGLETON_H +#define LOCATIONSINGLETON_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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONINGQUICK_PRIVATE_EXPORT LocationSingleton : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(QtPositioning) + QML_SINGLETON + QML_ADDED_IN_VERSION(5, 0) + +public: + explicit LocationSingleton(QObject *parent = 0); + + Q_INVOKABLE QGeoCoordinate coordinate() const; + Q_INVOKABLE QGeoCoordinate coordinate(double latitude, double longitude, + double altitude = qQNaN()) const; + + Q_INVOKABLE QGeoShape shape() const; + + Q_INVOKABLE QGeoRectangle rectangle() const; + Q_INVOKABLE QGeoRectangle rectangle(const QGeoCoordinate ¢er, + double width, double height) const; + Q_INVOKABLE QGeoRectangle rectangle(const QGeoCoordinate &topLeft, + const QGeoCoordinate &bottomRight) const; + Q_INVOKABLE QGeoRectangle rectangle(const QVariantList &coordinates) const; + + Q_INVOKABLE QGeoCircle circle() const; + Q_INVOKABLE QGeoCircle circle(const QGeoCoordinate ¢er, qreal radius = -1.0) const; + + Q_INVOKABLE QGeoPath path() const; + Q_INVOKABLE QGeoPath path(const QJSValue &value, qreal width = 0.0) const; + + Q_INVOKABLE QGeoPolygon polygon() const; + Q_INVOKABLE QGeoPolygon polygon(const QVariantList &value) const; + Q_INVOKABLE QGeoPolygon polygon(const QVariantList &perimeter, const QVariantList &holes) const; + + Q_INVOKABLE QGeoCircle shapeToCircle(const QGeoShape &shape) const; + Q_INVOKABLE QGeoRectangle shapeToRectangle(const QGeoShape &shape) const; + Q_INVOKABLE QGeoPath shapeToPath(const QGeoShape &shape) const; + Q_INVOKABLE QGeoPolygon shapeToPolygon(const QGeoShape &shape) const; + + Q_REVISION(5, 12) Q_INVOKABLE QGeoCoordinate mercatorToCoord(const QPointF &mercator) const; + Q_REVISION(5, 12) Q_INVOKABLE QPointF coordToMercator(const QGeoCoordinate &coord) const; +}; + +QT_END_NAMESPACE + +#endif // LOCATIONSINGLETON_H diff --git a/src/positioningquick/positioningplugin.cpp b/src/positioningquick/positioningplugin.cpp new file mode 100644 index 0000000..3d87822 --- /dev/null +++ b/src/positioningquick/positioningplugin.cpp @@ -0,0 +1,525 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmlvaluetype coordinate + \ingroup qmlvaluetypes + \inqmlmodule QtPositioning + \ingroup qml-QtPositioning5-basictypes + \since 5.2 + + \brief The coordinate type represents and stores a geographic position. + + This type is a QML representation of \l QGeoCoordinate and represents a geographic + position in the form of \l {latitude}, \l longitude and \l altitude attributes. + The \l latitude attribute specifies the number of + decimal degrees above and below the equator. A positive latitude indicates the Northern + Hemisphere and a negative latitude indicates the Southern Hemisphere. The \l longitude + attribute specifies the number of decimal degrees east and west. A positive longitude + indicates the Eastern Hemisphere and a negative longitude indicates the Western Hemisphere. + The \l altitude attribute specifies the number of meters above sea level. Together, these + attributes specify a 3-dimensional position anywhere on or near the Earth's surface. + + The \l isValid attribute can be used to test if a coordinate is valid. A coordinate is + considered valid if it has a valid latitude and longitude. A valid altitude is not required. + The latitude must be between -90 and 90 inclusive and the longitude must be between -180 and + 180 inclusive. + + The \c coordinate type is used by many other types in the Qt Location module, for specifying + the position of an object on a Map, the current position of a device and many other tasks. + They also feature a number of important utility methods that make otherwise complex + calculations simple to use, such as \l {atDistanceAndAzimuth}(). + + \section1 Accuracy + + The latitude, longitude and altitude attributes stored in the coordinate type are represented + as doubles, giving them approximately 16 decimal digits of precision -- enough to specify + micrometers. The calculations performed in coordinate's methods such as \l {azimuthTo}() and + \l {distanceTo}() also use doubles for all intermediate values, but the inherent inaccuracies in + their spherical Earth model dominate the amount of error in their output. + + \section1 Example Usage + + Use properties of type \l var to store a \c {coordinate}. To create a \c coordinate use + one of the methods described below. In all cases, specifying the \l altitude attribute is + optional. + + To create a \c coordinate value, use the \l{QtPositioning::coordinate}{QtPositioning.coordinate()} + function: + + \qml + import QtPositioning + + Location { coordinate: QtPositioning.coordinate(-27.5, 153.1) } + \endqml + + or as separate \l latitude, \l longitude and \l altitude components: + + \qml + Location { + coordinate { + latitude: -27.5 + longitude: 153.1 + } + } + \endqml + + When integrating with C++, note that any QGeoCoordinate value passed into QML from C++ is + automatically converted into a \c coordinate value, and vice-versa. + + \section1 Properties + + \section2 latitude + + \code + real latitude + \endcode + + This property holds the latitude value of the geographical position + (decimal degrees). A positive latitude indicates the Northern Hemisphere, + and a negative latitude indicates the Southern Hemisphere. + If the property has not been set, its default value is NaN. + + For more details see the \l {QGeoCoordinate::latitude} property + + \section2 longitude + + \code + real longitude + \endcode + + This property holds the longitude value of the geographical position + (decimal degrees). A positive longitude indicates the Eastern Hemisphere, + and a negative longitude indicates the Western Hemisphere + If the property has not been set, its default value is NaN. + + For more details see the \l {QGeoCoordinate::longitude} property + + \section2 altitude + + \code + real altitude + \endcode + + This property holds the altitude value (meters above sea level). + If the property has not been set, its default value is NaN. + + For more details see the \l {QGeoCoordinate::altitude} property + + \section2 isValid + + \code + bool isValid + \endcode + + This property holds the current validity of the coordinate. Coordinates + are considered valid if they have been set with a valid latitude and + longitude (altitude is not required). + + The latitude must be between -90 to 90 inclusive to be considered valid, + and the longitude must be between -180 to 180 inclusive to be considered + valid. + + This is a read-only property. + + \section1 Methods + + \section2 distanceTo() + + \code + real distanceTo(coordinate other) + \endcode + + Returns the distance (in meters) from this coordinate to the coordinate specified by \a other. + Altitude is not used in the calculation. + + This calculation returns the great-circle distance between the two coordinates, with an + assumption that the Earth is spherical for the purpose of this calculation. + + \section2 azimuthTo() + + \code + real azimuth(coordinate other) + \endcode + + Returns the azimuth (or bearing) in degrees from this coordinate to the coordinate specified by + \a other. Altitude is not used in the calculation. + + There is an assumption that the Earth is spherical for the purpose of this calculation. + + \section2 atDistanceAndAzimuth() + + \code + coordinate atDistanceAndAzimuth(real distance, real azimuth) + \endcode + + Returns the coordinate that is reached by traveling \a distance metres from this coordinate at + \a azimuth degrees along a great-circle. + + There is an assumption that the Earth is spherical for the purpose of this calculation. +*/ + +/*! + \qmlvaluetype geoshape + \ingroup qmlvaluetypes + \inqmlmodule QtPositioning + \ingroup qml-QtPositioning5-basictypes + \since 5.2 + + \brief A geoshape type represents an abstract geographic area. + + This type is a QML representation of \l QGeoShape which is an abstract geographic area. + It includes attributes and methods common to all geographic areas. To create objects + that represent a valid geographic area use \l {georectangle} or \l {geocircle}. + + The \l isValid attribute can be used to test if the geoshape represents a valid geographic + area. + + The \l isEmpty attribute can be used to test if the geoshape represents a region with a + geometrical area of 0. + + The \l {contains}() method can be used to test if a \l {coordinate} is + within the geoshape. + + \section1 Example Usage + + Use properties of type \l var to store a \c {geoshape}. To create a \c geoshape use one + of the methods described below. + + To create a \c geoshape value, specify it as a "shape()" string: + + \qml + import QtPositioning + + Item { + property var region: "shape()" + } + \endqml + + or with the \l {QtPositioning::shape}{QtPositioning.shape()} function: + + \qml + import QtPositioning + + Item { + property var region: QtPositioning.shape() + } + \endqml + + When integrating with C++, note that any QGeoShape value passed into QML from C++ is + automatically converted into a \c geoshape value, and vice-versa. + + \section1 Properties + + \section2 isEmpty + + \code + bool isEmpty + \endcode + + Returns whether this geoshape is empty. An empty geoshape is a region which has + a geometrical area of 0. + + \section2 isValid + + \code + bool isValid + \endcode + + Returns whether this geoshape is valid. + + A geoshape is considered to be invalid if some of the data that is required to + unambiguously describe the geoshape has not been set or has been set to an + unsuitable value. + + \section2 type + + \code + ShapeType type + \endcode + + Returns the current type of the shape. + + \list + \li \c GeoShape.UnknownType - The shape's type is not known. + \li \c GeoShape.RectangleType - The shape is a \l georectangle. + \li \c GeoShape.CircleType - The shape is a \l geocircle. + \li \c GeoShape.PathType - The shape is a \l geopath. (Since Qt 5.9) + \li \c GeoShape.PolygonType - The shape is a \l geopolygon. (Since Qt 5.10) + \endlist + + This QML property was introduced by Qt 5.5. + + \section1 Methods + + \section2 contains() + + \code + bool contains(coordinate coord) + \endcode + + Returns true if the \l {QtPositioning::coordinate}{coordinate} specified by \a coord is within + this geoshape; Otherwise returns false. +*/ + +/*! + \qmlvaluetype georectangle + \ingroup qmlvaluetypes + \inqmlmodule QtPositioning + \ingroup qml-QtPositioning5-basictypes + \since 5.2 + + \brief The georectangle type represents a rectangular geographic area. + + The \c georectangle type is a \l {geoshape} that represents a + rectangular geographic area. The type is direct representation of a \l QGeoRectangle. + It is defined by a pair of \l {coordinate}{coordinates} which represent the top-left + and bottom-right corners of the \c {georectangle}. The coordinates are accessible + from the \l topLeft and \l bottomRight attributes. + + A \c georectangle is considered invalid if the top-left or bottom-right coordinates are invalid + or if the top-left coordinate is south of the bottom-right coordinate. + + The coordinates of the four corners of the \c georectangle can be accessed with the + \l {topLeft}, \l {topRight}, \l {bottomLeft} and \l {bottomRight} attributes. The \l center + attribute can be used to get the coordinate of the center of the \c georectangle. The \l width + and \l height attributes can be used to get the width and height of the \c georectangle in + degrees. Setting one of these attributes will cause the other attributes to be adjusted + accordingly. + + \section1 Limitations + + A \c georectangle can never cross the poles. + + If the height or center of a \c georectangle is adjusted such that it would cross one of the + poles the height is modified such that the \c georectangle touches but does not cross the pole + and that the center coordinate is still in the center of the \c georectangle. + + \section1 Example Usage + + Use properties of type \l var to store a \c {georectangle}. To create a \c georectangle + value, use the \l {QtPositioning::rectangle}{QtPositioning.rectangle()} function: + + \qml + import QtPositioning + + Item { + property var region: QtPositioning.rectangle(QtPositioning.coordinate(-27.5, 153.1), QtPositioning.coordinate(-27.6, 153.2)) + } + \endqml + + When integrating with C++, note that any QGeoRectangle value passed into QML from C++ is + automatically converted into a \c georectangle value, and vice-versa. + + \section1 Properties + + \section2 bottomLeft + + \code + coordinate bottomLeft + \endcode + + This property holds the bottom left coordinate of this georectangle. + + \section2 bottomRight + + \code + coordinate bottomRight + \endcode + + This property holds the bottom right coordinate of this georectangle. + + \section2 center + + \code + coordinate center + \endcode + + This property holds the center coordinate of this georectangle. For more details + see \l {QGeoRectangle::setCenter()}. + + \section2 height + + \code + double height + \endcode + + This property holds the height of this georectangle (in degrees). For more details + see \l {QGeoRectangle::setHeight()}. + + \note If the georectangle is invalid, it is not possible to set the height. QtPositioning + releases prior to Qt 5.5 permitted the setting of the height even on invalid georectangles. + + \section2 topLeft + + \code + coordinate topLeft + \endcode + + This property holds the top left coordinate of this georectangle. + + \section2 topRight + + \code + coordinate topRight + \endcode + + This property holds the top right coordinate of this georectangle. + + \section2 width + + \code + double width + \endcode + + This property holds the width of this georectangle (in degrees). For more details + see \l {QGeoRectangle::setWidth()}. + + \note If the georectangle is invalid, it is not possible to set the width. QtPositioning + releases prior to Qt 5.5 permitted the setting of the width even on invalid georectangles. +*/ + +/*! + \qmlvaluetype geocircle + \ingroup qmlvaluetypes + \inqmlmodule QtPositioning + \ingroup qml-QtPositioning5-basictypes + \since 5.2 + + \brief The geocircle type represents a circular geographic area. + + The \c geocircle type is a \l {geoshape} that represents a circular + geographic area. It is a direct representation of a \l QGeoCircle and is defined + in terms of a \l {coordinate} which specifies the \l center of the circle and + a qreal which specifies the \l radius of the circle in meters. + + The circle is considered invalid if the \l center coordinate is invalid or if + the \l radius is less than zero. + + \section1 Example Usage + + Use properties of type \l var to store a \c {geocircle}. To create a \c geocircle value, + use the \l {QtPositioning::circle}{QtPositioning.circle()} function: + + \qml + import QtPositioning + + Item { + property var region: QtPositioning.circle(QtPositioning.coordinate(-27.5, 153.1), 1000) + } + \endqml + + When integrating with C++, note that any QGeoCircle value passed into QML from C++ is + automatically converted into a \c geocircle value, and vise-versa. + + \section1 Properties + + \section2 center + + \code + coordinate radius + \endcode + + This property holds the coordinate of the center of the geocircle. + + \section2 radius + + \code + real radius + \endcode + + This property holds the radius of the geocircle in meters. + + The default value for the radius is -1 indicating an invalid geocircle area. +*/ + +/*! + \qmlvaluetype geopath + \ingroup qmlvaluetypes + \inqmlmodule QtPositioning + \ingroup qml-QtPositioning5-basictypes + \since 5.9 + + \brief The geopath type represents a geographic path. + + The \c geopath type is a \l {geoshape} that represents a geographic + path. It is a direct representation of a \l QGeoPath and is defined + in terms of a \l {path} which holds the list of geo coordinates in the + path. + + The path is considered invalid if it is empty. + + When integrating with C++, note that any QGeoPath value passed into QML from C++ is + automatically converted into a \c geopath value, and vice versa. + + \section1 Properties + + \section2 path + + This property holds the list of coordinates defining the path. + + \section2 width + + This property holds the width of the path in meters. This is currently only used + when calling the \l {contains}() method. + + The default value for the width is 0. +*/ + +/*! + \qmlvaluetype geopolygon + \ingroup qmlvaluetypes + \inqmlmodule QtPositioning + \ingroup qml-QtPositioning5-basictypes + \since 5.10 + + \brief The geopolygon type represents a geographic polygon. + + The \c geopolygon type is a \l [QML] geoshape that represents a geographic + polygon. It is a direct representation of QGeoPolygon and is defined in + terms of a \l path which holds a list of geo coordinates in the polygon. + + The polygon is considered invalid if its path holds less than three + coordinates. + + When integrating with C++, note that any QGeoPolygon value passed into QML + is automatically converted into a \c geopolygon, and vice versa. + + \section1 Properties + + \section2 path + + This property holds the list of coordinates defining the polygon. +*/ + +class QtPositioningDeclarativeModule: public QQmlEngineExtensionPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtPositioningDeclarativeModule(QObject *parent = 0) : QQmlEngineExtensionPlugin(parent) + { + volatile auto registration = &qml_register_types_QtPositioning; + Q_UNUSED(registration) + } +}; + +void QtPositioningDeclarative_initializeModule() +{ + qRegisterAnimationInterpolator(q_coordinateInterpolator); +} + +Q_CONSTRUCTOR_FUNCTION(QtPositioningDeclarative_initializeModule) + +QT_END_NAMESPACE + +#include "positioningplugin.moc" diff --git a/src/positioningquick/qdeclarativegeoaddress.cpp b/src/positioningquick/qdeclarativegeoaddress.cpp new file mode 100644 index 0000000..4c0123d --- /dev/null +++ b/src/positioningquick/qdeclarativegeoaddress.cpp @@ -0,0 +1,346 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qdeclarativegeoaddress_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Address + \inqmlmodule QtPositioning + \since 5.2 + + \brief The Address QML type represents a specific location as a street address. + + An Address is used as a unit of data for queries such as (Reverse) Geocoding + or Places searches -- many of these operations either accept an Address + or return one. + + Not all properties of an Address are necessarily available or relevant + in all parts of the world and all locales. The \l district, \l state and + \l county properties are particularly area-specific for many data sources, + and often only one or two of these are available or useful. + + The Address has a \l text property which holds a formatted string. It + is the recommended way to display an address to the user and typically + takes the format of an address as found on an envelope, but this is not always + the case. The \l text may be automatically generated from constituent + address properties such as \l street, \l city and and so on, but can also + be explicitly assigned. See \l text for details. + + \section2 Example Usage + + The following code snippet shows the declaration of an Address object. + + \code + Address { + id: address + street: "53 Brandl St" + city: "Eight Mile Plains" + country: "Australia" + countryCode: "AUS" + } + \endcode + + This could then be used, for example, as the value of a geocoding query, + to get an exact longitude and latitude for the address. + + \sa {QGeoAddress} +*/ + +QDeclarativeGeoAddress::QDeclarativeGeoAddress(QObject *parent) : + QObject(parent) +{ +} + +QDeclarativeGeoAddress::QDeclarativeGeoAddress(const QGeoAddress &address, QObject *parent) : + QObject(parent), m_address(address) +{ +} + +/*! + \qmlproperty QGeoAddress QtPositioning::Address::address + + For details on how to use this property to interface between C++ and QML see + "\l {Address - QGeoAddress} {Interfaces between C++ and QML Code}". +*/ +QGeoAddress QDeclarativeGeoAddress::address() const +{ + return m_address; +} + +void QDeclarativeGeoAddress::setAddress(const QGeoAddress &address) +{ + // Elaborate but takes care of emiting needed signals + setText(address.text()); + setCountry(address.country()); + setCountryCode(address.countryCode()); + setState(address.state()); + setCounty(address.county()); + setCity(address.city()); + setDistrict(address.district()); + setStreet(address.street()); + setStreetNumber(address.streetNumber()); + setPostalCode(address.postalCode()); + m_address = address; +} + +/*! + \qmlproperty string QtPositioning::Address::text + + This property holds the address as a single formatted string. It is the recommended + string to use to display the address to the user. It typically takes the format of + an address as found on an envelope, but this is not always necessarily the case. + + The address \c text is either automatically generated or explicitly assigned, + this can be determined by checking \l isTextGenerated. + + If an empty string is assigned to \c text, then \l isTextGenerated will be set + to true and \c text will return a string which is locally formatted according to + \l countryCode and based on the properties of the address. Modifying the address + properties such as \l street, \l city and so on may cause the contents of \c text to + change. + + If a non-empty string is assigned to \c text, then \l isTextGenerated will be + set to false and \c text will always return the explicitly assigned string. + Modifying address properties will not affect the \c text property. +*/ +QString QDeclarativeGeoAddress::text() const +{ + return m_address.text(); +} + +void QDeclarativeGeoAddress::setText(const QString &address) +{ + QString oldText = m_address.text(); + bool oldIsTextGenerated = m_address.isTextGenerated(); + m_address.setText(address); + + if (oldText != m_address.text()) + emit textChanged(); + if (oldIsTextGenerated != m_address.isTextGenerated()) + emit isTextGeneratedChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::country + + This property holds the country of the address as a single formatted string. +*/ +QString QDeclarativeGeoAddress::country() const +{ + return m_address.country(); +} + +void QDeclarativeGeoAddress::setCountry(const QString &country) +{ + if (m_address.country() == country) + return; + QString oldText = m_address.text(); + m_address.setCountry(country); + emit countryChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::countryCode + + This property holds the country code of the address as a single formatted string. +*/ +QString QDeclarativeGeoAddress::countryCode() const +{ + return m_address.countryCode(); +} + +void QDeclarativeGeoAddress::setCountryCode(const QString &countryCode) +{ + if (m_address.countryCode() == countryCode) + return; + QString oldText = m_address.text(); + m_address.setCountryCode(countryCode); + emit countryCodeChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::state + + This property holds the state of the address as a single formatted string. +*/ +QString QDeclarativeGeoAddress::state() const +{ + return m_address.state(); +} + +void QDeclarativeGeoAddress::setState(const QString &state) +{ + if (m_address.state() == state) + return; + QString oldText = m_address.text(); + m_address.setState(state); + emit stateChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::county + + This property holds the county of the address as a single formatted string. +*/ +QString QDeclarativeGeoAddress::county() const +{ + return m_address.county(); +} + +void QDeclarativeGeoAddress::setCounty(const QString &county) +{ + if (m_address.county() == county) + return; + QString oldText = m_address.text(); + m_address.setCounty(county); + emit countyChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::city + + This property holds the city of the address as a single formatted string. +*/ +QString QDeclarativeGeoAddress::city() const +{ + return m_address.city(); +} + +void QDeclarativeGeoAddress::setCity(const QString &city) +{ + if (m_address.city() == city) + return; + QString oldText = m_address.text(); + m_address.setCity(city); + emit cityChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::district + + This property holds the district of the address as a single formatted string. +*/ +QString QDeclarativeGeoAddress::district() const +{ + return m_address.district(); +} + +void QDeclarativeGeoAddress::setDistrict(const QString &district) +{ + if (m_address.district() == district) + return; + QString oldText = m_address.text(); + m_address.setDistrict(district); + emit districtChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::street + + This property holds the street of the address. + + \note Before Qt6 this property could also contain things like a unit number, + a building name, or anything else that might be used to distinguish one + address from another. Since Qt6 use \l{QtPositioning::Address::}{streetNumber} + property for such information. +*/ +QString QDeclarativeGeoAddress::street() const +{ + return m_address.street(); +} + +void QDeclarativeGeoAddress::setStreet(const QString &street) +{ + if (m_address.street() == street) + return; + QString oldText = m_address.text(); + m_address.setStreet(street); + emit streetChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::streetNumber + \since QtPositioning 6.2 + + This property holds the street number of the address like a unit number, + a building name, or anything else that might be used to distinguish one + address from another. +*/ +QString QDeclarativeGeoAddress::streetNumber() const +{ + return m_address.streetNumber(); +} + +void QDeclarativeGeoAddress::setStreetNumber(const QString &streetNumber) +{ + if (m_address.streetNumber() == streetNumber) + return; + QString oldText = m_address.text(); + m_address.setStreetNumber(streetNumber); + emit streetNumberChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty string QtPositioning::Address::postalCode + + This property holds the postal code of the address as a single formatted string. +*/ +QString QDeclarativeGeoAddress::postalCode() const +{ + return m_address.postalCode(); +} + +void QDeclarativeGeoAddress::setPostalCode(const QString &postalCode) +{ + if (m_address.postalCode() == postalCode) + return; + QString oldText = m_address.text(); + m_address.setPostalCode(postalCode); + emit postalCodeChanged(); + + if (m_address.isTextGenerated() && oldText != m_address.text()) + emit textChanged(); +} + +/*! + \qmlproperty bool QtPositioning::Address::isTextGenerated + + This property holds a boolean that if true, indicates that \l text is automatically + generated from address properties. If false, it indicates that the \l text has been + explicitly assigned. + +*/ +bool QDeclarativeGeoAddress::isTextGenerated() const +{ + return m_address.isTextGenerated(); +} + +QT_END_NAMESPACE + +#include "moc_qdeclarativegeoaddress_p.cpp" diff --git a/src/positioningquick/qdeclarativegeoaddress_p.h b/src/positioningquick/qdeclarativegeoaddress_p.h new file mode 100644 index 0000000..19b4b26 --- /dev/null +++ b/src/positioningquick/qdeclarativegeoaddress_p.h @@ -0,0 +1,93 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QDECLARATIVEGEOADDRESS_P_H +#define QDECLARATIVEGEOADDRESS_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 +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONINGQUICK_PRIVATE_EXPORT QDeclarativeGeoAddress : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(Address) + QML_ADDED_IN_VERSION(5, 0) + + Q_PROPERTY(QGeoAddress address READ address WRITE setAddress) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + Q_PROPERTY(QString country READ country WRITE setCountry NOTIFY countryChanged) + Q_PROPERTY(QString countryCode READ countryCode WRITE setCountryCode NOTIFY countryCodeChanged) + Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged) + Q_PROPERTY(QString county READ county WRITE setCounty NOTIFY countyChanged) + Q_PROPERTY(QString city READ city WRITE setCity NOTIFY cityChanged) + Q_PROPERTY(QString district READ district WRITE setDistrict NOTIFY districtChanged) + Q_PROPERTY(QString street READ street WRITE setStreet NOTIFY streetChanged) + Q_PROPERTY(QString streetNumber READ streetNumber WRITE setStreetNumber + NOTIFY streetNumberChanged REVISION(6, 2)) + Q_PROPERTY(QString postalCode READ postalCode WRITE setPostalCode NOTIFY postalCodeChanged) + Q_PROPERTY(bool isTextGenerated READ isTextGenerated NOTIFY isTextGeneratedChanged) + +public: + explicit QDeclarativeGeoAddress(QObject *parent = 0); + QDeclarativeGeoAddress(const QGeoAddress &address, QObject *parent = 0); + QGeoAddress address() const; + void setAddress(const QGeoAddress &address); + + QString text() const; + void setText(const QString &address); + + QString country() const; + void setCountry(const QString &country); + QString countryCode() const; + void setCountryCode(const QString &countryCode); + QString state() const; + void setState(const QString &state); + QString county() const; + void setCounty(const QString &county); + QString city() const; + void setCity(const QString &city); + QString district() const; + void setDistrict(const QString &district); + QString street() const; + void setStreet(const QString &street); + QString streetNumber() const; + void setStreetNumber(const QString &streetNumber); + QString postalCode() const; + void setPostalCode(const QString &postalCode); + bool isTextGenerated() const; + +Q_SIGNALS: + void textChanged(); + void countryChanged(); + void countryCodeChanged(); + void stateChanged(); + void countyChanged(); + void cityChanged(); + void districtChanged(); + void streetChanged(); + void streetNumberChanged(); + void postalCodeChanged(); + void isTextGeneratedChanged(); + +private: + QGeoAddress m_address; +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVEGEOADDRESS_P_H diff --git a/src/positioningquick/qdeclarativegeolocation.cpp b/src/positioningquick/qdeclarativegeolocation.cpp new file mode 100644 index 0000000..64b3090 --- /dev/null +++ b/src/positioningquick/qdeclarativegeolocation.cpp @@ -0,0 +1,212 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qdeclarativegeolocation_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Location + \inqmlmodule QtPositioning + \since 5.2 + + \brief The Location type holds location data. + + Location types represent a geographic "location", in a human sense. This + consists of a specific \l {coordinate}, an \l {address} and a + \l {boundingShape}{bounding shape}. + The \l {boundingShape}{bounding shape} represents the recommended region + to display when viewing this location. + + The Location type is most commonly seen as the contents of a search + model such as the GeocodeModel. When a GeocodeModel returns the list of + locations found for a given query, it represents these as Location objects. + + \section2 Example Usage + + The following example shows a simple Location object being declared: + + \code + Location { + coordinate { + latitude: -27.3 + longitude: 153.1 + } + address: Address { + ... + } + } + \endcode +*/ + +/*! + \qmlproperty VariantMap QDeclarativeGeoLocation::extendedAttributes + + This property holds the extended attributes for this Location. + Extended attributes are backend-dependent and can be location-dependent. + + \since 5.13 +*/ + +QDeclarativeGeoLocation::QDeclarativeGeoLocation(QObject *parent) +: QObject(parent) + +{ + setLocation(QGeoLocation()); +} + +QDeclarativeGeoLocation::QDeclarativeGeoLocation(const QGeoLocation &src, QObject *parent) +: QObject(parent) +{ + setLocation(src); +} + +QDeclarativeGeoLocation::~QDeclarativeGeoLocation() +{ +} + +/*! + \qmlproperty QGeoLocation QtPositioning::Location::location + + For details on how to use this property to interface between C++ and QML see + "\l {Location - QGeoLocation} {Interfaces between C++ and QML Code}". + + \note This property updates the whole geo location information, so using it + will result in breaking of all the bindings for all other properties. +*/ +void QDeclarativeGeoLocation::setLocation(const QGeoLocation &src) +{ + if (m_address && m_address->parent() == this) { + m_address->setAddress(src.address()); + } else if (!m_address || m_address->parent() != this) { + m_address.setValue(new QDeclarativeGeoAddress(src.address(), this)); + m_address.notify(); + } + + setCoordinate(src.coordinate()); + setBoundingShape(src.boundingShape()); + setExtendedAttributes(src.extendedAttributes()); +} + +QGeoLocation QDeclarativeGeoLocation::location() const +{ + QGeoLocation retValue; + retValue.setAddress(m_address ? m_address->address() : QGeoAddress()); + retValue.setCoordinate(m_coordinate); + retValue.setBoundingShape(m_boundingShape); + retValue.setExtendedAttributes(m_extendedAttributes); + return retValue; +} + +/*! + \qmlproperty Address QtPositioning::Location::address + + This property holds the address of the location which can be use to retrieve address details of the location. +*/ +void QDeclarativeGeoLocation::setAddress(QDeclarativeGeoAddress *address) +{ + m_address.removeBindingUnlessInWrapper(); + if (m_address == address) + return; + + // implicitly deleting m_address.value() will force the QML bindings to + // be reevaluated by the QML engine. So we defer the deletion of the old + // address until a new value is assigned to the m_address. + QDeclarativeGeoAddress *oldAddress = nullptr; + if (m_address && m_address->parent() == this) + oldAddress = m_address.value(); + + m_address.setValueBypassingBindings(address); + m_address.notify(); + delete oldAddress; +} + +QBindable QDeclarativeGeoLocation::bindableAddress() +{ + return QBindable(&m_address); +} + +QDeclarativeGeoAddress *QDeclarativeGeoLocation::address() const +{ + return m_address; +} + +/*! + \qmlproperty coordinate QtPositioning::Location::coordinate + + This property holds the exact geographical coordinate of the location which can be used to retrieve the latitude, longitude and altitude of the location. + + \note this property's changed() signal is currently emitted only if the + whole object changes, not if only the contents of the object change. +*/ +void QDeclarativeGeoLocation::setCoordinate(const QGeoCoordinate coordinate) +{ + m_coordinate = coordinate; +} + +QBindable QDeclarativeGeoLocation::bindableCoordinate() +{ + return QBindable(&m_coordinate); +} + +QGeoCoordinate QDeclarativeGeoLocation::coordinate() const +{ + return m_coordinate; +} + +/*! + \since QtPositioning 6.2 + + \qmlproperty geoshape QtPositioning::Location::boundingShape + + This property holds the recommended region to use when displaying the location. + For example, a building's location may have a region centered around the building, + but the region is large enough to show it's immediate surrounding geographical + context. + + \note This property's changed() signal is currently emitted only if the + whole object changes, not if only the contents of the object change. + + \note This property was introduced in Qt6 instead of boundingBox property. + It returns a \l geoshape instead of a \l georectangle. + Use \l QGeoShape::boundingGeoRectangle() to obtain a bounding + \l georectangle for the shape. + + If you need to convert the returned shape to a specific type, use the + \c type property of \l geoshape together with convenience + methods from \l [QML]{QtPositioning} like + \l {QtPositioning::shapeToRectangle}{QtPositioning.shapeToRectangle()}. +*/ +void QDeclarativeGeoLocation::setBoundingShape(const QGeoShape &boundingShape) +{ + m_boundingShape = boundingShape; +} + +QBindable QDeclarativeGeoLocation::bindableBoundingShape() +{ + return QBindable(&m_boundingShape); +} + +QVariantMap QDeclarativeGeoLocation::extendedAttributes() const +{ + return m_extendedAttributes; +} + +void QDeclarativeGeoLocation::setExtendedAttributes(const QVariantMap &attributes) +{ + m_extendedAttributes = attributes; +} + +QBindable QDeclarativeGeoLocation::bindableExtendedAttributes() +{ + return QBindable(&m_extendedAttributes); +} + +QGeoShape QDeclarativeGeoLocation::boundingShape() const +{ + return m_boundingShape; +} + +QT_END_NAMESPACE + +#include "moc_qdeclarativegeolocation_p.cpp" diff --git a/src/positioningquick/qdeclarativegeolocation_p.h b/src/positioningquick/qdeclarativegeolocation_p.h new file mode 100644 index 0000000..0cbe23c --- /dev/null +++ b/src/positioningquick/qdeclarativegeolocation_p.h @@ -0,0 +1,78 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QDECLARATIVEGEOLOCATION_P_H +#define QDECLARATIVEGEOLOCATION_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 +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONINGQUICK_PRIVATE_EXPORT QDeclarativeGeoLocation : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(Location) + QML_ADDED_IN_VERSION(5, 0) + + Q_PROPERTY(QGeoLocation location READ location WRITE setLocation) + Q_PROPERTY(QDeclarativeGeoAddress *address READ address WRITE setAddress BINDABLE + bindableAddress) + Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate BINDABLE + bindableCoordinate) + Q_PROPERTY(QGeoShape boundingShape READ boundingShape WRITE setBoundingShape BINDABLE + bindableBoundingShape REVISION(6, 2)) + Q_PROPERTY(QVariantMap extendedAttributes READ extendedAttributes WRITE setExtendedAttributes + BINDABLE bindableExtendedAttributes REVISION(5, 13)) + +public: + explicit QDeclarativeGeoLocation(QObject *parent = 0); + explicit QDeclarativeGeoLocation(const QGeoLocation &src, QObject *parent = 0); + ~QDeclarativeGeoLocation(); + + QGeoLocation location() const; + void setLocation(const QGeoLocation &src); + + QDeclarativeGeoAddress *address() const; + void setAddress(QDeclarativeGeoAddress *address); + QBindable bindableAddress(); + + QGeoCoordinate coordinate() const; + void setCoordinate(const QGeoCoordinate coordinate); + QBindable bindableCoordinate(); + + QGeoShape boundingShape() const; + void setBoundingShape(const QGeoShape &boundingShape); + QBindable bindableBoundingShape(); + + QVariantMap extendedAttributes() const; + void setExtendedAttributes(const QVariantMap &attributes); + QBindable bindableExtendedAttributes(); + +private: + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QDeclarativeGeoLocation, QDeclarativeGeoAddress *, m_address, + &QDeclarativeGeoLocation::setAddress, nullptr) + Q_OBJECT_BINDABLE_PROPERTY(QDeclarativeGeoLocation, QGeoShape, m_boundingShape) + Q_OBJECT_BINDABLE_PROPERTY(QDeclarativeGeoLocation, QGeoCoordinate, m_coordinate) + Q_OBJECT_BINDABLE_PROPERTY(QDeclarativeGeoLocation, QVariantMap, m_extendedAttributes) +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVELOCATION_P_H diff --git a/src/positioningquick/qdeclarativepluginparameter.cpp b/src/positioningquick/qdeclarativepluginparameter.cpp new file mode 100644 index 0000000..9180f49 --- /dev/null +++ b/src/positioningquick/qdeclarativepluginparameter.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qdeclarativepluginparameter_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype PluginParameter + \inqmlmodule QtPositioning + \ingroup qml-QtPositioning5-common + \since QtPositioning 5.14 + + \brief The PluginParameter type describes a parameter for a + \omit + plugin, either geoservice \l Plugin, or + \endomit + position plugin. + + The PluginParameter object is used to provide a parameter of some kind + to a plugin. Typically, these parameters contain details like an application + token for access to a service, or a proxy server to use for network access, + or the serial port to which a serial GPS receiver is connected. + + To set such a parameter, declare a PluginParameter inside an element that + accepts plugin parameters as configuration objects, such as a + \omit + \l Plugin object, or a + \endomit + \l PositionSource object, and set values for its \l{name} and \l{value} + properties. A list of valid parameter names for each plugin is available + from the + \omit + \l {Qt Location#Plugin References and Parameters}{plugin reference pages} + for geoservice plugins, and + \endomit + \l {Qt Positioning plugins#Default plugins}{default plugins page} for + position plugins. + + \section2 Example Usage + + The following example shows the instantiation of the + \l {Qt Positioning NMEA plugin}{NMEA} plugin with the \e nmea.source + parameter that specifies the data source. + + \code + PositionSource { + name: "nmea" + PluginParameter { name: "nmea.source"; value: "serial:/dev/ttyACM0" } + } + \endcode +*/ + +/*! + \qmlproperty string PluginParameter::name + + This property holds the name of the plugin parameter as a single formatted string. + This property is a write-once property. +*/ + +/*! + \qmlproperty QVariant PluginParameter::value + + This property holds the value of the plugin parameter which support different types of values (variant). + This property is a write-once property. +*/ + +QDeclarativePluginParameter::QDeclarativePluginParameter(QObject *parent) + : QObject(parent) {} + +QDeclarativePluginParameter::~QDeclarativePluginParameter() {} + +void QDeclarativePluginParameter::setName(const QString &name) +{ + if (!name_.isEmpty() || name.isEmpty()) + return; + + name_ = name; + + emit nameChanged(name_); + if (value_.isValid()) + emit initialized(); +} + +QString QDeclarativePluginParameter::name() const +{ + return name_; +} + +void QDeclarativePluginParameter::setValue(const QVariant &value) +{ + if (value_.isValid() || !value.isValid() || value.isNull()) + return; + + value_ = value; + + emit valueChanged(value_); + if (!name_.isEmpty()) + emit initialized(); +} + +QVariant QDeclarativePluginParameter::value() const +{ + return value_; +} + +bool QDeclarativePluginParameter::isInitialized() const +{ + return !name_.isEmpty() && value_.isValid(); +} + +QT_END_NAMESPACE + +#include "moc_qdeclarativepluginparameter_p.cpp" diff --git a/src/positioningquick/qdeclarativepluginparameter_p.h b/src/positioningquick/qdeclarativepluginparameter_p.h new file mode 100644 index 0000000..1825dfb --- /dev/null +++ b/src/positioningquick/qdeclarativepluginparameter_p.h @@ -0,0 +1,63 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QDECLARATIVEPLUGINPARAMETER_P_H +#define QDECLARATIVEPLUGINPARAMETER_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 +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONINGQUICK_PRIVATE_EXPORT QDeclarativePluginParameter : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(PluginParameter) + QML_ADDED_IN_VERSION(5, 14) + + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) + +public: + explicit QDeclarativePluginParameter(QObject *parent = 0); + ~QDeclarativePluginParameter(); + + void setName(const QString &name); + QString name() const; + + void setValue(const QVariant &value); + QVariant value() const; + + bool isInitialized() const; + +Q_SIGNALS: + void nameChanged(const QString &name); + void valueChanged(const QVariant &value); + void initialized(); + +private: + QString name_; + QVariant value_; +}; + + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativePluginParameter) + +#endif // QDECLARATIVEPLUGINPARAMETER_P_H diff --git a/src/positioningquick/qdeclarativeposition.cpp b/src/positioningquick/qdeclarativeposition.cpp new file mode 100644 index 0000000..feeab66 --- /dev/null +++ b/src/positioningquick/qdeclarativeposition.cpp @@ -0,0 +1,645 @@ +// Copyright (C) 2016 Jolla Ltd. +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include +#include "qdeclarativeposition_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Position + //! \instantiates QDeclarativePosition + \inqmlmodule QtPositioning + \since 5.2 + + \brief The Position type holds positional data at a particular point in time, + such as coordinate (longitude, latitude, altitude) and speed. + + The Position type holds values related to geographic location such as + a \l coordinate (longitude, latitude, and altitude), the \l timestamp when + the Position was obtained, the \l speed at that time, and the accuracy of + the data. + + Primarily, it is used in the \l{PositionSource::position}{position} property + of a \l{PositionSource}, as the basic unit of data available from the system + location data source. + + Not all properties of a Position object are necessarily valid or available + (for example latitude and longitude may be valid, but speed update has not been + received or set manually). As a result, corresponding "valid" properties + are available (for example \l{coordinate} and \l{longitudeValid}, \l{latitudeValid} + etc) to discern whether the data is available and valid in this position + update. + + Position objects are read-only and can only be produced by a PositionSource. + + \section2 Example Usage + + See the example given for the \l{PositionSource} type, or the + \l{geoflickr}{GeoFlickr} example application. + + \sa PositionSource, coordinate +*/ + +namespace +{ + +bool equalOrNaN(qreal a, qreal b) +{ + return a == b || (qIsNaN(a) && qIsNaN(b)); +} + +bool exclusiveNaN(qreal a, qreal b) +{ + return qIsNaN(a) != qIsNaN(b); +} + +} + +QDeclarativePosition::QDeclarativePosition(QObject *parent) +: QObject(parent) +{ +} + +QDeclarativePosition::~QDeclarativePosition() +{ +} + +void QDeclarativePosition::setPosition(const QGeoPositionInfo &info) +{ + // timestamp + const QDateTime pTimestamp = m_info.timestamp(); + const QDateTime timestamp = info.timestamp(); + const bool timestampChanged = pTimestamp != timestamp; + + // coordinate + const QGeoCoordinate pCoordinate = m_info.coordinate(); + const QGeoCoordinate coordinate = info.coordinate(); + const bool coordinateChanged = pCoordinate != coordinate; + const bool latitudeValidChanged = exclusiveNaN(pCoordinate.latitude(), coordinate.latitude()); + const bool longitudeValidChanged = + exclusiveNaN(pCoordinate.longitude(), coordinate.longitude()); + const bool altitudeValidChanged = exclusiveNaN(pCoordinate.altitude(), coordinate.altitude()); + + // direction + const qreal pDirection = m_info.attribute(QGeoPositionInfo::Direction); + const qreal direction = info.attribute(QGeoPositionInfo::Direction); + const bool directionChanged = !equalOrNaN(pDirection, direction); + const bool directionValidChanged = exclusiveNaN(pDirection, direction); + + // ground speed + const qreal pSpeed = m_info.attribute(QGeoPositionInfo::GroundSpeed); + const qreal speed = info.attribute(QGeoPositionInfo::GroundSpeed); + const bool speedChanged = !equalOrNaN(pSpeed, speed); + const bool speedValidChanged = exclusiveNaN(pSpeed, speed); + + // vertical speed + const qreal pVerticalSpeed = m_info.attribute(QGeoPositionInfo::VerticalSpeed); + const qreal verticalSpeed = info.attribute(QGeoPositionInfo::VerticalSpeed); + const bool verticalSpeedChanged = !equalOrNaN(pVerticalSpeed, verticalSpeed); + const bool verticalSpeedValidChanged = exclusiveNaN(pVerticalSpeed, verticalSpeed); + + // magnetic variation + const qreal pMagneticVariation = m_info.attribute(QGeoPositionInfo::MagneticVariation); + const qreal magneticVariation = info.attribute(QGeoPositionInfo::MagneticVariation); + const bool magneticVariationChanged = !equalOrNaN(pMagneticVariation, magneticVariation); + const bool magneticVariationValidChanged = exclusiveNaN(pMagneticVariation, magneticVariation); + + // horizontal accuracy + const qreal pHorizontalAccuracy = m_info.attribute(QGeoPositionInfo::HorizontalAccuracy); + const qreal horizontalAccuracy = info.attribute(QGeoPositionInfo::HorizontalAccuracy); + const bool horizontalAccuracyChanged = !equalOrNaN(pHorizontalAccuracy, horizontalAccuracy); + const bool horizontalAccuracyValidChanged = + exclusiveNaN(pHorizontalAccuracy, horizontalAccuracy); + + // vertical accuracy + const qreal pVerticalAccuracy = m_info.attribute(QGeoPositionInfo::VerticalAccuracy); + const qreal verticalAccuracy = info.attribute(QGeoPositionInfo::VerticalAccuracy); + const bool verticalAccuracyChanged = !equalOrNaN(pVerticalAccuracy, verticalAccuracy); + const bool verticalAccuracyValidChanged = exclusiveNaN(pVerticalAccuracy, verticalAccuracy); + + // direction accuracy + const qreal pDirectionAccuracy = m_info.attribute(QGeoPositionInfo::DirectionAccuracy); + const qreal directionAccuracy = info.attribute(QGeoPositionInfo::DirectionAccuracy); + const bool directionAccuracyChanged = !equalOrNaN(pDirectionAccuracy, directionAccuracy); + const bool directionAccuracyValidChanged = exclusiveNaN(pDirectionAccuracy, directionAccuracy); + + m_info = info; + + if (timestampChanged) + m_computedTimestamp.notify(); + + if (coordinateChanged) + m_computedCoordinate.notify(); + if (latitudeValidChanged) + m_computedLatitudeValid.notify(); + if (longitudeValidChanged) + m_computedLongitudeValid.notify(); + if (altitudeValidChanged) + m_computedAltitudeValid.notify(); + + if (directionChanged) + m_computedDirection.notify(); + if (directionValidChanged) + m_computedDirectionValid.notify(); + + if (speedChanged) + m_computedSpeed.notify(); + if (speedValidChanged) + m_computedSpeedValid.notify(); + + if (verticalSpeedChanged) + m_computedVerticalSpeed.notify(); + if (verticalSpeedValidChanged) + m_computedVerticalSpeedValid.notify(); + + if (horizontalAccuracyChanged) + m_computedHorizontalAccuracy.notify(); + if (horizontalAccuracyValidChanged) + m_computedHorizontalAccuracyValid.notify(); + + if (verticalAccuracyChanged) + m_computedVerticalAccuracy.notify(); + if (verticalAccuracyValidChanged) + m_computedVerticalAccuracyValid.notify(); + + if (magneticVariationChanged) + m_computedMagneticVariation.notify(); + if (magneticVariationValidChanged) + m_computedMagneticVariationValid.notify(); + + if (directionAccuracyChanged) + m_computedDirectionAccuracy.notify(); + if (directionAccuracyValidChanged) + m_computedDirectionAccuracyValid.notify(); +} + +const QGeoPositionInfo &QDeclarativePosition::position() const +{ + return m_info; +} + +QBindable QDeclarativePosition::bindableLatitudeValid() const +{ + return QBindable(&m_computedLatitudeValid); +} + +QBindable QDeclarativePosition::bindableLongitudeValid() const +{ + return QBindable(&m_computedLongitudeValid); +} + +QBindable QDeclarativePosition::bindableAltitudeValid() const +{ + return QBindable(&m_computedAltitudeValid); +} + +QBindable QDeclarativePosition::bindableCoordinate() const +{ + return QBindable(&m_computedCoordinate); +} + +QBindable QDeclarativePosition::bindableTimestamp() const +{ + return QBindable(&m_computedTimestamp); +} + +QBindable QDeclarativePosition::bindableSpeed() const +{ + return QBindable(&m_computedSpeed); +} + +QBindable QDeclarativePosition::bindableSpeedValid() const +{ + return QBindable(&m_computedSpeedValid); +} + +QBindable QDeclarativePosition::bindableHorizontalAccuracy() const +{ + return QBindable(&m_computedHorizontalAccuracy); +} + +QBindable QDeclarativePosition::binableVerticalAccuracy() const +{ + return QBindable(&m_computedVerticalAccuracy); +} + +QBindable QDeclarativePosition::bindableHorizontalAccuracyValid() const +{ + return QBindable(&m_computedHorizontalAccuracyValid); +} + +QBindable QDeclarativePosition::bindableVerticalAccuracyValid() const +{ + return QBindable(&m_computedVerticalAccuracyValid); +} + +QBindable QDeclarativePosition::bindableDirectionValid() const +{ + return QBindable(&m_computedDirectionValid); +} + +QBindable QDeclarativePosition::bindableDirection() const +{ + return QBindable(&m_computedDirection); +} + +QBindable QDeclarativePosition::bindableVerticalSpeedValid() const +{ + return QBindable(&m_computedVerticalSpeedValid); +} + +QBindable QDeclarativePosition::bindableVerticalSpeed() const +{ + return QBindable(&m_computedVerticalSpeed); +} + +QBindable QDeclarativePosition::bindableMagneticVariation() const +{ + return QBindable(&m_computedMagneticVariation); +} + +QBindable QDeclarativePosition::bindableMagneticVariationValid() const +{ + return QBindable(&m_computedMagneticVariationValid); +} + +QBindable QDeclarativePosition::bindableDirectionAccuracy() const +{ + return QBindable(&m_computedDirectionAccuracy); +} + +QBindable QDeclarativePosition::bindableDirectionAccuracyValid() const +{ + return QBindable(&m_computedDirectionAccuracyValid); +} + +/*! + \qmlproperty coordinate Position::coordinate + + This property holds the latitude, longitude, and altitude value of the Position. + + It is a read-only property. + + \sa longitudeValid, latitudeValid, altitudeValid +*/ +QGeoCoordinate QDeclarativePosition::coordinate() const +{ + return m_computedCoordinate.value(); +} + +QGeoCoordinate QDeclarativePosition::coordinateActualCalculation() const +{ + return m_info.coordinate(); +} + +/*! + \qmlproperty bool Position::latitudeValid + + This property is true if coordinate's latitude has been set + (to indicate whether that data has been received or not, as every update + does not necessarily contain all data). + + \sa coordinate +*/ +bool QDeclarativePosition::isLatitudeValid() const +{ + return m_computedLatitudeValid.value(); +} + +bool QDeclarativePosition::isLatitudeValidActualCalculation() const +{ + return !qIsNaN(m_info.coordinate().latitude()); +} + +/*! + \qmlproperty bool Position::longitudeValid + + This property is true if coordinate's longitude has been set + (to indicate whether that data has been received or not, as every update + does not necessarily contain all data). + + \sa coordinate +*/ +bool QDeclarativePosition::isLongitudeValid() const +{ + return m_computedLongitudeValid.value(); +} + +bool QDeclarativePosition::isLongitudeValidActualCalculation() const +{ + return !qIsNaN(m_info.coordinate().longitude()); +} + +/*! + \qmlproperty bool Position::speedValid + + This property is true if \l speed has been set + (to indicate whether that data has been received or not, as every update + does not necessarily contain all data). + + \sa speed +*/ +bool QDeclarativePosition::isSpeedValid() const +{ + return m_computedSpeedValid.value(); +} + +bool QDeclarativePosition::isSpeedValidActualCalculation() const +{ + return !qIsNaN(m_info.attribute(QGeoPositionInfo::GroundSpeed)); +} + +/*! + \qmlproperty bool Position::altitudeValid + + This property is true if coordinate's altitude has been set + (to indicate whether that data has been received or not, as every update + does not necessarily contain all data). + + \sa coordinate +*/ +bool QDeclarativePosition::isAltitudeValid() const +{ + return m_computedAltitudeValid.value(); +} + +bool QDeclarativePosition::isAltitudeValidActualCalculation() const +{ + return !qIsNaN(m_info.coordinate().altitude()); +} + +/*! + \qmlproperty double Position::speed + + This property holds the value of speed (groundspeed, meters / second). + + It is a read-only property. + + \sa speedValid, coordinate +*/ +double QDeclarativePosition::speed() const +{ + return m_computedSpeed.value(); +} + +double QDeclarativePosition::speedActualCalculation() const +{ + return m_info.attribute(QGeoPositionInfo::GroundSpeed); +} + +/*! + \qmlproperty real Position::horizontalAccuracy + + This property holds the horizontal accuracy of the coordinate (in meters). + + \sa horizontalAccuracyValid, coordinate +*/ +qreal QDeclarativePosition::horizontalAccuracy() const +{ + return m_computedHorizontalAccuracy.value(); +} + +qreal QDeclarativePosition::horizontalAccuracyActualCalculation() const +{ + return m_info.attribute(QGeoPositionInfo::HorizontalAccuracy); +} + +/*! + \qmlproperty bool Position::horizontalAccuracyValid + + This property is true if \l horizontalAccuracy has been set + (to indicate whether that data has been received or not, as every update + does not necessarily contain all data). + + \sa horizontalAccuracy +*/ +bool QDeclarativePosition::isHorizontalAccuracyValid() const +{ + return m_computedHorizontalAccuracyValid.value(); +} + +bool QDeclarativePosition::isHorizontalAccuracyValidActualCalculation() const +{ + return !qIsNaN(m_info.attribute(QGeoPositionInfo::HorizontalAccuracy)); +} + +/*! + \qmlproperty real Position::verticalAccuracy + + This property holds the vertical accuracy of the coordinate (in meters). + + \sa verticalAccuracyValid, coordinate +*/ +qreal QDeclarativePosition::verticalAccuracy() const +{ + return m_computedVerticalAccuracy.value(); +} + +qreal QDeclarativePosition::verticalAccuracyActualCalculation() const +{ + return m_info.attribute(QGeoPositionInfo::VerticalAccuracy); +} + +/*! + \qmlproperty bool Position::verticalAccuracyValid + + This property is true if \l verticalAccuracy has been set + (to indicate whether that data has been received or not, as every update + does not necessarily contain all data). + + \sa verticalAccuracy +*/ +bool QDeclarativePosition::isVerticalAccuracyValid() const +{ + return m_computedVerticalAccuracyValid.value(); +} + +bool QDeclarativePosition::isVerticalAccuracyValidActualCalculation() const +{ + return !qIsNaN(m_info.attribute(QGeoPositionInfo::VerticalAccuracy)); +} + +/*! + \qmlproperty date Position::timestamp + + This property holds the timestamp when this position + was received. If the property has not been set, it is invalid. + + It is a read-only property. +*/ +QDateTime QDeclarativePosition::timestamp() const +{ + return m_computedTimestamp.value(); +} + +QDateTime QDeclarativePosition::timestampActualCalculation() const +{ + return m_info.timestamp(); +} + +/*! + \qmlproperty bool Position::directionValid + \since Qt Positioning 5.3 + + This property is true if \l direction has been set (to indicate whether that data has been + received or not, as every update does not necessarily contain all data). + + \sa direction +*/ +bool QDeclarativePosition::isDirectionValid() const +{ + return m_computedDirectionValid.value(); +} + +bool QDeclarativePosition::isDirectionValidActualCalculation() const +{ + return !qIsNaN(m_info.attribute(QGeoPositionInfo::Direction)); +} + +/*! + \qmlproperty double Position::direction + \since Qt Positioning 5.3 + + This property holds the value of the direction of travel in degrees from true north. + + It is a read-only property. + + \sa directionValid +*/ +double QDeclarativePosition::direction() const +{ + return m_computedDirection.value(); +} + +double QDeclarativePosition::directionActualCalculation() const +{ + return m_info.attribute(QGeoPositionInfo::Direction); +} + +/*! + \qmlproperty bool Position::verticalSpeedValid + \since Qt Positioning 5.3 + + This property is true if \l verticalSpeed has been set (to indicate whether that data has been + received or not, as every update does not necessarily contain all data). + + \sa verticalSpeed +*/ +bool QDeclarativePosition::isVerticalSpeedValid() const +{ + return m_computedVerticalSpeedValid.value(); +} + +bool QDeclarativePosition::isVerticalSpeedValidActualCalculation() const +{ + return !qIsNaN(m_info.attribute(QGeoPositionInfo::VerticalSpeed)); +} + +/*! + \qmlproperty double Position::verticalSpeed + \since Qt Positioning 5.3 + + This property holds the value of the vertical speed in meters per second. + + It is a read-only property. + + \sa verticalSpeedValid +*/ +double QDeclarativePosition::verticalSpeed() const +{ + return m_computedVerticalSpeed.value(); +} + +double QDeclarativePosition::verticalSpeedActualCalculation() const +{ + return m_info.attribute(QGeoPositionInfo::VerticalSpeed); +} + +/*! + \qmlproperty bool Position::magneticVariationValid + \since Qt Positioning 5.4 + + This property is true if \l magneticVariation has been set (to indicate whether that data has been + received or not, as every update does not necessarily contain all data). + + \sa magneticVariation +*/ +bool QDeclarativePosition::isMagneticVariationValid() const +{ + return m_computedMagneticVariationValid.value(); +} + +bool QDeclarativePosition::isMagneticVariationValidActualCalculation() const +{ + return !qIsNaN(m_info.attribute(QGeoPositionInfo::MagneticVariation)); +} + +/*! + \qmlproperty double Position::magneticVariation + \since Qt Positioning 5.4 + + This property holds the angle between the horizontal component of the + magnetic field and true north, in degrees. Also known as magnetic + declination. A positive value indicates a clockwise direction from + true north and a negative value indicates a counter-clockwise direction. + + It is a read-only property. + + \sa magneticVariationValid +*/ +double QDeclarativePosition::magneticVariation() const +{ + return m_computedMagneticVariation.value(); +} + +double QDeclarativePosition::magneticVariationActualCalculation() const +{ + return m_info.attribute(QGeoPositionInfo::MagneticVariation); +} + +/*! + \qmlproperty bool Position::directionAccuracyValid + \since Qt Positioning 6.3 + + This property is \c true if \l directionAccuracy has been set. + + \sa directionAccuracy +*/ +bool QDeclarativePosition::isDirectionAccuracyValid() const +{ + return m_computedDirectionAccuracyValid.value(); +} + +bool QDeclarativePosition::isDirectionAccuracyValidActualCalculation() const +{ + return !qIsNaN(m_info.attribute(QGeoPositionInfo::DirectionAccuracy)); +} + +/*! + \qmlproperty double Position::directionAccuracy + \since Qt Positioning 6.3 + + This property holds the accuracy of the provided \l direction in degrees. + This property is valid for Android and macOS/iOS only. See + \l {QGeoPositionInfo::Attribute} documentation for more details. + + \sa direction, directionAccuracyValid +*/ +double QDeclarativePosition::directionAccuracy() const +{ + return m_computedDirectionAccuracy.value(); +} + +double QDeclarativePosition::directionAccuracyActualCalculation() const +{ + return m_info.attribute(QGeoPositionInfo::DirectionAccuracy); +} + +QT_END_NAMESPACE + +#include "moc_qdeclarativeposition_p.cpp" diff --git a/src/positioningquick/qdeclarativeposition_p.h b/src/positioningquick/qdeclarativeposition_p.h new file mode 100644 index 0000000..2d0fd95 --- /dev/null +++ b/src/positioningquick/qdeclarativeposition_p.h @@ -0,0 +1,184 @@ +// Copyright (C) 2016 Jolla Ltd. +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QDECLARATIVEPOSITION_H +#define QDECLARATIVEPOSITION_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 +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_POSITIONINGQUICK_PRIVATE_EXPORT QDeclarativePosition : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(Position) + QML_ADDED_IN_VERSION(5, 0) + + Q_PROPERTY(bool latitudeValid READ isLatitudeValid BINDABLE bindableLatitudeValid) + Q_PROPERTY(bool longitudeValid READ isLongitudeValid BINDABLE bindableLongitudeValid) + Q_PROPERTY(bool altitudeValid READ isAltitudeValid BINDABLE bindableAltitudeValid) + Q_PROPERTY(QGeoCoordinate coordinate READ coordinate BINDABLE bindableCoordinate) + Q_PROPERTY(QDateTime timestamp READ timestamp BINDABLE bindableTimestamp) + Q_PROPERTY(double speed READ speed BINDABLE bindableSpeed) + Q_PROPERTY(bool speedValid READ isSpeedValid BINDABLE bindableSpeedValid) + Q_PROPERTY(qreal horizontalAccuracy READ horizontalAccuracy BINDABLE bindableHorizontalAccuracy) + Q_PROPERTY(qreal verticalAccuracy READ verticalAccuracy BINDABLE binableVerticalAccuracy) + Q_PROPERTY(bool horizontalAccuracyValid READ isHorizontalAccuracyValid BINDABLE + bindableHorizontalAccuracyValid) + Q_PROPERTY(bool verticalAccuracyValid READ isVerticalAccuracyValid BINDABLE + bindableVerticalAccuracyValid) + + Q_PROPERTY(bool directionValid READ isDirectionValid BINDABLE bindableDirectionValid + REVISION(5, 1)) + Q_PROPERTY(double direction READ direction BINDABLE bindableDirection REVISION(5, 1)) + Q_PROPERTY(bool verticalSpeedValid READ isVerticalSpeedValid BINDABLE bindableVerticalSpeedValid + REVISION(5, 1)) + Q_PROPERTY(double verticalSpeed READ verticalSpeed BINDABLE bindableVerticalSpeed + REVISION(5, 1)) + + Q_PROPERTY(double magneticVariation READ magneticVariation BINDABLE bindableMagneticVariation + REVISION(5, 2)) + Q_PROPERTY(bool magneticVariationValid READ isMagneticVariationValid BINDABLE + bindableMagneticVariationValid REVISION(5, 2)) + + Q_PROPERTY(double directionAccuracy READ directionAccuracy BINDABLE bindableDirectionAccuracy + REVISION(6, 3)) + Q_PROPERTY(bool directionAccuracyValid READ isDirectionAccuracyValid BINDABLE + bindableDirectionAccuracyValid REVISION(6, 3)) + +public: + explicit QDeclarativePosition(QObject *parent = 0); + ~QDeclarativePosition(); + + bool isLatitudeValid() const; + bool isLongitudeValid() const; + bool isAltitudeValid() const; + QDateTime timestamp() const; + double speed() const; + bool isSpeedValid() const; + QGeoCoordinate coordinate() const; + bool isHorizontalAccuracyValid() const; + qreal horizontalAccuracy() const; + bool isVerticalAccuracyValid() const; + qreal verticalAccuracy() const; + + bool isDirectionValid() const; + double direction() const; + + bool isVerticalSpeedValid() const; + double verticalSpeed() const; + + bool isMagneticVariationValid() const; + double magneticVariation() const; + + void setPosition(const QGeoPositionInfo &info); + const QGeoPositionInfo &position() const; + + bool isDirectionAccuracyValid() const; + double directionAccuracy() const; + + QBindable bindableLatitudeValid() const; + QBindable bindableLongitudeValid() const; + QBindable bindableAltitudeValid() const; + QBindable bindableCoordinate() const; + QBindable bindableTimestamp() const; + QBindable bindableSpeed() const; + QBindable bindableSpeedValid() const; + QBindable bindableHorizontalAccuracy() const; + QBindable binableVerticalAccuracy() const; + QBindable bindableHorizontalAccuracyValid() const; + QBindable bindableVerticalAccuracyValid() const; + QBindable bindableDirectionValid() const; + QBindable bindableDirection() const; + QBindable bindableVerticalSpeedValid() const; + QBindable bindableVerticalSpeed() const; + QBindable bindableMagneticVariation() const; + QBindable bindableMagneticVariationValid() const; + QBindable bindableDirectionAccuracy() const; + QBindable bindableDirectionAccuracyValid() const; + +private: + bool isLatitudeValidActualCalculation() const; + bool isLongitudeValidActualCalculation() const; + bool isAltitudeValidActualCalculation() const; + QGeoCoordinate coordinateActualCalculation() const; + QDateTime timestampActualCalculation() const; + double speedActualCalculation() const; + bool isSpeedValidActualCalculation() const; + qreal horizontalAccuracyActualCalculation() const; + qreal verticalAccuracyActualCalculation() const; + bool isHorizontalAccuracyValidActualCalculation() const; + bool isVerticalAccuracyValidActualCalculation() const; + bool isDirectionValidActualCalculation() const; + double directionActualCalculation() const; + bool isVerticalSpeedValidActualCalculation() const; + double verticalSpeedActualCalculation() const; + double magneticVariationActualCalculation() const; + bool isMagneticVariationValidActualCalculation() const; + double directionAccuracyActualCalculation() const; + bool isDirectionAccuracyValidActualCalculation() const; + + QGeoPositionInfo m_info; + + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedLatitudeValid, + &QDeclarativePosition::isLatitudeValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedLongitudeValid, + &QDeclarativePosition::isLongitudeValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedAltitudeValid, + &QDeclarativePosition::isAltitudeValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, QGeoCoordinate, m_computedCoordinate, + &QDeclarativePosition::coordinateActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, QDateTime, m_computedTimestamp, + &QDeclarativePosition::timestampActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, double, m_computedSpeed, + &QDeclarativePosition::speedActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedSpeedValid, + &QDeclarativePosition::isSpeedValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, qreal, m_computedHorizontalAccuracy, + &QDeclarativePosition::horizontalAccuracyActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, qreal, m_computedVerticalAccuracy, + &QDeclarativePosition::verticalAccuracyActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedHorizontalAccuracyValid, + &QDeclarativePosition::isHorizontalAccuracyValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedVerticalAccuracyValid, + &QDeclarativePosition::isVerticalAccuracyValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedDirectionValid, + &QDeclarativePosition::isDirectionValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, double, m_computedDirection, + &QDeclarativePosition::directionActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedVerticalSpeedValid, + &QDeclarativePosition::isVerticalSpeedValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, double, m_computedVerticalSpeed, + &QDeclarativePosition::verticalSpeedActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, double, m_computedMagneticVariation, + &QDeclarativePosition::magneticVariationActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedMagneticVariationValid, + &QDeclarativePosition::isMagneticVariationValidActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, double, m_computedDirectionAccuracy, + &QDeclarativePosition::directionAccuracyActualCalculation) + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePosition, bool, m_computedDirectionAccuracyValid, + &QDeclarativePosition::isDirectionAccuracyValidActualCalculation) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativePosition) + +#endif diff --git a/src/positioningquick/qdeclarativepositionsource.cpp b/src/positioningquick/qdeclarativepositionsource.cpp new file mode 100644 index 0000000..f84285a --- /dev/null +++ b/src/positioningquick/qdeclarativepositionsource.cpp @@ -0,0 +1,872 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qdeclarativepositionsource_p.h" +#include "qdeclarativeposition_p.h" + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmltype PositionSource + //! \instantiates QDeclarativePositionSource + \inqmlmodule QtPositioning + \since 5.2 + + \brief The PositionSource type provides the device's current position. + + The PositionSource type provides information about the user device's + current position. The position is available as a \l{Position} type, which + contains all the standard parameters typically available from GPS and other + similar systems, including longitude, latitude, speed and accuracy details. + + As different position sources are available on different platforms and + devices, these are categorized by their basic type (Satellite, NonSatellite, + and AllPositioningMethods). The available methods for the current platform + can be enumerated in the \l{supportedPositioningMethods} property. + + To indicate which methods are suitable for your application, set the + \l{preferredPositioningMethods} property. If the preferred methods are not + available, the default source of location data for the platform will be + chosen instead. If no default source is available (because none are installed + for the runtime platform, or because it is disabled), the \l{valid} property + will be set to false. + + The \l updateInterval property can then be used to indicate how often your + application wishes to receive position updates. The \l{start}(), + \l{stop}() and \l{update}() methods can be used to control the operation + of the PositionSource, as well as the \l{active} property, which when set + is equivalent to calling \l{start}() or \l{stop}(). + + When the PositionSource is active, position updates can be retrieved + either by simply using the \l{position} property in a binding (as the + value of another item's property), or by providing an implementation of + the \c {onPositionChanged} signal-handler. + + \section2 Example Usage + + The following example shows a simple PositionSource used to receive + updates every second and print the longitude and latitude out to + the console. + + \code + PositionSource { + id: src + updateInterval: 1000 + active: true + + onPositionChanged: { + var coord = src.position.coordinate; + console.log("Coordinate:", coord.longitude, coord.latitude); + } + } + \endcode + + The \l{geoflickr}{GeoFlickr} example application shows how to use + a PositionSource in your application to retrieve local data for users + from a REST web service. + + \section2 Controlling Operation State + + As it's mentioned above, PositionSource provides two ways to control its + operation state: + + \list + \li By using the \l active \l {Qt Bindable Properties}{bindable} property. + \li By using \l start() and \l stop() methods. + \endlist + + \note It's very important not to mix these approaches. If a bindable + \l active property is used to control the PositionSource object, but later + \l start() or \l stop() is called from the other part of the code, the + binding is broken, which may result in, for example, a UI element that is + not connected to any underlying object anymore. + + Consider the following example of \b {bad code} where the \c active property + is bound to the CheckBox state, and calling \l stop() in the \c onClicked + signal handler breaks that binding. + + \qml + Window { + width: 640 + height: 480 + visible: true + + PositionSource { + id: posSource + name: "geoclue2" + active: cb.checked + } + + Column { + anchors.centerIn: parent + spacing: 20 + CheckBox { + id: cb + } + Button { + id: btn + text: "Stop" + onClicked: { + posSource.stop() + } + } + } + } + \endqml + + Once the \e Stop button is clicked, \l stop() is executed, and the binding + for the \l active property is broken. At this point the CheckBox UI element + is no longer controlling the PositionSource object. + + A straightforward fix in this case is to update the CheckBox state from + the \c onClicked handler. As soon as the CheckBox is unchecked, the + \l active property will be notified, and the PositionSource object's state + will update accordingly. The UI will also be in a consistent state. + + \qml + Button { + id: btn + text: "Stop" + onClicked: { + cb.checked = false + } + } + \endqml + + \note Using \l update() to request a single position update \e {does not} + have any effect on the \l active property's bindings, so they can be used + together without any problems. + + \sa {QtPositioning::Position}, {QGeoPositionInfoSource}, {PluginParameter}, + {Qt Bindable Properties} + +*/ + +QDeclarativePositionSource::QDeclarativePositionSource() +{ + m_position.setValueBypassingBindings(new QDeclarativePosition(this)); +} + +QDeclarativePositionSource::~QDeclarativePositionSource() +{ + delete m_positionSource; +} + + +/*! + \qmlproperty string PositionSource::name + + This property holds the unique internal name for the plugin currently + providing position information. + + Setting the property causes the PositionSource to use a particular positioning provider. If + the PositionSource is active at the time that the name property is changed, it will become + inactive. If the specified positioning provider cannot be loaded the position source will + become invalid. + + Changing the name property may cause the \l {updateInterval}, \l {supportedPositioningMethods} + and \l {preferredPositioningMethods} properties to change as well. +*/ + + +QString QDeclarativePositionSource::name() const +{ + return m_sourceName; +} + +void QDeclarativePositionSource::setName(const QString &newName) +{ + m_sourceName.removeBindingUnlessInWrapper(); + if (m_positionSource && m_positionSource->sourceName() == newName) + return; + + if (newName.isEmpty() && m_defaultSourceUsed) + return; // previously attached to a default source, now requesting the same. + + const QString previousName = name(); + + if (!m_componentComplete || !m_parametersInitialized) { + if (previousName != newName) { + m_sourceName.setValueBypassingBindings(newName); + m_sourceName.notify(); + } + return; + } + + // tryAttach() will update the m_sourceName correctly + tryAttach(newName, false); +} + +QBindable QDeclarativePositionSource::bindableName() +{ + return QBindable(&m_sourceName); +} + +QBindable QDeclarativePositionSource::bindablePosition() const +{ + return QBindable(&m_position); +} + +/*! + \internal +*/ +void QDeclarativePositionSource::tryAttach(const QString &newName, bool useFallback) +{ + const QString previousName = name(); + const bool sourceExisted = (m_positionSource != nullptr); + + int previousUpdateInterval = updateInterval(); + PositioningMethods previousPositioningMethods = supportedPositioningMethods(); + PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods(); + + m_defaultSourceUsed = false; + + if (newName.isEmpty()) { + setSource(QGeoPositionInfoSource::createDefaultSource(parameterMap(), this)); + m_defaultSourceUsed = true; + } else { + setSource(QGeoPositionInfoSource::createSource(newName, parameterMap(), this)); + if (!m_positionSource && useFallback) { + setSource(QGeoPositionInfoSource::createDefaultSource(parameterMap(), this)); + m_defaultSourceUsed = true; + } + } + + if (m_positionSource) { + m_sourceName.setValueBypassingBindings(m_positionSource->sourceName()); + + connect(m_positionSource, SIGNAL(positionUpdated(QGeoPositionInfo)), + this, SLOT(positionUpdateReceived(QGeoPositionInfo))); + connect(m_positionSource, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error)), + this, SLOT(sourceErrorReceived(QGeoPositionInfoSource::Error))); + + m_positionSource->setUpdateInterval(m_updateInterval); + m_positionSource->setPreferredPositioningMethods( + static_cast(int(m_preferredPositioningMethods))); + + if (m_startRequested) { + const QGeoPositionInfo &lastKnown = m_positionSource->lastKnownPosition(); + if (lastKnown.isValid()) + setPosition(lastKnown); + } + } else { + m_sourceName.setValueBypassingBindings(newName); + m_defaultSourceUsed = false; + if (m_active) { + // We do not want to break the binding here, because we just want to + // give the user an opportunity to select another plugin and keep + // working. + m_active.setValueBypassingBindings(false); + m_active.notify(); + } + } + + if (previousUpdateInterval != updateInterval()) + emit updateIntervalChanged(); + + if (previousPreferredPositioningMethods != preferredPositioningMethods()) + emit preferredPositioningMethodsChanged(); + + if (previousPositioningMethods != supportedPositioningMethods()) + notifySupportedPositioningMethodsChanged(); + + const bool sourceCurrentlyExists = (m_positionSource != nullptr); + if (sourceExisted != sourceCurrentlyExists) { + m_isValid.notify(); + emit validityChanged(); + } + + if (m_active) { // implies m_positionSource + // If m_active is true, then the previous position source existed! + Q_ASSERT(sourceExisted); + // New source is set. It should be inactive by default. + // But we do not want to break the binding. + m_active.setValueBypassingBindings(false); + m_active.notify(); + } else if (m_startRequested) { + m_startRequested = false; + executeStart(); + } + + if (previousName != m_sourceName) + m_sourceName.notify(); +} + +/*! + \qmlproperty bool PositionSource::valid + + This property is true if the PositionSource object has acquired a valid + backend plugin to provide data. If false, other methods on the PositionSource + will have no effect. + + Applications should check this property to determine whether positioning is + available and enabled on the runtime platform, and react accordingly. +*/ +bool QDeclarativePositionSource::isValid() const +{ + return m_isValid.value(); +} + +QBindable QDeclarativePositionSource::bindableIsValid() const +{ + return QBindable(&m_isValid); +} + +bool QDeclarativePositionSource::isValidActualComputation() const +{ + return m_positionSource != nullptr; +} + +/*! + \internal +*/ +void QDeclarativePositionSource::onParameterInitialized() +{ + m_parametersInitialized = true; + for (QDeclarativePluginParameter *p: std::as_const(m_parameters)) { + if (!p->isInitialized()) { + m_parametersInitialized = false; + break; + } + } + + // If here, componentComplete has been called. + if (m_parametersInitialized) + tryAttach(m_sourceName.value()); +} + +void QDeclarativePositionSource::notifySupportedPositioningMethodsChanged() +{ + m_supportedPositioningMethods.notify(); + emit supportedPositioningMethodsChanged(); +} + +void QDeclarativePositionSource::setPosition(const QGeoPositionInfo &pi) +{ + m_position.value()->setPosition(pi); + m_position.notify(); + emit positionChanged(); +} + +void QDeclarativePositionSource::setSource(QGeoPositionInfoSource *source) +{ + if (m_positionSource) + delete m_positionSource; + + if (!source) { + m_positionSource = nullptr; + } else { + m_positionSource = source; + connect(m_positionSource, &QGeoPositionInfoSource::supportedPositioningMethodsChanged, + this, &QDeclarativePositionSource::notifySupportedPositioningMethodsChanged); + } +} + +bool QDeclarativePositionSource::parametersReady() +{ + for (const QDeclarativePluginParameter *p: std::as_const(m_parameters)) { + if (!p->isInitialized()) + return false; + } + return true; +} + +/*! + \internal +*/ +QVariantMap QDeclarativePositionSource::parameterMap() const +{ + QVariantMap map; + + for (const auto *parameter : m_parameters) + map.insert(parameter->name(), parameter->value()); + + return map; +} + +/*! + \internal +*/ +void QDeclarativePositionSource::setUpdateInterval(int updateInterval) +{ + if (m_positionSource) { + int previousUpdateInterval = m_positionSource->updateInterval(); + + m_updateInterval = updateInterval; + + if (previousUpdateInterval != updateInterval) { + m_positionSource->setUpdateInterval(updateInterval); + if (previousUpdateInterval != m_positionSource->updateInterval()) + emit updateIntervalChanged(); + } + } else { + if (m_updateInterval != updateInterval) { + m_updateInterval = updateInterval; + emit updateIntervalChanged(); + } + } +} + +/*! + \qmlproperty int PositionSource::updateInterval + + This property holds the desired interval between updates (milliseconds). + + \sa {QGeoPositionInfoSource::updateInterval()} +*/ + +int QDeclarativePositionSource::updateInterval() const +{ + if (!m_positionSource) + return m_updateInterval; + + return m_positionSource->updateInterval(); +} + +/*! + \qmlproperty enumeration PositionSource::supportedPositioningMethods + + This property holds the supported positioning methods of the + current source. + + \list + \li PositionSource.NoPositioningMethods - No positioning methods supported (no source). + \li PositionSource.SatellitePositioningMethods - Satellite-based positioning methods such as GPS are supported. + \li PositionSource.NonSatellitePositioningMethods - Non-satellite-based methods are supported. + \li PositionSource.AllPositioningMethods - Both satellite-based and non-satellite positioning methods are supported. + \endlist + +*/ + +QDeclarativePositionSource::PositioningMethods +QDeclarativePositionSource::supportedPositioningMethods() const +{ + return m_supportedPositioningMethods.value(); +} + +QDeclarativePositionSource::PositioningMethods +QDeclarativePositionSource::supportedMethodsActualComputation() const +{ + if (m_positionSource) { + return static_cast( + int(m_positionSource->supportedPositioningMethods())); + } + return QDeclarativePositionSource::NoPositioningMethods; +} + +QBindable +QDeclarativePositionSource::bindableSupportedPositioningMethods() const +{ + return QBindable(&m_supportedPositioningMethods); +} + +/*! + \qmlproperty enumeration PositionSource::preferredPositioningMethods + + This property holds the preferred positioning methods of the + current source. + + \list + \li PositionSource.NoPositioningMethods - No positioning method is preferred. + \li PositionSource.SatellitePositioningMethods - Satellite-based positioning methods such as GPS should be preferred. + \li PositionSource.NonSatellitePositioningMethods - Non-satellite-based methods should be preferred. + \li PositionSource.AllPositioningMethods - Any positioning methods are acceptable. + \endlist + +*/ + +void QDeclarativePositionSource::setPreferredPositioningMethods(PositioningMethods methods) +{ + if (m_positionSource) { + PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods(); + + m_preferredPositioningMethods = methods; + + if (previousPreferredPositioningMethods != methods) { + m_positionSource->setPreferredPositioningMethods( + static_cast(int(methods))); + if (previousPreferredPositioningMethods != m_positionSource->preferredPositioningMethods()) + emit preferredPositioningMethodsChanged(); + } + } else { + if (m_preferredPositioningMethods != methods) { + m_preferredPositioningMethods = methods; + emit preferredPositioningMethodsChanged(); + } + } +} + +QDeclarativePositionSource::PositioningMethods QDeclarativePositionSource::preferredPositioningMethods() const +{ + if (m_positionSource) { + return static_cast( + int(m_positionSource->preferredPositioningMethods())); + } + return m_preferredPositioningMethods; +} + +/*! + \qmlmethod PositionSource::start() + + Requests updates from the location source. + Uses \l updateInterval if set, default interval otherwise. + If there is no source available, this method has no effect. + + \note Calling this method breaks the bindings of + \l {PositionSource::}{active} property. + + \sa stop, update, active +*/ + +void QDeclarativePositionSource::start() +{ + if (m_positionSource) { + m_active.removeBindingUnlessInWrapper(); + executeStart(); + } +} + +/*! + \qmlmethod PositionSource::update(int timeout) + + A convenience method to request single update from the location source. + If there is no source available, this method has no effect. + + If the position source is not active, it will be activated for as + long as it takes to receive an update, or until the request times + out. The request timeout period is source-specific. + + The \a timeout is specified in milliseconds. If the \a timeout is zero + (the default value), it defaults to a reasonable timeout period as + appropriate for the source. + + \sa start, stop, active +*/ + +void QDeclarativePositionSource::update(int timeout) +{ + if (m_positionSource) { + m_singleUpdate = true; + if (!m_active) { + // Questionable: we do not want this method to break the binding. + // Mostly because it can be called while the updates are already + // running. + m_active.setValueBypassingBindings(true); + m_active.notify(); + } + // Use default timeout value. Set active before calling the + // update request because on some platforms there may + // be results immediately. + m_positionSource->requestUpdate(timeout); + } +} + +/*! + \qmlmethod PositionSource::stop() + + Stops updates from the location source. + If there is no source available or it is not active, + this method has no effect. + + \note Calling this method breaks the bindings of + \l {PositionSource::}{active} property. + + \sa start, update, active +*/ + +void QDeclarativePositionSource::stop() +{ + if (m_positionSource) { + m_positionSource->stopUpdates(); + m_regularUpdates = false; + // Try to break the binding even if we do not actually need to update + // the active state. The m_active can be updated later, when the + // single update request finishes. + m_active.removeBindingUnlessInWrapper(); + if (m_active && !m_singleUpdate) { + m_active.setValueBypassingBindings(false); + m_active.notify(); + } + } +} + +/*! + \qmlproperty bool PositionSource::active + + This property indicates whether the position source is active. + Setting this property to false equals calling \l stop, and + setting this property true equals calling \l start. + + \sa start, stop, update +*/ +void QDeclarativePositionSource::setActive(bool active) +{ + // We need to remove binding, if this method is called explicitly. + // Other changes to m_active are done inside start() and stop() methods. + m_active.removeBindingUnlessInWrapper(); + if (active == m_active) + return; + + if (active) { + // If the component is not completed yet, we need to defer the + // actual executeStart() call until everything is set up. + if (m_componentComplete && m_parametersInitialized) + executeStart(); + else + m_startRequested = true; + } else { + stop(); + } +} + +bool QDeclarativePositionSource::isActive() const +{ + return m_active; +} + +/*! + \qmlproperty Position PositionSource::position + + This property holds the last known positional data. + It is a read-only property. + + The Position type has different positional member variables, + whose validity can be checked with appropriate validity functions + (for example sometimes an update does not have speed or altitude data). + + However, whenever a \c {positionChanged} signal has been received, at least + position::coordinate::latitude, position::coordinate::longitude, and position::timestamp can + be assumed to be valid. + + \sa start, stop, update +*/ + +QDeclarativePosition *QDeclarativePositionSource::position() +{ + return m_position.value(); +} + +void QDeclarativePositionSource::positionUpdateReceived(const QGeoPositionInfo &update) +{ + setPosition(update); + + if (m_singleUpdate && m_active) { + // we need to reset m_singleUpdate because we got one + m_singleUpdate = false; + if (!m_regularUpdates) { + // but we change the active state only if the regular updates are + // also stopped + m_active.setValueBypassingBindings(false); + m_active.notify(); + } + } +} + + +/*! + \qmlproperty enumeration PositionSource::sourceError + + This property holds the error which last occurred with the PositionSource. + + \list + \li PositionSource.AccessError - The connection setup to the remote positioning backend failed because the + application lacked the required privileges. + \li PositionSource.ClosedError - The positioning backend closed the connection, which happens for example in case + the user is switching location services to off. As soon as the location service is re-enabled + regular updates will resume. + \li PositionSource.NoError - No error has occurred. + \li PositionSource.UnknownSourceError - An unidentified error occurred. + \li PositionSource.UpdateTimeoutError - The current position could not be + retrieved within the specified timeout, or this PositionSource determined + that it will not be able to provide further regular updates. + \endlist + +*/ + +QDeclarativePositionSource::SourceError QDeclarativePositionSource::sourceError() const +{ + return m_sourceError; +} + +QBindable +QDeclarativePositionSource::bindableSourceError() const +{ + return QBindable(&m_sourceError); +} + +QGeoPositionInfoSource *QDeclarativePositionSource::positionSource() const +{ + return m_positionSource; +} + +/*! + \qmlproperty list PositionSource::parameters + \qmldefault + + This property holds the list of plugin parameters. + + \since QtPositioning 5.14 +*/ +QQmlListProperty QDeclarativePositionSource::parameters() +{ + return QQmlListProperty(this, + 0, + parameter_append, + parameter_count, + parameter_at, + parameter_clear); +} + +/*! + \internal +*/ +void QDeclarativePositionSource::parameter_append(QQmlListProperty *prop, QDeclarativePluginParameter *parameter) +{ + QDeclarativePositionSource *p = static_cast(prop->object); + p->m_parameters.append(parameter); +} + +/*! + \internal +*/ +qsizetype QDeclarativePositionSource::parameter_count(QQmlListProperty *prop) +{ + return static_cast(prop->object)->m_parameters.size(); +} + +/*! + \internal +*/ +QDeclarativePluginParameter *QDeclarativePositionSource::parameter_at(QQmlListProperty *prop, qsizetype index) +{ + return static_cast(prop->object)->m_parameters[index]; +} + +/*! + \internal +*/ +void QDeclarativePositionSource::parameter_clear(QQmlListProperty *prop) +{ + QDeclarativePositionSource *p = static_cast(prop->object); + p->m_parameters.clear(); +} + +void QDeclarativePositionSource::executeStart() +{ + if (m_positionSource) { + m_positionSource->startUpdates(); + + // If this method is called directly from start(), the binding is + // already broken there (for the consistency with stop()). + // If this method is called by a timer, started in setActive(), we do + // not need to break the binding, because it was already done (if + // needed). + + m_regularUpdates = true; + if (!m_active) { + m_active.setValueBypassingBindings(true); + m_active.notify(); + } + } +} + +void QDeclarativePositionSource::componentComplete() +{ + m_componentComplete = true; + m_parametersInitialized = true; + for (QDeclarativePluginParameter *p: std::as_const(m_parameters)) { + if (!p->isInitialized()) { + m_parametersInitialized = false; + connect(p, &QDeclarativePluginParameter::initialized, + this, &QDeclarativePositionSource::onParameterInitialized); + } + } + + if (m_parametersInitialized) + tryAttach(m_sourceName.value()); +} + +/*! + \qmlmethod bool PositionSource::setBackendProperty(string name, Variant value) + + Sets the backend-specific property named \a name to \a value. + Returns true on success, false otherwise, including if called on an uninitialized PositionSource. + Supported backend-specific properties are listed and described in + \l {Qt Positioning plugins#Default plugins}. + + \since Qt Positioning 5.14 + + \sa backendProperty, QGeoPositionInfoSource::setBackendProperty +*/ +bool QDeclarativePositionSource::setBackendProperty(const QString &name, const QVariant &value) +{ + if (m_positionSource) + return m_positionSource->setBackendProperty(name, value); + return false; +} + +/*! + \qmlmethod Variant PositionSource::backendProperty(string name) + + Returns the value of the backend-specific property named \a name, if present. + Otherwise, including if called on an uninitialized PositionSource, the return value will be invalid. + Supported backend-specific properties are listed and described in + \l {Qt Positioning plugins#Default plugins}. + + \since Qt Positioning 5.14 + + \sa backendProperty, QGeoPositionInfoSource::setBackendProperty +*/ +QVariant QDeclarativePositionSource::backendProperty(const QString &name) const +{ + if (m_positionSource) + return m_positionSource->backendProperty(name); + return QVariant(); +} + +QBindable QDeclarativePositionSource::bindableActive() +{ + return QBindable(&m_active); +} + +/*! + \internal +*/ +void QDeclarativePositionSource::sourceErrorReceived(const QGeoPositionInfoSource::Error error) +{ + if (error == QGeoPositionInfoSource::AccessError) + m_sourceError.setValueBypassingBindings(QDeclarativePositionSource::AccessError); + else if (error == QGeoPositionInfoSource::ClosedError) + m_sourceError.setValueBypassingBindings(QDeclarativePositionSource::ClosedError); + else if (error == QGeoPositionInfoSource::UpdateTimeoutError) + m_sourceError.setValueBypassingBindings(QDeclarativePositionSource::UpdateTimeoutError); + else if (error == QGeoPositionInfoSource::NoError) + return; //nothing to do + else + m_sourceError.setValueBypassingBindings(QDeclarativePositionSource::UnknownSourceError); + + m_sourceError.notify(); + emit sourceErrorChanged(); + + // if an error occurred during single update, the update is stopped, so we + // need to change the active state. + if (m_active && m_singleUpdate) { + m_singleUpdate = false; + if (!m_regularUpdates) { + m_active.setValueBypassingBindings(false); + m_active.notify(); + } + } +} + +QT_END_NAMESPACE + +#include "moc_qdeclarativepositionsource_p.cpp" diff --git a/src/positioningquick/qdeclarativepositionsource_p.h b/src/positioningquick/qdeclarativepositionsource_p.h new file mode 100644 index 0000000..537d345 --- /dev/null +++ b/src/positioningquick/qdeclarativepositionsource_p.h @@ -0,0 +1,186 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QDECLARATIVEPOSITIONSOURCE_H +#define QDECLARATIVEPOSITIONSOURCE_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 +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QFile; +class QTcpSocket; + +class Q_POSITIONINGQUICK_PRIVATE_EXPORT QDeclarativePositionSource : public QObject, public QQmlParserStatus +{ + Q_OBJECT + QML_NAMED_ELEMENT(PositionSource) + QML_ADDED_IN_VERSION(5, 0) + + Q_PROPERTY(QDeclarativePosition *position READ position NOTIFY positionChanged + BINDABLE bindablePosition) + Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged + BINDABLE bindableActive) + Q_PROPERTY(bool valid READ isValid NOTIFY validityChanged BINDABLE bindableIsValid) + Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval + NOTIFY updateIntervalChanged) + Q_PROPERTY(PositioningMethods supportedPositioningMethods READ supportedPositioningMethods + NOTIFY supportedPositioningMethodsChanged + BINDABLE bindableSupportedPositioningMethods) + Q_PROPERTY(PositioningMethods preferredPositioningMethods READ preferredPositioningMethods + WRITE setPreferredPositioningMethods NOTIFY preferredPositioningMethodsChanged) + Q_PROPERTY(SourceError sourceError READ sourceError NOTIFY sourceErrorChanged + BINDABLE bindableSourceError) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged BINDABLE bindableName) + Q_PROPERTY(QQmlListProperty parameters READ parameters REVISION(5, 14)) + Q_ENUMS(PositioningMethod) + + Q_CLASSINFO("DefaultProperty", "parameters") + Q_INTERFACES(QQmlParserStatus) + +public: + enum PositioningMethod { + NoPositioningMethods = QGeoPositionInfoSource::NoPositioningMethods, + SatellitePositioningMethods = QGeoPositionInfoSource::SatellitePositioningMethods, + NonSatellitePositioningMethods = QGeoPositionInfoSource::NonSatellitePositioningMethods, + AllPositioningMethods = QGeoPositionInfoSource::AllPositioningMethods + }; + + Q_DECLARE_FLAGS(PositioningMethods, PositioningMethod) + Q_FLAGS(PositioningMethods) + + enum SourceError { + AccessError = QGeoPositionInfoSource::AccessError, + ClosedError = QGeoPositionInfoSource::ClosedError, + UnknownSourceError = QGeoPositionInfoSource::UnknownSourceError, + NoError = QGeoPositionInfoSource::NoError, + UpdateTimeoutError = QGeoPositionInfoSource::UpdateTimeoutError, + }; + Q_ENUMS(SourceError) + + QDeclarativePositionSource(); + ~QDeclarativePositionSource(); + void setUpdateInterval(int updateInterval); + void setActive(bool active); + void setPreferredPositioningMethods(PositioningMethods methods); + + QString name() const; + void setName(const QString &name); + + int updateInterval() const; + bool isActive() const; + bool isValid() const; + QDeclarativePosition *position(); + PositioningMethods supportedPositioningMethods() const; + PositioningMethods preferredPositioningMethods() const; + SourceError sourceError() const; + QGeoPositionInfoSource *positionSource() const; + QQmlListProperty parameters(); + QVariantMap parameterMap() const; + + // Virtuals from QQmlParserStatus + void classBegin() override { } + void componentComplete() override; + + Q_REVISION(5, 14) Q_INVOKABLE bool setBackendProperty(const QString &name, const QVariant &value); + Q_REVISION(5, 14) Q_INVOKABLE QVariant backendProperty(const QString &name) const; + + QBindable bindableSupportedPositioningMethods() const; + QBindable bindableSourceError() const; + QBindable bindableIsValid() const; + QBindable bindableName(); + QBindable bindablePosition() const; + QBindable bindableActive(); + +public Q_SLOTS: + void update(int timeout = 0); + void start(); + void stop(); + +Q_SIGNALS: + void positionChanged(); + void activeChanged(); + void updateIntervalChanged(); + void supportedPositioningMethodsChanged(); + void preferredPositioningMethodsChanged(); + void sourceErrorChanged(); + void nameChanged(); + void validityChanged(); + +private Q_SLOTS: + void positionUpdateReceived(const QGeoPositionInfo &update); + void sourceErrorReceived(const QGeoPositionInfoSource::Error error); + void onParameterInitialized(); + void notifySupportedPositioningMethodsChanged(); + +private: + void setPosition(const QGeoPositionInfo &pi); + void setSource(QGeoPositionInfoSource *source); + bool parametersReady(); + void tryAttach(const QString &name, bool useFallback = true); + + static void parameter_append(QQmlListProperty *prop, QDeclarativePluginParameter *mapObject); + static qsizetype parameter_count(QQmlListProperty *prop); + static QDeclarativePluginParameter *parameter_at(QQmlListProperty *prop, qsizetype index); + static void parameter_clear(QQmlListProperty *prop); + + bool isValidActualComputation() const; + PositioningMethods supportedMethodsActualComputation() const; + + void executeStart(); + + QGeoPositionInfoSource *m_positionSource = nullptr; + PositioningMethods m_preferredPositioningMethods = AllPositioningMethods; + bool m_singleUpdate = false; + bool m_regularUpdates = false; + int m_updateInterval = 0; + QList m_parameters; + bool m_componentComplete = false; + bool m_parametersInitialized = false; + bool m_startRequested = false; + + bool m_defaultSourceUsed = false; + Q_OBJECT_COMPAT_PROPERTY(QDeclarativePositionSource, QString, m_sourceName, + &QDeclarativePositionSource::setName, + &QDeclarativePositionSource::nameChanged) + + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QDeclarativePositionSource, bool, m_active, + &QDeclarativePositionSource::setActive, + &QDeclarativePositionSource::activeChanged, false) + + Q_OBJECT_BINDABLE_PROPERTY(QDeclarativePositionSource, QDeclarativePosition *, m_position) + + Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QDeclarativePositionSource, SourceError, m_sourceError, + NoError) + + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePositionSource, PositioningMethods, + m_supportedPositioningMethods, + &QDeclarativePositionSource::supportedMethodsActualComputation) + + Q_OBJECT_COMPUTED_PROPERTY(QDeclarativePositionSource, bool, m_isValid, + &QDeclarativePositionSource::isValidActualComputation) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativePositionSource) + +#endif diff --git a/src/positioningquick/qpositioningquickglobal.h b/src/positioningquick/qpositioningquickglobal.h new file mode 100644 index 0000000..a04bc15 --- /dev/null +++ b/src/positioningquick/qpositioningquickglobal.h @@ -0,0 +1,20 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QPOSITIONINGQUICKGLOBAL_H +#define QPOSITIONINGQUICKGLOBAL_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 +#include + +#endif // QPOSITIONINGQUICKGLOBAL_H diff --git a/src/positioningquick/qpositioningquickglobal_p.h b/src/positioningquick/qpositioningquickglobal_p.h new file mode 100644 index 0000000..6c7db02 --- /dev/null +++ b/src/positioningquick/qpositioningquickglobal_p.h @@ -0,0 +1,26 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QPOSITIONINGQUICKGLOBAL_P_H +#define QPOSITIONINGQUICKGLOBAL_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 "qpositioningquickglobal.h" +#include + +QT_BEGIN_NAMESPACE + +void Q_POSITIONINGQUICK_PRIVATE_EXPORT qml_register_types_QtPositioning(); + +QT_END_NAMESPACE + +#endif // QPOSITIONINGQUICKGLOBAL_P_H diff --git a/src/positioningquick/qpositioningquickmodule.cpp b/src/positioningquick/qpositioningquickmodule.cpp new file mode 100644 index 0000000..87e2d3a --- /dev/null +++ b/src/positioningquick/qpositioningquickmodule.cpp @@ -0,0 +1,4 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "moc_qpositioningquickmodule_p.cpp" diff --git a/src/positioningquick/qpositioningquickmodule_p.h b/src/positioningquick/qpositioningquickmodule_p.h new file mode 100644 index 0000000..803f257 --- /dev/null +++ b/src/positioningquick/qpositioningquickmodule_p.h @@ -0,0 +1,115 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QT_POSITIONINGQUICKMODULE_P_H +#define QT_POSITIONINGQUICKMODULE_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 +#include "qpositioningquickglobal_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +struct QGeoCoordinateForeign +{ + Q_GADGET + QML_FOREIGN(QGeoCoordinate) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoAddressForeign +{ + Q_GADGET + QML_FOREIGN(QGeoAddress) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoRectangleForeign +{ + Q_GADGET + QML_FOREIGN(QGeoRectangle) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoCircleForeign +{ + Q_GADGET + QML_FOREIGN(QGeoCircle) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoPathForeign +{ + Q_GADGET + QML_FOREIGN(QGeoPath) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoPolygonForeign +{ + Q_GADGET + QML_FOREIGN(QGeoPolygon) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoLocationForeign +{ + Q_GADGET + QML_FOREIGN(QGeoLocation) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoShapeForeign +{ + Q_GADGET + QML_FOREIGN(QGeoShape) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoCoordinateObjectForeign +{ + Q_GADGET + QML_FOREIGN(QGeoCoordinateObject) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +struct QGeoPositionInfoForeign +{ + Q_GADGET + QML_FOREIGN(QGeoPositionInfo) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(5, 0) +}; + +QT_END_NAMESPACE + +#endif // QT_POSITIONINGQUICKMODULE_P_H diff --git a/src/positioningquick/qquickgeocoordinateanimation.cpp b/src/positioningquick/qquickgeocoordinateanimation.cpp new file mode 100644 index 0000000..273db7c --- /dev/null +++ b/src/positioningquick/qquickgeocoordinateanimation.cpp @@ -0,0 +1,263 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qquickgeocoordinateanimation_p.h" +#include "qquickgeocoordinateanimation_p_p.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmltype CoordinateAnimation + \inherits PropertyAnimation + \inqmlmodule QtPositioning + \since 5.3 + + \brief A PropertyAnimation for geo coordinate properties. + + A specialized \l{PropertyAnimation} that defines an animation + between two \l{coordinate}{coordinates}. + + By default, a \l{latitude} of the \l{coordinate} is animated in the direction of shortest + (geodesic) distance between those coordinates. Since CoordinateAnimation uses Mercator + map projection, the \l{latitude} animation is always between -90 and 90 degrees. + The \l{longitude} animation path is not limited and can go over 180 degrees + in both west and east directions. + + The \l{direction} property can be set to specify the direction in which the \l{longitude} + animation should occur. + + \sa {Animation and Transitions in Qt Quick} +*/ + +QVariant q_coordinateInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress) +{ + if (from == to) { + if (progress < 0.5) { + return QVariant::fromValue(from); + } else { + return QVariant::fromValue(to); + } + } + + QGeoCoordinate result = QWebMercator::coordinateInterpolation(from, to, progress); + + return QVariant::fromValue(result); +} + +QVariant q_coordinateShortestInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress) +{ + const QGeoMercatorCoordinatePrivate* fromMercator = + static_cast(QGeoCoordinatePrivate::get(&from)); + const QGeoMercatorCoordinatePrivate* toMercator = + static_cast(QGeoCoordinatePrivate::get(&to)); + + double toX = toMercator->m_mercatorX; + double toY = toMercator->m_mercatorY; + double fromX = fromMercator->m_mercatorX; + double fromY = fromMercator->m_mercatorY; + double x; + if (0.5 < qAbs(toX - fromX)) { + // handle dateline crossing + double ex = toX; + double sx = fromX; + if (ex < sx) + sx -= 1.0; + else if (sx < ex) + ex -= 1.0; + + x = sx + (ex - sx) * progress; + + if (x < 0.0) + x += 1.0; + + } else { + x = fromX + (toX - fromX) * progress; + } + + double y = fromY + (toY - fromY) * progress; + + QGeoCoordinate result = QWebMercator::mercatorToCoord(QDoubleVector2D(x, y)); + result.setAltitude(from.altitude() + (to.altitude() - from.altitude()) * progress); + return QVariant::fromValue(result); +} + +QVariant q_coordinateEastInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress) +{ + const QGeoMercatorCoordinatePrivate* fromMercator = + static_cast(QGeoCoordinatePrivate::get(&from)); + const QGeoMercatorCoordinatePrivate* toMercator = + static_cast(QGeoCoordinatePrivate::get(&to)); + + double toX = toMercator->m_mercatorX; + double toY = toMercator->m_mercatorY; + double fromX = fromMercator->m_mercatorX; + double fromY = fromMercator->m_mercatorY; + double diff = toX - fromX; + + while (diff < 0.0) { + toX += 1.0; + diff += 1.0; + } + + double x = fromX + (toX - fromX) * progress; + double y = fromY + (toY - fromY) * progress; + + while (x > 1.0) + x -= 1.0; + + QGeoCoordinate result = QWebMercator::mercatorToCoord(QDoubleVector2D(x, y)); + result.setAltitude(from.altitude() + (to.altitude() - from.altitude()) * progress); + + return QVariant::fromValue(result); +} + +QVariant q_coordinateWestInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress) +{ + const QGeoMercatorCoordinatePrivate* fromMercator = + static_cast(QGeoCoordinatePrivate::get(&from)); + const QGeoMercatorCoordinatePrivate* toMercator = + static_cast(QGeoCoordinatePrivate::get(&to)); + + double toX = toMercator->m_mercatorX; + double toY = toMercator->m_mercatorY; + double fromX = fromMercator->m_mercatorX; + double fromY = fromMercator->m_mercatorY; + double diff = toX - fromX; + + while (diff > 0.0) { + toX -= 1.0; + diff -= 1.0; + } + + double x = fromX + (toX - fromX) * progress; + double y = fromY + (toY - fromY) * progress; + + while (x < 0.0) + x += 1.0; + + QGeoCoordinate result = QWebMercator::mercatorToCoord(QDoubleVector2D(x, y)); + result.setAltitude(from.altitude() + (to.altitude() - from.altitude()) * progress); + + return QVariant::fromValue(result); +} + +QQuickGeoCoordinateAnimation::QQuickGeoCoordinateAnimation(QObject *parent) + : QQuickPropertyAnimation(*(new QQuickGeoCoordinateAnimationPrivate), parent) + +{ + Q_D(QQuickGeoCoordinateAnimation); + d->interpolatorType = qMetaTypeId(); + d->defaultToInterpolatorType = true; + d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); +} + +QQuickGeoCoordinateAnimation::~QQuickGeoCoordinateAnimation() +{ +} + +/*! + \qmlproperty coordinate CoordinateAnimation::from + This property holds the coordinate where the animation should begin. +*/ +QGeoCoordinate QQuickGeoCoordinateAnimation::from() const +{ + Q_D(const QQuickGeoCoordinateAnimation); + return d->from.value(); +} + +void QQuickGeoCoordinateAnimation::setFrom(const QGeoCoordinate &f) +{ + QGeoMercatorCoordinatePrivate *mercator = new QGeoMercatorCoordinatePrivate(); + QDoubleVector2D fromVector = QWebMercator::coordToMercator(f); + mercator->lat = f.latitude(); + mercator->lng = f.longitude(); + mercator->alt = f.altitude(); + mercator->m_mercatorX = fromVector.x(); + mercator->m_mercatorY = fromVector.y(); + QGeoCoordinate from(*mercator); + QQuickPropertyAnimation::setFrom(QVariant::fromValue(from)); +} + +/*! + \qmlproperty coordinate CoordinateAnimation::to + This property holds the coordinate where the animation should end. +*/ +QGeoCoordinate QQuickGeoCoordinateAnimation::to() const +{ + Q_D(const QQuickGeoCoordinateAnimation); + return d->to.value(); +} + +void QQuickGeoCoordinateAnimation::setTo(const QGeoCoordinate &t) +{ + QGeoMercatorCoordinatePrivate *mercator = new QGeoMercatorCoordinatePrivate(); + QDoubleVector2D toVector = QWebMercator::coordToMercator(t); + mercator->lat = t.latitude(); + mercator->lng = t.longitude(); + mercator->alt = t.altitude(); + mercator->m_mercatorX = toVector.x(); + mercator->m_mercatorY = toVector.y(); + QGeoCoordinate to(*mercator); + QQuickPropertyAnimation::setTo(QVariant::fromValue(to)); +} + +/*! + \qmlproperty enumeration CoordinateAnimation::direction + This property holds the direction of the \l{longitude} animation of the \l{coordinate}. + + Possible values are: + + \list + \li CoordinateAnimation.Shortest (default) - the longitude animation goes in the direction + that produces the shortest animation path. + \li CoordinateAnimation.West - the longitude animation always goes into western direction + and may cross the date line. + \li CoordinateAnimation.East - the longitude animation always goes into eastern direction + and may cross the date line. + \endlist + \since 5.5 +*/ + + +QQuickGeoCoordinateAnimation::Direction QQuickGeoCoordinateAnimation::direction() const +{ + Q_D(const QQuickGeoCoordinateAnimation); + return d->m_direction.value(); +} + +void QQuickGeoCoordinateAnimation::setDirection(QQuickGeoCoordinateAnimation::Direction direction) +{ + Q_D( QQuickGeoCoordinateAnimation); + d->m_direction.removeBindingUnlessInWrapper(); + if (d->m_direction.value() == direction) + return; + + d->m_direction.setValueBypassingBindings(direction); + switch (direction) { + case West: + d->interpolator = reinterpret_cast(reinterpret_cast(&q_coordinateWestInterpolator)); + break; + case East: + d->interpolator = reinterpret_cast(reinterpret_cast(&q_coordinateEastInterpolator)); + break; + case Shortest: + default: + d->interpolator = reinterpret_cast(reinterpret_cast(&q_coordinateShortestInterpolator)); + break; + } + d->m_direction.notify(); +} + +QBindable QQuickGeoCoordinateAnimation::bindableDirection() +{ + Q_D(QQuickGeoCoordinateAnimation); + return QBindable(&d->m_direction); +} + +QT_END_NAMESPACE + +#include "moc_qquickgeocoordinateanimation_p.cpp" diff --git a/src/positioningquick/qquickgeocoordinateanimation_p.h b/src/positioningquick/qquickgeocoordinateanimation_p.h new file mode 100644 index 0000000..d705fef --- /dev/null +++ b/src/positioningquick/qquickgeocoordinateanimation_p.h @@ -0,0 +1,68 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QQUICKGEOCOORDINATEANIMATION_P_H +#define QQUICKGEOCOORDINATEANIMATION_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 +#include +#include + +QT_BEGIN_NAMESPACE + +class QQuickGeoCoordinateAnimationPrivate; + +class Q_POSITIONINGQUICK_PRIVATE_EXPORT QQuickGeoCoordinateAnimation : public QQuickPropertyAnimation +{ + Q_OBJECT + QML_NAMED_ELEMENT(CoordinateAnimation) + QML_ADDED_IN_VERSION(5, 3) + Q_DECLARE_PRIVATE(QQuickGeoCoordinateAnimation) + Q_PROPERTY(QGeoCoordinate from READ from WRITE setFrom) + Q_PROPERTY(QGeoCoordinate to READ to WRITE setTo) + Q_PROPERTY(Direction direction READ direction WRITE setDirection NOTIFY directionChanged + BINDABLE bindableDirection) + +public: + enum Direction { + Shortest, + West, + East + }; + Q_ENUM(Direction) + + QQuickGeoCoordinateAnimation(QObject *parent=0); + ~QQuickGeoCoordinateAnimation(); + + QGeoCoordinate from() const; + void setFrom(const QGeoCoordinate &); + + QGeoCoordinate to() const; + void setTo(const QGeoCoordinate &); + + Direction direction() const; + void setDirection(Direction direction); + QBindable bindableDirection(); + +Q_SIGNALS: + void directionChanged(); +}; + +QVariant Q_POSITIONINGQUICK_PRIVATE_EXPORT q_coordinateInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress); + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickGeoCoordinateAnimation) + +#endif // QQUICKCOORDINATEANIMATION_P_H diff --git a/src/positioningquick/qquickgeocoordinateanimation_p_p.h b/src/positioningquick/qquickgeocoordinateanimation_p_p.h new file mode 100644 index 0000000..df06436 --- /dev/null +++ b/src/positioningquick/qquickgeocoordinateanimation_p_p.h @@ -0,0 +1,46 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QQUICKGEOCOORDINATEANIMATION_P_P_H +#define QQUICKGEOCOORDINATEANIMATION_P_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 "qquickgeocoordinateanimation_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class QQuickGeoCoordinateAnimationPrivate : public QQuickPropertyAnimationPrivate +{ + Q_DECLARE_PUBLIC(QQuickGeoCoordinateAnimation) +public: + void setDirection(QQuickGeoCoordinateAnimation::Direction direction) + { + q_func()->setDirection(direction); + } + void directionChanged() + { + Q_EMIT q_func()->directionChanged(); + } + + Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QQuickGeoCoordinateAnimationPrivate, + QQuickGeoCoordinateAnimation::Direction, m_direction, + &QQuickGeoCoordinateAnimationPrivate::setDirection, + &QQuickGeoCoordinateAnimationPrivate::directionChanged, + QQuickGeoCoordinateAnimation::Shortest) +}; + +QT_END_NAMESPACE + +#endif // QQUICKGEOCOORDINATEANIMATION_P_P_H diff --git a/sync.profile b/sync.profile new file mode 100644 index 0000000..8883d80 --- /dev/null +++ b/sync.profile @@ -0,0 +1,6 @@ +%modules = ( # path to module name map + "QtPositioning" => "$basedir/src/positioning", + "QtPositioningQuick" => "$basedir/src/positioningquick", +); +%moduleheaders = ( # restrict the module headers to those found in relative path +); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..2214137 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,7 @@ +# Generated from tests.pro. + +if(QT_BUILD_STANDALONE_TESTS) + # Add qt_find_package calls for extra dependencies that need to be found when building + # the standalone tests here. +endif() +qt_build_tests() diff --git a/tests/applications/positioning_backend/CMakeLists.txt b/tests/applications/positioning_backend/CMakeLists.txt new file mode 100644 index 0000000..0591cf2 --- /dev/null +++ b/tests/applications/positioning_backend/CMakeLists.txt @@ -0,0 +1,28 @@ +# Generated from positioning_backend.pro. + +##################################################################### +## posbackendtesting Binary: +##################################################################### + +qt_internal_add_executable(posbackendtesting + GUI + SOURCES + logwidget.cpp logwidget.h + main.cpp + widget.cpp widget.h widget.ui + PUBLIC_LIBRARIES + Qt::Gui + Qt::Positioning + Qt::Widgets + ENABLE_AUTOGEN_TOOLS + uic +) + +#### Keys ignored in scope 1:.:.:positioning_backend.pro:: +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +#### Keys ignored in scope 2:.:.:positioning_backend.pro:WINRT: +# WINRT_MANIFEST.capabilities_device = "location" diff --git a/tests/applications/positioning_backend/logwidget.cpp b/tests/applications/positioning_backend/logwidget.cpp new file mode 100644 index 0000000..3d6a1ec --- /dev/null +++ b/tests/applications/positioning_backend/logwidget.cpp @@ -0,0 +1,21 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "logwidget.h" +#include + +LogWidget::LogWidget(QWidget *parent) : QWidget(parent) +{ + QVBoxLayout *verticalLayout = new QVBoxLayout(this); + verticalLayout->setSpacing(6); + verticalLayout->setContentsMargins(11, 11, 11, 11); + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + + editor = new QPlainTextEdit(this); + verticalLayout->addWidget(editor); +} + +void LogWidget::appendLog(const QString &line) +{ + editor->appendPlainText(line); +} diff --git a/tests/applications/positioning_backend/logwidget.h b/tests/applications/positioning_backend/logwidget.h new file mode 100644 index 0000000..8f3b32c --- /dev/null +++ b/tests/applications/positioning_backend/logwidget.h @@ -0,0 +1,22 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef LOGWIDGET_H +#define LOGWIDGET_H + +#include +#include + +class LogWidget : public QWidget +{ + Q_OBJECT +public: + explicit LogWidget(QWidget *parent = nullptr); + + void appendLog(const QString &line); + +private: + QPlainTextEdit *editor; +}; + +#endif // LOGWIDGET_H diff --git a/tests/applications/positioning_backend/main.cpp b/tests/applications/positioning_backend/main.cpp new file mode 100644 index 0000000..69f4932 --- /dev/null +++ b/tests/applications/positioning_backend/main.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "widget.h" +#include "logwidget.h" +#include + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + //QLoggingCategory::setFilterRules("qt.positioning.*=true"); + QApplication a(argc, argv); + + LogWidget *log = new LogWidget; + Widget *w1 = new Widget(log); + Widget *w2 = new Widget(log); + + QTabWidget tabWidget; + tabWidget.setTabPosition(QTabWidget::South); + + tabWidget.addTab(w1, "Instance 1"); + tabWidget.addTab(w2, "Instance 2"); + tabWidget.addTab(log, "Logs"); + + tabWidget.show(); + return a.exec(); +} diff --git a/tests/applications/positioning_backend/widget.cpp b/tests/applications/positioning_backend/widget.cpp new file mode 100644 index 0000000..196b411 --- /dev/null +++ b/tests/applications/positioning_backend/widget.cpp @@ -0,0 +1,163 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "widget.h" +#include "ui_widget.h" +#include +#include + +Widget::Widget(LogWidget *logWidget, QWidget *parent) : + QWidget(parent), + log(logWidget), + ui(new Ui::Widget) +{ + ui->setupUi(this); + qDebug() << "Available:" << QGeoPositionInfoSource::availableSources(); + m_posSource = QGeoPositionInfoSource::createDefaultSource(this); + if (!m_posSource) + qFatal("No Position Source created!"); + connect(m_posSource, SIGNAL(positionUpdated(QGeoPositionInfo)), + this, SLOT(positionUpdated(QGeoPositionInfo))); + + connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), + this, SLOT(setInterval(int))); + + ui->groupBox->setLayout(ui->gridLayout); + ui->horizontalSlider->setMinimum(m_posSource->minimumUpdateInterval()); + ui->labelTimeOut->setVisible(false); + + connect(m_posSource, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error)), + this, SLOT(errorChanged(QGeoPositionInfoSource::Error))); + connect(m_posSource, &QGeoPositionInfoSource::supportedPositioningMethodsChanged, + this, [this]() { + auto methods = m_posSource->supportedPositioningMethods(); + const QString status = QStringLiteral("Satellite: %1 ").arg(bool(methods & QGeoPositionInfoSource::SatellitePositioningMethods)) + + QStringLiteral("Non-Satellite: %1").arg(bool(methods & QGeoPositionInfoSource::NonSatellitePositioningMethods)); + + qDebug() << "Available Positioning Methods Changed" << status; + log->appendLog(status); + }); +} + +void Widget::positionUpdated(QGeoPositionInfo gpsPos) +{ + QGeoCoordinate coord = gpsPos.coordinate(); + ui->labelLatitude->setText(QString::number(coord.latitude())); + ui->labelLongitude->setText(QString::number(coord.longitude())); + ui->labelAltitude->setText(QString::number(coord.altitude())); + ui->labelTimeStamp->setText(gpsPos.timestamp().toString()); + if (gpsPos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) + ui->labelHAccuracy->setText(QString::number(gpsPos.attribute(QGeoPositionInfo::HorizontalAccuracy))); + else + ui->labelHAccuracy->setText(QStringLiteral("N/A")); + + if (gpsPos.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) + ui->labelVAccuracy->setText(QString::number(gpsPos.attribute(QGeoPositionInfo::VerticalAccuracy))); + else + ui->labelVAccuracy->setText(QStringLiteral("N/A")); + + if (gpsPos.hasAttribute(QGeoPositionInfo::Direction)) + ui->labelDirection->setText(QString::number(gpsPos.attribute(QGeoPositionInfo::Direction))); + else + ui->labelDirection->setText(QStringLiteral("N/A")); + + if (gpsPos.hasAttribute(QGeoPositionInfo::GroundSpeed)) + ui->labelSpeed->setText(QString::number(gpsPos.attribute(QGeoPositionInfo::GroundSpeed))); + else + ui->labelSpeed->setText(QStringLiteral("N/A")); + + log->appendLog(coord.toString()); +} + +void Widget::positionTimedOut() +{ + ui->labelTimeOut->setVisible(true); +} + +void Widget::errorChanged(QGeoPositionInfoSource::Error err) +{ + if (err == QGeoPositionInfoSource::UpdateTimeoutError) { + // handle timeout + positionTimedOut(); + } else { + // handle other errors + ui->labelErrorState->setText(QString::number(err)); + m_posSource->stopUpdates(); + ui->checkBox->setChecked(false); + } +} + +Widget::~Widget() +{ + delete ui; +} + +void Widget::setInterval(int msec) +{ + m_posSource->setUpdateInterval(msec); +} + +void Widget::on_buttonRetrieve_clicked() +{ + // Requesting current position for _one_ time + m_posSource->requestUpdate(10000); +} + +void Widget::on_buttonStart_clicked() +{ + // Either start or stop the current position info source + bool running = ui->checkBox->isChecked(); + if (running) { + ui->checkBox->setChecked(false); + m_posSource->stopUpdates(); + } else { + ui->checkBox->setChecked(true); + m_posSource->startUpdates(); + } +} + +void Widget::on_radioButton_clicked() +{ + m_posSource->setPreferredPositioningMethods(QGeoPositionInfoSource::NoPositioningMethods); +} + +void Widget::on_radioButton_2_clicked() +{ + m_posSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods); +} + +void Widget::on_radioButton_3_clicked() +{ + m_posSource->setPreferredPositioningMethods(QGeoPositionInfoSource::NonSatellitePositioningMethods); +} + +void Widget::on_radioButton_4_clicked() +{ + m_posSource->setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods); +} + +void Widget::on_buttonUpdateSupported_clicked() +{ + QGeoPositionInfoSource::PositioningMethods m = m_posSource->supportedPositioningMethods(); + QString text; + switch (m) { + case QGeoPositionInfoSource::NoPositioningMethods: + text = QStringLiteral("None"); + break; + case QGeoPositionInfoSource::SatellitePositioningMethods: + text = QStringLiteral("Satellite"); + break; + case QGeoPositionInfoSource::NonSatellitePositioningMethods: + text = QStringLiteral("Non Satellite"); + break; + case QGeoPositionInfoSource::AllPositioningMethods: + text = QStringLiteral("All"); + break; + } + + ui->labelSupported->setText(text); +} + +void Widget::on_buttonResetError_clicked() +{ + ui->labelErrorState->setText(QStringLiteral("N/A")); +} diff --git a/tests/applications/positioning_backend/widget.h b/tests/applications/positioning_backend/widget.h new file mode 100644 index 0000000..bc2d0fe --- /dev/null +++ b/tests/applications/positioning_backend/widget.h @@ -0,0 +1,45 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#ifndef WIDGET_H +#define WIDGET_H + +#include "logwidget.h" + +#include +#include + +namespace Ui { + class Widget; +} + +class Widget : public QWidget +{ + Q_OBJECT + +public: + explicit Widget(LogWidget *log, QWidget *parent = nullptr); + ~Widget(); + +public slots: + void positionUpdated(QGeoPositionInfo gpsPos); + void setInterval(int msec); + void positionTimedOut(); + void errorChanged(QGeoPositionInfoSource::Error err); +private slots: + void on_buttonRetrieve_clicked(); + void on_buttonStart_clicked(); + void on_radioButton_2_clicked(); + void on_radioButton_clicked(); + void on_radioButton_3_clicked(); + void on_radioButton_4_clicked(); + + void on_buttonUpdateSupported_clicked(); + void on_buttonResetError_clicked(); + +private: + LogWidget *log = nullptr; + Ui::Widget *ui; + QGeoPositionInfoSource *m_posSource; +}; + +#endif // WIDGET_H diff --git a/tests/applications/positioning_backend/widget.ui b/tests/applications/positioning_backend/widget.ui new file mode 100644 index 0000000..9cb1566 --- /dev/null +++ b/tests/applications/positioning_backend/widget.ui @@ -0,0 +1,334 @@ + + + Widget + + + + 0 + 0 + 276 + 467 + + + + Widget + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Latitude: + + + + + + + N/A + + + + + + + Longitude: + + + + + + + N/A + + + + + + + Altitude: + + + + + + + N/A + + + + + + + TimeStamp: + + + + + + + N/A + + + + + + + Horizontal Accuracy: + + + + + + + N/A + + + + + + + Vertical Accuracy: + + + + + + + N/A + + + + + + + TimeOut: + + + + + + + true + + + !!!!!TimeOut!!!!! + + + + + + + Supported Methods: + + + + + + + Error State: + + + + + + + + + N/A + + + + + + + Reset + + + + + + + + + + + N/A + + + + + + + Update + + + + + + + + + Direction: + + + + + + + N/A + + + + + + + Speed: + + + + + + + N/A + + + + + + + + + Method + + + + + 43 + 21 + 254 + 71 + + + + + + + None + + + + + + + Satelite + + + true + + + + + + + Non-Satelite + + + + + + + All + + + + + + + + + + + + + Interval: + + + + + + + 50 + + + 10000 + + + Qt::Horizontal + + + + + + + 0 + + + + + + + + + false + + + Running + + + + + + + + + Start/Stop + + + + + + + Retrieve + + + + + + + + + + + + horizontalSlider + valueChanged(int) + labelInterval + setNum(int) + + + 217 + 137 + + + 386 + 138 + + + + + diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt new file mode 100644 index 0000000..6a4e45c --- /dev/null +++ b/tests/auto/CMakeLists.txt @@ -0,0 +1,35 @@ +# Generated from auto.pro. + +add_subdirectory(doublevectors) +add_subdirectory(qgeoaddress) +add_subdirectory(qgeoshape) +add_subdirectory(qgeorectangle) +add_subdirectory(qgeocircle) +add_subdirectory(qgeopath) +add_subdirectory(qgeopolygon) +add_subdirectory(qgeocoordinate) +add_subdirectory(qgeocoordinateobject) +add_subdirectory(qgeolocation) +add_subdirectory(qgeopositioninfo) +add_subdirectory(qgeosatelliteinfo) +add_subdirectory(qgeosatelliteinfosource) +add_subdirectory(qnmeasatelliteinfosource) +add_subdirectory(cmake) +if (QT6_IS_SHARED_LIBS_BUILD) + add_subdirectory(positionplugin) + add_subdirectory(positionplugintest) + add_subdirectory(qgeoareamonitor) + add_subdirectory(qgeopositioninfosource) + add_subdirectory(qnmeapositioninfosource) +endif() +if(TARGET Qt::Quick) + add_subdirectory(qdeclarativegeolocation) + add_subdirectory(qdeclarativeposition) + add_subdirectory(qquickgeocoordinateanimation) + if (QT6_IS_SHARED_LIBS_BUILD) + add_subdirectory(dummypositionplugin) + add_subdirectory(declarative_positioning_core) + add_subdirectory(qdeclarativepositionsource) + add_subdirectory(declarative_geolocation) + endif() +endif() diff --git a/tests/auto/bic/data/QtPositioning.5.10.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.10.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..cd57ca0 --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.10.0.linux-gcc-amd64.txt @@ -0,0 +1,4773 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f13e8ed68a0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f13e8fad060) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f13e8fad2a0) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f13e8fad4e0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f13e8fad720) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f13e8fad8a0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f13e8fadc60) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f13e6c69420) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f13e6c694e0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f13e6c69840) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f13e6c69900) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f13e6c699c0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f13e6c69a80) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f13e6c69d20) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f13e6c69f00) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f13e6cdb3c0) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f13e6cdb420) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f13e6d4f0c0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f13e6d4f120) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f13e6cac208) 0 empty + std::input_iterator_tag (0x0x7f13e6d4f180) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f13e6cac270) 0 empty + std::forward_iterator_tag (0x0x7f13e6cac2d8) 0 empty + std::input_iterator_tag (0x0x7f13e6d4f1e0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f13e6cac340) 0 empty + std::bidirectional_iterator_tag (0x0x7f13e6cac3a8) 0 empty + std::forward_iterator_tag (0x0x7f13e6cac410) 0 empty + std::input_iterator_tag (0x0x7f13e6d4f240) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f13e6d4fea0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f13e6d4ff00) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f13e6d4ff60) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f13e6a0b000) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f13e6a0b060) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f13e6a0bb40) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f13e6a0bd80) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f13e6a0be40) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f13e6a0bea0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f13e6a0bf60) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f13e6abf000) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f13e6abf480) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f13e6abf4e0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f13e6abf540) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f13e6cac958) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f13e6abf5a0) 0 nearly-empty + primary-for std::bad_exception (0x0x7f13e6cac958) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f13e6abf600) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f13e6abf660) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f13e6cacb60) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f13e6abfa80) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f13e6cacb60) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f13e6cacbc8) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f13e6cacc30) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f13e6cacbc8) + std::exception (0x0x7f13e6abfae0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f13e6cacc30) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f13e6abfb40) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f13e6839780) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f13e663c480) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f13e663c4e0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f13e66e13c0) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f13e66e1420) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f13e66e14e0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f13e66e1540) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f13e66e15a0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f13e66e1600) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f13e66e1720) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f13e66e1780) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f13e66e1ba0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f13e66e1c00) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f13e6219420) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f13e6219480) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f13e62d3420) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f13e608a240) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f13e623d9c0) 0 + std::iterator (0x0x7f13e608a300) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f13e623da28) 0 + std::_Bit_iterator_base (0x0x7f13e623da90) 0 + std::iterator (0x0x7f13e608a360) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f13e623daf8) 0 + std::_Bit_iterator_base (0x0x7f13e623db60) 0 + std::iterator (0x0x7f13e608a3c0) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f13e5e9a1e0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f13e5e9af60) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f13e5e9af00) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f13e5c01f00) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f13e4bcea20) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f13e4bcea80) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f13e490c540) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f13e490c5a0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f13e490c600) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f13e490c660) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f13e490c900) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f13e490ce40) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f13e4907888) 0 + std::__atomic_flag_base (0x0x7f13e490cea0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f13e4584000) 0 + QAtomicInteger (0x0x7f13e4584068) 0 + QBasicAtomicInteger (0x0x7f13e44b5600) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f13e435eba0) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f13e417cc00) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f13e417cd20) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f13e4362a90) 0 + QGenericArgument (0x0x7f13e417cd80) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f13e417cf00) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f13e3e1f000) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f13e3ea1060) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f13e3ea10c0) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f13e3ea1360) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f13e3ea13c0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f13e3ea1720) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f13e3ea1780) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f13e3ea17e0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f13e3ea1840) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f13e3ea18a0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f13e3ea1c60) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f13e3c47000) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f13e3ea1d20) 0 nearly-empty + primary-for std::logic_error (0x0x7f13e3c47000) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f13e3c47068) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f13e3c470d0) 0 + primary-for std::domain_error (0x0x7f13e3c47068) + std::exception (0x0x7f13e3ea1d80) 0 nearly-empty + primary-for std::logic_error (0x0x7f13e3c470d0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f13e3c47138) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f13e3c471a0) 0 + primary-for std::invalid_argument (0x0x7f13e3c47138) + std::exception (0x0x7f13e3ea1de0) 0 nearly-empty + primary-for std::logic_error (0x0x7f13e3c471a0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f13e3c47208) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f13e3c47270) 0 + primary-for std::length_error (0x0x7f13e3c47208) + std::exception (0x0x7f13e3ea1e40) 0 nearly-empty + primary-for std::logic_error (0x0x7f13e3c47270) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f13e3c472d8) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f13e3c47340) 0 + primary-for std::out_of_range (0x0x7f13e3c472d8) + std::exception (0x0x7f13e3ea1ea0) 0 nearly-empty + primary-for std::logic_error (0x0x7f13e3c47340) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f13e3c473a8) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f13e3ea1f00) 0 nearly-empty + primary-for std::runtime_error (0x0x7f13e3c473a8) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f13e3c47410) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f13e3c47478) 0 + primary-for std::range_error (0x0x7f13e3c47410) + std::exception (0x0x7f13e3ea1f60) 0 nearly-empty + primary-for std::runtime_error (0x0x7f13e3c47478) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f13e3c474e0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f13e3c47548) 0 + primary-for std::overflow_error (0x0x7f13e3c474e0) + std::exception (0x0x7f13e3c65000) 0 nearly-empty + primary-for std::runtime_error (0x0x7f13e3c47548) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f13e3c475b0) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f13e3c47618) 0 + primary-for std::underflow_error (0x0x7f13e3c475b0) + std::exception (0x0x7f13e3c65060) 0 nearly-empty + primary-for std::runtime_error (0x0x7f13e3c47618) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f13e3c651e0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f13e3c65420) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f13e3c655a0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f13e3c47af8) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f13e3c47b60) 0 + primary-for std::system_error (0x0x7f13e3c47af8) + std::exception (0x0x7f13e3c657e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f13e3c47b60) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f13e3ccc750) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f13e3ccc7b8) 0 + primary-for std::ios_base::failure (0x0x7f13e3ccc750) + std::runtime_error (0x0x7f13e3ccc820) 0 + primary-for std::system_error (0x0x7f13e3ccc7b8) + std::exception (0x0x7f13e3c65ae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f13e3ccc820) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f13e3c65b40) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f13e3c65ba0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f13e3c65c00) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f13e3c65a80) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f13e3da43c0) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f13e3da4a80) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f13e399b0d0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f13e399b1a0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f13e399b548 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f13e399b618 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f13e3950300) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f13e3950360) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f13e36d76c0) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f13e36d7a20) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f13e36d7ea0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f13e340ad20) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f13e34983c0) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f13e3498360) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f13e323c480) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f13e2fec0c0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f13e2feccc0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f13e2fecd20) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f13e2fecd80) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f13e2dde180) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f13e2dde1e0) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f13e2df4068) 0 empty + QListData::NotIndirectLayout (0x0x7f13e2dde240) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f13e2e75620) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f13e2dde2a0) 0 empty + QListData::NotIndirectLayout (0x0x7f13e2dde300) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f13e2df40d0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f13e2dde360) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f13e2dde3c0) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f13e2dde120) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f13e2dde840) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f13e2c21a80) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f13e2c21a20) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f13e2c22af8) 0 + QList (0x0x7f13e2c22b60) 0 + QListSpecialMethods (0x0x7f13e2c21c60) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f13e2cbe0c0) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f13e2cbeba0) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f13e2a9b240) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f13e2a9b3c0) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f13e2a9b480) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f13e2d61340) 0 + std::__uses_alloc_base (0x0x7f13e2a9b420) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f13e2bae4e0) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f13e2bae720) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f13e2bae7e0) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f13e2bae900) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f13e2baea80) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f13e2baeea0) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f13e2906000) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f13e2906960) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f13e2906d80) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f13e25e30c0) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f13e23f6900) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f13e2557780) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f13e25577e0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f13e25579c0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f13e2557960) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f13e221ec60) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f13e221ecc0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f13e221ed80) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f13e224a680) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f13e221ed20) 0 + primary-for QAbstractAnimation (0x0x7f13e224a680) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f13e221ee40) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f13e224a6e8) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f13e221ede0) 0 + primary-for QAnimationDriver (0x0x7f13e224a6e8) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f13e221ef00) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f13e224a750) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f13e221eea0) 0 + primary-for QEventLoop (0x0x7f13e224a750) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f13e22a8120) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f13e22a81e0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f13e22a8240) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f13e224a888) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f13e22a8180) 0 + primary-for QAbstractEventDispatcher (0x0x7f13e224a888) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f13e22a84e0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f13e224aa90) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f13e22a8540) 0 nearly-empty + primary-for std::bad_cast (0x0x7f13e224aa90) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f13e224aaf8) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f13e22a85a0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f13e224aaf8) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f13e1fa4d68) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f13e206c660) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f13e1fa4d68) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f13e206c720) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f13e206c780) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f13e206c8a0) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f13e206cd80) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f13e2121300) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f13e21216c0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f13e2121660) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f13e2121720) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f13e1f5a000) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f13e1f5a0c0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f13e1f5a060) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f13e1f5a120) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f13e2121f60) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f13e1bfdc00) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f13e1ca32a0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f13e1ca3240) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f13e1ca3360) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f13e1ca3300) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f13e19bf660) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f13e19bfd20) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f13e1b97480) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f13e1b88af8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f13e1b97420) 0 + primary-for QAbstractItemModel (0x0x7f13e1b88af8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f13e1b977e0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f13e1b88d00) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f13e1b88d68) 0 + primary-for QAbstractTableModel (0x0x7f13e1b88d00) + QObject (0x0x7f13e1b97780) 0 + primary-for QAbstractItemModel (0x0x7f13e1b88d68) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f13e1b978a0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f13e1b88dd0) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f13e1b88e38) 0 + primary-for QAbstractListModel (0x0x7f13e1b88dd0) + QObject (0x0x7f13e1b97840) 0 + primary-for QAbstractItemModel (0x0x7f13e1b88e38) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f13e1b97b40) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f13e1b97c00) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f13e1b88f70) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f13e189e000) 0 + primary-for QAbstractProxyModel (0x0x7f13e1b88f70) + QObject (0x0x7f13e1b97ba0) 0 + primary-for QAbstractItemModel (0x0x7f13e189e000) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f13e1b97cc0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f13e189e068) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f13e1b97c60) 0 + primary-for QAbstractState (0x0x7f13e189e068) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f13e1b97d80) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f13e189e0d0) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f13e1b97d20) 0 + primary-for QAbstractTransition (0x0x7f13e189e0d0) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f13e1b97e40) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f13e189e138) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f13e189e1a0) 0 + primary-for QAnimationGroup (0x0x7f13e189e138) + QObject (0x0x7f13e1b97de0) 0 + primary-for QAbstractAnimation (0x0x7f13e189e1a0) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f13e190bba0) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f13e190be40) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f13e190bf00) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f13e15a2240) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f13e189e820) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f13e15a21e0) 0 + primary-for QIODevice (0x0x7f13e189e820) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f13e15a2480) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f13e189e958) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f13e189e9c0) 0 + primary-for QBuffer (0x0x7f13e189e958) + QObject (0x0x7f13e15a2420) 0 + primary-for QIODevice (0x0x7f13e189e9c0) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f13e15a2540) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f13e15a24e0) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f13e15a2660) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f13e15a2600) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f13e15a2840) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f13e15a2a20) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f13e173d060) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f13e173d120) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f13e13bb120) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f13e13bb5a0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f13e13a3ea0) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f13e13bb600) 0 + primary-for QTimerEvent (0x0x7f13e13a3ea0) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f13e13a3f08) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f13e13bb660) 0 + primary-for QChildEvent (0x0x7f13e13a3f08) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f13e142d478) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f13e13bbb40) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f13e142d478) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f13e142d4e0) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f13e13bbba0) 0 + primary-for QDeferredDeleteEvent (0x0x7f13e142d4e0) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f13e13bbc60) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f13e142d548) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f13e13bbc00) 0 + primary-for QCoreApplication (0x0x7f13e142d548) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f13e13bbcc0) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f13e13bbd20) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f13e1493360) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f13e14933c0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f13e1493480) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f13e1493960) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f13e1493c00) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f13e11763c0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f13e1176420) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f13e1176360) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f13e1225540) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f13e1225a20) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f13e13499c0) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f13e1349c60) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f13e1349ea0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f13e107f060) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f13e107f5a0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f13e107f540) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f13e0de5a80) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f13e0de5b40) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f13e0eb6cc0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f13e0ed1410) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f13e0ed1478) 0 + primary-for QFileDevice (0x0x7f13e0ed1410) + QObject (0x0x7f13e0eb6c60) 0 + primary-for QIODevice (0x0x7f13e0ed1478) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f13e0eb6f00) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f13e0ed15b0) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f13e0ed1618) 0 + primary-for QFile (0x0x7f13e0ed15b0) + QIODevice (0x0x7f13e0ed1680) 0 + primary-for QFileDevice (0x0x7f13e0ed1618) + QObject (0x0x7f13e0eb6ea0) 0 + primary-for QIODevice (0x0x7f13e0ed1680) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f13e0f3f120) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f13e0f3f540) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f13e0f3ff00) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f13e0c33180) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f13e0cea5a0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f13e0ce28f0) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f13e0ce2958) 0 + primary-for QEventTransition (0x0x7f13e0ce28f0) + QObject (0x0x7f13e0cea540) 0 + primary-for QAbstractTransition (0x0x7f13e0ce2958) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f13e0ce29c0) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f13e0cea600) 0 nearly-empty + primary-for QException (0x0x7f13e0ce29c0) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f13e0ce2a28) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f13e0ce2a90) 0 nearly-empty + primary-for QUnhandledException (0x0x7f13e0ce2a28) + std::exception (0x0x7f13e0cea660) 0 nearly-empty + primary-for QException (0x0x7f13e0ce2a90) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f13e0cea6c0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f13e0cea780) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f13e0cea7e0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f13e0cea900) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f13e0ce2af8) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f13e0cea8a0) 0 + primary-for QFileSelector (0x0x7f13e0ce2af8) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f13e0cea9c0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f13e0ce2b60) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f13e0cea960) 0 + primary-for QFileSystemWatcher (0x0x7f13e0ce2b60) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f13e0ceaa80) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f13e0ce2bc8) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f13e0ce2c30) 0 + primary-for QFinalState (0x0x7f13e0ce2bc8) + QObject (0x0x7f13e0ceaa20) 0 + primary-for QAbstractState (0x0x7f13e0ce2c30) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f13e0ceaae0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f13e0ceab40) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f13e0ce2d68) 0 + QBasicMutex (0x0x7f13e0cead20) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f13e0cead80) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f13e0ceade0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f13e0ceae40) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f13e0ceaf60) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f13e0a6d7e0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f13e0b1f000) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f13e0a72ea0) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f13e0a6df60) 0 + primary-for QFutureWatcherBase (0x0x7f13e0a72ea0) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f13e0b1f600) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f13e0b317b8) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f13e0b31820) 0 + primary-for QHistoryState (0x0x7f13e0b317b8) + QObject (0x0x7f13e0b1f5a0) 0 + primary-for QAbstractState (0x0x7f13e0b31820) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f13e0b1f6c0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f13e0b31888) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f13e0b318f0) 0 + primary-for QIdentityProxyModel (0x0x7f13e0b31888) + QAbstractItemModel (0x0x7f13e0b31958) 0 + primary-for QAbstractProxyModel (0x0x7f13e0b318f0) + QObject (0x0x7f13e0b1f660) 0 + primary-for QAbstractItemModel (0x0x7f13e0b31958) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f13e0b1f720) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f13e0b1fde0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f13e07ce1a0) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f13e0b1fd80) 0 + primary-for QItemSelectionModel (0x0x7f13e07ce1a0) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f13e07ce3a8) 0 + QList (0x0x7f13e07ce410) 0 + QListSpecialMethods (0x0x7f13e0817120) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f13e0817600) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f13e05b3d20) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f13e061c2a0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f13e061c300) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f13e061c4e0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f13e061c540) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f13e061c480) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f13e06de780) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f13e06de7e0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f13e06dee40) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f13e06deea0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f13e06dede0) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f13e041f180) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f13e03e5750) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f13e041f120) 0 + primary-for QLibrary (0x0x7f13e03e5750) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f13e041f840) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f13e041f360) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f13e041fd20) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f13e041fd80) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f13e04f6060) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f13e04f6300) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f13e04f6c60) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f13e01b2600) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f13e01b2960) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f13e01b2ae0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f13e01b2a80) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f13e01b2c60) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f13e01b2f00) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f13dff3c5a0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f13dff3c600) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f13dff3cc00) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f13dff3cf00) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f13dff3cf60) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f13dfff32a0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f13dff5e9c0) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f13dfff3240) 0 + primary-for QMimeData (0x0x7f13dff5e9c0) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f13dfff3300) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f13dfff3600) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f13dfff36c0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f13dff5ebc8) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f13dfff3660) 0 + primary-for QObjectCleanupHandler (0x0x7f13dff5ebc8) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f13dfff3720) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f13dfff3ea0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f13e005b2d8) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f13e005b340) 0 + primary-for QParallelAnimationGroup (0x0x7f13e005b2d8) + QAbstractAnimation (0x0x7f13e005b3a8) 0 + primary-for QAnimationGroup (0x0x7f13e005b340) + QObject (0x0x7f13dfff3e40) 0 + primary-for QAbstractAnimation (0x0x7f13e005b3a8) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f13dfff3f60) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f13e005b410) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f13e005b478) 0 + primary-for QPauseAnimation (0x0x7f13e005b410) + QObject (0x0x7f13dfff3f00) 0 + primary-for QAbstractAnimation (0x0x7f13e005b478) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f13e008f180) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f13e008f480) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f13e005b680) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f13e008f420) 0 + primary-for QPluginLoader (0x0x7f13e005b680) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f13e008f4e0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f13e008fba0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f13e005bd00) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f13e005bd68) 0 + primary-for QProcess (0x0x7f13e005bd00) + QObject (0x0x7f13e008fb40) 0 + primary-for QIODevice (0x0x7f13e005bd68) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f13e008fc60) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f13e005bdd0) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f13e005be38) 0 + primary-for QVariantAnimation (0x0x7f13e005bdd0) + QObject (0x0x7f13e008fc00) 0 + primary-for QAbstractAnimation (0x0x7f13e005be38) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f13e008fd20) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f13e005bf08) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f13e005bf70) 0 + primary-for QPropertyAnimation (0x0x7f13e005bf08) + QAbstractAnimation (0x0x7f13dfd33000) 0 + primary-for QVariantAnimation (0x0x7f13e005bf70) + QObject (0x0x7f13e008fcc0) 0 + primary-for QAbstractAnimation (0x0x7f13dfd33000) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f13e008fe40) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f13e008fde0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f13dfdd12d8) 0 + QRandomGenerator (0x0x7f13dfda8de0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f13dfda8ea0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f13dfe34180) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f13dfe34240) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f13dfe34300) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f13dfe345a0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f13dfe34840) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f13dfe34ae0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f13dfe34d80) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f13dfc563c0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f13dfc566c0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f13dfc569c0) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f13dfc56b40) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f13dfc754e0) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f13dfc75548) 0 + primary-for QSaveFile (0x0x7f13dfc754e0) + QIODevice (0x0x7f13dfc755b0) 0 + primary-for QFileDevice (0x0x7f13dfc75548) + QObject (0x0x7f13dfc56ae0) 0 + primary-for QIODevice (0x0x7f13dfc755b0) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f13dfc56c00) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f13dfc56c60) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f13df9f32a0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f13df9d8dd0) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f13df9d8e38) 0 + primary-for QSequentialAnimationGroup (0x0x7f13df9d8dd0) + QAbstractAnimation (0x0x7f13df9d8ea0) 0 + primary-for QAnimationGroup (0x0x7f13df9d8e38) + QObject (0x0x7f13df9f3240) 0 + primary-for QAbstractAnimation (0x0x7f13df9d8ea0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f13df9f3360) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f13df9d8f08) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f13df9f3300) 0 + primary-for QSettings (0x0x7f13df9d8f08) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f13df9f3420) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f13df9d8f70) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f13df9f33c0) 0 + primary-for QSharedMemory (0x0x7f13df9d8f70) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f13df9f34e0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f13dfa42000) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f13df9f3480) 0 + primary-for QSignalMapper (0x0x7f13dfa42000) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f13df9f35a0) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f13dfa42068) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f13dfa420d0) 0 + primary-for QSignalTransition (0x0x7f13dfa42068) + QObject (0x0x7f13df9f3540) 0 + primary-for QAbstractTransition (0x0x7f13dfa420d0) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f13df9f3660) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f13dfa42138) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f13df9f3600) 0 + primary-for QSocketNotifier (0x0x7f13dfa42138) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f13df9f3720) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f13dfa421a0) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f13dfa42208) 0 + primary-for QSortFilterProxyModel (0x0x7f13dfa421a0) + QAbstractItemModel (0x0x7f13dfa42270) 0 + primary-for QAbstractProxyModel (0x0x7f13dfa42208) + QObject (0x0x7f13df9f36c0) 0 + primary-for QAbstractItemModel (0x0x7f13dfa42270) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f13df9f37e0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f13df9f3a20) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f13dfa42410) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f13dfa42478) 0 + primary-for QState (0x0x7f13dfa42410) + QObject (0x0x7f13df9f39c0) 0 + primary-for QAbstractState (0x0x7f13dfa42478) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f13df9f3b40) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f13dfa42618) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f13df9f3ba0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f13dfa42618) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f13dfa42680) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f13df9f3c00) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f13dfa42680) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f13dfa424e0) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f13dfa42548) 0 + primary-for QStateMachine (0x0x7f13dfa424e0) + QAbstractState (0x0x7f13dfa425b0) 0 + primary-for QState (0x0x7f13dfa42548) + QObject (0x0x7f13df9f3ae0) 0 + primary-for QAbstractState (0x0x7f13dfa425b0) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f13df9f3c60) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f13df73dba0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f13df79a6c0) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f13df75db60) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f13df75dbc8) 0 + primary-for QStringListModel (0x0x7f13df75db60) + QAbstractItemModel (0x0x7f13df75dc30) 0 + primary-for QAbstractListModel (0x0x7f13df75dbc8) + QObject (0x0x7f13df79a660) 0 + primary-for QAbstractItemModel (0x0x7f13df75dc30) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f13df79a720) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f13df79a7e0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f13df79a900) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f13df75dc98) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f13df75dd00) 0 + primary-for QTemporaryFile (0x0x7f13df75dc98) + QFileDevice (0x0x7f13df75dd68) 0 + primary-for QFile (0x0x7f13df75dd00) + QIODevice (0x0x7f13df75ddd0) 0 + primary-for QFileDevice (0x0x7f13df75dd68) + QObject (0x0x7f13df79a8a0) 0 + primary-for QIODevice (0x0x7f13df75ddd0) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f13df79a960) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f13df79aba0) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f13df79ab40) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f13df79ad80) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f13df79ade0) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f13df79ae40) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f13df79aea0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f13df8bc000) 0 + std::__mutex_base (0x0x7f13df79af00) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f13df8bc068) 0 + std::__recursive_mutex_base (0x0x7f13df79af60) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f13df8d2460) 0 + std::__mutex_base (0x0x7f13df8cf0c0) 0 + std::__timed_mutex_impl (0x0x7f13df8cf120) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f13df8e80e0) 0 + std::__recursive_mutex_base (0x0x7f13df8cf1e0) 0 + std::__timed_mutex_impl (0x0x7f13df8cf240) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f13df8cf2a0) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f13df8cf300) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f13df8cf360) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f13df8cf5a0) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f13df8bc1a0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f13df8cf660) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f13df8bc1a0) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f13df8bc208) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f13df8cf720) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f13df8bc208) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f13df8bc270) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f13df8cf7e0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f13df8bc270) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f13df8bc340) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f13df8cf8a0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f13df8bc340) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f13df8cf960) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f13df8cf9c0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f13df8cfa20) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f13df8cfa80) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f13df8bc618) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f13df8cfde0) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f13df8bc618) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f13df619660) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f13df619e40) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f13df2a9060) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f13df2a90c0) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f13df2a9000) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f13df3e0cc0) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f13df3e0d80) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f13df3e0de0) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f13df0cd480) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f13df0ca958) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f13df0ca9c0) 0 + primary-for std::future_error (0x0x7f13df0ca958) + std::exception (0x0x7f13df0cd5a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f13df0ca9c0) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f13df0cd6c0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f13df0cd660) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f13df228c00) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f13df162f70) 0 + std::__at_thread_exit_elt (0x0x7f13df228cc0) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f13df0cd840) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f13df0cd600) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f13deb7ab60) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f13deb75ba0) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f13deb7ab60) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f13debda300) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f13debd9618) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f13debda2a0) 0 + primary-for QThread (0x0x7f13debd9618) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f13debda420) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f13debd9680) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f13debda3c0) 0 + primary-for QThreadPool (0x0x7f13debd9680) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f13debda480) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f13debda5a0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f13debd96e8) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f13debda540) 0 + primary-for QTimeLine (0x0x7f13debd96e8) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f13debda660) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f13debd9750) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f13debda600) 0 + primary-for QTimer (0x0x7f13debd9750) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f13debdad20) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f13debdacc0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f13de8c1300) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f13de8c81a0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f13de8c12a0) 0 + primary-for QTranslator (0x0x7f13de8c81a0) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f13de8c1420) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f13de9daae0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f13de670180) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f13de670780) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f13de6707e0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f13de670ae0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f13de699c98) 0 + QVector (0x0x7f13de670ea0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f13de670f00) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f13de7671e0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f13de767480) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f13de767720) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f13de767780) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f13de4121e0) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7f13de412300) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7f13de412a80) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7f13de412ea0) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7f13de497360) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7f13de497420) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7f13de4974e0) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7f13de44d6e8) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7f13de497480) 0 + primary-for QGeoPositionInfoSource (0x0x7f13de44d6e8) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7f13de497720) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7f13de44d820) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7f13de4976c0) 0 + primary-for QGeoAreaMonitorSource (0x0x7f13de44d820) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7f13de44d888) 0 + QGeoShape (0x0x7f13de497780) 0 + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7f13de44db60) 0 + QGeoShape (0x0x7f13de497c60) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7f13de574060) 0 + +Class QGeoPath + size=8 align=8 + base size=8 base align=8 +QGeoPath (0x0x7f13de58e3a8) 0 + QGeoShape (0x0x7f13de5747e0) 0 + +Class QGeoPolygon + size=8 align=8 + base size=8 base align=8 +QGeoPolygon (0x0x7f13de58e5b0) 0 + QGeoShape (0x0x7f13de574ba0) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7f13de574f60) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7f13de5e4060) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7f13de58e7b8) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7f13de5e4000) 0 + primary-for QGeoSatelliteInfoSource (0x0x7f13de58e7b8) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7f13de5e4120) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7f13de5e4240) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7f13de58e820) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7f13de58e888) 0 + primary-for QNmeaPositionInfoSource (0x0x7f13de58e820) + QObject (0x0x7f13de5e41e0) 0 + primary-for QGeoPositionInfoSource (0x0x7f13de58e888) + diff --git a/tests/auto/bic/data/QtPositioning.5.11.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.11.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..0d9ef89 --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.11.0.linux-gcc-amd64.txt @@ -0,0 +1,4773 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f1d80fa6de0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f1d810875a0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f1d810877e0) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f1d81087a20) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f1d81087c60) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f1d81087de0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f1d7ec391e0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f1d7ecc0960) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f1d7ecc0a20) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f1d7ecc0d80) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f1d7ecc0e40) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f1d7ecc0f00) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f1d7ecf4000) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f1d7ecf42a0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f1d7ecf4480) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f1d7ecf4900) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f1d7ecf4960) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f1d7eda0600) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f1d7eda0660) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f1d7ed052d8) 0 empty + std::input_iterator_tag (0x0x7f1d7eda06c0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f1d7ed05340) 0 empty + std::forward_iterator_tag (0x0x7f1d7ed053a8) 0 empty + std::input_iterator_tag (0x0x7f1d7eda0720) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f1d7ed05410) 0 empty + std::bidirectional_iterator_tag (0x0x7f1d7ed05478) 0 empty + std::forward_iterator_tag (0x0x7f1d7ed054e0) 0 empty + std::input_iterator_tag (0x0x7f1d7eda0780) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f1d7ede6420) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f1d7ede6480) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f1d7ede64e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f1d7ede6540) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f1d7ede65a0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f1d7eaf60c0) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f1d7eaf6300) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f1d7eaf63c0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f1d7eaf6420) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f1d7eaf64e0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f1d7eaf6540) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f1d7eaf69c0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f1d7eaf6a20) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f1d7eaf6a80) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f1d7ed05a28) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f1d7eaf6ae0) 0 nearly-empty + primary-for std::bad_exception (0x0x7f1d7ed05a28) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f1d7eaf6b40) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f1d7eaf6ba0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f1d7ed05c30) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f1d7ec2c000) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f1d7ed05c30) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f1d7ed05c98) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f1d7ed05d00) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f1d7ed05c98) + std::exception (0x0x7f1d7ec2c060) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f1d7ed05d00) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f1d7ec2c0c0) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f1d7ec2ccc0) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f1d7ea299c0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f1d7ea29a20) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f1d7e733900) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f1d7e733960) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f1d7e733a20) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f1d7e733a80) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f1d7e733ae0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f1d7e733b40) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f1d7e733c60) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f1d7e733cc0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f1d7e49a120) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f1d7e49a180) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f1d7e291960) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f1d7e2919c0) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f1d7e2c5960) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f1d7e0b9780) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f1d7e2bfa90) 0 + std::iterator (0x0x7f1d7e0b9840) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f1d7e2bfaf8) 0 + std::_Bit_iterator_base (0x0x7f1d7e2bfb60) 0 + std::iterator (0x0x7f1d7e0b98a0) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f1d7e2bfbc8) 0 + std::_Bit_iterator_base (0x0x7f1d7e2bfc30) 0 + std::iterator (0x0x7f1d7e0b9900) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f1d7defc720) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f1d7dfe74e0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f1d7dfe7480) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f1d7dd91480) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f1d7cac7f60) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f1d7c981000) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f1d7ca0ea80) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f1d7ca0eae0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f1d7ca0eb40) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f1d7ca0eba0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f1d7ca0ee40) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f1d7c67c3c0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f1d7ca17958) 0 + std::__atomic_flag_base (0x0x7f1d7c67c420) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f1d7c2930d0) 0 + QAtomicInteger (0x0x7f1d7c293138) 0 + QBasicAtomicInteger (0x0x7f1d7c4a7b40) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f1d7be79120) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f1d7beec180) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f1d7beec2a0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f1d7c070b60) 0 + QGenericArgument (0x0x7f1d7beec300) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f1d7beec480) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f1d7beec540) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f1d7bfca5a0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f1d7bfca600) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f1d7bfca8a0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f1d7bfca900) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f1d7bfcac60) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f1d7bfcacc0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f1d7bfcad20) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f1d7bfcad80) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f1d7bfcade0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f1d7bd661e0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f1d7bd700d0) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f1d7bd662a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f1d7bd700d0) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f1d7bd70138) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f1d7bd701a0) 0 + primary-for std::domain_error (0x0x7f1d7bd70138) + std::exception (0x0x7f1d7bd66300) 0 nearly-empty + primary-for std::logic_error (0x0x7f1d7bd701a0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f1d7bd70208) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f1d7bd70270) 0 + primary-for std::invalid_argument (0x0x7f1d7bd70208) + std::exception (0x0x7f1d7bd66360) 0 nearly-empty + primary-for std::logic_error (0x0x7f1d7bd70270) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f1d7bd702d8) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f1d7bd70340) 0 + primary-for std::length_error (0x0x7f1d7bd702d8) + std::exception (0x0x7f1d7bd663c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f1d7bd70340) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f1d7bd703a8) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f1d7bd70410) 0 + primary-for std::out_of_range (0x0x7f1d7bd703a8) + std::exception (0x0x7f1d7bd66420) 0 nearly-empty + primary-for std::logic_error (0x0x7f1d7bd70410) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f1d7bd70478) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f1d7bd66480) 0 nearly-empty + primary-for std::runtime_error (0x0x7f1d7bd70478) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f1d7bd704e0) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f1d7bd70548) 0 + primary-for std::range_error (0x0x7f1d7bd704e0) + std::exception (0x0x7f1d7bd664e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f1d7bd70548) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f1d7bd705b0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f1d7bd70618) 0 + primary-for std::overflow_error (0x0x7f1d7bd705b0) + std::exception (0x0x7f1d7bd66540) 0 nearly-empty + primary-for std::runtime_error (0x0x7f1d7bd70618) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f1d7bd70680) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f1d7bd706e8) 0 + primary-for std::underflow_error (0x0x7f1d7bd70680) + std::exception (0x0x7f1d7bd665a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f1d7bd706e8) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f1d7bd66720) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f1d7bd66960) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f1d7bd66ae0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f1d7bd70bc8) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f1d7bd70c30) 0 + primary-for std::system_error (0x0x7f1d7bd70bc8) + std::exception (0x0x7f1d7bd66d20) 0 nearly-empty + primary-for std::runtime_error (0x0x7f1d7bd70c30) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f1d7be05820) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f1d7be05888) 0 + primary-for std::ios_base::failure (0x0x7f1d7be05820) + std::runtime_error (0x0x7f1d7be058f0) 0 + primary-for std::system_error (0x0x7f1d7be05888) + std::exception (0x0x7f1d7ba37060) 0 nearly-empty + primary-for std::runtime_error (0x0x7f1d7be058f0) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f1d7ba370c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f1d7ba37120) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f1d7ba37180) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f1d7ba37000) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f1d7ba37900) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f1d7bbbb000) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f1d7b6d91a0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f1d7b6d9270 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f1d7b6d9618 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f1d7b6d96e8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f1d7b9b4840) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f1d7b9b48a0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f1d7b816c00) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f1d7b816f60) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f1d7b50e420) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f1d7b5962a0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f1d7b596900) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f1d7b5968a0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f1d7b37b9c0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f1d7b117600) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f1d7af242a0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f1d7af24300) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f1d7af24360) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f1d7af24720) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f1d7af24780) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f1d7af371a0) 0 empty + QListData::NotIndirectLayout (0x0x7f1d7af247e0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f1d7afeda10) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f1d7af24840) 0 empty + QListData::NotIndirectLayout (0x0x7f1d7af248a0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f1d7af37208) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f1d7af24900) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f1d7af24960) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f1d7af246c0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f1d7af24de0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f1d7adb5060) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f1d7adb5000) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f1d7ada1c30) 0 + QList (0x0x7f1d7ada1c98) 0 + QListSpecialMethods (0x0x7f1d7adb5240) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f1d7adb5660) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f1d7aad4240) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f1d7aad48a0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f1d7aad4a20) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f1d7aad4ae0) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f1d7ae205b0) 0 + std::__uses_alloc_base (0x0x7f1d7aad4a80) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f1d7a8f9b40) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f1d7a8f9d80) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f1d7a8f9e40) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f1d7a8f9f60) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f1d7aa22120) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f1d7aa22540) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f1d7aa22660) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f1d7a73f000) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f1d7a73f420) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f1d7a73f720) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f1d7a58cf60) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f1d7a30ade0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f1d7a30ae40) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f1d7a37d060) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f1d7a37d000) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f1d7a415300) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f1d7a415360) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f1d7a415420) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f1d7a4117b8) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f1d7a4153c0) 0 + primary-for QAbstractAnimation (0x0x7f1d7a4117b8) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f1d7a4154e0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f1d7a411820) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f1d7a415480) 0 + primary-for QAnimationDriver (0x0x7f1d7a411820) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f1d7a4155a0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f1d7a411888) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f1d7a415540) 0 + primary-for QEventLoop (0x0x7f1d7a411888) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f1d7a415780) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f1d7a415840) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f1d7a4158a0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f1d7a4119c0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f1d7a4157e0) 0 + primary-for QAbstractEventDispatcher (0x0x7f1d7a4119c0) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f1d7a415b40) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f1d7a411bc8) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f1d7a415ba0) 0 nearly-empty + primary-for std::bad_cast (0x0x7f1d7a411bc8) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f1d7a411c30) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f1d7a415c00) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f1d7a411c30) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f1d7a164ea0) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f1d7a1d6cc0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f1d7a164ea0) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f1d7a1d6d80) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f1d7a1d6de0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f1d7a1d6f00) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f1d79e7f420) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f1d79e7f960) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f1d79e7fd20) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f1d79e7fcc0) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f1d79e7fd80) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f1d7a012660) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f1d7a012720) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f1d7a0126c0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f1d7a012780) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f1d7a012600) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f1d79a692a0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f1d79a69900) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f1d79a698a0) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f1d79a699c0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f1d79a69960) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f1d79b92cc0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f1d798d83c0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f1d79974ae0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f1d79975c30) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f1d79974a80) 0 + primary-for QAbstractItemModel (0x0x7f1d79975c30) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f1d799d53c0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f1d799d4340) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f1d799d43a8) 0 + primary-for QAbstractTableModel (0x0x7f1d799d4340) + QObject (0x0x7f1d799d5360) 0 + primary-for QAbstractItemModel (0x0x7f1d799d43a8) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f1d799d5480) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f1d799d4410) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f1d799d4478) 0 + primary-for QAbstractListModel (0x0x7f1d799d4410) + QObject (0x0x7f1d799d5420) 0 + primary-for QAbstractItemModel (0x0x7f1d799d4478) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f1d799d5720) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f1d799d57e0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f1d799d45b0) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f1d799d4618) 0 + primary-for QAbstractProxyModel (0x0x7f1d799d45b0) + QObject (0x0x7f1d799d5780) 0 + primary-for QAbstractItemModel (0x0x7f1d799d4618) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f1d799d58a0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f1d799d4680) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f1d799d5840) 0 + primary-for QAbstractState (0x0x7f1d799d4680) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f1d799d5960) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f1d799d46e8) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f1d799d5900) 0 + primary-for QAbstractTransition (0x0x7f1d799d46e8) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f1d799d5a20) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f1d799d4750) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f1d799d47b8) 0 + primary-for QAnimationGroup (0x0x7f1d799d4750) + QObject (0x0x7f1d799d59c0) 0 + primary-for QAbstractAnimation (0x0x7f1d799d47b8) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f1d79743780) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f1d79743a20) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f1d79743ae0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f1d79743de0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f1d799d4e38) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f1d79743d80) 0 + primary-for QIODevice (0x0x7f1d799d4e38) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f1d79822060) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f1d799d4f70) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f1d79821000) 0 + primary-for QBuffer (0x0x7f1d799d4f70) + QObject (0x0x7f1d79822000) 0 + primary-for QIODevice (0x0x7f1d79821000) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f1d79822120) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f1d798220c0) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f1d79822240) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f1d798221e0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f1d79822420) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f1d79822600) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f1d79822c00) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f1d79822cc0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f1d7961dcc0) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f1d7925b180) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f1d792304e0) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f1d7925b1e0) 0 + primary-for QTimerEvent (0x0x7f1d792304e0) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f1d79230548) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f1d7925b240) 0 + primary-for QChildEvent (0x0x7f1d79230548) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f1d79230a90) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f1d7925b720) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f1d79230a90) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f1d79230af8) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f1d7925b780) 0 + primary-for QDeferredDeleteEvent (0x0x7f1d79230af8) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f1d7925b840) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f1d79230b60) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f1d7925b7e0) 0 + primary-for QCoreApplication (0x0x7f1d79230b60) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f1d7925b8a0) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f1d7925b900) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f1d7925bf00) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f1d7925bf60) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f1d7936a060) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f1d7936a540) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f1d7936a7e0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f1d7936af60) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f1d79410000) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f1d7936af00) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f1d790bf120) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f1d790bf600) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f1d791f85a0) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f1d791f8840) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f1d791f8a80) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f1d791f8c00) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f1d78fb6180) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f1d78fb6120) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f1d78c80660) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f1d78c80720) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f1d78d588a0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f1d78d5cc98) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f1d78d5cd00) 0 + primary-for QFileDevice (0x0x7f1d78d5cc98) + QObject (0x0x7f1d78d58840) 0 + primary-for QIODevice (0x0x7f1d78d5cd00) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f1d78d58ae0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f1d78d5ce38) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f1d78d5cea0) 0 + primary-for QFile (0x0x7f1d78d5ce38) + QIODevice (0x0x7f1d78d5cf08) 0 + primary-for QFileDevice (0x0x7f1d78d5cea0) + QObject (0x0x7f1d78d58a80) 0 + primary-for QIODevice (0x0x7f1d78d5cf08) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f1d78d58cc0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f1d78e19120) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f1d78e19720) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f1d78e19960) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f1d78b6ed80) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f1d78b70b60) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f1d78b70bc8) 0 + primary-for QEventTransition (0x0x7f1d78b70b60) + QObject (0x0x7f1d78b6ed20) 0 + primary-for QAbstractTransition (0x0x7f1d78b70bc8) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f1d78b70c30) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f1d78b6ede0) 0 nearly-empty + primary-for QException (0x0x7f1d78b70c30) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f1d78b70c98) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f1d78b70d00) 0 nearly-empty + primary-for QUnhandledException (0x0x7f1d78b70c98) + std::exception (0x0x7f1d78b6ee40) 0 nearly-empty + primary-for QException (0x0x7f1d78b70d00) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f1d78b6eea0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f1d78b6ef60) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f1d78bea000) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f1d78bea120) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f1d78b70d68) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f1d78bea0c0) 0 + primary-for QFileSelector (0x0x7f1d78b70d68) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f1d78bea1e0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f1d78b70dd0) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f1d78bea180) 0 + primary-for QFileSystemWatcher (0x0x7f1d78b70dd0) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f1d78bea2a0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f1d78b70e38) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f1d78b70ea0) 0 + primary-for QFinalState (0x0x7f1d78b70e38) + QObject (0x0x7f1d78bea240) 0 + primary-for QAbstractState (0x0x7f1d78b70ea0) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f1d78bea300) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f1d78bea360) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f1d7889b000) 0 + QBasicMutex (0x0x7f1d78bea540) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f1d78bea5a0) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f1d78bea600) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f1d78bea660) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f1d78bea780) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f1d78913000) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f1d789137e0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f1d78991138) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f1d78913780) 0 + primary-for QFutureWatcherBase (0x0x7f1d78991138) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f1d78913de0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f1d78991a28) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f1d78991a90) 0 + primary-for QHistoryState (0x0x7f1d78991a28) + QObject (0x0x7f1d78913d80) 0 + primary-for QAbstractState (0x0x7f1d78991a90) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f1d78913ea0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f1d78991af8) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f1d78991b60) 0 + primary-for QIdentityProxyModel (0x0x7f1d78991af8) + QAbstractItemModel (0x0x7f1d78991bc8) 0 + primary-for QAbstractProxyModel (0x0x7f1d78991b60) + QObject (0x0x7f1d78913e40) 0 + primary-for QAbstractItemModel (0x0x7f1d78991bc8) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f1d78913f00) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f1d78658600) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f1d7865b410) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f1d786585a0) 0 + primary-for QItemSelectionModel (0x0x7f1d7865b410) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f1d7865b618) 0 + QList (0x0x7f1d7865b680) 0 + QListSpecialMethods (0x0x7f1d78658900) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f1d78658de0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f1d78465540) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f1d78465a80) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f1d78465ae0) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f1d78465cc0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f1d78465d20) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f1d78465c60) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f1d78566f60) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f1d785d9000) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f1d785d9660) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f1d785d96c0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f1d785d9600) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f1d78284960) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f1d782859c0) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f1d78284900) 0 + primary-for QLibrary (0x0x7f1d782859c0) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f1d78315060) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f1d78284b40) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f1d78315540) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f1d783155a0) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f1d78315840) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f1d78315ae0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f1d7800f480) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f1d7800fde0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f1d780b6180) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f1d780b6300) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f1d780b62a0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f1d780b6480) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f1d780b6720) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f1d780b6d80) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f1d780b6de0) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f1d77e7a420) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f1d77e7a720) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f1d77e7a780) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f1d77e7aa80) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f1d7820dc30) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f1d77e7aa20) 0 + primary-for QMimeData (0x0x7f1d7820dc30) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f1d77e7aae0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f1d77e7ade0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f1d77e7aea0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f1d7820de38) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f1d77e7ae40) 0 + primary-for QObjectCleanupHandler (0x0x7f1d7820de38) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f1d77e7af00) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f1d77f086c0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f1d77f0b548) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f1d77f0b5b0) 0 + primary-for QParallelAnimationGroup (0x0x7f1d77f0b548) + QAbstractAnimation (0x0x7f1d77f0b618) 0 + primary-for QAnimationGroup (0x0x7f1d77f0b5b0) + QObject (0x0x7f1d77f08660) 0 + primary-for QAbstractAnimation (0x0x7f1d77f0b618) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f1d77f08780) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f1d77f0b680) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f1d77f0b6e8) 0 + primary-for QPauseAnimation (0x0x7f1d77f0b680) + QObject (0x0x7f1d77f08720) 0 + primary-for QAbstractAnimation (0x0x7f1d77f0b6e8) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f1d77f08960) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f1d77f08c60) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f1d77f0b8f0) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f1d77f08c00) 0 + primary-for QPluginLoader (0x0x7f1d77f0b8f0) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f1d77f08cc0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f1d77f8a3c0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f1d77f0bf70) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f1d77f96000) 0 + primary-for QProcess (0x0x7f1d77f0bf70) + QObject (0x0x7f1d77f8a360) 0 + primary-for QIODevice (0x0x7f1d77f96000) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f1d77f8a480) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f1d77f96068) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f1d77f960d0) 0 + primary-for QVariantAnimation (0x0x7f1d77f96068) + QObject (0x0x7f1d77f8a420) 0 + primary-for QAbstractAnimation (0x0x7f1d77f960d0) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f1d77f8a540) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f1d77f961a0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f1d77f96208) 0 + primary-for QPropertyAnimation (0x0x7f1d77f961a0) + QAbstractAnimation (0x0x7f1d77f96270) 0 + primary-for QVariantAnimation (0x0x7f1d77f96208) + QObject (0x0x7f1d77f8a4e0) 0 + primary-for QAbstractAnimation (0x0x7f1d77f96270) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f1d77f8a660) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f1d77f8a600) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f1d77c78548) 0 + QRandomGenerator (0x0x7f1d77c76600) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f1d77c766c0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f1d77c76960) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f1d77c76a20) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f1d77c76ae0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f1d77c76d80) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f1d77d90060) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f1d77d90300) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f1d77d905a0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f1d77d90ba0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f1d77d90ea0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f1d77b961e0) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f1d77b96360) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f1d77a81750) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f1d77a817b8) 0 + primary-for QSaveFile (0x0x7f1d77a81750) + QIODevice (0x0x7f1d77a81820) 0 + primary-for QFileDevice (0x0x7f1d77a817b8) + QObject (0x0x7f1d77b96300) 0 + primary-for QIODevice (0x0x7f1d77a81820) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f1d77b96420) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f1d77b965a0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f1d778e3ba0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f1d778f50d0) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f1d778f5138) 0 + primary-for QSequentialAnimationGroup (0x0x7f1d778f50d0) + QAbstractAnimation (0x0x7f1d778f51a0) 0 + primary-for QAnimationGroup (0x0x7f1d778f5138) + QObject (0x0x7f1d778e3b40) 0 + primary-for QAbstractAnimation (0x0x7f1d778f51a0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f1d778e3c60) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f1d778f5208) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f1d778e3c00) 0 + primary-for QSettings (0x0x7f1d778f5208) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f1d778e3d20) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f1d778f5270) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f1d778e3cc0) 0 + primary-for QSharedMemory (0x0x7f1d778f5270) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f1d778e3de0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f1d778f52d8) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f1d778e3d80) 0 + primary-for QSignalMapper (0x0x7f1d778f52d8) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f1d778e3ea0) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f1d778f5340) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f1d778f53a8) 0 + primary-for QSignalTransition (0x0x7f1d778f5340) + QObject (0x0x7f1d778e3e40) 0 + primary-for QAbstractTransition (0x0x7f1d778f53a8) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f1d778e3f60) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f1d778f5410) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f1d778e3f00) 0 + primary-for QSocketNotifier (0x0x7f1d778f5410) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f1d77976060) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f1d778f5478) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f1d778f54e0) 0 + primary-for QSortFilterProxyModel (0x0x7f1d778f5478) + QAbstractItemModel (0x0x7f1d778f5548) 0 + primary-for QAbstractProxyModel (0x0x7f1d778f54e0) + QObject (0x0x7f1d77976000) 0 + primary-for QAbstractItemModel (0x0x7f1d778f5548) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f1d77976120) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f1d77976360) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f1d778f56e8) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f1d778f5750) 0 + primary-for QState (0x0x7f1d778f56e8) + QObject (0x0x7f1d77976300) 0 + primary-for QAbstractState (0x0x7f1d778f5750) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f1d77976480) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f1d778f58f0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f1d779764e0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f1d778f58f0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f1d778f5958) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f1d77976540) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f1d778f5958) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f1d778f57b8) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f1d778f5820) 0 + primary-for QStateMachine (0x0x7f1d778f57b8) + QAbstractState (0x0x7f1d778f5888) 0 + primary-for QState (0x0x7f1d778f5820) + QObject (0x0x7f1d77976420) 0 + primary-for QAbstractState (0x0x7f1d778f5888) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f1d779765a0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f1d7765c4e0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f1d776e98a0) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f1d776ed958) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f1d776ed9c0) 0 + primary-for QStringListModel (0x0x7f1d776ed958) + QAbstractItemModel (0x0x7f1d776eda28) 0 + primary-for QAbstractListModel (0x0x7f1d776ed9c0) + QObject (0x0x7f1d776e9840) 0 + primary-for QAbstractItemModel (0x0x7f1d776eda28) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f1d776e9900) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f1d776e99c0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f1d776e9ae0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f1d776eda90) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f1d776edaf8) 0 + primary-for QTemporaryFile (0x0x7f1d776eda90) + QFileDevice (0x0x7f1d776edb60) 0 + primary-for QFile (0x0x7f1d776edaf8) + QIODevice (0x0x7f1d776edbc8) 0 + primary-for QFileDevice (0x0x7f1d776edb60) + QObject (0x0x7f1d776e9a80) 0 + primary-for QIODevice (0x0x7f1d776edbc8) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f1d776e9b40) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f1d776e9d80) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f1d776e9d20) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f1d776e9f60) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f1d777d7000) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f1d777d7060) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f1d777d70c0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f1d776eddd0) 0 + std::__mutex_base (0x0x7f1d777d7120) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f1d776ede38) 0 + std::__recursive_mutex_base (0x0x7f1d777d7180) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f1d777f1b60) 0 + std::__mutex_base (0x0x7f1d777d72a0) 0 + std::__timed_mutex_impl (0x0x7f1d777d7300) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f1d7730f540) 0 + std::__recursive_mutex_base (0x0x7f1d777d73c0) 0 + std::__timed_mutex_impl (0x0x7f1d777d7420) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f1d777d7480) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f1d777d74e0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f1d777d7540) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f1d777d7780) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f1d776edf70) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f1d777d7840) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f1d776edf70) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f1d77369000) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f1d777d7900) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f1d77369000) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f1d77369068) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f1d777d79c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f1d77369068) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f1d77369138) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f1d777d7a80) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f1d77369138) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f1d777d7b40) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f1d777d7ba0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f1d777d7c00) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f1d777d7c60) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f1d77369410) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f1d7742f000) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f1d77369410) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f1d7742f840) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f1d771a8060) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f1d771a8240) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f1d771a82a0) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f1d771a81e0) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f1d76f18ea0) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f1d76f18f60) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f1d76f7c000) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f1d77003660) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f1d77005750) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f1d770057b8) 0 + primary-for std::future_error (0x0x7f1d77005750) + std::exception (0x0x7f1d77003780) 0 nearly-empty + primary-for std::logic_error (0x0x7f1d770057b8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f1d770038a0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f1d77003840) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f1d76cf7de0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f1d76cf6d68) 0 + std::__at_thread_exit_elt (0x0x7f1d76cf7ea0) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f1d77003a20) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f1d770037e0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f1d76abd958) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f1d76aa9d80) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f1d76abd958) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f1d767184e0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f1d7671e410) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f1d76718480) 0 + primary-for QThread (0x0x7f1d7671e410) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f1d76718600) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f1d7671e478) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f1d767185a0) 0 + primary-for QThreadPool (0x0x7f1d7671e478) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f1d76718660) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f1d76718780) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f1d7671e4e0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f1d76718720) 0 + primary-for QTimeLine (0x0x7f1d7671e4e0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f1d76718840) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f1d7671e548) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f1d767187e0) 0 + primary-for QTimer (0x0x7f1d7671e548) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f1d76718f00) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f1d76718ea0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f1d767ff4e0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f1d7671e5b0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f1d767ff480) 0 + primary-for QTranslator (0x0x7f1d7671e5b0) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f1d767ff600) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f1d7651bcc0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f1d765b7360) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f1d765b7960) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f1d765b79c0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f1d765b7c60) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f1d765e4a28) 0 + QVector (0x0x7f1d7666e060) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f1d7666e0c0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f1d7666e360) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f1d7666e600) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f1d7666e8a0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f1d7666e900) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f1d7635a360) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7f1d7635a480) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7f1d7635ac00) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7f1d763ce060) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7f1d763ce4e0) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7f1d763ce5a0) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7f1d763ce780) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7f1d7639a478) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7f1d763ce720) 0 + primary-for QGeoPositionInfoSource (0x0x7f1d7639a478) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7f1d763ce9c0) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7f1d7639a5b0) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7f1d763ce960) 0 + primary-for QGeoAreaMonitorSource (0x0x7f1d7639a5b0) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7f1d7639a618) 0 + QGeoShape (0x0x7f1d763cea20) 0 + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7f1d7639a8f0) 0 + QGeoShape (0x0x7f1d763cef00) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7f1d764c1300) 0 + +Class QGeoPath + size=8 align=8 + base size=8 base align=8 +QGeoPath (0x0x7f1d764eb138) 0 + QGeoShape (0x0x7f1d764c1a80) 0 + +Class QGeoPolygon + size=8 align=8 + base size=8 base align=8 +QGeoPolygon (0x0x7f1d764eb340) 0 + QGeoShape (0x0x7f1d764c1e40) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7f1d76121240) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7f1d76121300) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7f1d764eb548) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7f1d761212a0) 0 + primary-for QGeoSatelliteInfoSource (0x0x7f1d764eb548) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7f1d761213c0) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7f1d761214e0) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7f1d764eb5b0) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7f1d764eb618) 0 + primary-for QNmeaPositionInfoSource (0x0x7f1d764eb5b0) + QObject (0x0x7f1d76121480) 0 + primary-for QGeoPositionInfoSource (0x0x7f1d764eb618) + diff --git a/tests/auto/bic/data/QtPositioning.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..faae30f --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,4838 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f7e246782a0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f7e246bfa20) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f7e246bfc60) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f7e246bfea0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f7e2226a120) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f7e2226a2a0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f7e2226a660) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f7e222f5de0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f7e222f5ea0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f7e22326240) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f7e22326300) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f7e223263c0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f7e22326480) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f7e22326720) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f7e22326900) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f7e22326d80) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f7e22326de0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f7e223e0a80) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f7e223e0ae0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f7e2232a5b0) 0 empty + std::input_iterator_tag (0x0x7f7e223e0b40) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f7e2232a618) 0 empty + std::forward_iterator_tag (0x0x7f7e2232a680) 0 empty + std::input_iterator_tag (0x0x7f7e223e0ba0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f7e2232a6e8) 0 empty + std::bidirectional_iterator_tag (0x0x7f7e2232a750) 0 empty + std::forward_iterator_tag (0x0x7f7e2232a7b8) 0 empty + std::input_iterator_tag (0x0x7f7e223e0c00) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f7e2241d8a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f7e2241d900) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f7e2241d960) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f7e2241d9c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f7e2241da20) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f7e220fb540) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f7e220fb780) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f7e220fb840) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f7e220fb8a0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f7e220fb960) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f7e220fb9c0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f7e220fbe40) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f7e220fbea0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f7e220fbf00) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f7e2232ad00) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f7e220fbf60) 0 nearly-empty + primary-for std::bad_exception (0x0x7f7e2232ad00) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f7e22245000) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f7e22245060) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f7e2232af08) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f7e22245480) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f7e2232af08) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f7e2232af70) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f7e21e75000) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f7e2232af70) + std::exception (0x0x7f7e222454e0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f7e21e75000) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f7e22245540) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f7e21f13180) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f7e21f13e40) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f7e21f13ea0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f7e21d65d80) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f7e21d65de0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f7e21d65ea0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f7e21d65f00) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f7e21d65f60) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f7e21dfc000) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f7e21dfc120) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f7e21dfc180) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f7e21dfc5a0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f7e21dfc600) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f7e21c2ede0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f7e21c2ee40) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f7e218fdde0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f7e2169ec00) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f7e218f0d68) 0 + std::iterator (0x0x7f7e2169ecc0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f7e218f0dd0) 0 + std::_Bit_iterator_base (0x0x7f7e218f0e38) 0 + std::iterator (0x0x7f7e2169ed20) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f7e218f0ea0) 0 + std::_Bit_iterator_base (0x0x7f7e218f0f08) 0 + std::iterator (0x0x7f7e2169ed80) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f7e21498ba0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f7e215cd960) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f7e215cd900) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f7e21361900) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f7e1ff9f420) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f7e1ff9f480) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f7e20046f00) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f7e20046f60) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f7e1fc8f000) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f7e1fc8f060) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f7e1fc8f300) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f7e1fc8f840) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f7e1fc55c30) 0 + std::__atomic_flag_base (0x0x7f7e1fc8f8a0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f7e1fb293a8) 0 + QAtomicInteger (0x0x7f7e1fb29410) 0 + QBasicAtomicInteger (0x0x7f7e1f8eb000) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f7e1f7be5a0) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f7e1f51f780) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f7e1f51f8a0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f7e1f563000) 0 + QGenericArgument (0x0x7f7e1f51f900) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f7e1f51fa80) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f7e1f51fb40) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f7e1f602ba0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f7e1f602c00) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f7e1f602ea0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f7e1f602f00) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f7e1f2f22a0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f7e1f2f2300) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f7e1f2f2360) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f7e1f2f23c0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f7e1f2f2420) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f7e1f2f27e0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f7e1f336618) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f7e1f2f28a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f7e1f336618) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f7e1f336680) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f7e1f3366e8) 0 + primary-for std::domain_error (0x0x7f7e1f336680) + std::exception (0x0x7f7e1f2f2900) 0 nearly-empty + primary-for std::logic_error (0x0x7f7e1f3366e8) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f7e1f336750) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f7e1f3367b8) 0 + primary-for std::invalid_argument (0x0x7f7e1f336750) + std::exception (0x0x7f7e1f2f2960) 0 nearly-empty + primary-for std::logic_error (0x0x7f7e1f3367b8) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f7e1f336820) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f7e1f336888) 0 + primary-for std::length_error (0x0x7f7e1f336820) + std::exception (0x0x7f7e1f2f29c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f7e1f336888) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f7e1f3368f0) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f7e1f336958) 0 + primary-for std::out_of_range (0x0x7f7e1f3368f0) + std::exception (0x0x7f7e1f2f2a20) 0 nearly-empty + primary-for std::logic_error (0x0x7f7e1f336958) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f7e1f3369c0) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f7e1f2f2a80) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7e1f3369c0) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f7e1f336a28) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f7e1f336a90) 0 + primary-for std::range_error (0x0x7f7e1f336a28) + std::exception (0x0x7f7e1f2f2ae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7e1f336a90) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f7e1f336af8) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f7e1f336b60) 0 + primary-for std::overflow_error (0x0x7f7e1f336af8) + std::exception (0x0x7f7e1f2f2b40) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7e1f336b60) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f7e1f336bc8) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f7e1f336c30) 0 + primary-for std::underflow_error (0x0x7f7e1f336bc8) + std::exception (0x0x7f7e1f2f2ba0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7e1f336c30) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f7e1f2f2d20) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f7e1f2f2f60) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f7e1f416120) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f7e1f439068) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f7e1f4390d0) 0 + primary-for std::system_error (0x0x7f7e1f439068) + std::exception (0x0x7f7e1f416360) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7e1f4390d0) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f7e1f439c98) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f7e1f439d00) 0 + primary-for std::ios_base::failure (0x0x7f7e1f439c98) + std::runtime_error (0x0x7f7e1f439d68) 0 + primary-for std::system_error (0x0x7f7e1f439d00) + std::exception (0x0x7f7e1f416660) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7e1f439d68) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f7e1f4166c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f7e1f416720) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f7e1f416780) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f7e1f416600) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f7e1f416f00) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f7e1f176600) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f7e1ecf8680 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f7e1ecf8750 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f7e1ecf8af8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f7e1ecf8bc8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f7e1ef13e40) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f7e1ef13ea0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f7e1ea8d240) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f7e1ea8d5a0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f7e1ea8da20) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f7e1ebab8a0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f7e1ebabf00) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f7e1ebabea0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f7e1e688000) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f7e1e688c00) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f7e1e7ea8a0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f7e1e7ea900) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f7e1e7ea960) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f7e1e7ead20) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f7e1e7ead80) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f7e1e56f618) 0 empty + QListData::NotIndirectLayout (0x0x7f7e1e7eade0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f7e1e63f3f0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f7e1e7eae40) 0 empty + QListData::NotIndirectLayout (0x0x7f7e1e7eaea0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f7e1e56f680) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f7e1e7eaf00) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f7e1e7eaf60) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f7e1e7eacc0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f7e1e250420) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f7e1e3f1660) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f7e1e3f1600) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f7e1e4120d0) 0 + QList (0x0x7f7e1e412138) 0 + QListSpecialMethods (0x0x7f7e1e3f1840) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f7e1e3f1c60) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f7e1e0e1840) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f7e1e0e1ea0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f7e1deb6060) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f7e1deb6120) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f7e1e412a28) 0 + std::__uses_alloc_base (0x0x7f7e1deb60c0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f7e1dfa8180) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f7e1dfa83c0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f7e1dfa8480) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f7e1dfa85a0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f7e1dfa8720) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f7e1dfa8b40) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f7e1dfa8c60) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f7e1dd32600) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f7e1dd32a20) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f7e1dd32d20) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f7e1dc2f720) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f7e1d97e5a0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f7e1d97e600) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f7e1d97e7e0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f7e1d97e780) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f7e1da44a80) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f7e1da44ae0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f7e1da44ba0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f7e1da45d68) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f7e1da44b40) 0 + primary-for QAbstractAnimation (0x0x7f7e1da45d68) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f7e1da44c60) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f7e1da45dd0) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f7e1da44c00) 0 + primary-for QAnimationDriver (0x0x7f7e1da45dd0) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f7e1da44d20) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f7e1da45e38) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f7e1da44cc0) 0 + primary-for QEventLoop (0x0x7f7e1da45e38) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f7e1da44f00) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f7e1d6fb000) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f7e1d6fb060) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f7e1da45f70) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f7e1da44f60) 0 + primary-for QAbstractEventDispatcher (0x0x7f7e1da45f70) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f7e1d6fb300) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f7e1d717068) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f7e1d6fb360) 0 nearly-empty + primary-for std::bad_cast (0x0x7f7e1d717068) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f7e1d7170d0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f7e1d6fb3c0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f7e1d7170d0) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f7e1d491340) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f7e1d495480) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f7e1d491340) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f7e1d495540) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f7e1d4955a0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f7e1d4956c0) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f7e1d495ba0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f7e1d54c120) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f7e1d54c4e0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f7e1d54c480) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f7e1d54c540) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f7e1d54cde0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f7e1d54cea0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f7e1d54ce40) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f7e1d54cf00) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f7e1d54cd80) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f7e1d446a20) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f7e1d0dc0c0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f7e1d0dc060) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f7e1d0dc180) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f7e1d0dc120) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f7e1d200480) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f7e1d200b40) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f7e1cfe62a0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f7e1cfe90d0) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f7e1cfe6240) 0 + primary-for QAbstractItemModel (0x0x7f7e1cfe90d0) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f7e1cfe6b40) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f7e1cfe97b8) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f7e1cfe9820) 0 + primary-for QAbstractTableModel (0x0x7f7e1cfe97b8) + QObject (0x0x7f7e1cfe6ae0) 0 + primary-for QAbstractItemModel (0x0x7f7e1cfe9820) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f7e1cfe6c00) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f7e1cfe9888) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f7e1cfe98f0) 0 + primary-for QAbstractListModel (0x0x7f7e1cfe9888) + QObject (0x0x7f7e1cfe6ba0) 0 + primary-for QAbstractItemModel (0x0x7f7e1cfe98f0) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f7e1cfe6ea0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f7e1cfe6f60) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f7e1cfe9a28) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f7e1cfe9a90) 0 + primary-for QAbstractProxyModel (0x0x7f7e1cfe9a28) + QObject (0x0x7f7e1cfe6f00) 0 + primary-for QAbstractItemModel (0x0x7f7e1cfe9a90) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f7e1cd40060) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f7e1cfe9af8) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f7e1cd40000) 0 + primary-for QAbstractState (0x0x7f7e1cfe9af8) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f7e1cd40120) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f7e1cfe9b60) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f7e1cd400c0) 0 + primary-for QAbstractTransition (0x0x7f7e1cfe9b60) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f7e1cd401e0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f7e1cfe9bc8) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f7e1cfe9c30) 0 + primary-for QAnimationGroup (0x0x7f7e1cfe9bc8) + QObject (0x0x7f7e1cd40180) 0 + primary-for QAbstractAnimation (0x0x7f7e1cfe9c30) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f7e1cd8ff00) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f7e1cdd21e0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f7e1cdd22a0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f7e1cdd25a0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f7e1cdd72d8) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f7e1cdd2540) 0 + primary-for QIODevice (0x0x7f7e1cdd72d8) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f7e1cdd27e0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f7e1cdd7410) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f7e1cdd7478) 0 + primary-for QBuffer (0x0x7f7e1cdd7410) + QObject (0x0x7f7e1cdd2780) 0 + primary-for QIODevice (0x0x7f7e1cdd7478) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f7e1cdd28a0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f7e1cdd2840) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f7e1cdd29c0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f7e1cdd2960) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f7e1cdd2ba0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f7e1cdd2d80) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f7e1cb46060) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f7e1cb467e0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f7e1cb46840) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f7e1cb46780) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f7e1cc07960) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f7e1cc07f60) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f7e1c922240) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f7e1c922480) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f7e1c922b40) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f7e1c922cc0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f7e1c6a3240) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f7e1c6a31e0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f7e1c460540) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f7e1c460600) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f7e1c4e5960) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f7e1c4e5ae0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f7e1c571120) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f7e1c571420) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f7e1c5717e0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f7e1c2b7ea0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f7e1c3394e0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f7e1c339540) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f7e1c19b540) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f7e1c19bae0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f7e1c19bb40) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f7e1c19ba80) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f7e1becaba0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f7e1becac00) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f7e1becab40) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f7e1bc8f780) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f7e1bc8fb40) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f7e1bde6540) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f7e1bde6ba0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f7e1bde6c60) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f7e1bae6c60) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f7e1bb25120) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f7e1baf4a28) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f7e1bb25180) 0 + primary-for QTimerEvent (0x0x7f7e1baf4a28) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f7e1baf4a90) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f7e1bb251e0) 0 + primary-for QChildEvent (0x0x7f7e1baf4a90) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f7e1bb82000) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f7e1bb256c0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f7e1bb82000) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f7e1bb82068) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f7e1bb25720) 0 + primary-for QDeferredDeleteEvent (0x0x7f7e1bb82068) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f7e1bb257e0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f7e1bb820d0) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f7e1bb25780) 0 + primary-for QCoreApplication (0x0x7f7e1bb820d0) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f7e1bb25840) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f7e1bb258a0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f7e1bb25900) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f7e1bb259c0) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f7e1bb25ea0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f7e1b8453c0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f7e1b972240) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f7e1b962548) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f7e1b9625b0) 0 + primary-for QFileDevice (0x0x7f7e1b962548) + QObject (0x0x7f7e1b9721e0) 0 + primary-for QIODevice (0x0x7f7e1b9625b0) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f7e1b972480) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f7e1b9626e8) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f7e1b962750) 0 + primary-for QFile (0x0x7f7e1b9626e8) + QIODevice (0x0x7f7e1b9627b8) 0 + primary-for QFileDevice (0x0x7f7e1b962750) + QObject (0x0x7f7e1b972420) 0 + primary-for QIODevice (0x0x7f7e1b9627b8) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f7e1b972660) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f7e1b972a80) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f7e1b68e0c0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f7e1b68e300) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f7e1b774720) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f7e1b7777b8) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f7e1b777820) 0 + primary-for QEventTransition (0x0x7f7e1b7777b8) + QObject (0x0x7f7e1b7746c0) 0 + primary-for QAbstractTransition (0x0x7f7e1b777820) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f7e1b777888) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f7e1b774780) 0 nearly-empty + primary-for QException (0x0x7f7e1b777888) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f7e1b7778f0) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f7e1b777958) 0 nearly-empty + primary-for QUnhandledException (0x0x7f7e1b7778f0) + std::exception (0x0x7f7e1b7747e0) 0 nearly-empty + primary-for QException (0x0x7f7e1b777958) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f7e1b774840) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f7e1b774900) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f7e1b774960) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f7e1b774a80) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f7e1b7779c0) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f7e1b774a20) 0 + primary-for QFileSelector (0x0x7f7e1b7779c0) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f7e1b774b40) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f7e1b777a28) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f7e1b774ae0) 0 + primary-for QFileSystemWatcher (0x0x7f7e1b777a28) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f7e1b774c00) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f7e1b777a90) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f7e1b777af8) 0 + primary-for QFinalState (0x0x7f7e1b777a90) + QObject (0x0x7f7e1b774ba0) 0 + primary-for QAbstractState (0x0x7f7e1b777af8) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f7e1b774c60) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f7e1b774cc0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f7e1b777c30) 0 + QBasicMutex (0x0x7f7e1b774ea0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f7e1b774f00) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f7e1b774f60) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f7e1b4d4000) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f7e1b4d4120) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f7e1b4d4960) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f7e1b5a6180) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f7e1b51ad68) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f7e1b5a6120) 0 + primary-for QFutureWatcherBase (0x0x7f7e1b51ad68) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f7e1b5a6780) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f7e1b5e4680) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f7e1b5e46e8) 0 + primary-for QHistoryState (0x0x7f7e1b5e4680) + QObject (0x0x7f7e1b5a6720) 0 + primary-for QAbstractState (0x0x7f7e1b5e46e8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f7e1b5a6840) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f7e1b5e4750) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f7e1b5e47b8) 0 + primary-for QIdentityProxyModel (0x0x7f7e1b5e4750) + QAbstractItemModel (0x0x7f7e1b5e4820) 0 + primary-for QAbstractProxyModel (0x0x7f7e1b5e47b8) + QObject (0x0x7f7e1b5a67e0) 0 + primary-for QAbstractItemModel (0x0x7f7e1b5e4820) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f7e1b5a68a0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f7e1b5a6f60) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f7e1b283068) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f7e1b5a6f00) 0 + primary-for QItemSelectionModel (0x0x7f7e1b283068) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f7e1b283270) 0 + QList (0x0x7f7e1b2832d8) 0 + QListSpecialMethods (0x0x7f7e1b2a22a0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f7e1b2a2780) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f7e1b060ea0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f7e1b0d7420) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f7e1b0d7480) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f7e1b0d7660) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f7e1b0d76c0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f7e1b0d7600) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f7e1b197900) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f7e1b197960) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f7e1b226000) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f7e1b226060) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f7e1b197f60) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f7e1aeca300) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f7e1aec8618) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f7e1aeca2a0) 0 + primary-for QLibrary (0x0x7f7e1aec8618) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f7e1aeca9c0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f7e1aeca4e0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f7e1aecaea0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f7e1aecaf00) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f7e1afdb1e0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f7e1afdb7e0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f7e1ac6b180) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f7e1ac6b780) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f7e1ac6bae0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f7e1ac6bc60) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f7e1ac6bc00) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f7e1ac6bde0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f7e1adf00c0) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f7e1adf0720) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f7e1adf0780) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f7e1adf0d80) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f7e1a9d90c0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f7e1a9d9120) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f7e1a9d9420) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f7e1a9c0888) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f7e1a9d93c0) 0 + primary-for QMimeData (0x0x7f7e1a9c0888) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f7e1a9d9480) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f7e1a9d9780) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f7e1a9d9840) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f7e1a9c0a90) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f7e1a9d97e0) 0 + primary-for QObjectCleanupHandler (0x0x7f7e1a9c0a90) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f7e1a9d98a0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f7e1aa6f060) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f7e1aa691a0) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f7e1aa69208) 0 + primary-for QParallelAnimationGroup (0x0x7f7e1aa691a0) + QAbstractAnimation (0x0x7f7e1aa69270) 0 + primary-for QAnimationGroup (0x0x7f7e1aa69208) + QObject (0x0x7f7e1aa6f000) 0 + primary-for QAbstractAnimation (0x0x7f7e1aa69270) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f7e1aa6f120) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f7e1aa692d8) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f7e1aa69340) 0 + primary-for QPauseAnimation (0x0x7f7e1aa692d8) + QObject (0x0x7f7e1aa6f0c0) 0 + primary-for QAbstractAnimation (0x0x7f7e1aa69340) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f7e1aa6f300) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f7e1aa6f600) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f7e1aa69548) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f7e1aa6f5a0) 0 + primary-for QPluginLoader (0x0x7f7e1aa69548) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f7e1aa6f660) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f7e1aa6fd20) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f7e1aa69bc8) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f7e1aa69c30) 0 + primary-for QProcess (0x0x7f7e1aa69bc8) + QObject (0x0x7f7e1aa6fcc0) 0 + primary-for QIODevice (0x0x7f7e1aa69c30) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f7e1aa6fde0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f7e1aa69c98) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f7e1aa69d00) 0 + primary-for QVariantAnimation (0x0x7f7e1aa69c98) + QObject (0x0x7f7e1aa6fd80) 0 + primary-for QAbstractAnimation (0x0x7f7e1aa69d00) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f7e1aa6fea0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f7e1aa69dd0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f7e1aa69e38) 0 + primary-for QPropertyAnimation (0x0x7f7e1aa69dd0) + QAbstractAnimation (0x0x7f7e1aa69ea0) 0 + primary-for QVariantAnimation (0x0x7f7e1aa69e38) + QObject (0x0x7f7e1aa6fe40) 0 + primary-for QAbstractAnimation (0x0x7f7e1aa69ea0) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f7e1a755000) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f7e1aa6ff60) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f7e1a7d51a0) 0 + QRandomGenerator (0x0x7f7e1a7a1f60) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f7e1a7ff060) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f7e1a7ff300) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f7e1a7ff3c0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f7e1a7ff480) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f7e1a7ff720) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f7e1a7ff9c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f7e1a7ffc60) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f7e1a7fff00) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f7e1a6450c0) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f7e1a7d5d00) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f7e1a7d5d68) 0 + primary-for QSaveFile (0x0x7f7e1a7d5d00) + QIODevice (0x0x7f7e1a7d5dd0) 0 + primary-for QFileDevice (0x0x7f7e1a7d5d68) + QObject (0x0x7f7e1a645060) 0 + primary-for QIODevice (0x0x7f7e1a7d5dd0) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f7e1a6451e0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f7e1a645360) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f7e1a388960) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f7e1a38e680) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f7e1a38e6e8) 0 + primary-for QSequentialAnimationGroup (0x0x7f7e1a38e680) + QAbstractAnimation (0x0x7f7e1a38e750) 0 + primary-for QAnimationGroup (0x0x7f7e1a38e6e8) + QObject (0x0x7f7e1a388900) 0 + primary-for QAbstractAnimation (0x0x7f7e1a38e750) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f7e1a388a20) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f7e1a38e7b8) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f7e1a3889c0) 0 + primary-for QSettings (0x0x7f7e1a38e7b8) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f7e1a388ae0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f7e1a38e820) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f7e1a388a80) 0 + primary-for QSharedMemory (0x0x7f7e1a38e820) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f7e1a388ba0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f7e1a38e888) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f7e1a388b40) 0 + primary-for QSignalMapper (0x0x7f7e1a38e888) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f7e1a388c60) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f7e1a38e8f0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f7e1a38e958) 0 + primary-for QSignalTransition (0x0x7f7e1a38e8f0) + QObject (0x0x7f7e1a388c00) 0 + primary-for QAbstractTransition (0x0x7f7e1a38e958) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f7e1a388d20) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f7e1a38e9c0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f7e1a388cc0) 0 + primary-for QSocketNotifier (0x0x7f7e1a38e9c0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f7e1a388de0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f7e1a38ea28) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f7e1a38ea90) 0 + primary-for QSortFilterProxyModel (0x0x7f7e1a38ea28) + QAbstractItemModel (0x0x7f7e1a38eaf8) 0 + primary-for QAbstractProxyModel (0x0x7f7e1a38ea90) + QObject (0x0x7f7e1a388d80) 0 + primary-for QAbstractItemModel (0x0x7f7e1a38eaf8) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f7e1a388ea0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f7e1a451120) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f7e1a38ec98) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f7e1a38ed00) 0 + primary-for QState (0x0x7f7e1a38ec98) + QObject (0x0x7f7e1a4510c0) 0 + primary-for QAbstractState (0x0x7f7e1a38ed00) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f7e1a451240) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f7e1a38eea0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f7e1a4512a0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f7e1a38eea0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f7e1a38ef08) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f7e1a451300) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f7e1a38ef08) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f7e1a38ed68) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f7e1a38edd0) 0 + primary-for QStateMachine (0x0x7f7e1a38ed68) + QAbstractState (0x0x7f7e1a38ee38) 0 + primary-for QState (0x0x7f7e1a38edd0) + QObject (0x0x7f7e1a4511e0) 0 + primary-for QAbstractState (0x0x7f7e1a38ee38) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f7e1a451360) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f7e1a4fe2a0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f7e1a18e660) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f7e1a163f08) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f7e1a163f70) 0 + primary-for QStringListModel (0x0x7f7e1a163f08) + QAbstractItemModel (0x0x7f7e1a1ae000) 0 + primary-for QAbstractListModel (0x0x7f7e1a163f70) + QObject (0x0x7f7e1a18e600) 0 + primary-for QAbstractItemModel (0x0x7f7e1a1ae000) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f7e1a18e6c0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f7e1a18e780) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f7e1a18e8a0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f7e1a1ae068) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f7e1a1ae0d0) 0 + primary-for QTemporaryFile (0x0x7f7e1a1ae068) + QFileDevice (0x0x7f7e1a1ae138) 0 + primary-for QFile (0x0x7f7e1a1ae0d0) + QIODevice (0x0x7f7e1a1ae1a0) 0 + primary-for QFileDevice (0x0x7f7e1a1ae138) + QObject (0x0x7f7e1a18e840) 0 + primary-for QIODevice (0x0x7f7e1a1ae1a0) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f7e1a18e900) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f7e1a18eb40) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f7e1a18eae0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f7e1a18ed20) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f7e1a18ed80) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f7e1a18ede0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f7e1a18ee40) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f7e1a1ae3a8) 0 + std::__mutex_base (0x0x7f7e1a18eea0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f7e1a1ae410) 0 + std::__recursive_mutex_base (0x0x7f7e1a18ef00) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f7e1a2954d0) 0 + std::__mutex_base (0x0x7f7e1a29d060) 0 + std::__timed_mutex_impl (0x0x7f7e1a29d0c0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f7e1a295e70) 0 + std::__recursive_mutex_base (0x0x7f7e1a29d180) 0 + std::__timed_mutex_impl (0x0x7f7e1a29d1e0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f7e1a29d240) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f7e1a29d2a0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f7e1a29d300) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f7e1a29d540) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f7e1a1ae548) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f7e1a29d600) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f7e1a1ae548) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f7e1a1ae5b0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f7e1a29d6c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f7e1a1ae5b0) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f7e1a1ae618) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f7e1a29d780) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f7e1a1ae618) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f7e1a1ae6e8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f7e1a29d840) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f7e1a1ae6e8) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f7e1a29d900) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f7e1a29d960) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f7e1a29d9c0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f7e1a29da20) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f7e1a1ae9c0) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f7e1a29dd80) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f7e1a1ae9c0) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f7e19fef600) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f7e19fefde0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f7e19d7f000) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f7e19d7f060) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f7e19feff60) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f7e19eb6c60) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f7e19eb6d20) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f7e19eb6d80) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f7e19b83420) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f7e19b73d00) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f7e19b73d68) 0 + primary-for std::future_error (0x0x7f7e19b73d00) + std::exception (0x0x7f7e19b83540) 0 nearly-empty + primary-for std::logic_error (0x0x7f7e19b73d68) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f7e19b83660) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f7e19b83600) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f7e19cdeba0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f7e19d01340) 0 + std::__at_thread_exit_elt (0x0x7f7e19cdec60) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f7e19b837e0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f7e19b835a0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f7e19649f08) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f7e19654b40) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f7e19649f08) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f7e196bb2a0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f7e196b09c0) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f7e196bb240) 0 + primary-for QThread (0x0x7f7e196b09c0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f7e196bb3c0) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f7e196b0a28) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f7e196bb360) 0 + primary-for QThreadPool (0x0x7f7e196b0a28) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f7e196bb420) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f7e196bb540) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f7e196b0a90) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f7e196bb4e0) 0 + primary-for QTimeLine (0x0x7f7e196b0a90) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f7e196bb600) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f7e196b0af8) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f7e196bb5a0) 0 + primary-for QTimer (0x0x7f7e196b0af8) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f7e196bbd20) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f7e196bbcc0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f7e193a4300) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f7e1936c680) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f7e193a42a0) 0 + primary-for QTranslator (0x0x7f7e1936c680) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f7e193a4360) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f7e193a49c0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f7e193a4a20) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f7e193a4cc0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f7e194303a8) 0 + QVector (0x0x7f7e194570c0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f7e19457120) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f7e194573c0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f7e19457660) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f7e19457900) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f7e19457960) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f7e191583c0) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7f7e191584e0) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7f7e19158c60) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7f7e191ca0c0) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7f7e191ca540) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7f7e191ca600) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7f7e191ca7e0) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7f7e1915add0) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7f7e191ca780) 0 + primary-for QGeoPositionInfoSource (0x0x7f7e1915add0) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7f7e191caa20) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7f7e1915af08) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7f7e191ca9c0) 0 + primary-for QGeoAreaMonitorSource (0x0x7f7e1915af08) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7f7e1915af70) 0 + QGeoShape (0x0x7f7e191caa80) 0 + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7f7e19279270) 0 + QGeoShape (0x0x7f7e191caf60) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7f7e192bc360) 0 + +Class QGeoPath + size=8 align=8 + base size=8 base align=8 +QGeoPath (0x0x7f7e19279a90) 0 + QGeoShape (0x0x7f7e192bcae0) 0 + +Class QGeoPolygon + size=8 align=8 + base size=8 base align=8 +QGeoPolygon (0x0x7f7e19279c98) 0 + QGeoShape (0x0x7f7e192bcea0) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7f7e18f1e2a0) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7f7e18f1e360) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7f7e19279ea0) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7f7e18f1e300) 0 + primary-for QGeoSatelliteInfoSource (0x0x7f7e19279ea0) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7f7e18f1e420) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7f7e18f1e540) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7f7e19279f08) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7f7e19279f70) 0 + primary-for QNmeaPositionInfoSource (0x0x7f7e19279f08) + QObject (0x0x7f7e18f1e4e0) 0 + primary-for QGeoPositionInfoSource (0x0x7f7e19279f70) + diff --git a/tests/auto/bic/data/QtPositioning.5.13.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.13.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..7f69b2e --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.13.0.linux-gcc-amd64.txt @@ -0,0 +1,5208 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f3508200c60) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f3506ee4420) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f3506ee4660) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f3506ee48a0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f3506ee4ae0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f3506ee4c60) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f3506f20060) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7f3506f4f180) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f3506fa7840) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f3506fa7900) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7f3506fa7cc0) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7f3506fa7d20) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7f3506fa7d80) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7f3506fa7de0) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7f3506fa7e40) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f3506fa7f00) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f3506fd6000) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f3506fd60c0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f3506fd6180) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f3506fd64e0) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7f3506fd6840) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7f3506fd68a0) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7f3506fd6e40) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f3506c244e0) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7f3506f7ddd0) 0 empty + std::__nonesuch (0x0x7f3506c249c0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f3506ca0360) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f3506ca03c0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f3506cff0c0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f3506cff120) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f3506c8e2d8) 0 empty + std::input_iterator_tag (0x0x7f3506cff180) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f3506c8e340) 0 empty + std::forward_iterator_tag (0x0x7f3506c8e3a8) 0 empty + std::input_iterator_tag (0x0x7f3506cff1e0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f3506c8e410) 0 empty + std::bidirectional_iterator_tag (0x0x7f3506c8e478) 0 empty + std::forward_iterator_tag (0x0x7f3506c8e4e0) 0 empty + std::input_iterator_tag (0x0x7f3506cff240) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f3506d92d20) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f3506d92e40) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f3506db0180) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f3506db0480) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f3506db05a0) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f3506a3e8a0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f3506a3eba0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f3506a3ec00) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7f3506a3ecc0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f3506a3ed20) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7f3506a3ed80) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7f3506a3ede0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f3506a810c0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f3506a81360) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f3506a813c0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f3506b38180) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f3506c8e820) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7f3506b38360) 0 nearly-empty + primary-for std::bad_exception (0x0x7f3506c8e820) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f3506b38540) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f3506c8e888) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7f3506b38900) 0 nearly-empty + primary-for std::bad_cast (0x0x7f3506c8e888) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f3506c8e8f0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7f3506b38ae0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f3506c8e8f0) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f3506b38cc0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f3506b702a0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f3506c8e958) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7f3506b70960) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f3506c8e958) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f3506c8e9c0) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7f3506c8ea28) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f3506c8e9c0) + std::exception (0x0x7f3506b70b40) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f3506c8ea28) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f3506b70d20) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7f3506b70f00) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f3506819420) 0 empty + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f35069ceea0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f35069cef60) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f3506491900) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f3506491a20) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f3506491d80) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f35064d1300) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f350650ba80) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f35065a1ea0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f3506551888) 0 + std::__atomic_flag_base (0x0x7f35065a1f00) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f3506129000) 0 + QAtomicInteger (0x0x7f3506129068) 0 + QBasicAtomicInteger (0x0x7f35060daea0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f3505d0b1e0) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f3505d50780) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f3505d50ea0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f3505f7abc8) 0 + QGenericArgument (0x0x7f3505d90180) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f3505d905a0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f3505d909c0) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f3505a424e0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f3505a42780) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f3505b0d5a0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f3505b0d900) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f3505b69c00) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f3505868480) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f3505868540) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f3505916660) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f3505916720) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f3505916780) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f35059167e0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f3505916840) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f3505916960) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f35059169c0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f3505655960) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f35056559c0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f3505411a20) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f3505411ba0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f3505581d20) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f35055d2120) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f35055d23c0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f35055d25a0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f350521c5a0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f3505439d00) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7f350521c660) 0 nearly-empty + primary-for std::logic_error (0x0x7f3505439d00) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f3505439d68) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7f3505439dd0) 0 + primary-for std::domain_error (0x0x7f3505439d68) + std::exception (0x0x7f350521c6c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f3505439dd0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f3505439e38) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7f3505439ea0) 0 + primary-for std::invalid_argument (0x0x7f3505439e38) + std::exception (0x0x7f350521c720) 0 nearly-empty + primary-for std::logic_error (0x0x7f3505439ea0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f3505439f08) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7f3505439f70) 0 + primary-for std::length_error (0x0x7f3505439f08) + std::exception (0x0x7f350521c780) 0 nearly-empty + primary-for std::logic_error (0x0x7f3505439f70) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f3505439208) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7f3505439270) 0 + primary-for std::out_of_range (0x0x7f3505439208) + std::exception (0x0x7f350521c7e0) 0 nearly-empty + primary-for std::logic_error (0x0x7f3505439270) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f35054395b0) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7f350521c840) 0 nearly-empty + primary-for std::runtime_error (0x0x7f35054395b0) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f3505439618) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7f3505253000) 0 + primary-for std::range_error (0x0x7f3505439618) + std::exception (0x0x7f350521c8a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f3505253000) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f3505253068) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7f35052530d0) 0 + primary-for std::overflow_error (0x0x7f3505253068) + std::exception (0x0x7f350521c900) 0 nearly-empty + primary-for std::runtime_error (0x0x7f35052530d0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f3505253138) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7f35052531a0) 0 + primary-for std::underflow_error (0x0x7f3505253138) + std::exception (0x0x7f350521c960) 0 nearly-empty + primary-for std::runtime_error (0x0x7f35052531a0) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f350521cae0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f350521ce40) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f350527a6c0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f35052535b0) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7f3505253618) 0 + primary-for std::system_error (0x0x7f35052535b0) + std::exception (0x0x7f35052a12a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f3505253618) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f3505253888) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7f35052538f0) 0 + primary-for std::ios_base::failure (0x0x7f3505253888) + std::runtime_error (0x0x7f3505253958) 0 + primary-for std::system_error (0x0x7f35052538f0) + std::exception (0x0x7f35052d6840) 0 nearly-empty + primary-for std::runtime_error (0x0x7f3505253958) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f35052d68a0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f35052d6900) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f35052d6960) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f35052d67e0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f35053ca2a0) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f3505090480) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2 entries +0 ((& std::basic_ostream::_ZTVSo) + 24) +8 ((& std::basic_ostream::_ZTVSo) + 64) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2 entries +0 ((& std::basic_istream::_ZTVSi) + 24) +8 ((& std::basic_istream::_ZTVSi) + 64) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream (0x0x7f3504c40068 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream (0x0x7f3504c40138 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7 entries +0 ((& std::basic_iostream::_ZTVSd) + 24) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream::_ZTVSd) + 104) +48 ((& std::basic_iostream::_ZTVSd) + 64) + +Construction vtable for std::basic_istream (0x0x7f3504c40f08 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream (0x0x7f3504c40270 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f3504c6ade0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f3504c6ae40) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f3504dd7240) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f3504a630c0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f3504a63540) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f3504b39300) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f3504bb9d20) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f3504bb9cc0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f350498aea0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f350472b720) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f350453da20) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f350453dae0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f3504212000) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f3504556208) 0 + std::iterator (0x0x7f3504212720) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f3504556340) 0 + std::_Bit_iterator_base (0x0x7f35045563a8) 0 + std::iterator (0x0x7f3504212d80) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f3504556410) 0 + std::_Bit_iterator_base (0x0x7f3504556478) 0 + std::iterator (0x0x7f35042435a0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f3503ffac00) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f35040fd9c0) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f35040fda20) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f3504556f70) 0 empty + QListData::NotIndirectLayout (0x0x7f35040fda80) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f35040f30e0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f35040fdae0) 0 empty + QListData::NotIndirectLayout (0x0x7f35040fdb40) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f3504556680) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f35040fdba0) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f35040fdc00) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f35040fd960) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f3503debde0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f3503ee6480) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f3503ee6420) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f3503ed3c30) 0 + QList (0x0x7f3503ed3c98) 0 + QListSpecialMethods (0x0x7f3503ee66c0) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f3503fb0240) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f3503c37360) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7f3503c376c0) 0 + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7f3503a17c60) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f3503a17cc0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f3503a17e40) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f3503a17f00) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f3503a38000) 0 + std::__uses_alloc_base (0x0x7f3503a17ea0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f3503ba72a0) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f35037bc720) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f35037bca80) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f35037e1000) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f35037e1540) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f3503847720) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f3503847de0) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f350387bc60) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f350355a360) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f35035b38a0) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f35033f76c0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f3503126180) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f35031261e0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f35031263c0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f3503126360) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f35031eb1e0) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f35031eb360) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f35031ebc00) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f35031ea208) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7f35031ebba0) 0 + primary-for QAbstractAnimation (0x0x7f35031ea208) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f3503228000) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f35031ea270) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7f35031ebf60) 0 + primary-for QAnimationDriver (0x0x7f35031ea270) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f3503228240) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f35031ea2d8) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7f35032281e0) 0 + primary-for QEventLoop (0x0x7f35031ea2d8) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f3503228ae0) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f3503228ba0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f3503228c00) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f35031ea410) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7f3503228b40) 0 + primary-for QAbstractEventDispatcher (0x0x7f35031ea410) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f35032b6d68) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7f3502f052a0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f35032b6d68) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f3502f05360) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f3502f053c0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f3502f056c0) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f3502cfd660) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f3502d35300) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f3502e03c60) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f3502e03c00) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f3502e03f00) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f3502b2c4e0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f3502b2c5a0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f3502b2c540) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f3502b2c600) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f3502b2c480) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f3502c858a0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f3502ccbf00) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f3502ccbea0) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f35028f2060) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f35028f2000) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f35029b01e0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f3502a06de0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f3502ad2c00) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f35026e0958) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7f3502ad2ba0) 0 + primary-for QAbstractItemModel (0x0x7f35026e0958) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f35027b5000) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f35026e0f70) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7f35027b1000) 0 + primary-for QAbstractTableModel (0x0x7f35026e0f70) + QObject (0x0x7f350272bf60) 0 + primary-for QAbstractItemModel (0x0x7f35027b1000) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f35027b5180) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f35027b1068) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7f35027b10d0) 0 + primary-for QAbstractListModel (0x0x7f35027b1068) + QObject (0x0x7f35027b5120) 0 + primary-for QAbstractItemModel (0x0x7f35027b10d0) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f35027b58a0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f35027b5960) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f35027b11a0) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7f35027b1208) 0 + primary-for QAbstractProxyModel (0x0x7f35027b11a0) + QObject (0x0x7f35027b5900) 0 + primary-for QAbstractItemModel (0x0x7f35027b1208) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f35027b5ba0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f35027b1270) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16) + QObject (0x0x7f35027b5b40) 0 + primary-for QAbstractState (0x0x7f35027b1270) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f35027b5de0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f35027b12d8) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16) + QObject (0x0x7f35027b5d80) 0 + primary-for QAbstractTransition (0x0x7f35027b12d8) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f350284d120) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f35027b1340) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7f35027b13a8) 0 + primary-for QAnimationGroup (0x0x7f35027b1340) + QObject (0x0x7f350284d0c0) 0 + primary-for QAbstractAnimation (0x0x7f35027b13a8) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f350289f480) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f35024df840) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f350252fcc0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f35025a00c0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f35025948f0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7f35025a0060) 0 + primary-for QIODevice (0x0x7f35025948f0) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f35025a0a20) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f3502594a28) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7f3502594a90) 0 + primary-for QBuffer (0x0x7f3502594a28) + QObject (0x0x7f35025a09c0) 0 + primary-for QIODevice (0x0x7f3502594a90) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f35025a0cc0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f35025a0c60) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f35025a0e40) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f35025a0de0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f3502608d20) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f3502663cc0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f35026ce5a0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f350233a240) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f350233a2a0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f350233a1e0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f350240e960) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f35020f8f00) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f350215c7e0) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f3502200300) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f3502226f60) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f3502256120) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f3501eddd20) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f3501eddcc0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f3502086d80) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f3502086e40) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f3501d36180) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f3501d36900) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f3501dde7e0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f3501e4a5a0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f3501ebf000) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f3501be7f60) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f3501c78ae0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f3501c78ba0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f35016ebba0) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f3501781600) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f3501781660) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f35017815a0) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f3501896060) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f35018960c0) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f3501896000) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f350168d7e0) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f3501349780) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f350137d4e0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f35013ff600) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f35013ff7e0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f35010f6d80) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f35011804e0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f3501157c30) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7f35011808a0) 0 + primary-for QTimerEvent (0x0x7f3501157c30) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f3501157c98) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7f3501180960) 0 + primary-for QChildEvent (0x0x7f3501157c98) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f35011b1208) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7f35011bf000) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f35011b1208) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f35011b1270) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7f35011bf0c0) 0 + primary-for QDeferredDeleteEvent (0x0x7f35011b1270) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f35011bf1e0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f35011b12d8) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7f35011bf180) 0 + primary-for QCoreApplication (0x0x7f35011b12d8) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f35011bf420) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7f35011bf5a0) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +216 (int (*)(...))QConcatenateTablesProxyModel::mimeData +224 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +232 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QConcatenateTablesProxyModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QConcatenateTablesProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7f35011b1340) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7f35011b13a8) 0 + primary-for QConcatenateTablesProxyModel (0x0x7f35011b1340) + QObject (0x0x7f35011bf540) 0 + primary-for QAbstractItemModel (0x0x7f35011b13a8) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f35011bf780) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f35011bf8a0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f35011bfa20) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f3501281180) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f35012818a0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f3500fc2600) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f3500fc05b0) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7f3500fc0618) 0 + primary-for QFileDevice (0x0x7f3500fc05b0) + QObject (0x0x7f3500fc25a0) 0 + primary-for QIODevice (0x0x7f3500fc0618) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f3500fc2f00) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f3500fc0750) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7f3500fc07b8) 0 + primary-for QFile (0x0x7f3500fc0750) + QIODevice (0x0x7f3500fc0820) 0 + primary-for QFileDevice (0x0x7f3500fc07b8) + QObject (0x0x7f3500fc2ea0) 0 + primary-for QIODevice (0x0x7f3500fc0820) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f35010285a0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f3501093960) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f3500d00cc0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f3500d4d480) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f3500e555a0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f3500e16a90) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16) + QAbstractTransition (0x0x7f3500e16af8) 0 + primary-for QEventTransition (0x0x7f3500e16a90) + QObject (0x0x7f3500e55540) 0 + primary-for QAbstractTransition (0x0x7f3500e16af8) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f3500e16b60) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7f3500e55780) 0 nearly-empty + primary-for QException (0x0x7f3500e16b60) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f3500e16bc8) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7f3500e16c30) 0 nearly-empty + primary-for QUnhandledException (0x0x7f3500e16bc8) + std::exception (0x0x7f3500e557e0) 0 nearly-empty + primary-for QException (0x0x7f3500e16c30) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f3500e55840) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f3500e55900) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f3500e55960) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f3500e55ba0) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f3500e16c98) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7f3500e55b40) 0 + primary-for QFileSelector (0x0x7f3500e16c98) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f3500e55de0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f3500e16d00) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7f3500e55d80) 0 + primary-for QFileSystemWatcher (0x0x7f3500e16d00) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f3500aae060) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f3500e16d68) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16) + QAbstractState (0x0x7f3500e16dd0) 0 + primary-for QFinalState (0x0x7f3500e16d68) + QObject (0x0x7f3500aae000) 0 + primary-for QAbstractState (0x0x7f3500e16dd0) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f3500aae240) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f3500aae4e0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f3500e16ea0) 0 + QBasicMutex (0x0x7f3500b2f180) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f3500b2f3c0) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f3500b2f840) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f3500b2fe40) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f3500b87060) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f3500bd4840) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f3500c71b40) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f3500c5e4e0) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7f3500c71ae0) 0 + primary-for QFutureWatcherBase (0x0x7f3500c5e4e0) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f3500899ea0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f3500c5ed00) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16) + QAbstractState (0x0x7f3500c5ed68) 0 + primary-for QHistoryState (0x0x7f3500c5ed00) + QObject (0x0x7f3500899e40) 0 + primary-for QAbstractState (0x0x7f3500c5ed68) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f35008cc1e0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f3500c5edd0) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7f3500c5ee38) 0 + primary-for QIdentityProxyModel (0x0x7f3500c5edd0) + QAbstractItemModel (0x0x7f3500c5eea0) 0 + primary-for QAbstractProxyModel (0x0x7f3500c5ee38) + QObject (0x0x7f35008cc180) 0 + primary-for QAbstractItemModel (0x0x7f3500c5eea0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f35008cc3c0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f3500985cc0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f350098f820) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7f3500985c60) 0 + primary-for QItemSelectionModel (0x0x7f350098f820) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f350098f9c0) 0 + QList (0x0x7f350098fa28) 0 + QListSpecialMethods (0x0x7f35009bd7e0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f3500a56120) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f35007b0300) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f35007f62a0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f35007f6540) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f35008398a0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f3500839900) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f3500839840) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f35005657e0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f3500565840) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f35005d4060) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f35005d40c0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f35005d4000) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f35002e7420) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f35002d7a90) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7f35002e73c0) 0 + primary-for QLibrary (0x0x7f35002d7a90) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f35003302a0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f35002e7d80) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f35003c99c0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f35003c9a20) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f3500438840) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f35000a89c0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f3500119d80) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f35001c5060) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f35002591e0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f3500259420) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f35002593c0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f3500259840) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f34fff11780) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f34ffd57f60) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f34ffd7f000) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f34ffde2840) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f34ffe21a80) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f34ffe21ba0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f34ffe80180) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f34ffe776e8) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7f34ffe80120) 0 + primary-for QMimeData (0x0x7f34ffe776e8) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f34ffe80360) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f34ffade480) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f34ffade540) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f34ffad9a28) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7f34ffade4e0) 0 + primary-for QObjectCleanupHandler (0x0x7f34ffad9a28) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f34ffade660) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f34ffb4cde0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f34ffb622d8) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7f34ffb62340) 0 + primary-for QParallelAnimationGroup (0x0x7f34ffb622d8) + QAbstractAnimation (0x0x7f34ffb623a8) 0 + primary-for QAnimationGroup (0x0x7f34ffb62340) + QObject (0x0x7f34ffb4cd80) 0 + primary-for QAbstractAnimation (0x0x7f34ffb623a8) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f34ffb76060) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f34ffb62410) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7f34ffb62478) 0 + primary-for QPauseAnimation (0x0x7f34ffb62410) + QObject (0x0x7f34ffb76000) 0 + primary-for QAbstractAnimation (0x0x7f34ffb62478) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f34ffb76c60) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f34ffbc4de0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f34ffbd17b8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7f34ffbc4d80) 0 + primary-for QPluginLoader (0x0x7f34ffbd17b8) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f34ffbc4f00) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f34ffc3c5a0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f34ffc3f410) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7f34ffc3f478) 0 + primary-for QProcess (0x0x7f34ffc3f410) + QObject (0x0x7f34ffc3c540) 0 + primary-for QIODevice (0x0x7f34ffc3f478) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f34ffc3cc60) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f34ffc3f4e0) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7f34ffc3f548) 0 + primary-for QVariantAnimation (0x0x7f34ffc3f4e0) + QObject (0x0x7f34ffc3cc00) 0 + primary-for QAbstractAnimation (0x0x7f34ffc3f548) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f34ffc3cf00) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f34ffc3f618) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7f34ffc3f680) 0 + primary-for QPropertyAnimation (0x0x7f34ffc3f618) + QAbstractAnimation (0x0x7f34ffc3f6e8) 0 + primary-for QVariantAnimation (0x0x7f34ffc3f680) + QObject (0x0x7f34ffc3cea0) 0 + primary-for QAbstractAnimation (0x0x7f34ffc3f6e8) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f34ff904660) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f34ffa0d3c0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f34ffa0d360) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f34ff7fa120) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f34ff606d80) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f34ff606d20) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f34ff2283a8) 0 + QRandomGenerator (0x0x7f34ff22f8a0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f34ff254480) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f34ff254720) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f34ff254c00) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f34ff2d9120) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f34ff322f00) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f34ff39aea0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f34ff040f00) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f34ff149060) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f34ff149300) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f34ff0d0d68) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7f34ff0d0dd0) 0 + primary-for QSaveFile (0x0x7f34ff0d0d68) + QIODevice (0x0x7f34ff0d0e38) 0 + primary-for QFileDevice (0x0x7f34ff0d0dd0) + QObject (0x0x7f34ff1492a0) 0 + primary-for QIODevice (0x0x7f34ff0d0e38) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f34ff149900) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f34ff149a80) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f34fee74d20) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f34fee7cb60) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7f34fee7cbc8) 0 + primary-for QSequentialAnimationGroup (0x0x7f34fee7cb60) + QAbstractAnimation (0x0x7f34fee7cc30) 0 + primary-for QAnimationGroup (0x0x7f34fee7cbc8) + QObject (0x0x7f34fee74cc0) 0 + primary-for QAbstractAnimation (0x0x7f34fee7cc30) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f34fee74f60) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f34fee7cc98) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7f34fee74f00) 0 + primary-for QSettings (0x0x7f34fee7cc98) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f34feeb5420) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f34fee7cd00) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7f34feeb53c0) 0 + primary-for QSharedMemory (0x0x7f34fee7cd00) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f34feeb5660) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f34fee7cd68) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7f34feeb5600) 0 + primary-for QSignalMapper (0x0x7f34fee7cd68) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f34feeb58a0) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f34fee7cdd0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16) + QAbstractTransition (0x0x7f34fee7ce38) 0 + primary-for QSignalTransition (0x0x7f34fee7cdd0) + QObject (0x0x7f34feeb5840) 0 + primary-for QAbstractTransition (0x0x7f34fee7ce38) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f34feeb5b40) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f34fee7cea0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7f34feeb5ae0) 0 + primary-for QSocketNotifier (0x0x7f34fee7cea0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f34feeb5d80) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f34fee7cf08) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7f34fee7cf70) 0 + primary-for QSortFilterProxyModel (0x0x7f34fee7cf08) + QAbstractItemModel (0x0x7f34feefb000) 0 + primary-for QAbstractProxyModel (0x0x7f34fee7cf70) + QObject (0x0x7f34feeb5d20) 0 + primary-for QAbstractItemModel (0x0x7f34feefb000) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f34fef241e0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f34fef24ae0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f34feefb1a0) 0 + vptr=((& QState::_ZTV6QState) + 16) + QAbstractState (0x0x7f34feefb208) 0 + primary-for QState (0x0x7f34feefb1a0) + QObject (0x0x7f34fef24a80) 0 + primary-for QAbstractState (0x0x7f34feefb208) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f34fef24f60) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f34feefb3a8) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16) + QEvent (0x0x7f34fef72000) 0 + primary-for QStateMachine::SignalEvent (0x0x7f34feefb3a8) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f34feefb410) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16) + QEvent (0x0x7f34fef72060) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f34feefb410) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f34feefb270) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16) + QState (0x0x7f34feefb2d8) 0 + primary-for QStateMachine (0x0x7f34feefb270) + QAbstractState (0x0x7f34feefb340) 0 + primary-for QState (0x0x7f34feefb2d8) + QObject (0x0x7f34fef24f00) 0 + primary-for QAbstractState (0x0x7f34feefb340) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f34fef72420) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f34ff010420) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f34fec9c780) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QStringListModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f34fec92548) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7f34fec925b0) 0 + primary-for QStringListModel (0x0x7f34fec92548) + QAbstractItemModel (0x0x7f34fec92618) 0 + primary-for QAbstractListModel (0x0x7f34fec925b0) + QObject (0x0x7f34fec9c720) 0 + primary-for QAbstractItemModel (0x0x7f34fec92618) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f34fec9c8a0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f34fec9c960) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f34fec9ca80) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f34fec92680) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7f34fec926e8) 0 + primary-for QTemporaryFile (0x0x7f34fec92680) + QFileDevice (0x0x7f34fec92750) 0 + primary-for QFile (0x0x7f34fec926e8) + QIODevice (0x0x7f34fec927b8) 0 + primary-for QFileDevice (0x0x7f34fec92750) + QObject (0x0x7f34fec9ca20) 0 + primary-for QIODevice (0x0x7f34fec927b8) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f34fec9cde0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f34fed03660) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0 +64 0 + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f34fed03600) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f34fed69060) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f34fed69240) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f34fed69420) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f34fec929c0) 0 + std::__mutex_base (0x0x7f34fed69480) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f34fed69660) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f34fed696c0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f34fed69720) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f34fedac180) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f34fec92a28) 0 + std::__recursive_mutex_base (0x0x7f34fedac1e0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f34fed5fee0) 0 + std::__mutex_base (0x0x7f34fedac5a0) 0 + std::__timed_mutex_impl (0x0x7f34fedac600) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f34fedcd230) 0 + std::__recursive_mutex_base (0x0x7f34fedac960) 0 + std::__timed_mutex_impl (0x0x7f34fedac9c0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f34fedf1120) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f34fec92b60) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7f34fedf1660) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f34fec92b60) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f34fec92bc8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7f34fedf1780) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f34fec92bc8) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f34fec92c30) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7f34fedf18a0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f34fec92c30) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f34fec92d00) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7f34fedf19c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f34fec92d00) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f34fea20a20) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f34fea20d20) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f34fea40060) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f34fea403c0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f34fec92d68) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7f34feabe5a0) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f34fec92d68) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f34feb26540) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7f34feb26960) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f34fe8727e0) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7f34fe89ec60) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f34fe89ecc0) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f34fe89ec00) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f34fe7620c0) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f34fe762480) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f34fe7624e0) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f34fe4e47e0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f34fe4e9618) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7f34fe4e9680) 0 + primary-for std::future_error (0x0x7f34fe4e9618) + std::exception (0x0x7f34fe4e4f00) 0 nearly-empty + primary-for std::logic_error (0x0x7f34fe4e9680) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f34fe519660) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f34fe519600) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f34fe2d8d80) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f34fe2d7ea0) 0 + std::__at_thread_exit_elt (0x0x7f34fe2d8e40) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f34fe5197e0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f34fe5195a0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f34fda71bc8) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7f34fda92e40) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f34fda71bc8) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f34fdacb720) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f34fda71f08) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7f34fdacb6c0) 0 + primary-for QThread (0x0x7f34fda71f08) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f34fdacbae0) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f34fda71f70) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7f34fdacba80) 0 + primary-for QThreadPool (0x0x7f34fda71f70) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f34fdacbcc0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f34fdb123c0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f34fdb1b000) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7f34fdb12360) 0 + primary-for QTimeLine (0x0x7f34fdb1b000) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f34fdb12600) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f34fdb1b068) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7f34fdb125a0) 0 + primary-for QTimer (0x0x7f34fdb1b068) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f34fdb59f60) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f34fdb59f00) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f34fd81b060) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f34fdc0e750) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7f34fd81b000) 0 + primary-for QTranslator (0x0x7f34fdc0e750) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7f34fd81b2a0) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QTransposeProxyModel::insertRows +264 (int (*)(...))QTransposeProxyModel::insertColumns +272 (int (*)(...))QTransposeProxyModel::removeRows +280 (int (*)(...))QTransposeProxyModel::removeColumns +288 (int (*)(...))QTransposeProxyModel::moveRows +296 (int (*)(...))QTransposeProxyModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QTransposeProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QTransposeProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QTransposeProxyModel::setSourceModel +392 (int (*)(...))QTransposeProxyModel::mapToSource +400 (int (*)(...))QTransposeProxyModel::mapFromSource +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7f34fdc0e7b8) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7f34fdc0e820) 0 + primary-for QTransposeProxyModel (0x0x7f34fdc0e7b8) + QAbstractItemModel (0x0x7f34fdc0e888) 0 + primary-for QAbstractProxyModel (0x0x7f34fdc0e820) + QObject (0x0x7f34fd81b240) 0 + primary-for QAbstractItemModel (0x0x7f34fdc0e888) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f34fd81b480) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f34fd8a2e40) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f34fd8a2f60) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f34fd94e360) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f34fd9a7f08) 0 + QVector (0x0x7f34fd9b4a80) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f34fd9b4d80) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f34fd630d20) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f34fd68cd20) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f34fd6f6de0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f34fd6f6e40) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f34fd735d20) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7f34fd735f00) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7f34fd7db540) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7f34fd42eb40) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7f34fd478d20) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7f34fd478de0) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7f34fd4bf120) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7f34fd4839c0) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16) + QObject (0x0x7f34fd4bf0c0) 0 + primary-for QGeoPositionInfoSource (0x0x7f34fd4839c0) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7f34fd4bf960) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7f34fd483af8) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16) + QObject (0x0x7f34fd4bf900) 0 + primary-for QGeoAreaMonitorSource (0x0x7f34fd483af8) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7f34fd483b60) 0 + QGeoShape (0x0x7f34fd4bfa80) 0 + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7f34fd53ff08) 0 + QGeoShape (0x0x7f34fd543f00) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7f34fd5d2120) 0 + +Class QGeoPath + size=8 align=8 + base size=8 base align=8 +QGeoPath (0x0x7f34fd11d9c0) 0 + QGeoShape (0x0x7f34fd121780) 0 + +Class QGeoPolygon + size=8 align=8 + base size=8 base align=8 +QGeoPolygon (0x0x7f34fd168b60) 0 + QGeoShape (0x0x7f34fd172960) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7f34fd1c1b40) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7f34fd1c1c60) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7f34fd1b6ea0) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16) + QObject (0x0x7f34fd1c1c00) 0 + primary-for QGeoSatelliteInfoSource (0x0x7f34fd1b6ea0) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7f34fd1c1de0) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16) + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7f34fd1f8060) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7f34fd1b6f08) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16) + QGeoPositionInfoSource (0x0x7f34fd1b6f70) 0 + primary-for QNmeaPositionInfoSource (0x0x7f34fd1b6f08) + QObject (0x0x7f34fd1f8000) 0 + primary-for QGeoPositionInfoSource (0x0x7f34fd1b6f70) + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd235420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd235780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd235960) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd235cc0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd235ea0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd26f240) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd26f420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd26f780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd26f960) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd26fcc0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd26fea0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd2a7240) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd2a7420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd2a7780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd2a7960) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd2a7cc0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd3061e0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd306540) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd3066c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd306a20) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fd306ba0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fd306f00) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fcf340c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fcf34420) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fcf345a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fcf34900) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fcf34a80) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fcf34de0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fcf34f60) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fcf68300) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f34fcf68480) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f34fcf687e0) 0 empty + diff --git a/tests/auto/bic/data/QtPositioning.5.14.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.14.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..789cea6 --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.14.0.linux-gcc-amd64.txt @@ -0,0 +1,5268 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7fe9fb51bd80) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7fe9fb5f3540) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7fe9fb5f3780) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7fe9fb5f39c0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7fe9fb5f3c00) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7fe9fb5f3d80) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7fe9fb62b180) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7fe9fb6612a0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7fe9fb6b5960) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7fe9fb6b5a20) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7fe9fb6b5de0) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7fe9fb6b5e40) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7fe9fb6b5ea0) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7fe9fb6b5f00) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7fe9fb6b5f60) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7fe9fb6e1060) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7fe9fb6e1120) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7fe9fb6e11e0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7fe9fb6e12a0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7fe9fb6e1600) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7fe9fb6e1960) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7fe9fb6e19c0) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7fe9fb6e1f60) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7fe9fb330600) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7fe9fb691d68) 0 empty + std::__nonesuch (0x0x7fe9fb330ae0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fe9fb3af480) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fe9fb3af4e0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fe9fb40c1e0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fe9fb40c240) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fe9fb3a5270) 0 empty + std::input_iterator_tag (0x0x7fe9fb40c2a0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fe9fb3a52d8) 0 empty + std::forward_iterator_tag (0x0x7fe9fb3a5340) 0 empty + std::input_iterator_tag (0x0x7fe9fb40c300) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fe9fb3a53a8) 0 empty + std::bidirectional_iterator_tag (0x0x7fe9fb3a5410) 0 empty + std::forward_iterator_tag (0x0x7fe9fb3a5478) 0 empty + std::input_iterator_tag (0x0x7fe9fb40c360) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7fe9fb499e40) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7fe9fb499f60) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7fe9fb4c12a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fe9fb4c15a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fe9fb4c16c0) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fe9fb14f9c0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fe9fb14fcc0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fe9fb14fd20) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7fe9fb14fde0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fe9fb14fe40) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7fe9fb14fea0) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7fe9fb14ff00) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fe9fb1901e0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fe9fb190480) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fe9fb1904e0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fe9fb2492a0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fe9fb3a57b8) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7fe9fb249480) 0 nearly-empty + primary-for std::bad_exception (0x0x7fe9fb3a57b8) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7fe9fb249660) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7fe9fb3a5820) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7fe9fb249a20) 0 nearly-empty + primary-for std::bad_cast (0x0x7fe9fb3a5820) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7fe9fb3a5888) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7fe9fb249c00) 0 nearly-empty + primary-for std::bad_typeid (0x0x7fe9fb3a5888) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7fe9fb249de0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7fe9fb2823c0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fe9fb3a58f0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7fe9fb282a80) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fe9fb3a58f0) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7fe9fb3a5958) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7fe9fb3a59c0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7fe9fb3a5958) + std::exception (0x0x7fe9fb282c60) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fe9fb3a59c0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fe9fb282e40) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7fe9fb2b3060) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fe9faf29540) 0 empty + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fe9fab9ba80) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fe9fab9bba0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fe9fab9bd80) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fe9fabde480) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fe9fac18c00) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7fe9facd0120) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7fe9fac5f820) 0 + std::__atomic_flag_base (0x0x7fe9facd0180) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fe9fac5ff70) 0 + QAtomicInteger (0x0x7fe9fa842000) 0 + QBasicAtomicInteger (0x0x7fe9fa7f93c0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fe9fa43bf00) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fe9fa4a24e0) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fe9fa4a2c00) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fe9fa694c30) 0 + QGenericArgument (0x0x7fe9fa4a2ea0) 0 + +Class QMetaObject::SuperData + size=8 align=8 + base size=8 base align=8 +QMetaObject::SuperData (0x0x7fe9fa4dc360) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7fe9fa4dc300) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fe9fa4dcc00) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fe9fa18d720) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fe9fa18de40) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fe9fa25dc60) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7fe9fa29c000) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fe9fa2e2300) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fe9f9f96b40) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fe9f9f96c00) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fe9fa05dd20) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fe9fa05dde0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fe9fa05de40) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fe9fa05dea0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fe9fa05df00) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fe9fa0b5060) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fe9fa0b50c0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7fe9f9dd5060) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fe9f9dd50c0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7fe9f9b81120) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7fe9f9b812a0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fe9f9d07420) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fe9f9d077e0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fe9f9d07a80) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fe9f9d07c60) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7fe9f9953c60) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7fe9f9b93d68) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7fe9f9953d20) 0 nearly-empty + primary-for std::logic_error (0x0x7fe9f9b93d68) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7fe9f9b93dd0) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7fe9f9b93e38) 0 + primary-for std::domain_error (0x0x7fe9f9b93dd0) + std::exception (0x0x7fe9f9953d80) 0 nearly-empty + primary-for std::logic_error (0x0x7fe9f9b93e38) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7fe9f9b93ea0) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7fe9f9b93f08) 0 + primary-for std::invalid_argument (0x0x7fe9f9b93ea0) + std::exception (0x0x7fe9f9953de0) 0 nearly-empty + primary-for std::logic_error (0x0x7fe9f9b93f08) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7fe9f9b93f70) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7fe9f9b93270) 0 + primary-for std::length_error (0x0x7fe9f9b93f70) + std::exception (0x0x7fe9f9953e40) 0 nearly-empty + primary-for std::logic_error (0x0x7fe9f9b93270) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7fe9f9b932d8) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7fe9f9b93618) 0 + primary-for std::out_of_range (0x0x7fe9f9b932d8) + std::exception (0x0x7fe9f9953ea0) 0 nearly-empty + primary-for std::logic_error (0x0x7fe9f9b93618) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7fe9f9b93680) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7fe9f9953f00) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe9f9b93680) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7fe9f99b3000) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7fe9f99b3068) 0 + primary-for std::range_error (0x0x7fe9f99b3000) + std::exception (0x0x7fe9f9953f60) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe9f99b3068) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7fe9f99b30d0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7fe9f99b3138) 0 + primary-for std::overflow_error (0x0x7fe9f99b30d0) + std::exception (0x0x7fe9f99b9000) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe9f99b3138) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7fe9f99b31a0) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7fe9f99b3208) 0 + primary-for std::underflow_error (0x0x7fe9f99b31a0) + std::exception (0x0x7fe9f99b9060) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe9f99b3208) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7fe9f99b91e0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7fe9f99b9540) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7fe9f99b9d80) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7fe9f99b3618) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7fe9f99b3680) 0 + primary-for std::system_error (0x0x7fe9f99b3618) + std::exception (0x0x7fe9f99ee960) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe9f99b3680) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7fe9f99b38f0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7fe9f99b3958) 0 + primary-for std::ios_base::failure (0x0x7fe9f99b38f0) + std::runtime_error (0x0x7fe9f99b39c0) 0 + primary-for std::system_error (0x0x7fe9f99b3958) + std::exception (0x0x7fe9f9a23f00) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe9f99b39c0) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fe9f9a23f60) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fe9f9a56000) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fe9f9a56060) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fe9f9a23ea0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fe9f9718960) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fe9f97c2b40) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2 entries +0 ((& std::basic_ostream::_ZTVSo) + 24) +8 ((& std::basic_ostream::_ZTVSo) + 64) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2 entries +0 ((& std::basic_istream::_ZTVSi) + 24) +8 ((& std::basic_istream::_ZTVSi) + 64) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream (0x0x7fe9f939d0d0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream (0x0x7fe9f939d1a0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7 entries +0 ((& std::basic_iostream::_ZTVSd) + 24) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream::_ZTVSd) + 104) +48 ((& std::basic_iostream::_ZTVSd) + 64) + +Construction vtable for std::basic_istream (0x0x7fe9f939df70 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream (0x0x7fe9f939d340 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7fe9f93fc4e0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7fe9f93fc540) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7fe9f9116900) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7fe9f91ba780) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7fe9f91bac00) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fe9f929bcc0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7fe9f8f53c60) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7fe9f8f53b40) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7fe9f8e14ae0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7fe9f8b876c0) 0 + +Class QtPrivate::ArgBase + size=1 align=1 + base size=1 base align=1 +QtPrivate::ArgBase (0x0x7fe9f88144e0) 0 + +Class QtPrivate::QStringViewArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QStringViewArg (0x0x7fe9f8c15d68) 0 + QtPrivate::ArgBase (0x0x7fe9f8814540) 0 + +Class QtPrivate::QLatin1StringArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QLatin1StringArg (0x0x7fe9f8c15dd0) 0 + QtPrivate::ArgBase (0x0x7fe9f8814720) 0 + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7fe9f88e4660) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7fe9f88e46c0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7fe9f88e4840) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7fe9f88e4900) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7fe9f88f41a0) 0 + std::__uses_alloc_base (0x0x7fe9f88e48a0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7fe9f8644c60) 0 empty + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7fe9f86b6410) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7fe9f86bf5a0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7fe9f86b6410) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7fe9f86bf660) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7fe9f86bf6c0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7fe9f86bf9c0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7fe9f84b8e40) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7fe9f84b8f00) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fe9f81ec660) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fe9f84fef70) 0 + std::iterator (0x0x7fe9f81ecd80) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fe9f821d0d0) 0 + std::_Bit_iterator_base (0x0x7fe9f821d138) 0 + std::iterator (0x0x7fe9f8216420) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fe9f821d1a0) 0 + std::_Bit_iterator_base (0x0x7fe9f821d208) 0 + std::iterator (0x0x7fe9f8216c00) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fe9f806e780) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7fe9f813a540) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7fe9f813a5a0) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7fe9f821ddd0) 0 empty + QListData::NotIndirectLayout (0x0x7fe9f813a600) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7fe9f80958c0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fe9f813a660) 0 empty + QListData::NotIndirectLayout (0x0x7fe9f813a6c0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7fe9f821de38) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fe9f813a720) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7fe9f813a780) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7fe9f813a4e0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7fe9f7e2b900) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7fe9f7f0be40) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7fe9f7f0bde0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7fe9f7f10a28) 0 + QList (0x0x7fe9f7f10a90) 0 + QListSpecialMethods (0x0x7fe9f7f3a0c0) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fe9f7c09000) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fe9f7c90240) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7fe9f7c905a0) 0 + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7fe9f7a15ba0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7fe9f7a15f00) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7fe9f7a36480) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7fe9f7a369c0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7fe9f7a8aba0) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7fe9f7abf2a0) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fe9f7759120) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fe9f77b07e0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fe9f7804d20) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7fe9f76d3300) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7fe9f73abd80) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7fe9f73abde0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fe9f7412000) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fe9f73abf60) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7fe9f7482de0) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fe9f7482f60) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fe9f74b6840) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fe9f7475bc8) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7fe9f74b67e0) 0 + primary-for QAbstractAnimation (0x0x7fe9f7475bc8) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fe9f74b6c00) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fe9f7475c30) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7fe9f74b6ba0) 0 + primary-for QAnimationDriver (0x0x7fe9f7475c30) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fe9f74b6e40) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fe9f7475c98) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7fe9f74b6de0) 0 + primary-for QEventLoop (0x0x7fe9f7475c98) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fe9f7103720) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fe9f71037e0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fe9f7103840) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fe9f7475dd0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7fe9f7103780) 0 + primary-for QAbstractEventDispatcher (0x0x7fe9f7475dd0) + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7fe9f716b840) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7fe9f71934e0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7fe9f725ae40) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7fe9f725ade0) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fe9f7283120) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7fe9f6f90840) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7fe9f6f90900) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7fe9f6f908a0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7fe9f6f90960) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7fe9f6f907e0) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7fe9f7089c00) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7fe9f6d532a0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7fe9f6d53240) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7fe9f6d533c0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7fe9f6d53360) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fe9f6e1e540) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fe9f6e8f180) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fe9f6b46f60) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fe9f6b43f70) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7fe9f6b46f00) 0 + primary-for QAbstractItemModel (0x0x7fe9f6b43f70) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fe9f6c28360) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fe9f6b8d5b0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7fe9f6b8d618) 0 + primary-for QAbstractTableModel (0x0x7fe9f6b8d5b0) + QObject (0x0x7fe9f6c28300) 0 + primary-for QAbstractItemModel (0x0x7fe9f6b8d618) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fe9f6c284e0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fe9f6b8d680) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7fe9f6b8d6e8) 0 + primary-for QAbstractListModel (0x0x7fe9f6b8d680) + QObject (0x0x7fe9f6c28480) 0 + primary-for QAbstractItemModel (0x0x7fe9f6b8d6e8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fe9f6c28c00) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fe9f6c28cc0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fe9f6b8d7b8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7fe9f6b8d820) 0 + primary-for QAbstractProxyModel (0x0x7fe9f6b8d7b8) + QObject (0x0x7fe9f6c28c60) 0 + primary-for QAbstractItemModel (0x0x7fe9f6b8d820) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7fe9f6c28f00) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7fe9f6b8d888) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16) + QObject (0x0x7fe9f6c28ea0) 0 + primary-for QAbstractState (0x0x7fe9f6b8d888) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7fe9f6cb7180) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7fe9f6b8d8f0) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16) + QObject (0x0x7fe9f6cb7120) 0 + primary-for QAbstractTransition (0x0x7fe9f6b8d8f0) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fe9f6cb7480) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fe9f6b8d958) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7fe9f6b8d9c0) 0 + primary-for QAnimationGroup (0x0x7fe9f6b8d958) + QObject (0x0x7fe9f6cb7420) 0 + primary-for QAbstractAnimation (0x0x7fe9f6b8d9c0) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fe9f6918780) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7fe9f69b0120) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7fe9f6a115a0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fe9f6a5c840) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fe9f6a51f70) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7fe9f6a5c7e0) 0 + primary-for QIODevice (0x0x7fe9f6a51f70) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fe9f6aa41e0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fe9f6a840d0) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7fe9f6a84138) 0 + primary-for QBuffer (0x0x7fe9f6a840d0) + QObject (0x0x7fe9f6aa4180) 0 + primary-for QIODevice (0x0x7fe9f6a84138) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fe9f6aa4480) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7fe9f6aa4420) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7fe9f6aa4600) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7fe9f6aa45a0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fe9f6af34e0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fe9f67333c0) 0 + +Class QCalendar::YearMonthDay + size=12 align=4 + base size=12 base align=4 +QCalendar::YearMonthDay (0x0x7fe9f68a08a0) 0 + +Class QCalendar + size=8 align=8 + base size=8 base align=8 +QCalendar (0x0x7fe9f68a0840) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fe9f68d90c0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fe9f6531960) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7fe9f659b600) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7fe9f659b660) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fe9f659b5a0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fe9f6668d20) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fe9f66b9600) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7fe9f635e2a0) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7fe9f6365138) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7fe9f63b0120) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7fe9f6365138) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7fe9f63651a0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7fe9f63b0240) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7fe9f63651a0) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7fe9f6365208) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7fe9f63b0360) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7fe9f6365208) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7fe9f63652d8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7fe9f63b0480) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7fe9f63652d8) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7fe9f63d64e0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7fe9f63d67e0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7fe9f63d6ae0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7fe9f63d6e40) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7fe9f6365340) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7fe9f6476060) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7fe9f6365340) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7fe9f64db000) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7fe9f64db420) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7fe9f62232a0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fe9f6251780) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fe9f6251900) 0 + +Class QtPrivate::EnableInternalData + size=1 align=1 + base size=0 base align=1 +QtPrivate::EnableInternalData (0x0x7fe9f62db240) 0 empty + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7fe9f5f08900) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fe9f5f088a0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fe9f6099240) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fe9f6099300) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7fe9f5d1e540) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fe9f5d1ecc0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fe9f5dd8ba0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fe9f5e3e960) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fe9f5ebd3c0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fe9f5c0b360) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7fe9f5c71ea0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7fe9f5c71f60) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7fe9f5adab40) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7fe9f57805a0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7fe9f5780600) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7fe9f5780540) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7fe9f54fe1e0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7fe9f54fe240) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7fe9f54fe180) 0 + +Class qfloat16::Wrap + size=2 align=2 + base size=2 base align=2 +qfloat16::Wrap (0x0x7fe9f53039c0) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7fe9f5303960) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7fe9f53e7660) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7fe9f541b3c0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fe9f549e4e0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fe9f549e6c0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fe9f5192cc0) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7fe9f528e240) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7fe9f525ad68) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7fe9f528e600) 0 + primary-for QTimerEvent (0x0x7fe9f525ad68) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7fe9f525add0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7fe9f528e6c0) 0 + primary-for QChildEvent (0x0x7fe9f525add0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7fe9f52bb340) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7fe9f528ed20) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fe9f52bb340) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7fe9f52bb3a8) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7fe9f528ede0) 0 + primary-for QDeferredDeleteEvent (0x0x7fe9f52bb3a8) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fe9f528ef00) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fe9f52bb410) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7fe9f528eea0) 0 + primary-for QCoreApplication (0x0x7fe9f52bb410) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fe9f52e7180) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7fe9f52e7300) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +216 (int (*)(...))QConcatenateTablesProxyModel::mimeData +224 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +232 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QConcatenateTablesProxyModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QConcatenateTablesProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7fe9f52bb478) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7fe9f52bb4e0) 0 + primary-for QConcatenateTablesProxyModel (0x0x7fe9f52bb478) + QObject (0x0x7fe9f52e72a0) 0 + primary-for QAbstractItemModel (0x0x7fe9f52bb4e0) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fe9f52e74e0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fe9f52e7600) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7fe9f52e7780) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fe9f4f59ea0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7fe9f4f98600) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fe9f50d2300) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fe9f50c86e8) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7fe9f50c8750) 0 + primary-for QFileDevice (0x0x7fe9f50c86e8) + QObject (0x0x7fe9f50d22a0) 0 + primary-for QIODevice (0x0x7fe9f50c8750) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fe9f50d2c00) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fe9f50c8888) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7fe9f50c88f0) 0 + primary-for QFile (0x0x7fe9f50c8888) + QIODevice (0x0x7fe9f50c8958) 0 + primary-for QFileDevice (0x0x7fe9f50c88f0) + QObject (0x0x7fe9f50d2ba0) 0 + primary-for QIODevice (0x0x7fe9f50c8958) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fe9f4d472a0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fe9f4e16180) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fe9f4b3f180) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fe9f4b3f900) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7fe9f4c6fa20) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7fe9f4c3a618) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16) + QAbstractTransition (0x0x7fe9f4c3a680) 0 + primary-for QEventTransition (0x0x7fe9f4c3a618) + QObject (0x0x7fe9f4c6f9c0) 0 + primary-for QAbstractTransition (0x0x7fe9f4c3a680) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fe9f4c3a6e8) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7fe9f4c6fc00) 0 nearly-empty + primary-for QException (0x0x7fe9f4c3a6e8) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7fe9f4c3a750) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7fe9f4c3a7b8) 0 nearly-empty + primary-for QUnhandledException (0x0x7fe9f4c3a750) + std::exception (0x0x7fe9f4c6fc60) 0 nearly-empty + primary-for QException (0x0x7fe9f4c3a7b8) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7fe9f4c6fcc0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fe9f4c6fd80) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fe9f4c6fde0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fe9f4cb3060) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fe9f4c3a820) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7fe9f4cb3000) 0 + primary-for QFileSelector (0x0x7fe9f4c3a820) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fe9f4cb32a0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fe9f4c3a888) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7fe9f4cb3240) 0 + primary-for QFileSystemWatcher (0x0x7fe9f4c3a888) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7fe9f4cb34e0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7fe9f4c3a8f0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16) + QAbstractState (0x0x7fe9f4c3a958) 0 + primary-for QFinalState (0x0x7fe9f4c3a8f0) + QObject (0x0x7fe9f4cb3480) 0 + primary-for QAbstractState (0x0x7fe9f4c3a958) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7fe9f4cb36c0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fe9f4cb3960) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fe9f4c3aa28) 0 + QBasicMutex (0x0x7fe9f490c600) 0 + +Class QRecursiveMutex + size=8 align=8 + base size=8 base align=8 +QRecursiveMutex (0x0x7fe9f4c3aa90) 0 + QMutex (0x0x7fe9f4c3aaf8) 0 + QBasicMutex (0x0x7fe9f490c840) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7fe9f490c8a0) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fe9f490cea0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fe9f493b4e0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fe9f493b6c0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7fe9f49afea0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7fe9f49c1410) 0 + std::__mutex_base (0x0x7fe9f49aff00) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7fe9f49d4120) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7fe9f49d4180) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7fe9f49d41e0) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7fe9f49d4c00) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7fe9f49c1478) 0 + std::__recursive_mutex_base (0x0x7fe9f49d4c60) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7fe9f49d2af0) 0 + std::__mutex_base (0x0x7fe9f4a0a060) 0 + std::__timed_mutex_impl (0x0x7fe9f4a0a0c0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7fe9f49d2e70) 0 + std::__recursive_mutex_base (0x0x7fe9f4a0a420) 0 + std::__timed_mutex_impl (0x0x7fe9f4a0a480) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7fe9f4a0aba0) 0 + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fe9f4a0ade0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fe9f46f1180) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fe9f46ce270) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7fe9f46f1120) 0 + primary-for QFutureWatcherBase (0x0x7fe9f46ce270) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7fe9f47224e0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7fe9f46cea90) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16) + QAbstractState (0x0x7fe9f46ceaf8) 0 + primary-for QHistoryState (0x0x7fe9f46cea90) + QObject (0x0x7fe9f4722480) 0 + primary-for QAbstractState (0x0x7fe9f46ceaf8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fe9f47227e0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fe9f46ceb60) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7fe9f46cebc8) 0 + primary-for QIdentityProxyModel (0x0x7fe9f46ceb60) + QAbstractItemModel (0x0x7fe9f46cec30) 0 + primary-for QAbstractProxyModel (0x0x7fe9f46cebc8) + QObject (0x0x7fe9f4722780) 0 + primary-for QAbstractItemModel (0x0x7fe9f46cec30) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fe9f47229c0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fe9f4808300) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fe9f48025b0) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7fe9f48082a0) 0 + primary-for QItemSelectionModel (0x0x7fe9f48025b0) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7fe9f4802750) 0 + QList (0x0x7fe9f48027b8) 0 + QListSpecialMethods (0x0x7fe9f4808de0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7fe9f48b1720) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7fe9f46143c0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7fe9f4661360) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7fe9f4661600) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7fe9f46a5960) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7fe9f46a59c0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7fe9f46a5900) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fe9f43d38a0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fe9f43d3900) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7fe9f443b120) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7fe9f443b180) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7fe9f443b0c0) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fe9f41615a0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7fe9f4160410) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7fe9f4161540) 0 + primary-for QLibrary (0x0x7fe9f4160410) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7fe9f41ab420) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7fe9f4161f00) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fe9f4242ba0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fe9f4242c00) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fe9f3eb3a80) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fe9f3f23c60) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fe9f3fc2060) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7fe9f403b300) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fe9f3cda840) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7fe9f3cdaa80) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fe9f3cdaa20) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fe9f3cdaea0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fe9f3d90de0) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fe9f3c01600) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7fe9f3c01660) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7fe9f3c69ea0) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fe9f37c60c0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7fe9f37c61e0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fe9f3809780) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fe9f3814068) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7fe9f3809720) 0 + primary-for QMimeData (0x0x7fe9f3814068) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fe9f3809960) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fe9f38da8a0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fe9f38da960) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7fe9f38d1bc8) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7fe9f38da900) 0 + primary-for QObjectCleanupHandler (0x0x7fe9f38d1bc8) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7fe9f38daa80) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fe9f3966240) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fe9f395e478) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7fe9f395e4e0) 0 + primary-for QParallelAnimationGroup (0x0x7fe9f395e478) + QAbstractAnimation (0x0x7fe9f395e548) 0 + primary-for QAnimationGroup (0x0x7fe9f395e4e0) + QObject (0x0x7fe9f39661e0) 0 + primary-for QAbstractAnimation (0x0x7fe9f395e548) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fe9f3966480) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fe9f395e5b0) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7fe9f395e618) 0 + primary-for QPauseAnimation (0x0x7fe9f395e5b0) + QObject (0x0x7fe9f3966420) 0 + primary-for QAbstractAnimation (0x0x7fe9f395e618) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7fe9f399e000) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fe9f35d9180) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fe9f35cf958) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7fe9f35d9120) 0 + primary-for QPluginLoader (0x0x7fe9f35cf958) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fe9f35d92a0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fe9f36a9720) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fe9f369bdd0) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7fe9f369be38) 0 + primary-for QProcess (0x0x7fe9f369bdd0) + QObject (0x0x7fe9f36a96c0) 0 + primary-for QIODevice (0x0x7fe9f369be38) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fe9f36a9de0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fe9f369bea0) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7fe9f369bf08) 0 + primary-for QVariantAnimation (0x0x7fe9f369bea0) + QObject (0x0x7fe9f36a9d80) 0 + primary-for QAbstractAnimation (0x0x7fe9f369bf08) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fe9f36f80c0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fe9f36f9000) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7fe9f36f9068) 0 + primary-for QPropertyAnimation (0x0x7fe9f36f9000) + QAbstractAnimation (0x0x7fe9f36f90d0) 0 + primary-for QVariantAnimation (0x0x7fe9f36f9068) + QObject (0x0x7fe9f36f8060) 0 + primary-for QAbstractAnimation (0x0x7fe9f36f90d0) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7fe9f376e7e0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7fe9f3479540) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7fe9f34794e0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7fe9f32692a0) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7fe9f3074f00) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7fe9f3074ea0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7fe9f3103d68) 0 + QRandomGenerator (0x0x7fe9f311da20) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fe9f3142600) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fe9f31428a0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fe9f3142d80) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fe9f2dcc2a0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fe9f2e42180) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fe9f2ebf1e0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fe9f2f76240) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fe9f2c31360) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fe9f2c31600) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fe9f2bdd750) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7fe9f2bdd7b8) 0 + primary-for QSaveFile (0x0x7fe9f2bdd750) + QIODevice (0x0x7fe9f2bdd820) 0 + primary-for QFileDevice (0x0x7fe9f2bdd7b8) + QObject (0x0x7fe9f2c315a0) 0 + primary-for QIODevice (0x0x7fe9f2bdd820) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fe9f2c31c00) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7fe9f2c31d80) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fe9f2d2e9c0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fe9f2d42000) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7fe9f2d42068) 0 + primary-for QSequentialAnimationGroup (0x0x7fe9f2d42000) + QAbstractAnimation (0x0x7fe9f2d420d0) 0 + primary-for QAnimationGroup (0x0x7fe9f2d42068) + QObject (0x0x7fe9f2d2e960) 0 + primary-for QAbstractAnimation (0x0x7fe9f2d420d0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fe9f2d2ec00) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fe9f2d42138) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7fe9f2d2eba0) 0 + primary-for QSettings (0x0x7fe9f2d42138) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fe9f2d770c0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fe9f2d421a0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7fe9f2d77060) 0 + primary-for QSharedMemory (0x0x7fe9f2d421a0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fe9f2d77300) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fe9f2d42208) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7fe9f2d772a0) 0 + primary-for QSignalMapper (0x0x7fe9f2d42208) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7fe9f2d77540) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7fe9f2d42270) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16) + QAbstractTransition (0x0x7fe9f2d422d8) 0 + primary-for QSignalTransition (0x0x7fe9f2d42270) + QObject (0x0x7fe9f2d774e0) 0 + primary-for QAbstractTransition (0x0x7fe9f2d422d8) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fe9f2d777e0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fe9f2d42340) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7fe9f2d77780) 0 + primary-for QSocketNotifier (0x0x7fe9f2d42340) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fe9f2d77a20) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fe9f2d423a8) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7fe9f2d42410) 0 + primary-for QSortFilterProxyModel (0x0x7fe9f2d423a8) + QAbstractItemModel (0x0x7fe9f2d42478) 0 + primary-for QAbstractProxyModel (0x0x7fe9f2d42410) + QObject (0x0x7fe9f2d779c0) 0 + primary-for QAbstractItemModel (0x0x7fe9f2d42478) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fe9f2d77e40) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7fe9f29f6780) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7fe9f2d42618) 0 + vptr=((& QState::_ZTV6QState) + 16) + QAbstractState (0x0x7fe9f2d42680) 0 + primary-for QState (0x0x7fe9f2d42618) + QObject (0x0x7fe9f29f6720) 0 + primary-for QAbstractState (0x0x7fe9f2d42680) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7fe9f29f6c00) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7fe9f2d42820) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16) + QEvent (0x0x7fe9f29f6c60) 0 + primary-for QStateMachine::SignalEvent (0x0x7fe9f2d42820) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7fe9f2d42888) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16) + QEvent (0x0x7fe9f29f6cc0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7fe9f2d42888) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7fe9f2d426e8) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16) + QState (0x0x7fe9f2d42750) 0 + primary-for QStateMachine (0x0x7fe9f2d426e8) + QAbstractState (0x0x7fe9f2d427b8) 0 + primary-for QState (0x0x7fe9f2d42750) + QObject (0x0x7fe9f29f6ba0) 0 + primary-for QAbstractState (0x0x7fe9f2d427b8) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fe9f2a4e0c0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fe9f2b26e40) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fe9f27d51e0) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QStringListModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7fe9f27c21a0) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7fe9f27c2208) 0 + primary-for QStringListModel (0x0x7fe9f27c21a0) + QAbstractItemModel (0x0x7fe9f27c2270) 0 + primary-for QAbstractListModel (0x0x7fe9f27c2208) + QObject (0x0x7fe9f27d5180) 0 + primary-for QAbstractItemModel (0x0x7fe9f27c2270) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fe9f27d5300) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fe9f27d53c0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fe9f27d54e0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fe9f27c22d8) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7fe9f27c2340) 0 + primary-for QTemporaryFile (0x0x7fe9f27c22d8) + QFileDevice (0x0x7fe9f27c23a8) 0 + primary-for QFile (0x0x7fe9f27c2340) + QIODevice (0x0x7fe9f27c2410) 0 + primary-for QFileDevice (0x0x7fe9f27c23a8) + QObject (0x0x7fe9f27d5480) 0 + primary-for QIODevice (0x0x7fe9f27c2410) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7fe9f27d5840) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7fe9f28500c0) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0 +64 0 + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7fe9f2850060) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7fe9f2850a80) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7fe9f2850c60) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7fe9f2850ea0) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7fe9f2850f00) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7fe9f2850e40) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7fe9f273f300) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7fe9f273f6c0) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7fe9f273f720) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7fe9f24c6a20) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7fe9f24ca7b8) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7fe9f24ca820) 0 + primary-for std::future_error (0x0x7fe9f24ca7b8) + std::exception (0x0x7fe9f24f4180) 0 nearly-empty + primary-for std::logic_error (0x0x7fe9f24ca820) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7fe9f24f48a0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7fe9f24f4840) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7fe9f2310000) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7fe9f22f9068) 0 + std::__at_thread_exit_elt (0x0x7fe9f23100c0) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7fe9f24f4a20) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7fe9f24f47e0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7fe9f1a53d68) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7fe9f1aaf0c0) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7fe9f1a53d68) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fe9f1aaf960) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fe9f1ac10d0) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7fe9f1aaf900) 0 + primary-for QThread (0x0x7fe9f1ac10d0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fe9f1aafd20) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fe9f1ac1138) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7fe9f1aafcc0) 0 + primary-for QThreadPool (0x0x7fe9f1ac1138) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fe9f1aaff00) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fe9f1af4600) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fe9f1ac11a0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7fe9f1af45a0) 0 + primary-for QTimeLine (0x0x7fe9f1ac11a0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fe9f1af4840) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7fe9f1ac1208) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7fe9f1af47e0) 0 + primary-for QTimer (0x0x7fe9f1ac1208) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7fe9f1b621e0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fe9f1b62180) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fe9f18002a0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fe9f17f58f0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7fe9f1800240) 0 + primary-for QTranslator (0x0x7fe9f17f58f0) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7fe9f18004e0) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QTransposeProxyModel::insertRows +264 (int (*)(...))QTransposeProxyModel::insertColumns +272 (int (*)(...))QTransposeProxyModel::removeRows +280 (int (*)(...))QTransposeProxyModel::removeColumns +288 (int (*)(...))QTransposeProxyModel::moveRows +296 (int (*)(...))QTransposeProxyModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QTransposeProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QTransposeProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QTransposeProxyModel::setSourceModel +392 (int (*)(...))QTransposeProxyModel::mapToSource +400 (int (*)(...))QTransposeProxyModel::mapFromSource +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7fe9f17f5958) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7fe9f17f59c0) 0 + primary-for QTransposeProxyModel (0x0x7fe9f17f5958) + QAbstractItemModel (0x0x7fe9f17f5a28) 0 + primary-for QAbstractProxyModel (0x0x7fe9f17f59c0) + QObject (0x0x7fe9f1800480) 0 + primary-for QAbstractItemModel (0x0x7fe9f17f5a28) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fe9f18006c0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fe9f18f8ba0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7fe9f18f8cc0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7fe9f19a50c0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7fe9f14fdd00) 0 + QVector (0x0x7fe9f15097e0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fe9f1509ae0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7fe9f158ca80) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7fe9f15e9a80) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fe9f1654b40) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fe9f1654ba0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fe9f1693a80) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7fe9f1693c60) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7fe9f13372a0) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7fe9f13878a0) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7fe9f13dba80) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7fe9f13dbb40) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7fe9f13dbe40) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7fe9f13e17b8) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16) + QObject (0x0x7fe9f13dbde0) 0 + primary-for QGeoPositionInfoSource (0x0x7fe9f13e17b8) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7fe9f142f6c0) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7fe9f13e18f0) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16) + QObject (0x0x7fe9f142f660) 0 + primary-for QGeoAreaMonitorSource (0x0x7fe9f13e18f0) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7fe9f13e1958) 0 + QGeoShape (0x0x7fe9f142f7e0) 0 + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7fe9f149cd00) 0 + QGeoShape (0x0x7fe9f14a6c60) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7fe9f111be40) 0 + +Class QGeoPath + size=8 align=8 + base size=8 base align=8 +QGeoPath (0x0x7fe9f11857b8) 0 + QGeoShape (0x0x7fe9f118a4e0) 0 + +Class QGeoPolygon + size=8 align=8 + base size=8 base align=8 +QGeoPolygon (0x0x7fe9f11d1958) 0 + QGeoShape (0x0x7fe9f11d56c0) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7fe9f12248a0) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7fe9f12249c0) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7fe9f1215c98) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16) + QObject (0x0x7fe9f1224960) 0 + primary-for QGeoSatelliteInfoSource (0x0x7fe9f1215c98) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7fe9f1224b40) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16) + +Vtable for QGeoPositionInfoSourceFactoryV2 +QGeoPositionInfoSourceFactoryV2::_ZTV31QGeoPositionInfoSourceFactoryV2: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QGeoPositionInfoSourceFactoryV2) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactoryV2 + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactoryV2 (0x0x7fe9f1215d00) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactoryV2::_ZTV31QGeoPositionInfoSourceFactoryV2) + 16) + QGeoPositionInfoSourceFactory (0x0x7fe9f1224d20) 0 nearly-empty + primary-for QGeoPositionInfoSourceFactoryV2 (0x0x7fe9f1215d00) + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7fe9f1224f60) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7fe9f1215d68) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16) + QGeoPositionInfoSource (0x0x7fe9f1215dd0) 0 + primary-for QNmeaPositionInfoSource (0x0x7fe9f1215d68) + QObject (0x0x7fe9f1224f00) 0 + primary-for QGeoPositionInfoSource (0x0x7fe9f1215dd0) + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f12a0360) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f12a06c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f12a08a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f12a0c00) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f12a0de0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0edc180) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0edc360) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0edc6c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0edc8a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0edcc00) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0edcde0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0f12180) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0f12360) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0f126c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0f128a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0f12c00) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0f74120) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0f74480) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0f74600) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0f74960) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0f74ae0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0f74e40) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0fa4000) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0fa4360) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0fa44e0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0fa4840) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0fa49c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0fa4d20) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0fa4ea0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0fd7240) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fe9f0fd73c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fe9f0fd7720) 0 empty + diff --git a/tests/auto/bic/data/QtPositioning.5.15.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.15.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..3b5b77b --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.15.0.linux-gcc-amd64.txt @@ -0,0 +1,5278 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7fd8a8528240) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7fd8a85749c0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7fd8a8574c00) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7fd8a8574e40) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7fd8a85a00c0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7fd8a85a0240) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7fd8a85a0600) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7fd8a85d9720) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7fd8a862fde0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7fd8a862fea0) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7fd8a865f2a0) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7fd8a865f300) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7fd8a865f360) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7fd8a865f3c0) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7fd8a865f420) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7fd8a865f4e0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7fd8a865f5a0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7fd8a865f660) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7fd8a865f720) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7fd8a865fa80) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7fd8a865fde0) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7fd8a865fe40) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7fd8a82a5420) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7fd8a82a5a80) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7fd8a828e618) 0 empty + std::__nonesuch (0x0x7fd8a82a5f60) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fd8a8328900) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fd8a8328960) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fd8a8386660) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fd8a83866c0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fd8a828eaf8) 0 empty + std::input_iterator_tag (0x0x7fd8a8386720) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fd8a828eb60) 0 empty + std::forward_iterator_tag (0x0x7fd8a828ebc8) 0 empty + std::input_iterator_tag (0x0x7fd8a8386780) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fd8a828ec30) 0 empty + std::bidirectional_iterator_tag (0x0x7fd8a828ec98) 0 empty + std::forward_iterator_tag (0x0x7fd8a828ed00) 0 empty + std::input_iterator_tag (0x0x7fd8a83867e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7fd8a8438300) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7fd8a8438420) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7fd8a8438720) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fd8a8438a20) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fd8a8438b40) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fd8a80c8e40) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fd8a8112180) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fd8a81121e0) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7fd8a81122a0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fd8a8112300) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7fd8a8112360) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7fd8a81123c0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fd8a8112660) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fd8a8112900) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fd8a8112960) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fd8a81c7720) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fd8a83f6068) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7fd8a81c7900) 0 nearly-empty + primary-for std::bad_exception (0x0x7fd8a83f6068) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7fd8a81c7ae0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7fd8a83f60d0) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7fd8a81c7ea0) 0 nearly-empty + primary-for std::bad_cast (0x0x7fd8a83f60d0) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7fd8a83f6138) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7fd8a81f50c0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7fd8a83f6138) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7fd8a81f52a0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7fd8a81f5840) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fd8a83f61a0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7fd8a81f5f00) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fd8a83f61a0) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7fd8a83f6208) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7fd8a83f6270) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7fd8a83f6208) + std::exception (0x0x7fd8a822e120) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fd8a83f6270) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fd8a822e300) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7fd8a822e4e0) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fd8a7ea29c0) 0 empty + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fd8a7b1df00) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fd8a7b4b060) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fd8a7b4b240) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fd8a7b4b900) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fd8a7bb20c0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7fd8a7c4a600) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7fd8a7bf30d0) 0 + std::__atomic_flag_base (0x0x7fd8a7c4a660) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fd8a7bf3820) 0 + QAtomicInteger (0x0x7fd8a7bf3888) 0 + QBasicAtomicInteger (0x0x7fd8a777e8a0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fd8a73e2420) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fd8a741c9c0) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fd8a7460120) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fd8a740b4e0) 0 + QGenericArgument (0x0x7fd8a74603c0) 0 + +Class QMetaObject::SuperData + size=8 align=8 + base size=8 base align=8 +QMetaObject::SuperData (0x0x7fd8a7460840) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7fd8a74607e0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fd8a70b2120) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fd8a7119c00) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fd8a713b360) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fd8a720c180) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7fd8a720c4e0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fd8a726a7e0) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fd8a6f64060) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fd8a6f64120) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fd8a7017240) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fd8a7017300) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fd8a7017360) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fd8a70173c0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fd8a7017420) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fd8a7017540) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fd8a70175a0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7fd8a6d56540) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fd8a6d565a0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7fd8a6b0b600) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7fd8a6b0b780) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fd8a6c82900) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fd8a6c82cc0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fd8a6c82f60) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fd8a68d3180) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7fd8a6919180) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7fd8a68e5478) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7fd8a6919240) 0 nearly-empty + primary-for std::logic_error (0x0x7fd8a68e5478) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7fd8a68e54e0) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7fd8a68e5548) 0 + primary-for std::domain_error (0x0x7fd8a68e54e0) + std::exception (0x0x7fd8a69192a0) 0 nearly-empty + primary-for std::logic_error (0x0x7fd8a68e5548) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7fd8a68e55b0) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7fd8a68e5618) 0 + primary-for std::invalid_argument (0x0x7fd8a68e55b0) + std::exception (0x0x7fd8a6919300) 0 nearly-empty + primary-for std::logic_error (0x0x7fd8a68e5618) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7fd8a68e5680) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7fd8a68e56e8) 0 + primary-for std::length_error (0x0x7fd8a68e5680) + std::exception (0x0x7fd8a6919360) 0 nearly-empty + primary-for std::logic_error (0x0x7fd8a68e56e8) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7fd8a68e5750) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7fd8a68e57b8) 0 + primary-for std::out_of_range (0x0x7fd8a68e5750) + std::exception (0x0x7fd8a69193c0) 0 nearly-empty + primary-for std::logic_error (0x0x7fd8a68e57b8) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7fd8a68e5820) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7fd8a6919420) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd8a68e5820) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7fd8a68e5888) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7fd8a68e58f0) 0 + primary-for std::range_error (0x0x7fd8a68e5888) + std::exception (0x0x7fd8a6919480) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd8a68e58f0) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7fd8a68e5958) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7fd8a68e59c0) 0 + primary-for std::overflow_error (0x0x7fd8a68e5958) + std::exception (0x0x7fd8a69194e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd8a68e59c0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7fd8a68e5a28) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7fd8a68e5a90) 0 + primary-for std::underflow_error (0x0x7fd8a68e5a28) + std::exception (0x0x7fd8a6919540) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd8a68e5a90) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7fd8a69196c0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7fd8a6919a20) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7fd8a69712a0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7fd8a68e5ea0) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7fd8a68e5f08) 0 + primary-for std::system_error (0x0x7fd8a68e5ea0) + std::exception (0x0x7fd8a6971e40) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd8a68e5f08) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7fd8a69c21a0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7fd8a69c2208) 0 + primary-for std::ios_base::failure (0x0x7fd8a69c21a0) + std::runtime_error (0x0x7fd8a69c2270) 0 + primary-for std::system_error (0x0x7fd8a69c2208) + std::exception (0x0x7fd8a69d2420) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd8a69c2270) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fd8a69d2480) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fd8a69d24e0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fd8a69d2540) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fd8a69d23c0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fd8a66a0e40) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fd8a67a2060) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2 entries +0 ((& std::basic_ostream::_ZTVSo) + 24) +8 ((& std::basic_ostream::_ZTVSo) + 64) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2 entries +0 ((& std::basic_istream::_ZTVSi) + 24) +8 ((& std::basic_istream::_ZTVSi) + 64) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream (0x0x7fd8a631a958 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream (0x0x7fd8a631aa28 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7 entries +0 ((& std::basic_iostream::_ZTVSd) + 24) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream::_ZTVSd) + 104) +48 ((& std::basic_iostream::_ZTVSd) + 64) + +Construction vtable for std::basic_istream (0x0x7fd8a635b6e8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream (0x0x7fd8a635b7b8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7fd8a637f9c0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7fd8a637fa20) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7fd8a60b0de0) 0 + +Class QByteArray::FromBase64Result + size=16 align=8 + base size=12 base align=8 +QByteArray::FromBase64Result (0x0x7fd8a6154b40) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7fd8a625b060) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7fd8a625b4e0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fd8a5f426c0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7fd8a5fff840) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7fd8a5fff720) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7fd8a5ad2660) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7fd8a5c5f240) 0 + +Class QtPrivate::ArgBase + size=1 align=1 + base size=1 base align=1 +QtPrivate::ArgBase (0x0x7fd8a59f70c0) 0 + +Class QtPrivate::QStringViewArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QStringViewArg (0x0x7fd8a58e9f70) 0 + QtPrivate::ArgBase (0x0x7fd8a59f7120) 0 + +Class QtPrivate::QLatin1StringArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QLatin1StringArg (0x0x7fd8a5a03000) 0 + QtPrivate::ArgBase (0x0x7fd8a59f7300) 0 + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7fd8a56bf420) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7fd8a56bf480) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7fd8a56bf600) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7fd8a56bf6c0) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7fd8a5a033a8) 0 + std::__uses_alloc_base (0x0x7fd8a56bf660) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7fd8a5823a20) 0 empty + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7fd8a548a618) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7fd8a54a1360) 0 nearly-empty + primary-for std::bad_function_call (0x0x7fd8a548a618) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7fd8a54a1420) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7fd8a54a1480) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7fd8a54a1780) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7fd8a5294c00) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7fd8a5294cc0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fd8a53ca3c0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fd8a530e1a0) 0 + std::iterator (0x0x7fd8a53caae0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fd8a530e2d8) 0 + std::_Bit_iterator_base (0x0x7fd8a530e340) 0 + std::iterator (0x0x7fd8a53fa180) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fd8a530e3a8) 0 + std::_Bit_iterator_base (0x0x7fd8a530e410) 0 + std::iterator (0x0x7fd8a53fa960) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fd8a5212180) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7fd8a4ebcf00) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7fd8a4ebcf60) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7fd8a530ef08) 0 empty + QListData::NotIndirectLayout (0x0x7fd8a4ed8000) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7fd8a4eb1230) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fd8a4ed8060) 0 empty + QListData::NotIndirectLayout (0x0x7fd8a4ed80c0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7fd8a530ef70) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fd8a4ed8120) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7fd8a4ed8180) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7fd8a4ebcea0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7fd8a4fd5300) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7fd8a4cb1840) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7fd8a4cb17e0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7fd8a4ca7b60) 0 + QList (0x0x7fd8a4ca7bc8) 0 + QListSpecialMethods (0x0x7fd8a4cb1a80) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fd8a4d80840) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fd8a4e13a80) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7fd8a4e13de0) 0 + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7fd8a4b6d420) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7fd8a4b6d780) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7fd8a4b6dcc0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7fd8a4798240) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7fd8a4801540) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7fd8a4801c00) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fd8a4855c60) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fd8a490ed80) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fd8a458b300) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7fd8a442b960) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7fd8a455e420) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7fd8a455e480) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fd8a455e660) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fd8a455e600) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7fd8a4234480) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fd8a4234600) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fd8a4234ea0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fd8a4235340) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7fd8a4234e40) 0 + primary-for QAbstractAnimation (0x0x7fd8a4235340) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fd8a426d2a0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fd8a42353a8) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7fd8a426d240) 0 + primary-for QAnimationDriver (0x0x7fd8a42353a8) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fd8a426d4e0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fd8a4235410) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7fd8a426d480) 0 + primary-for QEventLoop (0x0x7fd8a4235410) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fd8a426dd80) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fd8a426de40) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fd8a426dea0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fd8a4235548) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7fd8a426dde0) 0 + primary-for QAbstractEventDispatcher (0x0x7fd8a4235548) + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7fd8a42edea0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7fd8a4319b40) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7fd8a40116c0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7fd8a4011660) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fd8a4011960) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7fd8a4140420) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7fd8a41404e0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7fd8a4140480) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7fd8a4140540) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7fd8a41403c0) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7fd8a3ea17e0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7fd8a3ee3e40) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7fd8a3ee3de0) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7fd8a3ee3f60) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7fd8a3ee3f00) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fd8a3be4300) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fd8a3c3cf00) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fd8a3d0bd20) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fd8a3d1a7b8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7fd8a3d0bcc0) 0 + primary-for QAbstractItemModel (0x0x7fd8a3d1a7b8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fd8a39f2120) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fd8a3d1add0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7fd8a3d1ae38) 0 + primary-for QAbstractTableModel (0x0x7fd8a3d1add0) + QObject (0x0x7fd8a39f20c0) 0 + primary-for QAbstractItemModel (0x0x7fd8a3d1ae38) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fd8a39f22a0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fd8a3d1aea0) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7fd8a3d1af08) 0 + primary-for QAbstractListModel (0x0x7fd8a3d1aea0) + QObject (0x0x7fd8a39f2240) 0 + primary-for QAbstractItemModel (0x0x7fd8a3d1af08) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fd8a39f29c0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fd8a39f2a80) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fd8a3a53000) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7fd8a3a53068) 0 + primary-for QAbstractProxyModel (0x0x7fd8a3a53000) + QObject (0x0x7fd8a39f2a20) 0 + primary-for QAbstractItemModel (0x0x7fd8a3a53068) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7fd8a39f2cc0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7fd8a3a530d0) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16) + QObject (0x0x7fd8a39f2c60) 0 + primary-for QAbstractState (0x0x7fd8a3a530d0) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7fd8a39f2f00) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7fd8a3a53138) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16) + QObject (0x0x7fd8a39f2ea0) 0 + primary-for QAbstractTransition (0x0x7fd8a3a53138) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fd8a3a8e240) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fd8a3a531a0) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7fd8a3a53208) 0 + primary-for QAnimationGroup (0x0x7fd8a3a531a0) + QObject (0x0x7fd8a3a8e1e0) 0 + primary-for QAbstractAnimation (0x0x7fd8a3a53208) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fd8a3ae2540) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7fd8a3b5cea0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7fd8a378aea0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fd8a37fa180) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fd8a37ebaf8) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7fd8a37fa120) 0 + primary-for QIODevice (0x0x7fd8a37ebaf8) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fd8a37faae0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fd8a37ebc30) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7fd8a37ebc98) 0 + primary-for QBuffer (0x0x7fd8a37ebc30) + QObject (0x0x7fd8a37faa80) 0 + primary-for QIODevice (0x0x7fd8a37ebc98) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fd8a37fad80) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7fd8a37fad20) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7fd8a37faf00) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7fd8a37faea0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fd8a3862de0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fd8a38becc0) 0 + +Class QCalendar::YearMonthDay + size=12 align=4 + base size=12 base align=4 +QCalendar::YearMonthDay (0x0x7fd8a364e1e0) 0 + +Class QCalendar + size=8 align=8 + base size=8 base align=8 +QCalendar (0x0x7fd8a364e180) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fd8a364e9c0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fd8a36d42a0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7fd8a3723f00) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7fd8a3723f60) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fd8a3723ea0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fd8a3418660) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fd8a3418f00) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7fd8a34edba0) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7fd8a3410c98) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7fd8a3535a20) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7fd8a3410c98) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7fd8a3410d00) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7fd8a3535b40) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7fd8a3410d00) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7fd8a3410d68) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7fd8a3535c60) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7fd8a3410d68) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7fd8a3410e38) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7fd8a3535d80) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7fd8a3410e38) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7fd8a3561de0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7fd8a3187120) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7fd8a3187420) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7fd8a3187780) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7fd8a3410ea0) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7fd8a31fa960) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7fd8a3410ea0) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7fd8a3269900) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7fd8a3269d20) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7fd8a2f9eba0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fd8a30050c0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fd8a3005240) 0 + +Class QtPrivate::EnableInternalData + size=1 align=1 + base size=0 base align=1 +QtPrivate::EnableInternalData (0x0x7fd8a305cb40) 0 empty + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7fd8a30b8240) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fd8a30b81e0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fd8a2e2db40) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fd8a2e2dc00) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7fd8a2eabe40) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fd8a2ee0600) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fd8a2b8b4e0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fd8a2bf02a0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fd8a2c46cc0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fd8a298dc60) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7fd8a2a1f7e0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7fd8a2a1f8a0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7fd8a2859ba0) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7fd8a28ed540) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7fd8a28ed5a0) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7fd8a28ed4e0) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7fd8a2668180) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7fd8a26681e0) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7fd8a2668120) 0 + +Class qfloat16::Wrap + size=2 align=2 + base size=2 base align=2 +qfloat16::Wrap (0x0x7fd8a246e960) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7fd8a246e900) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7fd8a255a720) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7fd8a21e4cc0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fd8a220f5a0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fd8a220f780) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fd8a2308d80) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7fd8a2005300) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7fd8a1fd0d68) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7fd8a20056c0) 0 + primary-for QTimerEvent (0x0x7fd8a1fd0d68) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7fd8a1fd0dd0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7fd8a2005780) 0 + primary-for QChildEvent (0x0x7fd8a1fd0dd0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7fd8a2031340) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7fd8a2005de0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fd8a2031340) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7fd8a20313a8) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7fd8a2005ea0) 0 + primary-for QDeferredDeleteEvent (0x0x7fd8a20313a8) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fd8a204b000) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fd8a2031410) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7fd8a2005f60) 0 + primary-for QCoreApplication (0x0x7fd8a2031410) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fd8a204b240) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7fd8a204b3c0) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +216 (int (*)(...))QConcatenateTablesProxyModel::mimeData +224 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +232 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QConcatenateTablesProxyModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QConcatenateTablesProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7fd8a2031478) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7fd8a20314e0) 0 + primary-for QConcatenateTablesProxyModel (0x0x7fd8a2031478) + QObject (0x0x7fd8a204b360) 0 + primary-for QAbstractItemModel (0x0x7fd8a20314e0) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fd8a204b5a0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fd8a204b6c0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7fd8a204b840) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fd8a21070c0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7fd8a21077e0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fd8a1e4e4e0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fd8a1e476e8) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7fd8a1e47750) 0 + primary-for QFileDevice (0x0x7fd8a1e476e8) + QObject (0x0x7fd8a1e4e480) 0 + primary-for QIODevice (0x0x7fd8a1e47750) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fd8a1e4ede0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fd8a1e47888) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7fd8a1e478f0) 0 + primary-for QFile (0x0x7fd8a1e47888) + QIODevice (0x0x7fd8a1e47958) 0 + primary-for QFileDevice (0x0x7fd8a1e478f0) + QObject (0x0x7fd8a1e4ed80) 0 + primary-for QIODevice (0x0x7fd8a1e47958) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fd8a1ec1480) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fd8a1b8d360) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fd8a1ca8360) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fd8a1ca8ae0) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7fd8a19a4c00) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7fd8a1976618) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16) + QAbstractTransition (0x0x7fd8a1976680) 0 + primary-for QEventTransition (0x0x7fd8a1976618) + QObject (0x0x7fd8a19a4ba0) 0 + primary-for QAbstractTransition (0x0x7fd8a1976680) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fd8a19766e8) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7fd8a19a4de0) 0 nearly-empty + primary-for QException (0x0x7fd8a19766e8) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7fd8a1976750) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7fd8a19767b8) 0 nearly-empty + primary-for QUnhandledException (0x0x7fd8a1976750) + std::exception (0x0x7fd8a19a4e40) 0 nearly-empty + primary-for QException (0x0x7fd8a19767b8) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7fd8a19a4ea0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fd8a19a4f60) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fd8a19ec000) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fd8a19ec240) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fd8a1976820) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7fd8a19ec1e0) 0 + primary-for QFileSelector (0x0x7fd8a1976820) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fd8a19ec480) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fd8a1976888) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7fd8a19ec420) 0 + primary-for QFileSystemWatcher (0x0x7fd8a1976888) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7fd8a19ec6c0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7fd8a19768f0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16) + QAbstractState (0x0x7fd8a1976958) 0 + primary-for QFinalState (0x0x7fd8a19768f0) + QObject (0x0x7fd8a19ec660) 0 + primary-for QAbstractState (0x0x7fd8a1976958) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7fd8a19ec8a0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fd8a19ecb40) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fd8a1976a28) 0 + QBasicMutex (0x0x7fd8a1a897e0) 0 + +Class QRecursiveMutex + size=8 align=8 + base size=8 base align=8 +QRecursiveMutex (0x0x7fd8a1976a90) 0 + QMutex (0x0x7fd8a1976af8) 0 + QBasicMutex (0x0x7fd8a1a89a20) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7fd8a1a89a80) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fd8a1ab70c0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fd8a1ab76c0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fd8a1ab78a0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7fd8a17480c0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7fd8a1b40410) 0 + std::__mutex_base (0x0x7fd8a1748120) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7fd8a1748300) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7fd8a1748360) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7fd8a17483c0) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7fd8a1748de0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7fd8a1b40478) 0 + std::__recursive_mutex_base (0x0x7fd8a1748e40) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7fd8a1745930) 0 + std::__mutex_base (0x0x7fd8a1785240) 0 + std::__timed_mutex_impl (0x0x7fd8a17852a0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7fd8a1797310) 0 + std::__recursive_mutex_base (0x0x7fd8a1785600) 0 + std::__timed_mutex_impl (0x0x7fd8a1785660) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7fd8a1785d80) 0 + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fd8a17cb000) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fd8a1875360) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fd8a184f270) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7fd8a1875300) 0 + primary-for QFutureWatcherBase (0x0x7fd8a184f270) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7fd8a18996c0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7fd8a184fa90) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16) + QAbstractState (0x0x7fd8a184faf8) 0 + primary-for QHistoryState (0x0x7fd8a184fa90) + QObject (0x0x7fd8a1899660) 0 + primary-for QAbstractState (0x0x7fd8a184faf8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fd8a18999c0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QIdentityProxyModel::moveRows +296 (int (*)(...))QIdentityProxyModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fd8a184fb60) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7fd8a184fbc8) 0 + primary-for QIdentityProxyModel (0x0x7fd8a184fb60) + QAbstractItemModel (0x0x7fd8a184fc30) 0 + primary-for QAbstractProxyModel (0x0x7fd8a184fbc8) + QObject (0x0x7fd8a1899960) 0 + primary-for QAbstractItemModel (0x0x7fd8a184fc30) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fd8a1899ba0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fd8a15824e0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fd8a157f5b0) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7fd8a1582480) 0 + primary-for QItemSelectionModel (0x0x7fd8a157f5b0) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7fd8a157f750) 0 + QList (0x0x7fd8a157f7b8) 0 + QListSpecialMethods (0x0x7fd8a15fa000) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7fd8a1634900) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7fd8a16702a0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7fd8a16c6240) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7fd8a16c64e0) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7fd8a170b840) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7fd8a170b8a0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7fd8a170b7e0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fd8a13b3e40) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fd8a13b3ea0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7fd8a11ffde0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7fd8a11ffe40) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7fd8a11ffd80) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fd8a12d2120) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7fd8a12cf138) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7fd8a12d20c0) 0 + primary-for QLibrary (0x0x7fd8a12cf138) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7fd8a12d2f60) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7fd8a12d2a80) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fd8a0ff93c0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fd8a0ff9420) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fd8a10772a0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fd8a10e7480) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fd8a0d4e840) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7fd8a0dcbae0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fd8a0e95060) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7fd8a0e952a0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fd8a0e95240) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fd8a0e956c0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fd8a0b55600) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fd8a0917de0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7fd8a0917e40) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7fd8a09a66c0) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fd8a09eb8a0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7fd8a09eb9c0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fd8a0a2af60) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fd8a0a2cc98) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7fd8a0a2af00) 0 + primary-for QMimeData (0x0x7fd8a0a2cc98) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fd8a0a4f180) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fd8a07150c0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fd8a0715180) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7fd8a070a820) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7fd8a0715120) 0 + primary-for QObjectCleanupHandler (0x0x7fd8a070a820) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7fd8a07152a0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fd8a0784a20) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fd8a07930d0) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7fd8a0793138) 0 + primary-for QParallelAnimationGroup (0x0x7fd8a07930d0) + QAbstractAnimation (0x0x7fd8a07931a0) 0 + primary-for QAnimationGroup (0x0x7fd8a0793138) + QObject (0x0x7fd8a07849c0) 0 + primary-for QAbstractAnimation (0x0x7fd8a07931a0) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fd8a0784c60) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fd8a0793208) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7fd8a0793270) 0 + primary-for QPauseAnimation (0x0x7fd8a0793208) + QObject (0x0x7fd8a0784c00) 0 + primary-for QAbstractAnimation (0x0x7fd8a0793270) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7fd8a07b77e0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fd8a07fc960) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fd8a07fe5b0) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7fd8a07fc900) 0 + primary-for QPluginLoader (0x0x7fd8a07fe5b0) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fd8a07fca80) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fd8a04c7f00) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fd8a04d4a28) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7fd8a04d4a90) 0 + primary-for QProcess (0x0x7fd8a04d4a28) + QObject (0x0x7fd8a04c7ea0) 0 + primary-for QIODevice (0x0x7fd8a04d4a90) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fd8a050b600) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fd8a04d4af8) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7fd8a04d4b60) 0 + primary-for QVariantAnimation (0x0x7fd8a04d4af8) + QObject (0x0x7fd8a050b5a0) 0 + primary-for QAbstractAnimation (0x0x7fd8a04d4b60) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fd8a050b8a0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fd8a04d4c30) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7fd8a04d4c98) 0 + primary-for QPropertyAnimation (0x0x7fd8a04d4c30) + QAbstractAnimation (0x0x7fd8a04d4d00) 0 + primary-for QVariantAnimation (0x0x7fd8a04d4c98) + QObject (0x0x7fd8a050b840) 0 + primary-for QAbstractAnimation (0x0x7fd8a04d4d00) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7fd8a05b3000) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7fd8a0690d20) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7fd8a0690cc0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7fd8a047fa80) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7fd8a02c0720) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7fd8a02c06c0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7fd89ff349c0) 0 + QRandomGenerator (0x0x7fd89ff60240) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fd89ff60de0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fd89ffe40c0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fd89ffe45a0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fd89ffe4a80) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fd8a005b960) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fd89fcd39c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fd89fd84a20) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fd89fe43b40) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fd89fe43de0) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fd89fe113a8) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7fd89fe11410) 0 + primary-for QSaveFile (0x0x7fd89fe113a8) + QIODevice (0x0x7fd89fe11478) 0 + primary-for QFileDevice (0x0x7fd89fe11410) + QObject (0x0x7fd89fe43d80) 0 + primary-for QIODevice (0x0x7fd89fe11478) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fd89fe9e480) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7fd89fe9e600) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fd89fb70240) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fd89fb68c30) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7fd89fb68c98) 0 + primary-for QSequentialAnimationGroup (0x0x7fd89fb68c30) + QAbstractAnimation (0x0x7fd89fb68d00) 0 + primary-for QAnimationGroup (0x0x7fd89fb68c98) + QObject (0x0x7fd89fb701e0) 0 + primary-for QAbstractAnimation (0x0x7fd89fb68d00) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fd89fb70480) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fd89fb68d68) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7fd89fb70420) 0 + primary-for QSettings (0x0x7fd89fb68d68) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fd89fb70900) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fd89fb68dd0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7fd89fb708a0) 0 + primary-for QSharedMemory (0x0x7fd89fb68dd0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fd89fb70b40) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fd89fb68e38) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7fd89fb70ae0) 0 + primary-for QSignalMapper (0x0x7fd89fb68e38) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7fd89fb70d80) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7fd89fb68ea0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16) + QAbstractTransition (0x0x7fd89fb68f08) 0 + primary-for QSignalTransition (0x0x7fd89fb68ea0) + QObject (0x0x7fd89fb70d20) 0 + primary-for QAbstractTransition (0x0x7fd89fb68f08) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fd89fbd8060) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fd89fb68f70) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7fd89fbd8000) 0 + primary-for QSocketNotifier (0x0x7fd89fb68f70) + +Class QSocketDescriptor + size=4 align=4 + base size=4 base align=4 +QSocketDescriptor (0x0x7fd89fbd8240) 0 + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fd89fbd8e40) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fd89fbf64e0) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7fd89fbf6548) 0 + primary-for QSortFilterProxyModel (0x0x7fd89fbf64e0) + QAbstractItemModel (0x0x7fd89fbf65b0) 0 + primary-for QAbstractProxyModel (0x0x7fd89fbf6548) + QObject (0x0x7fd89fbd8de0) 0 + primary-for QAbstractItemModel (0x0x7fd89fbf65b0) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fd89fc322a0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7fd89fc32ba0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7fd89fbf6750) 0 + vptr=((& QState::_ZTV6QState) + 16) + QAbstractState (0x0x7fd89fbf67b8) 0 + primary-for QState (0x0x7fd89fbf6750) + QObject (0x0x7fd89fc32b40) 0 + primary-for QAbstractState (0x0x7fd89fbf67b8) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7fd89fc89060) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7fd89fbf6958) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16) + QEvent (0x0x7fd89fc890c0) 0 + primary-for QStateMachine::SignalEvent (0x0x7fd89fbf6958) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7fd89fbf69c0) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16) + QEvent (0x0x7fd89fc89120) 0 + primary-for QStateMachine::WrappedEvent (0x0x7fd89fbf69c0) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7fd89fbf6820) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16) + QState (0x0x7fd89fbf6888) 0 + primary-for QStateMachine (0x0x7fd89fbf6820) + QAbstractState (0x0x7fd89fbf68f0) 0 + primary-for QState (0x0x7fd89fbf6888) + QObject (0x0x7fd89fc89000) 0 + primary-for QAbstractState (0x0x7fd89fbf68f0) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fd89fc89540) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fd89f997300) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fd89fa23660) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QStringListModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7fd89fa1a2d8) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7fd89fa1a340) 0 + primary-for QStringListModel (0x0x7fd89fa1a2d8) + QAbstractItemModel (0x0x7fd89fa1a3a8) 0 + primary-for QAbstractListModel (0x0x7fd89fa1a340) + QObject (0x0x7fd89fa23600) 0 + primary-for QAbstractItemModel (0x0x7fd89fa1a3a8) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fd89fa23780) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fd89fa23840) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fd89fa23960) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fd89fa1a410) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7fd89fa1a478) 0 + primary-for QTemporaryFile (0x0x7fd89fa1a410) + QFileDevice (0x0x7fd89fa1a4e0) 0 + primary-for QFile (0x0x7fd89fa1a478) + QIODevice (0x0x7fd89fa1a548) 0 + primary-for QFileDevice (0x0x7fd89fa1a4e0) + QObject (0x0x7fd89fa23900) 0 + primary-for QIODevice (0x0x7fd89fa1a548) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7fd89fa23cc0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7fd89faa1540) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0 +64 0 + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7fd89faa14e0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7fd89faa1f00) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7fd89f6f7120) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7fd89f6f7360) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7fd89f6f73c0) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7fd89f6f7300) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7fd89f580780) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7fd89f580b40) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7fd89f580ba0) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7fd89f316ea0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7fd89f31f8f0) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7fd89f31f958) 0 + primary-for std::future_error (0x0x7fd89f31f8f0) + std::exception (0x0x7fd89f342600) 0 nearly-empty + primary-for std::logic_error (0x0x7fd89f31f958) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7fd89f342d20) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7fd89f342cc0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7fd89f141480) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7fd89f1441a0) 0 + std::__at_thread_exit_elt (0x0x7fd89f141540) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7fd89f342ea0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7fd89f342c60) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7fd89eca4478) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7fd89e8e6120) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7fd89eca4478) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fd89e8e69c0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fd89eca47b8) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7fd89e8e6960) 0 + primary-for QThread (0x0x7fd89eca47b8) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fd89e8e6d80) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fd89eca4820) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7fd89e8e6d20) 0 + primary-for QThreadPool (0x0x7fd89eca4820) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fd89e8e6f60) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fd89e92f660) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fd89eca4888) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7fd89e92f600) 0 + primary-for QTimeLine (0x0x7fd89eca4888) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fd89e92f8a0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7fd89eca48f0) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7fd89e92f840) 0 + primary-for QTimer (0x0x7fd89eca48f0) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7fd89e99c240) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fd89e99c1e0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fd89ea3b300) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fd89ea40000) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7fd89ea3b2a0) 0 + primary-for QTranslator (0x0x7fd89ea40000) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7fd89ea3b540) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QTransposeProxyModel::insertRows +264 (int (*)(...))QTransposeProxyModel::insertColumns +272 (int (*)(...))QTransposeProxyModel::removeRows +280 (int (*)(...))QTransposeProxyModel::removeColumns +288 (int (*)(...))QTransposeProxyModel::moveRows +296 (int (*)(...))QTransposeProxyModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QTransposeProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QTransposeProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QTransposeProxyModel::setSourceModel +392 (int (*)(...))QTransposeProxyModel::mapToSource +400 (int (*)(...))QTransposeProxyModel::mapFromSource +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7fd89ea40068) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7fd89ea400d0) 0 + primary-for QTransposeProxyModel (0x0x7fd89ea40068) + QAbstractItemModel (0x0x7fd89ea40138) 0 + primary-for QAbstractProxyModel (0x0x7fd89ea400d0) + QObject (0x0x7fd89ea3b4e0) 0 + primary-for QAbstractItemModel (0x0x7fd89ea40138) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fd89ea3b720) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fd89e635c00) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7fd89e635d20) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7fd89e6e2120) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7fd89e74b410) 0 + QVector (0x0x7fd89e746840) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fd89e746b40) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7fd89e3cbae0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7fd89e428ae0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fd89e48eba0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fd89e48ec00) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fd89e4d0ae0) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7fd89e4d0cc0) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7fd89e573300) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7fd89e1c7900) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7fd89e21cae0) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7fd89e21cba0) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7fd89e21cea0) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7fd89e213ea0) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16) + QObject (0x0x7fd89e21ce40) 0 + primary-for QGeoPositionInfoSource (0x0x7fd89e213ea0) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7fd89e26f720) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7fd89e298000) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16) + QObject (0x0x7fd89e26f6c0) 0 + primary-for QGeoAreaMonitorSource (0x0x7fd89e298000) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7fd89e298068) 0 + QGeoShape (0x0x7fd89e26f840) 0 + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7fd89e2ee410) 0 + QGeoShape (0x0x7fd89e2e6cc0) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7fd89e356ea0) 0 + +Class QGeoPath + size=8 align=8 + base size=8 base align=8 +QGeoPath (0x0x7fd89e3b2ea0) 0 + QGeoShape (0x0x7fd89dfc5540) 0 + +Class QGeoPolygon + size=8 align=8 + base size=8 base align=8 +QGeoPolygon (0x0x7fd89e01d068) 0 + QGeoShape (0x0x7fd89e014720) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7fd89e061900) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7fd89e061a20) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7fd89e0663a8) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16) + QObject (0x0x7fd89e0619c0) 0 + primary-for QGeoSatelliteInfoSource (0x0x7fd89e0663a8) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7fd89e061ba0) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16) + +Vtable for QGeoPositionInfoSourceFactoryV2 +QGeoPositionInfoSourceFactoryV2::_ZTV31QGeoPositionInfoSourceFactoryV2: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QGeoPositionInfoSourceFactoryV2) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactoryV2 + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactoryV2 (0x0x7fd89e066410) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactoryV2::_ZTV31QGeoPositionInfoSourceFactoryV2) + 16) + QGeoPositionInfoSourceFactory (0x0x7fd89e061d80) 0 nearly-empty + primary-for QGeoPositionInfoSourceFactoryV2 (0x0x7fd89e066410) + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7fd89e0a6000) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7fd89e066478) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16) + QGeoPositionInfoSource (0x0x7fd89e0664e0) 0 + primary-for QNmeaPositionInfoSource (0x0x7fd89e066478) + QObject (0x0x7fd89e061f60) 0 + primary-for QGeoPositionInfoSource (0x0x7fd89e0664e0) + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e0de3c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e0de720) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e0de900) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e0dec60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e0dee40) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e11a1e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e11a3c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e11a720) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e11a900) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e11ac60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e11ae40) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e1531e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e1533c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e153720) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e153900) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e153c60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e1b2180) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e1b24e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e1b2660) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e1b29c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89e1b2b40) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89e1b2ea0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89dde2060) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89dde23c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89dde2540) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89dde28a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89dde2a20) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89dde2d80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89dde2f00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89de162a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fd89de16420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fd89de16780) 0 empty + diff --git a/tests/auto/bic/data/QtPositioning.5.3.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.3.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..d29c24a --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.3.0.linux-gcc-amd64.txt @@ -0,0 +1,3822 @@ +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f95f2df8f00) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f95f2df8f60) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f95f1d8fb40) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f95f1d8fba0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f95f1d26820) 0 empty + std::input_iterator_tag (0x0x7f95f1d8fc00) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f95f1d26888) 0 empty + std::forward_iterator_tag (0x0x7f95f1d268f0) 0 empty + std::input_iterator_tag (0x0x7f95f1d8fc60) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f95f1d26958) 0 empty + std::bidirectional_iterator_tag (0x0x7f95f1d269c0) 0 empty + std::forward_iterator_tag (0x0x7f95f1d26a28) 0 empty + std::input_iterator_tag (0x0x7f95f1d8fcc0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f95f1de9840) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f95f1de9a80) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f95f1de9b40) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f95f1de9ba0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f95f1de9c60) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f95f1de9cc0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f95f1eab180) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f95f1eab1e0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f95f1eab240) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f95f1d26d68) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f95f1eab2a0) 0 nearly-empty + primary-for std::bad_exception (0x0x7f95f1d26d68) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f95f1d26dd0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f95f1eab300) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f95f1d26dd0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f95f1eab360) 0 empty + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f95f0cb36c0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f95f0cb3720) 0 + +Class QtPrivate::big_ + size=2 align=1 + base size=2 base align=1 +QtPrivate::big_ (0x0x7f95f0cb3900) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f95f0a18060) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f95f0a180c0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f95f0a18120) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f95f0a18180) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f95f0a182a0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f95f06ee3a8) 0 + QAtomicInteger (0x0x7f95f06ee410) 0 + QBasicAtomicInteger (0x0x7f95f0a18d80) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f95f04f5ea0) 0 empty + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f95f069fde0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f95f05ca548) 0 + QGenericArgument (0x0x7f95f069fe40) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f95f0304000) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f95f0304120) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f95f0304360) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f95f03043c0) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f95f03044e0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f95f0304540) 0 + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f95f03048a0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f95f0304900) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f95f0304a80) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f95f0304ea0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 (int (*)(...))__cxxabiv1::__forced_unwind::~__forced_unwind +24 (int (*)(...))__cxxabiv1::__forced_unwind::~__forced_unwind +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f95f0304f00) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f95f02039c0) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f95f0203a20) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f95f0203ae0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f95f0203b40) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f95f0203ba0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f95f0203c00) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f95f0203d20) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f95f0203d80) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f95eff0a4e0) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f95eff0a660) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f95eff0a720) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f95eff0a6c0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f95eff0a8a0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f95eff0ab40) 0 + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f95eff0ad20) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f95eff0ad80) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f95eff0ade0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f95eff0ae40) 0 + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureE) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=16 align=8 + base size=16 base align=8 +std::ios_base::failure (0x0x7f95eff0e000) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureE) + 16u) + std::exception (0x0x7f95efbc92a0) 0 nearly-empty + primary-for std::ios_base::failure (0x0x7f95eff0e000) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f95efbc9300) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f95efbc9360) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f95efbc93c0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f95efbc9240) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f95efbc9540) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f95efbc9c00) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f95ef810a90 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 (int (*)(...))std::basic_istream<_CharT, _Traits>::~basic_istream > +32 (int (*)(...))std::basic_istream<_CharT, _Traits>::~basic_istream > +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 (int (*)(...))std::basic_istream::_ZTv0_n24_NSiD1Ev +72 (int (*)(...))std::basic_istream::_ZTv0_n24_NSiD0Ev + +Construction vtable for std::basic_ostream (0x0x7f95ef810b60 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 (int (*)(...))std::basic_ostream<_CharT, _Traits>::~basic_ostream > +32 (int (*)(...))std::basic_ostream<_CharT, _Traits>::~basic_ostream > +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 (int (*)(...))std::basic_ostream::_ZTv0_n24_NSoD1Ev +72 (int (*)(...))std::basic_ostream::_ZTv0_n24_NSoD0Ev + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f95ef810e38 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 (int (*)(...))std::basic_istream<_CharT, _Traits>::~basic_istream > +32 (int (*)(...))std::basic_istream<_CharT, _Traits>::~basic_istream > +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 (int (*)(...))std::basic_istream::_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED1Ev +72 (int (*)(...))std::basic_istream::_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED0Ev + +Construction vtable for std::basic_ostream (0x0x7f95ef810f08 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 (int (*)(...))std::basic_ostream<_CharT, _Traits>::~basic_ostream > +32 (int (*)(...))std::basic_ostream<_CharT, _Traits>::~basic_ostream > +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 (int (*)(...))std::basic_ostream::_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev +72 (int (*)(...))std::basic_ostream::_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f95ef8b0000) 0 + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f95ef8b0300) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f95ef8b02a0) 0 + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f95ef8b06c0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f95ef6a5420) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f95ef67d208) 0 + std::iterator (0x0x7f95ef6a54e0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f95ef67d270) 0 + std::_Bit_iterator_base (0x0x7f95ef67d2d8) 0 + std::iterator (0x0x7f95ef6a5540) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f95ef67d340) 0 + std::_Bit_iterator_base (0x0x7f95ef67d3a8) 0 + std::iterator (0x0x7f95ef6a55a0) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f95ef6a5960) 0 + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f95ef6a5d80) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f95ef6a5e40) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f95ef6a5f00) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f95ef180360) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f95ef1806c0) 0 + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f95ef180ae0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f95ef180cc0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f95ef180d80) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f95eeff3060) 0 + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f95eeff31e0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f95eeff3360) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f95eeff3300) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f95eeff3660) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f95eeff36c0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f95eeff3780) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 (int (*)(...))QAbstractAnimation::~QAbstractAnimation +48 (int (*)(...))QAbstractAnimation::~QAbstractAnimation +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f95ef204dd0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f95eeff3720) 0 + primary-for QAbstractAnimation (0x0x7f95ef204dd0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f95eeff3840) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f95ef204e38) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f95eeff37e0) 0 + primary-for QAnimationDriver (0x0x7f95ef204e38) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f95eeff3900) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 (int (*)(...))QAnimationGroup::~QAnimationGroup +48 (int (*)(...))QAnimationGroup::~QAnimationGroup +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f95ef204ea0) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f95ef204f08) 0 + primary-for QAnimationGroup (0x0x7f95ef204ea0) + QObject (0x0x7f95eeff38a0) 0 + primary-for QAbstractAnimation (0x0x7f95ef204f08) + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f95eeff39c0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f95ef204f70) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f95eecee000) 0 + primary-for QParallelAnimationGroup (0x0x7f95ef204f70) + QAbstractAnimation (0x0x7f95eecee068) 0 + primary-for QAnimationGroup (0x0x7f95eecee000) + QObject (0x0x7f95eeff3960) 0 + primary-for QAbstractAnimation (0x0x7f95eecee068) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f95eeff3a80) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f95eecee0d0) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f95eecee138) 0 + primary-for QPauseAnimation (0x0x7f95eecee0d0) + QObject (0x0x7f95eeff3a20) 0 + primary-for QAbstractAnimation (0x0x7f95eecee138) + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f95eeff3c60) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f95eeff3e40) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f95eeff3f00) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f95eee232a0) 0 + +Class QHashData + size=48 align=8 + base size=48 base align=8 +QHashData (0x0x7f95eee23240) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f95eee23300) 0 empty + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f95eee237e0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 (int (*)(...))QIODevice::~QIODevice +48 (int (*)(...))QIODevice::~QIODevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f95eeceea28) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f95eee23780) 0 + primary-for QIODevice (0x0x7f95eeceea28) + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f95eee23900) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f95eee239c0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f95eee23b40) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f95eee23ae0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f95eeceebc8) 0 + QList (0x0x7f95eee23cc0) 0 + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f95ee8fe000) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f95ee8fe0c0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f95ee8fe060) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f95ee8fe120) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f95eee23f60) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f95ee8fe3c0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f95ee8fe480) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f95ee8fe420) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f95ee8fe540) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f95ee8fe4e0) 0 + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f95eea14120) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f95ee9cc5b0) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f95ee9cc618) 0 + primary-for QVariantAnimation (0x0x7f95ee9cc5b0) + QObject (0x0x7f95eea140c0) 0 + primary-for QAbstractAnimation (0x0x7f95ee9cc618) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f95eea141e0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f95ee9cc6e8) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f95ee9cc750) 0 + primary-for QPropertyAnimation (0x0x7f95ee9cc6e8) + QAbstractAnimation (0x0x7f95ee9cc7b8) 0 + primary-for QVariantAnimation (0x0x7f95ee9cc750) + QObject (0x0x7f95eea14180) 0 + primary-for QAbstractAnimation (0x0x7f95ee9cc7b8) + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f95eea142a0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f95ee9cc820) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f95ee9cc888) 0 + primary-for QSequentialAnimationGroup (0x0x7f95ee9cc820) + QAbstractAnimation (0x0x7f95ee9cc8f0) 0 + primary-for QAnimationGroup (0x0x7f95ee9cc888) + QObject (0x0x7f95eea14240) 0 + primary-for QAbstractAnimation (0x0x7f95ee9cc8f0) + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f95eea14360) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QTextCodec::~QTextCodec +64 (int (*)(...))QTextCodec::~QTextCodec + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f95eea14300) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f95eea14480) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f95eea144e0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f95eea14540) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f95eea147e0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f95eea14960) 0 + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f95eea14de0) 0 empty + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f95ee7cd5a0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f95ee7cd6c0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f95ee7cd7e0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f95ee7cd960) 0 empty + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f95ee7cda20) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f95ee9ccf08) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f95ee9ccf70) 0 + primary-for QBuffer (0x0x7f95ee9ccf08) + QObject (0x0x7f95ee7cd9c0) 0 + primary-for QIODevice (0x0x7f95ee9ccf70) + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f95ee7cda80) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f95ee7cdd80) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f95ee7cdde0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f95ee7cdea0) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f95ee59f180) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f95ee59f3c0) 0 + +Class QDebug::Stream + size=72 align=8 + base size=72 base align=8 +QDebug::Stream (0x0x7f95ee59fa20) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f95ee59f9c0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f95ee59fb40) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f95ee59fc00) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f95ee59fcc0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f95ee5a2208) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f95ee5a2270) 0 + primary-for QFileDevice (0x0x7f95ee5a2208) + QObject (0x0x7f95ee59fc60) 0 + primary-for QIODevice (0x0x7f95ee5a2270) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f95ee59fe40) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f95ee5a23a8) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f95ee5a2410) 0 + primary-for QFile (0x0x7f95ee5a23a8) + QIODevice (0x0x7f95ee5a2478) 0 + primary-for QFileDevice (0x0x7f95ee5a2410) + QObject (0x0x7f95ee59fde0) 0 + primary-for QIODevice (0x0x7f95ee5a2478) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f95ee59ff60) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f95ee371240) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f95ee371540) 0 + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f95ee371720) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f95ee5a2958) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f95ee3716c0) 0 + primary-for QFileSelector (0x0x7f95ee5a2958) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f95ee3717e0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f95ee5a29c0) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f95ee371780) 0 + primary-for QFileSystemWatcher (0x0x7f95ee5a29c0) + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f95ee371840) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f95ee371960) 0 + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f95ee3719c0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f95ee371ba0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f95ee5a2a90) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f95ee5a2af8) 0 + primary-for QProcess (0x0x7f95ee5a2a90) + QObject (0x0x7f95ee371b40) 0 + primary-for QIODevice (0x0x7f95ee5a2af8) + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f95ee371c00) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f95ee371d80) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f95ee5a2b60) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f95ee5a2bc8) 0 + primary-for QSaveFile (0x0x7f95ee5a2b60) + QIODevice (0x0x7f95ee5a2c30) 0 + primary-for QFileDevice (0x0x7f95ee5a2bc8) + QObject (0x0x7f95ee371d20) 0 + primary-for QIODevice (0x0x7f95ee5a2c30) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f95ee371e40) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f95ee5a2c98) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f95ee371de0) 0 + primary-for QSettings (0x0x7f95ee5a2c98) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f95ee371ea0) 0 empty + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f95ee0f2000) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f95ee0f2120) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f95ee5a2dd0) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f95ee5a2e38) 0 + primary-for QTemporaryFile (0x0x7f95ee5a2dd0) + QFileDevice (0x0x7f95ee5a2ea0) 0 + primary-for QFile (0x0x7f95ee5a2e38) + QIODevice (0x0x7f95ee5a2f08) 0 + primary-for QFileDevice (0x0x7f95ee5a2ea0) + QObject (0x0x7f95ee0f20c0) 0 + primary-for QIODevice (0x0x7f95ee5a2f08) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f95ee0f2240) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f95ee0f2660) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f95ee0f27e0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f95ee0f2900) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f95ee0f2a80) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 (int (*)(...))QAbstractItemModel::~QAbstractItemModel +48 (int (*)(...))QAbstractItemModel::~QAbstractItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f95ee1602d8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f95ee0f2a20) 0 + primary-for QAbstractItemModel (0x0x7f95ee1602d8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f95ee0f2d80) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 (int (*)(...))QAbstractTableModel::~QAbstractTableModel +48 (int (*)(...))QAbstractTableModel::~QAbstractTableModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f95ee160410) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f95ee160478) 0 + primary-for QAbstractTableModel (0x0x7f95ee160410) + QObject (0x0x7f95ee0f2d20) 0 + primary-for QAbstractItemModel (0x0x7f95ee160478) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f95ee0f2e40) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 (int (*)(...))QAbstractListModel::~QAbstractListModel +48 (int (*)(...))QAbstractListModel::~QAbstractListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f95ee1604e0) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f95ee160548) 0 + primary-for QAbstractListModel (0x0x7f95ee1604e0) + QObject (0x0x7f95ee0f2de0) 0 + primary-for QAbstractItemModel (0x0x7f95ee160548) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f95ee0f2f00) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 (int (*)(...))QAbstractProxyModel::~QAbstractProxyModel +48 (int (*)(...))QAbstractProxyModel::~QAbstractProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f95ee1605b0) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f95ee160618) 0 + primary-for QAbstractProxyModel (0x0x7f95ee1605b0) + QObject (0x0x7f95ee0f2ea0) 0 + primary-for QAbstractItemModel (0x0x7f95ee160618) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f95edee8000) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f95ee160680) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f95ee1606e8) 0 + primary-for QIdentityProxyModel (0x0x7f95ee160680) + QAbstractItemModel (0x0x7f95ee160750) 0 + primary-for QAbstractProxyModel (0x0x7f95ee1606e8) + QObject (0x0x7f95ee0f2f60) 0 + primary-for QAbstractItemModel (0x0x7f95ee160750) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f95edee8060) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f95edee81e0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f95ee160820) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f95edee8180) 0 + primary-for QItemSelectionModel (0x0x7f95ee160820) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f95ee160958) 0 + QList (0x0x7f95edee83c0) 0 + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f95edee8480) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f95ee1609c0) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f95ee160a28) 0 + primary-for QSortFilterProxyModel (0x0x7f95ee1609c0) + QAbstractItemModel (0x0x7f95ee160a90) 0 + primary-for QAbstractProxyModel (0x0x7f95ee160a28) + QObject (0x0x7f95edee8420) 0 + primary-for QAbstractItemModel (0x0x7f95ee160a90) + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f95edee8540) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f95ee160af8) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f95ee160b60) 0 + primary-for QStringListModel (0x0x7f95ee160af8) + QAbstractItemModel (0x0x7f95ee160bc8) 0 + primary-for QAbstractListModel (0x0x7f95ee160b60) + QObject (0x0x7f95edee84e0) 0 + primary-for QAbstractItemModel (0x0x7f95ee160bc8) + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f95edee85a0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f95edee8660) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f95edee8780) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f95edee87e0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f95edee8720) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f95edee8840) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f95edee88a0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f95edee8960) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f95edee89c0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f95edee8900) 0 + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f95edee8ae0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f95ee160c30) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f95edee8a80) 0 + primary-for QEventLoop (0x0x7f95ee160c30) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f95edee8c00) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f95edee8cc0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f95edee8d20) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 (int (*)(...))QAbstractEventDispatcher::~QAbstractEventDispatcher +48 (int (*)(...))QAbstractEventDispatcher::~QAbstractEventDispatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f95ee160d68) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f95edee8c60) 0 + primary-for QAbstractEventDispatcher (0x0x7f95ee160d68) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 (int (*)(...))QAbstractNativeEventFilter::~QAbstractNativeEventFilter +24 (int (*)(...))QAbstractNativeEventFilter::~QAbstractNativeEventFilter +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f95edee8d80) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f95edee8de0) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f95edee8f00) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f95ee160e38) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f95edee8f60) 0 + primary-for QTimerEvent (0x0x7f95ee160e38) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f95ee160ea0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f95edd19000) 0 + primary-for QChildEvent (0x0x7f95ee160ea0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f95ee160f08) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f95edd19060) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f95ee160f08) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f95ee160f70) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f95edd190c0) 0 + primary-for QDeferredDeleteEvent (0x0x7f95ee160f70) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f95edd19180) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f95edd27000) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f95edd19120) 0 + primary-for QCoreApplication (0x0x7f95edd27000) + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f95edd191e0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f95edd19240) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f95edd19360) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f95edd19480) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f95edd194e0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f95edd19660) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f95edd27270) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f95edd19600) 0 + primary-for QMimeData (0x0x7f95edd27270) + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f95edd19720) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f95edd272d8) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f95edd196c0) 0 + primary-for QObjectCleanupHandler (0x0x7f95edd272d8) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f95edd19960) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f95edd27340) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f95edd19900) 0 + primary-for QSharedMemory (0x0x7f95edd27340) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f95edd19a20) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f95edd273a8) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f95edd199c0) 0 + primary-for QSignalMapper (0x0x7f95edd273a8) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f95edd19ae0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f95edd27410) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f95edd19a80) 0 + primary-for QSocketNotifier (0x0x7f95edd27410) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f95edd19b40) 0 + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f95edd19c60) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f95edd27478) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f95edd19c00) 0 + primary-for QTimer (0x0x7f95edd27478) + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f95edd19d80) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f95edd274e0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f95edd19d20) 0 + primary-for QTranslator (0x0x7f95edd274e0) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f95edd19de0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f95edd19f60) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 (int (*)(...))QFactoryInterface::~QFactoryInterface +24 (int (*)(...))QFactoryInterface::~QFactoryInterface +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f95edead000) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f95edead120) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f95edd275b0) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f95edead0c0) 0 + primary-for QLibrary (0x0x7f95edd275b0) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f95edead240) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f95edead3c0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f95edd27750) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f95edead360) 0 + primary-for QPluginLoader (0x0x7f95edd27750) + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f95edead420) 0 + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f95edead5a0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 (int (*)(...))QAbstractState::~QAbstractState +48 (int (*)(...))QAbstractState::~QAbstractState +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f95edd27820) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f95edead540) 0 + primary-for QAbstractState (0x0x7f95edd27820) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f95edead660) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 (int (*)(...))QAbstractTransition::~QAbstractTransition +48 (int (*)(...))QAbstractTransition::~QAbstractTransition +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f95edd27888) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f95edead600) 0 + primary-for QAbstractTransition (0x0x7f95edd27888) + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f95edead720) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f95edd278f0) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f95edd27958) 0 + primary-for QEventTransition (0x0x7f95edd278f0) + QObject (0x0x7f95edead6c0) 0 + primary-for QAbstractTransition (0x0x7f95edd27958) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f95edead7e0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f95edd279c0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f95edd27a28) 0 + primary-for QFinalState (0x0x7f95edd279c0) + QObject (0x0x7f95edead780) 0 + primary-for QAbstractState (0x0x7f95edd27a28) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f95edead8a0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f95edd27a90) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f95edd27af8) 0 + primary-for QHistoryState (0x0x7f95edd27a90) + QObject (0x0x7f95edead840) 0 + primary-for QAbstractState (0x0x7f95edd27af8) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f95edead960) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f95edd27b60) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f95edd27bc8) 0 + primary-for QSignalTransition (0x0x7f95edd27b60) + QObject (0x0x7f95edead900) 0 + primary-for QAbstractTransition (0x0x7f95edd27bc8) + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f95edeada20) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f95edd27c30) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f95edd27c98) 0 + primary-for QState (0x0x7f95edd27c30) + QObject (0x0x7f95edead9c0) 0 + primary-for QAbstractState (0x0x7f95edd27c98) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f95edeadb40) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f95edd27e38) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f95edeadba0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f95edd27e38) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f95edd27ea0) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f95edeadc00) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f95edd27ea0) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f95edd27d00) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f95edd27d68) 0 + primary-for QStateMachine (0x0x7f95edd27d00) + QAbstractState (0x0x7f95edd27dd0) 0 + primary-for QState (0x0x7f95edd27d68) + QObject (0x0x7f95edeadae0) 0 + primary-for QAbstractState (0x0x7f95edd27dd0) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f95edd27f08) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f95edeadc60) 0 nearly-empty + primary-for QException (0x0x7f95edd27f08) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f95edd27f70) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f95edbb5000) 0 nearly-empty + primary-for QUnhandledException (0x0x7f95edd27f70) + std::exception (0x0x7f95edeadcc0) 0 nearly-empty + primary-for QException (0x0x7f95edbb5000) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f95edeadd20) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f95edeadde0) 0 + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QRunnable::~QRunnable +32 (int (*)(...))QRunnable::~QRunnable + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f95edeade40) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f95edeadea0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f95edbb51a0) 0 + QBasicMutex (0x0x7f95edbed000) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f95edbed060) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f95edbed0c0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f95edbed120) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f95edbed2a0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f95edbed360) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f95edbed6c0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 (int (*)(...))QFutureWatcherBase::~QFutureWatcherBase +48 (int (*)(...))QFutureWatcherBase::~QFutureWatcherBase +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f95edbb5a90) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f95edbed660) 0 + primary-for QFutureWatcherBase (0x0x7f95edbb5a90) + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f95edbed7e0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f95edbed840) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f95edbed8a0) 0 + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f95edbed900) 0 + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f95edbed9c0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f95edbb5e38) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f95edbed960) 0 + primary-for QThread (0x0x7f95edbb5e38) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f95edbeda80) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f95edbb5ea0) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f95edbeda20) 0 + primary-for QThreadPool (0x0x7f95edbb5ea0) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f95edbedae0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f95edbedba0) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f95ed9a7180) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f95ed9a71e0) 0 + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f95ed9a7360) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f95ed9a7300) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f95ed9a74e0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f95ed9a75a0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f95ed9a7780) 0 + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f95ed9a7900) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f95ed9a7960) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f95ed9a79c0) 0 + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f95ed9a7a20) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f95ed9a7b40) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f95ed9a7c60) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f95ed9a7d80) 0 + +Class QLinkedListData + size=32 align=8 + base size=32 base align=8 +QLinkedListData (0x0x7f95ed9a7ea0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f95ed75a240) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f95ed75a360) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f95ed75a480) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f95ed75a540) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f95ed75a660) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f95ed75a780) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f95ed75a8a0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f95ed75a9c0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f95ed75acc0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f95ed75ae40) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f95ed63f0c0) 0 empty + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f95ed63fae0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f95ed63fc60) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f95ed6657b8) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f95ed63fc00) 0 + primary-for QTimeLine (0x0x7f95ed6657b8) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f95ed63fd20) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f95ed63fcc0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f95ed63ff60) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f95ed337000) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f95ed665a28) 0 + QVector (0x0x7f95ed3371e0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f95ed337240) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f95ed337360) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f95ed337480) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f95ed3375a0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f95ed337600) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f95ed337720) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7f95ed337840) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7f95ed337ae0) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7f95ed337d80) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7f95ed447060) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7f95ed447120) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7f95ed4471e0) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 (int (*)(...))QGeoPositionInfoSource::~QGeoPositionInfoSource +48 (int (*)(...))QGeoPositionInfoSource::~QGeoPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7f95ed665d00) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7f95ed447180) 0 + primary-for QGeoPositionInfoSource (0x0x7f95ed665d00) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7f95ed447360) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 (int (*)(...))QGeoAreaMonitorSource::~QGeoAreaMonitorSource +48 (int (*)(...))QGeoAreaMonitorSource::~QGeoAreaMonitorSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7f95ed665e38) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7f95ed447300) 0 + primary-for QGeoAreaMonitorSource (0x0x7f95ed665e38) + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7f95ed665ea0) 0 + QGeoShape (0x0x7f95ed4473c0) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7f95ed447600) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7f95ed4478a0) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7f95ed447960) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 (int (*)(...))QGeoSatelliteInfoSource::~QGeoSatelliteInfoSource +48 (int (*)(...))QGeoSatelliteInfoSource::~QGeoSatelliteInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7f95ed060000) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7f95ed447900) 0 + primary-for QGeoSatelliteInfoSource (0x0x7f95ed060000) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 (int (*)(...))QGeoPositionInfoSourceFactory::~QGeoPositionInfoSourceFactory +24 (int (*)(...))QGeoPositionInfoSourceFactory::~QGeoPositionInfoSourceFactory +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7f95ed447a20) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7f95ed060068) 0 + QGeoShape (0x0x7f95ed447ae0) 0 + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7f95ed447e40) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7f95ed060138) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7f95ed0601a0) 0 + primary-for QNmeaPositionInfoSource (0x0x7f95ed060138) + QObject (0x0x7f95ed447de0) 0 + primary-for QGeoPositionInfoSource (0x0x7f95ed0601a0) + diff --git a/tests/auto/bic/data/QtPositioning.5.4.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.4.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..3746cf7 --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.4.0.linux-gcc-amd64.txt @@ -0,0 +1,3854 @@ +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fb610c07060) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fb610c070c0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fb610c48c60) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fb610c48cc0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fb610bdc958) 0 empty + std::input_iterator_tag (0x0x7fb610c48d20) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fb610bdc9c0) 0 empty + std::forward_iterator_tag (0x0x7fb610bdca28) 0 empty + std::input_iterator_tag (0x0x7fb610c48d80) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fb610bdca90) 0 empty + std::bidirectional_iterator_tag (0x0x7fb610bdcaf8) 0 empty + std::forward_iterator_tag (0x0x7fb610bdcb60) 0 empty + std::input_iterator_tag (0x0x7fb610c48de0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7fb610c79960) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fb610c79ba0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fb610c79c60) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fb610c79cc0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fb610c79d80) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fb610c79de0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fb610d642a0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fb610d64300) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fb610d64360) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fb610bdcea0) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7fb610d643c0) 0 nearly-empty + primary-for std::bad_exception (0x0x7fb610bdcea0) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fb610bdcf08) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7fb610d64420) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fb610bdcf08) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fb610d64480) 0 empty + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7fb60fb587e0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7fb60fb58840) 0 + +Class QtPrivate::big_ + size=2 align=1 + base size=2 base align=1 +QtPrivate::big_ (0x0x7fb60fb58a20) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fb60f8c8300) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fb60f8c8360) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fb60f8c83c0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fb60f8c8420) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fb60f8c8540) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fb60f8cd680) 0 + QAtomicInteger (0x0x7fb60f8cd6e8) 0 + QBasicAtomicInteger (0x0x7fb60f70e060) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fb60f4e4180) 0 empty + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fb60f1ae0c0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fb60f452820) 0 + QGenericArgument (0x0x7fb60f1ae120) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7fb60f1ae2a0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fb60f1ae3c0) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fb60f1ae600) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fb60f1ae660) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fb60f1ae780) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7fb60f1ae7e0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fb60f1aeae0) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fb60f1aee40) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 (int (*)(...))__cxxabiv1::__forced_unwind::~__forced_unwind +24 (int (*)(...))__cxxabiv1::__forced_unwind::~__forced_unwind +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fb60f1aeea0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fb60efe4960) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7fb60efe49c0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fb60efe4a80) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fb60efe4ae0) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fb60efe4b40) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fb60efe4ba0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fb60efe4cc0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fb60efe4d20) 0 + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7fb60f0ed4e0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7fb60f0ed540) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7fb60f0ed6c0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fb60f0ed7e0) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7fb60f0ed960) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7fb60f0eda20) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7fb60f0ed9c0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7fb60f0edba0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7fb60f0ede40) 0 + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fb60ea19060) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fb60ea190c0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fb60ea19120) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fb60ea19180) 0 + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureE) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=16 align=8 + base size=16 base align=8 +std::ios_base::failure (0x0x7fb60ead6000) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureE) + 16u) + std::exception (0x0x7fb60ea195a0) 0 nearly-empty + primary-for std::ios_base::failure (0x0x7fb60ead6000) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fb60ea19600) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fb60ea19660) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fb60ea196c0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fb60ea19540) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fb60ea19840) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fb60ea19f00) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7fb60e693e38 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 (int (*)(...))std::basic_istream<_CharT, _Traits>::~basic_istream > +32 (int (*)(...))std::basic_istream<_CharT, _Traits>::~basic_istream > +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 (int (*)(...))std::basic_istream::_ZTv0_n24_NSiD1Ev +72 (int (*)(...))std::basic_istream::_ZTv0_n24_NSiD0Ev + +Construction vtable for std::basic_ostream (0x0x7fb60e693f08 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 (int (*)(...))std::basic_ostream<_CharT, _Traits>::~basic_ostream > +32 (int (*)(...))std::basic_ostream<_CharT, _Traits>::~basic_ostream > +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 (int (*)(...))std::basic_ostream::_ZTv0_n24_NSoD1Ev +72 (int (*)(...))std::basic_ostream::_ZTv0_n24_NSoD0Ev + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7fb60e6933a8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 (int (*)(...))std::basic_istream<_CharT, _Traits>::~basic_istream > +32 (int (*)(...))std::basic_istream<_CharT, _Traits>::~basic_istream > +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 (int (*)(...))std::basic_istream::_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED1Ev +72 (int (*)(...))std::basic_istream::_ZTv0_n24_NSt13basic_istreamIwSt11char_traitsIwEED0Ev + +Construction vtable for std::basic_ostream (0x0x7fb60e6934e0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 (int (*)(...))std::basic_ostream<_CharT, _Traits>::~basic_ostream > +32 (int (*)(...))std::basic_ostream<_CharT, _Traits>::~basic_ostream > +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 (int (*)(...))std::basic_ostream::_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED1Ev +72 (int (*)(...))std::basic_ostream::_ZTv0_n24_NSt13basic_ostreamIwSt11char_traitsIwEED0Ev + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fb60e6e1300) 0 + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7fb60e6e1660) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7fb60e6e1600) 0 + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fb60e6e1b40) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fb60e5678a0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fb60e766750) 0 + std::iterator (0x0x7fb60e567960) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fb60e7667b8) 0 + std::_Bit_iterator_base (0x0x7fb60e766820) 0 + std::iterator (0x0x7fb60e5679c0) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fb60e766888) 0 + std::_Bit_iterator_base (0x0x7fb60e7668f0) 0 + std::iterator (0x0x7fb60e567a20) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fb60e567de0) 0 + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7fb60e34d240) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7fb60e34d300) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7fb60e34d3c0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7fb60e34d7e0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7fb60e34db40) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7fb60e34dc60) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fb60e146480) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fb60e146660) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fb60e146720) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fb60df0ba80) 0 + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7fb60df0bc00) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fb60df0bde0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fb60df0bd80) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7fb60dbea120) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fb60dbea180) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fb60dbea240) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 (int (*)(...))QAbstractAnimation::~QAbstractAnimation +48 (int (*)(...))QAbstractAnimation::~QAbstractAnimation +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fb60df5f5b0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7fb60dbea1e0) 0 + primary-for QAbstractAnimation (0x0x7fb60df5f5b0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fb60dbea300) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fb60df5f618) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7fb60dbea2a0) 0 + primary-for QAnimationDriver (0x0x7fb60df5f618) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fb60dbea3c0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 (int (*)(...))QAnimationGroup::~QAnimationGroup +48 (int (*)(...))QAnimationGroup::~QAnimationGroup +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fb60df5f680) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7fb60df5f6e8) 0 + primary-for QAnimationGroup (0x0x7fb60df5f680) + QObject (0x0x7fb60dbea360) 0 + primary-for QAbstractAnimation (0x0x7fb60df5f6e8) + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fb60dbea480) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fb60df5f750) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7fb60df5f7b8) 0 + primary-for QParallelAnimationGroup (0x0x7fb60df5f750) + QAbstractAnimation (0x0x7fb60df5f820) 0 + primary-for QAnimationGroup (0x0x7fb60df5f7b8) + QObject (0x0x7fb60dbea420) 0 + primary-for QAbstractAnimation (0x0x7fb60df5f820) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fb60dbea540) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fb60df5f888) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7fb60df5f8f0) 0 + primary-for QPauseAnimation (0x0x7fb60df5f888) + QObject (0x0x7fb60dbea4e0) 0 + primary-for QAbstractAnimation (0x0x7fb60df5f8f0) + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fb60dbea720) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7fb60dbea900) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7fb60dbea9c0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7fb60dbead20) 0 + +Class QHashData + size=48 align=8 + base size=48 base align=8 +QHashData (0x0x7fb60dbeacc0) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fb60dbead80) 0 empty + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fb60da72300) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 (int (*)(...))QIODevice::~QIODevice +48 (int (*)(...))QIODevice::~QIODevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fb60dacc138) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7fb60da722a0) 0 + primary-for QIODevice (0x0x7fb60dacc138) + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fb60da72420) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7fb60da724e0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7fb60da72660) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7fb60da72600) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7fb60dacc340) 0 + QList (0x0x7fb60dacc3a8) 0 + QListSpecialMethods (0x0x7fb60da72840) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7fb60da72b40) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7fb60da72c00) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7fb60da72ba0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7fb60da72c60) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7fb60da72ae0) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7fb60da72f60) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7fb60d8f6060) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7fb60d8f6000) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7fb60d8f6120) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7fb60d8f60c0) 0 + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fb60d8f6cc0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fb60dacce38) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7fb60daccea0) 0 + primary-for QVariantAnimation (0x0x7fb60dacce38) + QObject (0x0x7fb60d8f6c60) 0 + primary-for QAbstractAnimation (0x0x7fb60daccea0) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fb60d8f6d80) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fb60daccf70) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7fb60dacc068) 0 + primary-for QPropertyAnimation (0x0x7fb60daccf70) + QAbstractAnimation (0x0x7fb60daccc98) 0 + primary-for QVariantAnimation (0x0x7fb60dacc068) + QObject (0x0x7fb60d8f6d20) 0 + primary-for QAbstractAnimation (0x0x7fb60daccc98) + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fb60d8f6e40) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fb60daccd00) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7fb60daccd68) 0 + primary-for QSequentialAnimationGroup (0x0x7fb60daccd00) + QAbstractAnimation (0x0x7fb60d5a6000) 0 + primary-for QAnimationGroup (0x0x7fb60daccd68) + QObject (0x0x7fb60d8f6de0) 0 + primary-for QAbstractAnimation (0x0x7fb60d5a6000) + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7fb60d8f6f00) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QTextCodec::~QTextCodec +64 (int (*)(...))QTextCodec::~QTextCodec + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7fb60d8f6ea0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7fb60d5c2060) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7fb60d5c20c0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fb60d5c2120) 0 + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fb60d5c2300) 0 empty + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fb60d5c2a80) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fb60d5c2ba0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fb60d5c2cc0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fb60d5c2e40) 0 empty + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fb60d5c2f00) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fb60d5a62d8) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7fb60d5a6340) 0 + primary-for QBuffer (0x0x7fb60d5a62d8) + QObject (0x0x7fb60d5c2ea0) 0 + primary-for QIODevice (0x0x7fb60d5a6340) + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fb60d5c2f60) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7fb60d3c92a0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fb60d3c9300) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fb60d3c93c0) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fb60d3c9660) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7fb60d3c98a0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7fb60d3c9f00) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fb60d3c9ea0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fb60d18a060) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fb60d18a120) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fb60d18a1e0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fb60d5a67b8) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7fb60d5a6820) 0 + primary-for QFileDevice (0x0x7fb60d5a67b8) + QObject (0x0x7fb60d18a180) 0 + primary-for QIODevice (0x0x7fb60d5a6820) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fb60d18a360) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fb60d5a6958) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7fb60d5a69c0) 0 + primary-for QFile (0x0x7fb60d5a6958) + QIODevice (0x0x7fb60d5a6a28) 0 + primary-for QFileDevice (0x0x7fb60d5a69c0) + QObject (0x0x7fb60d18a300) 0 + primary-for QIODevice (0x0x7fb60d5a6a28) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fb60d18a480) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fb60d18a720) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fb60d18aa20) 0 + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fb60d18ac00) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fb60d5a6f08) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7fb60d18aba0) 0 + primary-for QFileSelector (0x0x7fb60d5a6f08) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fb60d18acc0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fb60d5a6f70) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7fb60d18ac60) 0 + primary-for QFileSystemWatcher (0x0x7fb60d5a6f70) + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fb60d18ad20) 0 + +Class QLoggingCategory::AtomicBools + size=3 align=1 + base size=3 base align=1 +QLoggingCategory::AtomicBools (0x0x7fb60d18aea0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fb60d18ae40) 0 + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fb60d318060) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fb60d318240) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fb60d306138) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7fb60d3061a0) 0 + primary-for QProcess (0x0x7fb60d306138) + QObject (0x0x7fb60d3181e0) 0 + primary-for QIODevice (0x0x7fb60d3061a0) + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fb60d3182a0) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fb60d318420) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fb60d306208) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7fb60d306270) 0 + primary-for QSaveFile (0x0x7fb60d306208) + QIODevice (0x0x7fb60d3062d8) 0 + primary-for QFileDevice (0x0x7fb60d306270) + QObject (0x0x7fb60d3183c0) 0 + primary-for QIODevice (0x0x7fb60d3062d8) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fb60d3184e0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fb60d306340) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7fb60d318480) 0 + primary-for QSettings (0x0x7fb60d306340) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fb60d318540) 0 empty + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fb60d318660) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fb60d318900) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fb60d318a20) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fb60d3064e0) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7fb60d306548) 0 + primary-for QTemporaryFile (0x0x7fb60d3064e0) + QFileDevice (0x0x7fb60d3065b0) 0 + primary-for QFile (0x0x7fb60d306548) + QIODevice (0x0x7fb60d306618) 0 + primary-for QFileDevice (0x0x7fb60d3065b0) + QObject (0x0x7fb60d3189c0) 0 + primary-for QIODevice (0x0x7fb60d306618) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fb60d318b40) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fb60d0bd060) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fb60d0bd1e0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fb60d0bd300) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fb60d0bd480) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 (int (*)(...))QAbstractItemModel::~QAbstractItemModel +48 (int (*)(...))QAbstractItemModel::~QAbstractItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fb60d306af8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7fb60d0bd420) 0 + primary-for QAbstractItemModel (0x0x7fb60d306af8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fb60d0bd7e0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 (int (*)(...))QAbstractTableModel::~QAbstractTableModel +48 (int (*)(...))QAbstractTableModel::~QAbstractTableModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fb60d306c98) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7fb60d306d00) 0 + primary-for QAbstractTableModel (0x0x7fb60d306c98) + QObject (0x0x7fb60d0bd780) 0 + primary-for QAbstractItemModel (0x0x7fb60d306d00) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fb60d0bd8a0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 (int (*)(...))QAbstractListModel::~QAbstractListModel +48 (int (*)(...))QAbstractListModel::~QAbstractListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fb60d306d68) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7fb60d306dd0) 0 + primary-for QAbstractListModel (0x0x7fb60d306d68) + QObject (0x0x7fb60d0bd840) 0 + primary-for QAbstractItemModel (0x0x7fb60d306dd0) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fb60d0bd960) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 (int (*)(...))QAbstractProxyModel::~QAbstractProxyModel +48 (int (*)(...))QAbstractProxyModel::~QAbstractProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fb60d306e38) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7fb60d306ea0) 0 + primary-for QAbstractProxyModel (0x0x7fb60d306e38) + QObject (0x0x7fb60d0bd900) 0 + primary-for QAbstractItemModel (0x0x7fb60d306ea0) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fb60d0bda20) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fb60d306f08) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7fb60d306f70) 0 + primary-for QIdentityProxyModel (0x0x7fb60d306f08) + QAbstractItemModel (0x0x7fb60cdee000) 0 + primary-for QAbstractProxyModel (0x0x7fb60d306f70) + QObject (0x0x7fb60d0bd9c0) 0 + primary-for QAbstractItemModel (0x0x7fb60cdee000) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fb60d0bda80) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fb60d0bdc00) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fb60cdee0d0) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7fb60d0bdba0) 0 + primary-for QItemSelectionModel (0x0x7fb60cdee0d0) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7fb60cdee270) 0 + QList (0x0x7fb60cdee2d8) 0 + QListSpecialMethods (0x0x7fb60d0bde40) 0 empty + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fb60d0bdf00) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fb60cdee340) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7fb60cdee3a8) 0 + primary-for QSortFilterProxyModel (0x0x7fb60cdee340) + QAbstractItemModel (0x0x7fb60cdee410) 0 + primary-for QAbstractProxyModel (0x0x7fb60cdee3a8) + QObject (0x0x7fb60d0bdea0) 0 + primary-for QAbstractItemModel (0x0x7fb60cdee410) + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fb60ceb8000) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7fb60cdee478) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7fb60cdee4e0) 0 + primary-for QStringListModel (0x0x7fb60cdee478) + QAbstractItemModel (0x0x7fb60cdee548) 0 + primary-for QAbstractListModel (0x0x7fb60cdee4e0) + QObject (0x0x7fb60d0bdf60) 0 + primary-for QAbstractItemModel (0x0x7fb60cdee548) + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7fb60ceb8060) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7fb60ceb8120) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7fb60ceb81e0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7fb60ceb8240) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7fb60ceb8300) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7fb60ceb8360) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7fb60ceb82a0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fb60ceb83c0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fb60ceb8420) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7fb60ceb84e0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7fb60ceb8540) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7fb60ceb8480) 0 + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fb60ceb8660) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fb60cdee5b0) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7fb60ceb8600) 0 + primary-for QEventLoop (0x0x7fb60cdee5b0) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fb60ceb8780) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fb60ceb8840) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fb60ceb88a0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 (int (*)(...))QAbstractEventDispatcher::~QAbstractEventDispatcher +48 (int (*)(...))QAbstractEventDispatcher::~QAbstractEventDispatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fb60cdee6e8) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7fb60ceb87e0) 0 + primary-for QAbstractEventDispatcher (0x0x7fb60cdee6e8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 (int (*)(...))QAbstractNativeEventFilter::~QAbstractNativeEventFilter +24 (int (*)(...))QAbstractNativeEventFilter::~QAbstractNativeEventFilter +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fb60ceb8900) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fb60ceb8960) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7fb60ceb8a80) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7fb60cdee7b8) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7fb60ceb8ae0) 0 + primary-for QTimerEvent (0x0x7fb60cdee7b8) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7fb60cdee820) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7fb60ceb8b40) 0 + primary-for QChildEvent (0x0x7fb60cdee820) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7fb60cdee888) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7fb60ceb8ba0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fb60cdee888) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7fb60cdee8f0) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7fb60ceb8c00) 0 + primary-for QDeferredDeleteEvent (0x0x7fb60cdee8f0) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fb60ceb8cc0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fb60cdee958) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7fb60ceb8c60) 0 + primary-for QCoreApplication (0x0x7fb60cdee958) + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7fb60ceb8d20) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7fb60ceb8d80) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7fb60ceb8ea0) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fb60ccff000) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7fb60ccff060) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fb60ccff1e0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fb60cdeebc8) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7fb60ccff180) 0 + primary-for QMimeData (0x0x7fb60cdeebc8) + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fb60ccff2a0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7fb60cdeec30) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7fb60ccff240) 0 + primary-for QObjectCleanupHandler (0x0x7fb60cdeec30) + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fb60ccff3c0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fb60ccff540) 0 + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fb60ccffc00) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fb60cdeee38) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7fb60ccffba0) 0 + primary-for QSharedMemory (0x0x7fb60cdeee38) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fb60ccffcc0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fb60cdeeea0) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7fb60ccffc60) 0 + primary-for QSignalMapper (0x0x7fb60cdeeea0) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fb60ccffd80) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fb60cdeef08) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7fb60ccffd20) 0 + primary-for QSocketNotifier (0x0x7fb60cdeef08) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fb60ccffde0) 0 + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fb60ccfff00) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7fb60cdeef70) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7fb60ccffea0) 0 + primary-for QTimer (0x0x7fb60cdeef70) + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fb60ca600c0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fb60ca62068) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7fb60ca60060) 0 + primary-for QTranslator (0x0x7fb60ca62068) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fb60ca60120) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fb60ca602a0) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 (int (*)(...))QFactoryInterface::~QFactoryInterface +24 (int (*)(...))QFactoryInterface::~QFactoryInterface +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fb60ca60300) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fb60ca60420) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7fb60ca62138) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7fb60ca603c0) 0 + primary-for QLibrary (0x0x7fb60ca62138) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7fb60ca60540) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fb60ca606c0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fb60ca622d8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7fb60ca60660) 0 + primary-for QPluginLoader (0x0x7fb60ca622d8) + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fb60ca60720) 0 + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7fb60ca608a0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 (int (*)(...))QAbstractState::~QAbstractState +48 (int (*)(...))QAbstractState::~QAbstractState +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7fb60ca623a8) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7fb60ca60840) 0 + primary-for QAbstractState (0x0x7fb60ca623a8) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7fb60ca60960) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 (int (*)(...))QAbstractTransition::~QAbstractTransition +48 (int (*)(...))QAbstractTransition::~QAbstractTransition +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7fb60ca62410) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7fb60ca60900) 0 + primary-for QAbstractTransition (0x0x7fb60ca62410) + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7fb60ca60a20) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7fb60ca62478) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7fb60ca624e0) 0 + primary-for QEventTransition (0x0x7fb60ca62478) + QObject (0x0x7fb60ca609c0) 0 + primary-for QAbstractTransition (0x0x7fb60ca624e0) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7fb60ca60ae0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7fb60ca62548) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7fb60ca625b0) 0 + primary-for QFinalState (0x0x7fb60ca62548) + QObject (0x0x7fb60ca60a80) 0 + primary-for QAbstractState (0x0x7fb60ca625b0) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7fb60ca60ba0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7fb60ca62618) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7fb60ca62680) 0 + primary-for QHistoryState (0x0x7fb60ca62618) + QObject (0x0x7fb60ca60b40) 0 + primary-for QAbstractState (0x0x7fb60ca62680) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7fb60ca60c60) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7fb60ca626e8) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7fb60ca62750) 0 + primary-for QSignalTransition (0x0x7fb60ca626e8) + QObject (0x0x7fb60ca60c00) 0 + primary-for QAbstractTransition (0x0x7fb60ca62750) + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7fb60ca60d20) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7fb60ca627b8) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7fb60ca62820) 0 + primary-for QState (0x0x7fb60ca627b8) + QObject (0x0x7fb60ca60cc0) 0 + primary-for QAbstractState (0x0x7fb60ca62820) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7fb60ca60e40) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7fb60ca629c0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7fb60ca60ea0) 0 + primary-for QStateMachine::SignalEvent (0x0x7fb60ca629c0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7fb60ca62a28) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7fb60ca60f00) 0 + primary-for QStateMachine::WrappedEvent (0x0x7fb60ca62a28) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7fb60ca62888) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7fb60ca628f0) 0 + primary-for QStateMachine (0x0x7fb60ca62888) + QAbstractState (0x0x7fb60ca62958) 0 + primary-for QState (0x0x7fb60ca628f0) + QObject (0x0x7fb60ca60de0) 0 + primary-for QAbstractState (0x0x7fb60ca62958) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fb60ca62a90) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7fb60ca60f60) 0 nearly-empty + primary-for QException (0x0x7fb60ca62a90) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7fb60ca62af8) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7fb60ca62b60) 0 nearly-empty + primary-for QUnhandledException (0x0x7fb60ca62af8) + std::exception (0x0x7fb60c7a9000) 0 nearly-empty + primary-for QException (0x0x7fb60ca62b60) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7fb60c7a9060) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fb60c7a9120) 0 + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QRunnable::~QRunnable +32 (int (*)(...))QRunnable::~QRunnable + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7fb60c7a9180) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fb60c7a91e0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fb60ca62d00) 0 + QBasicMutex (0x0x7fb60c7a9300) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7fb60c7a9360) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fb60c7a93c0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fb60c7a9420) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fb60c7a95a0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fb60c7a9660) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fb60c7a99c0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 (int (*)(...))QFutureWatcherBase::~QFutureWatcherBase +48 (int (*)(...))QFutureWatcherBase::~QFutureWatcherBase +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fb60c834618) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7fb60c7a9960) 0 + primary-for QFutureWatcherBase (0x0x7fb60c834618) + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fb60c7a9ae0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fb60c7a9b40) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fb60c7a9ba0) 0 + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fb60c7a9c00) 0 + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fb60c7a9cc0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fb60c8349c0) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7fb60c7a9c60) 0 + primary-for QThread (0x0x7fb60c8349c0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fb60c7a9d80) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fb60c834a28) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7fb60c7a9d20) 0 + primary-for QThreadPool (0x0x7fb60c834a28) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fb60c7a9de0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fb60c7a9ea0) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7fb60c581480) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7fb60c5814e0) 0 + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fb60c581660) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7fb60c581600) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fb60c5817e0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fb60c5818a0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fb60c581a80) 0 + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fb60c581c00) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fb60c581c60) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fb60c581cc0) 0 + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fb60c581d20) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fb60c581e40) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fb60c581f60) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fb60c6f70c0) 0 + +Class QLinkedListData + size=32 align=8 + base size=32 base align=8 +QLinkedListData (0x0x7fb60c6f71e0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fb60c6f7540) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fb60c6f7660) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fb60c6f7780) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fb60c6f7840) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fb60c6f7960) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fb60c6f7a80) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fb60c6f7ba0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fb60c6f7cc0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fb60c20c000) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fb60c20c180) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fb60c20c3c0) 0 empty + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7fb60c20cde0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fb60c20cf60) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fb60c2a0340) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7fb60c20cf00) 0 + primary-for QTimeLine (0x0x7fb60c2a0340) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7fb60c2fc060) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fb60c2fc000) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7fb60c2fc2a0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7fb60c2fc300) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7fb60c2a05b0) 0 + QVector (0x0x7fb60c2fc4e0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fb60c2fc540) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7fb60c2fc660) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7fb60c2fc780) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fb60c2fc8a0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fb60c2fc900) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fb60c2fca20) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7fb60c2fcb40) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7fb60c2fcde0) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7fb60bfed0c0) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7fb60bfed360) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7fb60bfed420) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7fb60bfed4e0) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 (int (*)(...))QGeoPositionInfoSource::~QGeoPositionInfoSource +48 (int (*)(...))QGeoPositionInfoSource::~QGeoPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7fb60c2a0888) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7fb60bfed480) 0 + primary-for QGeoPositionInfoSource (0x0x7fb60c2a0888) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7fb60bfed660) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 (int (*)(...))QGeoAreaMonitorSource::~QGeoAreaMonitorSource +48 (int (*)(...))QGeoAreaMonitorSource::~QGeoAreaMonitorSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7fb60c2a09c0) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7fb60bfed600) 0 + primary-for QGeoAreaMonitorSource (0x0x7fb60c2a09c0) + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7fb60c2a0a28) 0 + QGeoShape (0x0x7fb60bfed6c0) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7fb60bfed900) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7fb60bfedba0) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7fb60bfedc60) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 (int (*)(...))QGeoSatelliteInfoSource::~QGeoSatelliteInfoSource +48 (int (*)(...))QGeoSatelliteInfoSource::~QGeoSatelliteInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7fb60c2a0b60) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7fb60bfedc00) 0 + primary-for QGeoSatelliteInfoSource (0x0x7fb60c2a0b60) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 (int (*)(...))QGeoPositionInfoSourceFactory::~QGeoPositionInfoSourceFactory +24 (int (*)(...))QGeoPositionInfoSourceFactory::~QGeoPositionInfoSourceFactory +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7fb60bfedd20) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7fb60c2a0bc8) 0 + QGeoShape (0x0x7fb60bfedde0) 0 + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7fb60c0d21e0) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7fb60c2a0d00) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7fb60c2a0d68) 0 + primary-for QNmeaPositionInfoSource (0x0x7fb60c2a0d00) + QObject (0x0x7fb60c0d2180) 0 + primary-for QGeoPositionInfoSource (0x0x7fb60c2a0d68) + diff --git a/tests/auto/bic/data/QtPositioning.5.6.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.6.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..42ed838 --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.6.0.linux-gcc-amd64.txt @@ -0,0 +1,4118 @@ +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f7583ec7ae0) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f7583ec7b40) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f7583f85780) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f7583f857e0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f7583f02958) 0 empty + std::input_iterator_tag (0x0x7f7583f85840) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f7583f029c0) 0 empty + std::forward_iterator_tag (0x0x7f7583f02a28) 0 empty + std::input_iterator_tag (0x0x7f7583f858a0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f7583f02a90) 0 empty + std::bidirectional_iterator_tag (0x0x7f7583f02af8) 0 empty + std::forward_iterator_tag (0x0x7f7583f02b60) 0 empty + std::input_iterator_tag (0x0x7f7583f85900) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f7583f85de0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f7583f85e40) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f7583f85ea0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f7583f85f00) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f7583f85f60) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f75840199c0) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f7584019c00) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f7584019cc0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f7584019d20) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f7584019de0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f7584019e40) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f7582cc5300) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f7582cc5360) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f7582cc53c0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f7583f02e38) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f7582cc5420) 0 nearly-empty + primary-for std::bad_exception (0x0x7f7583f02e38) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f7583f02ea0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f7582cc5480) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f7583f02ea0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f7582cc54e0) 0 empty + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f7582a5ec00) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f7582a5ec60) 0 + +Class QtPrivate::big_ + size=2 align=1 + base size=2 base align=1 +QtPrivate::big_ (0x0x7f7582a5ee40) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f7582b81ea0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f7582b81f00) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f7582b81f60) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f7582be9000) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f7582be9180) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f7582bb2618) 0 + QAtomicInteger (0x0x7f7582bb2680) 0 + QBasicAtomicInteger (0x0x7f7582be9cc0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f75826b1de0) 0 empty + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f75824ee2a0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f7582724888) 0 + QGenericArgument (0x0x7f75824ee300) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f75824ee480) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f75824ee540) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f75824ee600) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f75824ee660) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f75824ee7e0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f75824ee8a0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f75824eecc0) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f758227a060) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f758227a0c0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f758227af60) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f7582342000) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f75823420c0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f7582342120) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f7582342180) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f75823421e0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f7582342300) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f7582342360) 0 + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f7582342c00) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f7582342c60) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f7582342cc0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f7582342d20) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f7582200120) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f7582337c30) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f75822001e0) 0 nearly-empty + primary-for std::logic_error (0x0x7f7582337c30) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f7582337c98) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f7582337d00) 0 + primary-for std::domain_error (0x0x7f7582337c98) + std::exception (0x0x7f7582200240) 0 nearly-empty + primary-for std::logic_error (0x0x7f7582337d00) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f7582337d68) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f7582337dd0) 0 + primary-for std::invalid_argument (0x0x7f7582337d68) + std::exception (0x0x7f75822002a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f7582337dd0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f7582337e38) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f7582337ea0) 0 + primary-for std::length_error (0x0x7f7582337e38) + std::exception (0x0x7f7582200300) 0 nearly-empty + primary-for std::logic_error (0x0x7f7582337ea0) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f7582337f08) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f7582337f70) 0 + primary-for std::out_of_range (0x0x7f7582337f08) + std::exception (0x0x7f7582200360) 0 nearly-empty + primary-for std::logic_error (0x0x7f7582337f70) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f7582337138) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f75822003c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7582337138) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f7582337208) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f7582337270) 0 + primary-for std::range_error (0x0x7f7582337208) + std::exception (0x0x7f7582200420) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7582337270) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f75823372d8) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f75823373a8) 0 + primary-for std::overflow_error (0x0x7f75823372d8) + std::exception (0x0x7f7582200480) 0 nearly-empty + primary-for std::runtime_error (0x0x7f75823373a8) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f75823374e0) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f75823375b0) 0 + primary-for std::underflow_error (0x0x7f75823374e0) + std::exception (0x0x7f75822004e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f75823375b0) + +Class std::ios_base::system_error::error_code + size=16 align=8 + base size=16 base align=8 +std::ios_base::system_error::error_code (0x0x7f7582200600) 0 + +Vtable for std::ios_base::system_error +std::ios_base::system_error::_ZTVNSt8ios_base12system_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base12system_errorE) +16 (int (*)(...))std::ios_base::system_error::~system_error +24 (int (*)(...))std::ios_base::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::ios_base::system_error + size=32 align=8 + base size=32 base align=8 +std::ios_base::system_error (0x0x7f7582337958) 0 + vptr=((& std::ios_base::system_error::_ZTVNSt8ios_base12system_errorE) + 16u) + std::runtime_error (0x0x7f7582337a28) 0 + primary-for std::ios_base::system_error (0x0x7f7582337958) + std::exception (0x0x7f75822005a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f7582337a28) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f7582249000) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::ios_base::system_error (0x0x7f7582249068) 0 + primary-for std::ios_base::failure (0x0x7f7582249000) + std::runtime_error (0x0x7f75822490d0) 0 + primary-for std::ios_base::system_error (0x0x7f7582249068) + std::exception (0x0x7f7582200660) 0 nearly-empty + primary-for std::runtime_error (0x0x7f75822490d0) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f75822006c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f7582200720) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f7582200780) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f7582200540) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f7582200ea0) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f7581f505a0) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f7581a5d750 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f7581a5d820 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f7581a5dbc8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f7581a5dc98 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f7581cd5cc0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f7581cd5d20) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f7581b5f360) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f7581b5f540) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f7581b5f780) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f7581b5f840) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f7581b5f7e0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f7581b5fea0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f75819b72a0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f75819b7660) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f75819b76c0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f75819b7720) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f75819b7ae0) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f75819b7b40) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f7581b4ec98) 0 empty + QListData::NotIndirectLayout (0x0x7f75819b7ba0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f75817db310) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f75819b7c00) 0 empty + QListData::NotIndirectLayout (0x0x7f75819b7c60) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f7581b4ed00) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f75819b7cc0) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f75819b7d20) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f75819b7a80) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f758184a900) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f758184aae0) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f758184aa80) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f758152d068) 0 + QList (0x0x7f758152d0d0) 0 + QListSpecialMethods (0x0x7f758184acc0) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f758184af00) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f758158f600) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f758152dd00) 0 + std::iterator (0x0x7f758158f6c0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f758152dd68) 0 + std::_Bit_iterator_base (0x0x7f758152ddd0) 0 + std::iterator (0x0x7f758158f720) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f758152de38) 0 + std::_Bit_iterator_base (0x0x7f758152dea0) 0 + std::iterator (0x0x7f758158f780) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f758158fb40) 0 + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f758109f060) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f758109f120) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f758109f240) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f758109f3c0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f758109f660) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f758109f780) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f75811d2180) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f75811d2540) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f75811d2780) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f7580faa7e0) 0 + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f7580faa960) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f7580faab40) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f7580faaae0) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f7580faaea0) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f7580faaf00) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f7580caa000) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f7580ca5000) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f7580faaf60) 0 + primary-for QAbstractAnimation (0x0x7f7580ca5000) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f7580caa0c0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f7580ca5068) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f7580caa060) 0 + primary-for QAnimationDriver (0x0x7f7580ca5068) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f7580caa180) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f7580ca50d0) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f7580ca5138) 0 + primary-for QAnimationGroup (0x0x7f7580ca50d0) + QObject (0x0x7f7580caa120) 0 + primary-for QAbstractAnimation (0x0x7f7580ca5138) + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f7580caa240) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f7580ca51a0) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f7580ca5208) 0 + primary-for QParallelAnimationGroup (0x0x7f7580ca51a0) + QAbstractAnimation (0x0x7f7580ca5270) 0 + primary-for QAnimationGroup (0x0x7f7580ca5208) + QObject (0x0x7f7580caa1e0) 0 + primary-for QAbstractAnimation (0x0x7f7580ca5270) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f7580caa300) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f7580ca52d8) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f7580ca5340) 0 + primary-for QPauseAnimation (0x0x7f7580ca52d8) + QObject (0x0x7f7580caa2a0) 0 + primary-for QAbstractAnimation (0x0x7f7580ca5340) + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f7580d78660) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f7580d787e0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f7580d788a0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f7580d78c60) 0 + +Class QHashData + size=48 align=8 + base size=48 base align=8 +QHashData (0x0x7f7580d78c00) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f7580d78cc0) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f7580afc720) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f7580afc7e0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f7580afc780) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f7580afc840) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f7580afc6c0) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f7580afcb40) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f7580afcc00) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f7580afcba0) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f7580afccc0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f7580afcc60) 0 + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f75808c9900) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f75808f43a8) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f75808f4410) 0 + primary-for QVariantAnimation (0x0x7f75808f43a8) + QObject (0x0x7f75808c98a0) 0 + primary-for QAbstractAnimation (0x0x7f75808f4410) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f75808c99c0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f75808f44e0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f75808f4548) 0 + primary-for QPropertyAnimation (0x0x7f75808f44e0) + QAbstractAnimation (0x0x7f75808f45b0) 0 + primary-for QVariantAnimation (0x0x7f75808f4548) + QObject (0x0x7f75808c9960) 0 + primary-for QAbstractAnimation (0x0x7f75808f45b0) + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f75808c9a80) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f75808f4618) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f75808f4680) 0 + primary-for QSequentialAnimationGroup (0x0x7f75808f4618) + QAbstractAnimation (0x0x7f75808f46e8) 0 + primary-for QAnimationGroup (0x0x7f75808f4680) + QObject (0x0x7f75808c9a20) 0 + primary-for QAbstractAnimation (0x0x7f75808f46e8) + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f75808c9b40) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f75808c9ae0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f75808c9c60) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f75808c9cc0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f75808c9d20) 0 + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f75808c9f00) 0 empty + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f7580a066c0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f7580a06840) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f7580a069c0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f7580a06ba0) 0 empty + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f7580a06c60) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f75808f49c0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f7580a06c00) 0 + primary-for QIODevice (0x0x7f75808f49c0) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f7580a06de0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f75808f4af8) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f75808f4b60) 0 + primary-for QBuffer (0x0x7f75808f4af8) + QObject (0x0x7f7580a06d80) 0 + primary-for QIODevice (0x0x7f75808f4b60) + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f7580a06e40) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f7580a06f00) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f75807fb2a0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f75807fb300) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f75807fb3c0) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f75807fb5a0) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f75807fb7e0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f75807fbae0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f75807fba80) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f75807fbc60) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f75807fbd20) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f75807fbf00) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f758055d340) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f758055d3a8) 0 + primary-for QFileDevice (0x0x7f758055d340) + QObject (0x0x7f75807fbea0) 0 + primary-for QIODevice (0x0x7f758055d3a8) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f75806330c0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f758055d4e0) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f758055d548) 0 + primary-for QFile (0x0x7f758055d4e0) + QIODevice (0x0x7f758055d5b0) 0 + primary-for QFileDevice (0x0x7f758055d548) + QObject (0x0x7f7580633060) 0 + primary-for QIODevice (0x0x7f758055d5b0) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f75806331e0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f75806334e0) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f7580633840) 0 + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f7580633a20) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f758055da90) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f75806339c0) 0 + primary-for QFileSelector (0x0x7f758055da90) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f7580633ae0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f758055daf8) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f7580633a80) 0 + primary-for QFileSystemWatcher (0x0x7f758055daf8) + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f7580633b40) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f7580633cc0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f7580633c60) 0 + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f7580633e40) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f75803880c0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f758055dd00) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f758055dd68) 0 + primary-for QProcess (0x0x7f758055dd00) + QObject (0x0x7f7580388060) 0 + primary-for QIODevice (0x0x7f758055dd68) + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f7580388120) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f75803882a0) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f758055ddd0) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f758055de38) 0 + primary-for QSaveFile (0x0x7f758055ddd0) + QIODevice (0x0x7f758055dea0) 0 + primary-for QFileDevice (0x0x7f758055de38) + QObject (0x0x7f7580388240) 0 + primary-for QIODevice (0x0x7f758055dea0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f7580388360) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f758055df08) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f7580388300) 0 + primary-for QSettings (0x0x7f758055df08) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f75803883c0) 0 empty + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f75803884e0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f75803887e0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f7580388900) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f758043b068) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f758043b0d0) 0 + primary-for QTemporaryFile (0x0x7f758043b068) + QFileDevice (0x0x7f758043b138) 0 + primary-for QFile (0x0x7f758043b0d0) + QIODevice (0x0x7f758043b1a0) 0 + primary-for QFileDevice (0x0x7f758043b138) + QObject (0x0x7f75803888a0) 0 + primary-for QIODevice (0x0x7f758043b1a0) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f7580388a20) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f7580388e40) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f7580144060) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f75801441e0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f75801443c0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f758043b680) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f7580144360) 0 + primary-for QAbstractItemModel (0x0x7f758043b680) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f7580144720) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f758043b888) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f758043b8f0) 0 + primary-for QAbstractTableModel (0x0x7f758043b888) + QObject (0x0x7f75801446c0) 0 + primary-for QAbstractItemModel (0x0x7f758043b8f0) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f75801447e0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f758043b958) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f758043b9c0) 0 + primary-for QAbstractListModel (0x0x7f758043b958) + QObject (0x0x7f7580144780) 0 + primary-for QAbstractItemModel (0x0x7f758043b9c0) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f7580144ae0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f758043baf8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f758043bb60) 0 + primary-for QAbstractProxyModel (0x0x7f758043baf8) + QObject (0x0x7f7580144a80) 0 + primary-for QAbstractItemModel (0x0x7f758043bb60) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f7580144ba0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f758043bbc8) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f758043bc30) 0 + primary-for QIdentityProxyModel (0x0x7f758043bbc8) + QAbstractItemModel (0x0x7f758043bc98) 0 + primary-for QAbstractProxyModel (0x0x7f758043bc30) + QObject (0x0x7f7580144b40) 0 + primary-for QAbstractItemModel (0x0x7f758043bc98) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f7580144c00) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f7580144de0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f758043bdd0) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f7580144d80) 0 + primary-for QItemSelectionModel (0x0x7f758043bdd0) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f757ff17000) 0 + QList (0x0x7f757ff17068) 0 + QListSpecialMethods (0x0x7f757fef2060) 0 empty + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f757fef2480) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f757ff17138) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f757ff171a0) 0 + primary-for QSortFilterProxyModel (0x0x7f757ff17138) + QAbstractItemModel (0x0x7f757ff17208) 0 + primary-for QAbstractProxyModel (0x0x7f757ff171a0) + QObject (0x0x7f757fef2420) 0 + primary-for QAbstractItemModel (0x0x7f757ff17208) + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f757fef2540) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f757ff17270) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f757ff172d8) 0 + primary-for QStringListModel (0x0x7f757ff17270) + QAbstractItemModel (0x0x7f757ff17340) 0 + primary-for QAbstractListModel (0x0x7f757ff172d8) + QObject (0x0x7f757fef24e0) 0 + primary-for QAbstractItemModel (0x0x7f757ff17340) + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f757fef25a0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f757fef2660) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f757fef2720) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f757fef2780) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f757fef2840) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f757fef28a0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f757fef27e0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f757fef2900) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f757fef2960) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f757fef2a20) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f757fef2a80) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f757fef29c0) 0 + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f757fef2ba0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f757ff173a8) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f757fef2b40) 0 + primary-for QEventLoop (0x0x7f757ff173a8) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f757fef2cc0) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f757fef2d80) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f757fef2de0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f757ff174e0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f757fef2d20) 0 + primary-for QAbstractEventDispatcher (0x0x7f757ff174e0) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f757fef2e40) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f757fef2ea0) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f757fcc7060) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f757ff175b0) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f757fcc70c0) 0 + primary-for QTimerEvent (0x0x7f757ff175b0) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f757ff17618) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f757fcc7120) 0 + primary-for QChildEvent (0x0x7f757ff17618) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f757ff17680) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f757fcc7180) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f757ff17680) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f757ff176e8) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f757fcc71e0) 0 + primary-for QDeferredDeleteEvent (0x0x7f757ff176e8) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f757fcc72a0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f757ff17750) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f757fcc7240) 0 + primary-for QCoreApplication (0x0x7f757ff17750) + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f757fcc7300) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f757fcc7480) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f757fcc7600) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f757fcc7780) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f757fcc77e0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f757fcc79c0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f757ff178f0) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f757fcc7960) 0 + primary-for QMimeData (0x0x7f757ff178f0) + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f757fcc7a80) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f757ff17958) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f757fcc7a20) 0 + primary-for QObjectCleanupHandler (0x0x7f757ff17958) + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f757fcc7ae0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f757fcc7c60) 0 + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f757fad12a0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f757ff17d68) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f757fad1240) 0 + primary-for QSharedMemory (0x0x7f757ff17d68) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f757fad1360) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f757ff17dd0) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f757fad1300) 0 + primary-for QSignalMapper (0x0x7f757ff17dd0) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f757fad1420) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f757ff17e38) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f757fad13c0) 0 + primary-for QSocketNotifier (0x0x7f757ff17e38) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f757fad1480) 0 + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f757fad15a0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f757ff17ea0) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f757fad1540) 0 + primary-for QTimer (0x0x7f757ff17ea0) + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f757fad1720) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f757ff17f70) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f757fad16c0) 0 + primary-for QTranslator (0x0x7f757ff17f70) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f757fad1780) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f757fad1960) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f757fad19c0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f757fad1ae0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f757ff17c98) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f757fad1a80) 0 + primary-for QLibrary (0x0x7f757ff17c98) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f757fad1c00) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f757fad1de0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f757fbab0d0) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f757fad1d80) 0 + primary-for QPluginLoader (0x0x7f757fbab0d0) + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f757fad1e40) 0 + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f757fbf7060) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f757fbab1a0) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f757fbf7000) 0 + primary-for QAbstractState (0x0x7f757fbab1a0) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f757fbf7120) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f757fbab208) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f757fbf70c0) 0 + primary-for QAbstractTransition (0x0x7f757fbab208) + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f757fbf71e0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f757fbab270) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f757fbab2d8) 0 + primary-for QEventTransition (0x0x7f757fbab270) + QObject (0x0x7f757fbf7180) 0 + primary-for QAbstractTransition (0x0x7f757fbab2d8) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f757fbf72a0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f757fbab340) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f757fbab3a8) 0 + primary-for QFinalState (0x0x7f757fbab340) + QObject (0x0x7f757fbf7240) 0 + primary-for QAbstractState (0x0x7f757fbab3a8) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f757fbf7360) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f757fbab410) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f757fbab478) 0 + primary-for QHistoryState (0x0x7f757fbab410) + QObject (0x0x7f757fbf7300) 0 + primary-for QAbstractState (0x0x7f757fbab478) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f757fbf7420) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f757fbab4e0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f757fbab548) 0 + primary-for QSignalTransition (0x0x7f757fbab4e0) + QObject (0x0x7f757fbf73c0) 0 + primary-for QAbstractTransition (0x0x7f757fbab548) + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f757fbf74e0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f757fbab5b0) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f757fbab618) 0 + primary-for QState (0x0x7f757fbab5b0) + QObject (0x0x7f757fbf7480) 0 + primary-for QAbstractState (0x0x7f757fbab618) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f757fbf7600) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f757fbab7b8) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f757fbf7660) 0 + primary-for QStateMachine::SignalEvent (0x0x7f757fbab7b8) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f757fbab820) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f757fbf76c0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f757fbab820) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f757fbab680) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f757fbab6e8) 0 + primary-for QStateMachine (0x0x7f757fbab680) + QAbstractState (0x0x7f757fbab750) 0 + primary-for QState (0x0x7f757fbab6e8) + QObject (0x0x7f757fbf75a0) 0 + primary-for QAbstractState (0x0x7f757fbab750) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f757fbab888) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f757fbf7720) 0 nearly-empty + primary-for QException (0x0x7f757fbab888) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f757fbab8f0) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f757fbab958) 0 nearly-empty + primary-for QUnhandledException (0x0x7f757fbab8f0) + std::exception (0x0x7f757fbf7780) 0 nearly-empty + primary-for QException (0x0x7f757fbab958) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f757fbf77e0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f757fbf78a0) 0 + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f757fbf7900) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f757fbf7960) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f757fbabaf8) 0 + QBasicMutex (0x0x7f757fbf7ae0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f757fbf7b40) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f757fbf7c00) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f757fbf7c60) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f757fbf7de0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f757fbf7ea0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f757f976240) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f757f9373a8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f757f9761e0) 0 + primary-for QFutureWatcherBase (0x0x7f757f9373a8) + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f757f976360) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f757f9763c0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f757f976420) 0 + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f757f976480) 0 + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f757f976540) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f757f937820) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f757f9764e0) 0 + primary-for QThread (0x0x7f757f937820) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f757f976600) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f757f937888) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f757f9765a0) 0 + primary-for QThreadPool (0x0x7f757f937888) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f757f976660) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f757f976720) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f757f976c00) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f757f976de0) 0 + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f757f6fb060) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f757f6fb000) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f757f6fb1e0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f757f6fb2a0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f757f6fb540) 0 + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f757f6fb720) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f757f6fb780) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f757f6fb7e0) 0 + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f757f6fb840) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f757f6fb9c0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f757f6fbb40) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f757f6fbcc0) 0 + +Class QLinkedListData + size=32 align=8 + base size=32 base align=8 +QLinkedListData (0x0x7f757f6fbe40) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f757f44d600) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f757f44d780) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f757f44d900) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f757f44d9c0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f757f44dc00) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f757f44de40) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f757f631000) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f757f631180) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f757f6314e0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f757f6316c0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f757f631a80) 0 empty + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f757f2f04e0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f757f2f0660) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f757f258bc8) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f757f2f0600) 0 + primary-for QTimeLine (0x0x7f757f258bc8) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f757f2f0720) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f757f2f06c0) 0 + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f757f2f0a80) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f757f2f0a20) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f757f2f0d80) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f757f2f0f00) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f757f02d068) 0 + QVector (0x0x7f757f012180) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f757f0121e0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f757f012360) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f757f0124e0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f757f012660) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f757f0126c0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f757f0127e0) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7f757f012900) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7f757f012c00) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7f757f012f00) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7f757f118240) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7f757f118300) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7f757f1183c0) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7f757f02d340) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7f757f118360) 0 + primary-for QGeoPositionInfoSource (0x0x7f757f02d340) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7f757f118540) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7f757f02d478) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7f757f1184e0) 0 + primary-for QGeoAreaMonitorSource (0x0x7f757f02d478) + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7f757f02d4e0) 0 + QGeoShape (0x0x7f757f1185a0) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7f757f118840) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7f757f118b40) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7f757f118c00) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7f757f02d618) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7f757f118ba0) 0 + primary-for QGeoSatelliteInfoSource (0x0x7f757f02d618) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7f757f118cc0) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7f757f02d680) 0 + QGeoShape (0x0x7f757f118d80) 0 + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7f757eded1e0) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7f757f02d820) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7f757f02d888) 0 + primary-for QNmeaPositionInfoSource (0x0x7f757f02d820) + QObject (0x0x7f757eded180) 0 + primary-for QGeoPositionInfoSource (0x0x7f757f02d888) + diff --git a/tests/auto/bic/data/QtPositioning.5.7.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.7.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..cf3f81f --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.7.0.linux-gcc-amd64.txt @@ -0,0 +1,4400 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7ff717ebbd80) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7ff717f63540) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7ff717f63780) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7ff717f639c0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7ff717f63c00) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7ff717f63d80) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7ff717f97180) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7ff715c1b900) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7ff715c1b9c0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7ff715c1bd20) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7ff715c1bde0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7ff715c1bea0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7ff715c1bf60) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7ff715c52240) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7ff715c523c0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7ff715c52840) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7ff715c528a0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7ff715cfb540) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7ff715cfb5a0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7ff715c1f750) 0 empty + std::input_iterator_tag (0x0x7ff715cfb600) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7ff715c1f7b8) 0 empty + std::forward_iterator_tag (0x0x7ff715c1f820) 0 empty + std::input_iterator_tag (0x0x7ff715cfb660) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7ff715c1f888) 0 empty + std::bidirectional_iterator_tag (0x0x7ff715c1f8f0) 0 empty + std::forward_iterator_tag (0x0x7ff715c1f958) 0 empty + std::input_iterator_tag (0x0x7ff715cfb6c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7ff715d3d360) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7ff715d3d3c0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7ff715d3d420) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7ff715d3d480) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7ff715d3d4e0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7ff715a65000) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7ff715a65240) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7ff715a65300) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7ff715a65360) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7ff715a65420) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7ff715a65480) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7ff715a65900) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7ff715a65960) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7ff715a659c0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7ff715c1fea0) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7ff715a65a20) 0 nearly-empty + primary-for std::bad_exception (0x0x7ff715c1fea0) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7ff715a65a80) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7ff715a65ae0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7ff715b6f0d0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7ff715a65f00) 0 nearly-empty + primary-for std::bad_alloc (0x0x7ff715b6f0d0) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7ff715b6f138) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7ff715b6f1a0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7ff715b6f138) + std::exception (0x0x7ff715a65f60) 0 nearly-empty + primary-for std::bad_alloc (0x0x7ff715b6f1a0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7ff715b81000) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7ff715b81c00) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7ff715982900) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7ff715982960) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7ff715678840) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7ff7156788a0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7ff715678960) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7ff7156789c0) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7ff715678a20) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7ff715678a80) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7ff715678ba0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7ff715678c00) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7ff71542f060) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7ff71542f0c0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7ff7151ca8a0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7ff7151ca900) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7ff7151fc8a0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7ff714ff96c0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7ff7151d5f08) 0 + std::iterator (0x0x7ff714ff9780) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7ff7151d5f70) 0 + std::_Bit_iterator_base (0x0x7ff7151d56e8) 0 + std::iterator (0x0x7ff714ff97e0) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7ff7151d5750) 0 + std::_Bit_iterator_base (0x0x7ff7151d5a28) 0 + std::iterator (0x0x7ff714ff9840) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7ff714e26660) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7ff714f21420) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7ff714f213c0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7ff714cc13c0) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7ff713a87e40) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7ff713a87ea0) 0 + +Class QtPrivate::big_ + size=2 align=1 + base size=2 base align=1 +QtPrivate::big_ (0x0x7ff71383c2a0) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7ff7138f3780) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7ff7138f37e0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7ff7138f3840) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7ff7138f38a0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7ff7138f3a20) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7ff7138f3e40) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7ff713948138) 0 + std::__atomic_flag_base (0x0x7ff7138f3ea0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7ff713948888) 0 + QAtomicInteger (0x0x7ff7139488f0) 0 + QBasicAtomicInteger (0x0x7ff71349c420) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7ff7132d4cc0) 0 empty + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7ff713115ba0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7ff713291b60) 0 + QGenericArgument (0x0x7ff713115c00) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7ff713115d80) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7ff713115e40) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7ff712df1ea0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7ff712df1f00) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7ff712e970c0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7ff712e97180) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7ff712e975a0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7ff712e97600) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7ff712e97660) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7ff712e976c0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7ff712e97720) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7ff712e97ae0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7ff712e10d00) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7ff712e97ba0) 0 nearly-empty + primary-for std::logic_error (0x0x7ff712e10d00) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7ff712e10dd0) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7ff712fa9000) 0 + primary-for std::domain_error (0x0x7ff712e10dd0) + std::exception (0x0x7ff712e97c00) 0 nearly-empty + primary-for std::logic_error (0x0x7ff712fa9000) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7ff712fa9068) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7ff712fa90d0) 0 + primary-for std::invalid_argument (0x0x7ff712fa9068) + std::exception (0x0x7ff712e97c60) 0 nearly-empty + primary-for std::logic_error (0x0x7ff712fa90d0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7ff712fa9138) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7ff712fa91a0) 0 + primary-for std::length_error (0x0x7ff712fa9138) + std::exception (0x0x7ff712e97cc0) 0 nearly-empty + primary-for std::logic_error (0x0x7ff712fa91a0) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7ff712fa9208) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7ff712fa9270) 0 + primary-for std::out_of_range (0x0x7ff712fa9208) + std::exception (0x0x7ff712e97d20) 0 nearly-empty + primary-for std::logic_error (0x0x7ff712fa9270) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7ff712fa92d8) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7ff712e97d80) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff712fa92d8) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7ff712fa9340) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7ff712fa93a8) 0 + primary-for std::range_error (0x0x7ff712fa9340) + std::exception (0x0x7ff712e97de0) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff712fa93a8) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7ff712fa9410) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7ff712fa9478) 0 + primary-for std::overflow_error (0x0x7ff712fa9410) + std::exception (0x0x7ff712e97e40) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff712fa9478) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7ff712fa94e0) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7ff712fa9548) 0 + primary-for std::underflow_error (0x0x7ff712fa94e0) + std::exception (0x0x7ff712e97ea0) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff712fa9548) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7ff712bcb060) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7ff712bcb2a0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7ff712bcb420) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7ff712fa9a28) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7ff712fa9a90) 0 + primary-for std::system_error (0x0x7ff712fa9a28) + std::exception (0x0x7ff712bcb660) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff712fa9a90) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7ff712c27680) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7ff712c276e8) 0 + primary-for std::ios_base::failure (0x0x7ff712c27680) + std::runtime_error (0x0x7ff712c27750) 0 + primary-for std::system_error (0x0x7ff712c276e8) + std::exception (0x0x7ff712bcb960) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff712c27750) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7ff712bcb9c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7ff712bcba20) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7ff712bcba80) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7ff712bcb900) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7ff712cff240) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7ff712cff900) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7ff71291b000 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7ff71291b0d0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7ff71291b478 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7ff71291b548 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7ff7129391e0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7ff712939240) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7ff712637660) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7ff712637840) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7ff712637a80) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7ff712637b40) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7ff712637ae0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7ff712463ae0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7ff7121f6660) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7ff7121f6a80) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7ff7121f6ae0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7ff7121f6b40) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7ff7121f6f00) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7ff7121f6f60) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7ff7121fc618) 0 empty + QListData::NotIndirectLayout (0x0x7ff711ff3000) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7ff711fec850) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7ff711ff3060) 0 empty + QListData::NotIndirectLayout (0x0x7ff711ff30c0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7ff7121fc680) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7ff711ff3120) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7ff711ff3180) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7ff7121f6ea0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7ff711ff3d20) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7ff712181e40) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7ff712181de0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7ff712186f08) 0 + QList (0x0x7ff712186f70) 0 + QListSpecialMethods (0x0x7ff7121bc060) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7ff7121bc360) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7ff7121bc780) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7ff7121bcde0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7ff7121bcf60) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7ff711c36060) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7ff711dfdf70) 0 + std::__uses_alloc_base (0x0x7ff711c36000) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7ff711d2c0c0) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7ff711d2c300) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7ff711d2c3c0) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7ff711d2c4e0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7ff711d2c660) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7ff711d2ca20) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7ff711d2cb40) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7ff711ab54e0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7ff711ab58a0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7ff711ab5ae0) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7ff7118cf840) 0 + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7ff7118cf9c0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7ff7118cfba0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7ff7118cfb40) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7ff7118cff00) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7ff7118cff60) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7ff7115d6060) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7ff711b9c8f0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7ff7115d6000) 0 + primary-for QAbstractAnimation (0x0x7ff711b9c8f0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7ff7115d6120) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7ff711b9c958) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7ff7115d60c0) 0 + primary-for QAnimationDriver (0x0x7ff711b9c958) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7ff7115d61e0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7ff711b9c9c0) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7ff711b9ca28) 0 + primary-for QAnimationGroup (0x0x7ff711b9c9c0) + QObject (0x0x7ff7115d6180) 0 + primary-for QAbstractAnimation (0x0x7ff711b9ca28) + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7ff7115d62a0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7ff711b9ca90) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7ff711b9caf8) 0 + primary-for QParallelAnimationGroup (0x0x7ff711b9ca90) + QAbstractAnimation (0x0x7ff711b9cb60) 0 + primary-for QAnimationGroup (0x0x7ff711b9caf8) + QObject (0x0x7ff7115d6240) 0 + primary-for QAbstractAnimation (0x0x7ff711b9cb60) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7ff7115d6360) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7ff711b9cbc8) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7ff711b9cc30) 0 + primary-for QPauseAnimation (0x0x7ff711b9cbc8) + QObject (0x0x7ff7115d6300) 0 + primary-for QAbstractAnimation (0x0x7ff711b9cc30) + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7ff7116b36c0) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7ff711782780) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7ff711782840) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7ff711782c00) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7ff711782ba0) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7ff711782c60) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7ff7114ba6c0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7ff7114ba780) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7ff7114ba720) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7ff7114ba7e0) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7ff7114ba660) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7ff71123cae0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7ff71123ccc0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7ff71123cc60) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7ff71123cd80) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7ff71123cd20) 0 + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7ff710fcc720) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7ff710fd7208) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7ff710fd7270) 0 + primary-for QVariantAnimation (0x0x7ff710fd7208) + QObject (0x0x7ff710fcc6c0) 0 + primary-for QAbstractAnimation (0x0x7ff710fd7270) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7ff710fcc7e0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7ff710fd7340) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7ff710fd73a8) 0 + primary-for QPropertyAnimation (0x0x7ff710fd7340) + QAbstractAnimation (0x0x7ff710fd7410) 0 + primary-for QVariantAnimation (0x0x7ff710fd73a8) + QObject (0x0x7ff710fcc780) 0 + primary-for QAbstractAnimation (0x0x7ff710fd7410) + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7ff710fcc8a0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7ff710fd7478) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7ff710fd74e0) 0 + primary-for QSequentialAnimationGroup (0x0x7ff710fd7478) + QAbstractAnimation (0x0x7ff710fd7548) 0 + primary-for QAnimationGroup (0x0x7ff710fd74e0) + QObject (0x0x7ff710fcc840) 0 + primary-for QAbstractAnimation (0x0x7ff710fd7548) + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7ff710fcc960) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7ff710fcc900) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7ff710fccae0) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7ff710fccb40) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7ff710fccba0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7ff710fccd80) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7ff710fccf00) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7ff7111170c0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7ff7111172a0) 0 empty + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7ff711117360) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7ff710fd77b8) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7ff711117300) 0 + primary-for QIODevice (0x0x7ff710fd77b8) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7ff711117540) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7ff710fd78f0) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7ff710fd7958) 0 + primary-for QBuffer (0x0x7ff710fd78f0) + QObject (0x0x7ff7111174e0) 0 + primary-for QIODevice (0x0x7ff710fd7958) + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7ff7111175a0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7ff711117660) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7ff711117960) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7ff711117ba0) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7ff711117de0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7ff710b800c0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7ff710b80240) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7ff710b806c0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7ff710b80660) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7ff710d08780) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7ff710d08840) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7ff710d08900) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7ff710d09888) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7ff710d098f0) 0 + primary-for QFileDevice (0x0x7ff710d09888) + QObject (0x0x7ff710d088a0) 0 + primary-for QIODevice (0x0x7ff710d098f0) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7ff710d08ae0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7ff710d09a28) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7ff710d09a90) 0 + primary-for QFile (0x0x7ff710d09a28) + QIODevice (0x0x7ff710d09af8) 0 + primary-for QFileDevice (0x0x7ff710d09a90) + QObject (0x0x7ff710d08a80) 0 + primary-for QIODevice (0x0x7ff710d09af8) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7ff710d08c60) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7ff710d08f60) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7ff710a503c0) 0 + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7ff710a50600) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7ff710af2000) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7ff710a505a0) 0 + primary-for QFileSelector (0x0x7ff710af2000) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7ff710a506c0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7ff710af2068) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7ff710a50660) 0 + primary-for QFileSystemWatcher (0x0x7ff710af2068) + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7ff710a50720) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7ff710a508a0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7ff710a50840) 0 + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7ff710a50a20) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7ff710af2138) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7ff710a50a80) 0 nearly-empty + primary-for std::bad_cast (0x0x7ff710af2138) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7ff710af21a0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7ff710a50ae0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7ff710af21a0) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7ff7108d5410) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7ff710873ba0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7ff7108d5410) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7ff710873c60) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7ff710873cc0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7ff710873de0) 0 + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7ff71093d300) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7ff71093d540) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7ff7108d5c30) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7ff7108d5c98) 0 + primary-for QProcess (0x0x7ff7108d5c30) + QObject (0x0x7ff71093d4e0) 0 + primary-for QIODevice (0x0x7ff7108d5c98) + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7ff71093d5a0) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7ff71093d720) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7ff7108d5d00) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7ff7108d5d68) 0 + primary-for QSaveFile (0x0x7ff7108d5d00) + QIODevice (0x0x7ff7108d5dd0) 0 + primary-for QFileDevice (0x0x7ff7108d5d68) + QObject (0x0x7ff71093d6c0) 0 + primary-for QIODevice (0x0x7ff7108d5dd0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7ff71093d7e0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7ff7108d5e38) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7ff71093d780) 0 + primary-for QSettings (0x0x7ff7108d5e38) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7ff71093d840) 0 empty + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7ff71093d9c0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7ff71093dcc0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7ff71093dde0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7ff71066b000) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7ff71066b068) 0 + primary-for QTemporaryFile (0x0x7ff71066b000) + QFileDevice (0x0x7ff71066b0d0) 0 + primary-for QFile (0x0x7ff71066b068) + QIODevice (0x0x7ff71066b138) 0 + primary-for QFileDevice (0x0x7ff71066b0d0) + QObject (0x0x7ff71093dd80) 0 + primary-for QIODevice (0x0x7ff71066b138) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7ff71093df00) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7ff71037f3c0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7ff71037f5a0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7ff71037f720) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7ff710498600) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7ff710484f70) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7ff7104985a0) 0 + primary-for QAbstractItemModel (0x0x7ff710484f70) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7ff710498960) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7ff7104f71a0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7ff7104f7208) 0 + primary-for QAbstractTableModel (0x0x7ff7104f71a0) + QObject (0x0x7ff710498900) 0 + primary-for QAbstractItemModel (0x0x7ff7104f7208) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7ff710498a20) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7ff7104f7270) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7ff7104f72d8) 0 + primary-for QAbstractListModel (0x0x7ff7104f7270) + QObject (0x0x7ff7104989c0) 0 + primary-for QAbstractItemModel (0x0x7ff7104f72d8) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7ff710498d20) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7ff7104f7410) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7ff7104f7478) 0 + primary-for QAbstractProxyModel (0x0x7ff7104f7410) + QObject (0x0x7ff710498cc0) 0 + primary-for QAbstractItemModel (0x0x7ff7104f7478) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7ff710498de0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7ff7104f74e0) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7ff7104f7548) 0 + primary-for QIdentityProxyModel (0x0x7ff7104f74e0) + QAbstractItemModel (0x0x7ff7104f75b0) 0 + primary-for QAbstractProxyModel (0x0x7ff7104f7548) + QObject (0x0x7ff710498d80) 0 + primary-for QAbstractItemModel (0x0x7ff7104f75b0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7ff710498e40) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7ff71021d0c0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7ff7104f7820) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7ff71021d060) 0 + primary-for QItemSelectionModel (0x0x7ff7104f7820) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7ff7104f7a28) 0 + QList (0x0x7ff7104f7a90) 0 + QListSpecialMethods (0x0x7ff71021d360) 0 empty + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7ff71021d780) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7ff7104f7b60) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7ff7104f7bc8) 0 + primary-for QSortFilterProxyModel (0x0x7ff7104f7b60) + QAbstractItemModel (0x0x7ff7104f7c30) 0 + primary-for QAbstractProxyModel (0x0x7ff7104f7bc8) + QObject (0x0x7ff71021d720) 0 + primary-for QAbstractItemModel (0x0x7ff7104f7c30) + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7ff71021d840) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7ff7104f7c98) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7ff7104f7d00) 0 + primary-for QStringListModel (0x0x7ff7104f7c98) + QAbstractItemModel (0x0x7ff7104f7d68) 0 + primary-for QAbstractListModel (0x0x7ff7104f7d00) + QObject (0x0x7ff71021d7e0) 0 + primary-for QAbstractItemModel (0x0x7ff7104f7d68) + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7ff71021d8a0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7ff71021d960) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7ff71021da20) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7ff71021da80) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7ff71021db40) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7ff71021dba0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7ff71021dae0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7ff71021dc60) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7ff71021dcc0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7ff71021dd80) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7ff71021dde0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7ff71021dd20) 0 + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7ff71002d000) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7ff7104f7f70) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7ff71021df60) 0 + primary-for QEventLoop (0x0x7ff7104f7f70) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7ff71002d180) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7ff71002d240) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7ff71002d2a0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7ff7100380d0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7ff71002d1e0) 0 + primary-for QAbstractEventDispatcher (0x0x7ff7100380d0) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7ff71002d300) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7ff71002d360) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7ff71002d4e0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7ff7100381a0) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7ff71002d540) 0 + primary-for QTimerEvent (0x0x7ff7100381a0) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7ff710038208) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7ff71002d5a0) 0 + primary-for QChildEvent (0x0x7ff710038208) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7ff710038270) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7ff71002d600) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7ff710038270) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7ff7100382d8) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7ff71002d660) 0 + primary-for QDeferredDeleteEvent (0x0x7ff7100382d8) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7ff71002d720) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7ff710038340) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7ff71002d6c0) 0 + primary-for QCoreApplication (0x0x7ff710038340) + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7ff71002d7e0) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7ff71002d960) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7ff71002db40) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7ff71002dba0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7ff71002dd80) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7ff7100384e0) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7ff71002dd20) 0 + primary-for QMimeData (0x0x7ff7100384e0) + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7ff71002de40) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7ff710038548) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7ff71002dde0) 0 + primary-for QObjectCleanupHandler (0x0x7ff710038548) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7ff70fd690c0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7ff7100385b0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7ff70fd69060) 0 + primary-for QSharedMemory (0x0x7ff7100385b0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7ff70fd69180) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7ff710038618) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7ff70fd69120) 0 + primary-for QSignalMapper (0x0x7ff710038618) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7ff70fd69240) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7ff710038680) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7ff70fd691e0) 0 + primary-for QSocketNotifier (0x0x7ff710038680) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7ff70fd692a0) 0 + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7ff70fd693c0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7ff7100386e8) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7ff70fd69360) 0 + primary-for QTimer (0x0x7ff7100386e8) + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7ff70fd69540) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7ff7100387b8) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7ff70fd694e0) 0 + primary-for QTranslator (0x0x7ff7100387b8) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7ff70fd695a0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7ff70fd69780) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7ff70fd697e0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7ff70fd69900) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7ff710038888) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7ff70fd698a0) 0 + primary-for QLibrary (0x0x7ff710038888) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7ff70fd69a80) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7ff70fd69c60) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7ff710038a28) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7ff70fd69c00) 0 + primary-for QPluginLoader (0x0x7ff710038a28) + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7ff70fd69cc0) 0 + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7ff70fd69ea0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7ff710038af8) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7ff70fd69e40) 0 + primary-for QAbstractState (0x0x7ff710038af8) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7ff70fd69f60) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7ff710038b60) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7ff70fd69f00) 0 + primary-for QAbstractTransition (0x0x7ff710038b60) + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7ff70febb060) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7ff710038bc8) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7ff710038c30) 0 + primary-for QEventTransition (0x0x7ff710038bc8) + QObject (0x0x7ff70febb000) 0 + primary-for QAbstractTransition (0x0x7ff710038c30) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7ff70febb120) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7ff710038c98) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7ff710038d00) 0 + primary-for QFinalState (0x0x7ff710038c98) + QObject (0x0x7ff70febb0c0) 0 + primary-for QAbstractState (0x0x7ff710038d00) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7ff70febb1e0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7ff710038d68) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7ff710038dd0) 0 + primary-for QHistoryState (0x0x7ff710038d68) + QObject (0x0x7ff70febb180) 0 + primary-for QAbstractState (0x0x7ff710038dd0) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7ff70febb2a0) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7ff710038e38) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7ff710038ea0) 0 + primary-for QSignalTransition (0x0x7ff710038e38) + QObject (0x0x7ff70febb240) 0 + primary-for QAbstractTransition (0x0x7ff710038ea0) + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7ff70febb360) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7ff710038f08) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7ff710038f70) 0 + primary-for QState (0x0x7ff710038f08) + QObject (0x0x7ff70febb300) 0 + primary-for QAbstractState (0x0x7ff710038f70) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7ff70febb480) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7ff70ff22138) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7ff70febb4e0) 0 + primary-for QStateMachine::SignalEvent (0x0x7ff70ff22138) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7ff70ff221a0) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7ff70febb540) 0 + primary-for QStateMachine::WrappedEvent (0x0x7ff70ff221a0) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7ff70ff22000) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7ff70ff22068) 0 + primary-for QStateMachine (0x0x7ff70ff22000) + QAbstractState (0x0x7ff70ff220d0) 0 + primary-for QState (0x0x7ff70ff22068) + QObject (0x0x7ff70febb420) 0 + primary-for QAbstractState (0x0x7ff70ff220d0) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7ff70ff22208) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7ff70febb5a0) 0 nearly-empty + primary-for QException (0x0x7ff70ff22208) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7ff70ff22270) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7ff70ff222d8) 0 nearly-empty + primary-for QUnhandledException (0x0x7ff70ff22270) + std::exception (0x0x7ff70febb600) 0 nearly-empty + primary-for QException (0x0x7ff70ff222d8) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7ff70febb660) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7ff70febb720) 0 + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7ff70febb780) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7ff70febb7e0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7ff70ff22410) 0 + QBasicMutex (0x0x7ff70febba20) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7ff70febba80) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7ff70febbb40) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7ff70febbba0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7ff70febbd20) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7ff70febbde0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7ff70fc9f180) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7ff70ff22c98) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7ff70fc9f120) 0 + primary-for QFutureWatcherBase (0x0x7ff70ff22c98) + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7ff70fc9f2a0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7ff70fc9f540) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7ff70fc9f5a0) 0 + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7ff70fc9f600) 0 + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7ff70fc9f6c0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7ff70fd07270) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7ff70fc9f660) 0 + primary-for QThread (0x0x7ff70fd07270) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7ff70fc9f780) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7ff70fd072d8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7ff70fc9f720) 0 + primary-for QThreadPool (0x0x7ff70fd072d8) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7ff70fc9f7e0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7ff70fc9f8a0) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7ff70fc9fd80) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7ff70fa64000) 0 + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7ff70fa64240) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7ff70fa641e0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7ff70fa643c0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7ff70fa64480) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7ff70fb2e240) 0 + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7ff70fb2e420) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7ff70fb2e480) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7ff70fb2e4e0) 0 + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7ff70fb2e540) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7ff70fb2e6c0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7ff70fb2e840) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7ff70fb2e9c0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7ff70fb2eb40) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7ff70f8a3300) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7ff70f8a3480) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7ff70f8a3600) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7ff70f8a36c0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7ff70f8a3900) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7ff70f8a3b40) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7ff70f8a3cc0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7ff70f8a3e40) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7ff70f72c2a0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7ff70f72c480) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7ff70f72c840) 0 empty + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7ff70f4102a0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7ff70f410480) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7ff70f4410d0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7ff70f410420) 0 + primary-for QTimeLine (0x0x7ff70f4410d0) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7ff70f410540) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7ff70f4104e0) 0 + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7ff70f4108a0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7ff70f410840) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7ff70f53e660) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7ff70f20d360) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7ff70f20b8f0) 0 + QVector (0x0x7ff70f20d600) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7ff70f20d660) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7ff70f20d7e0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7ff70f20d960) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7ff70f20dae0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7ff70f20db40) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7ff70f20dc60) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7ff70f20dd80) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7ff70f32b0c0) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7ff70f32b3c0) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7ff70f32b6c0) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7ff70f32b780) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7ff70f32b840) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7ff70f20bf70) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7ff70f32b7e0) 0 + primary-for QGeoPositionInfoSource (0x0x7ff70f20bf70) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7ff70f32ba20) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7ff70f20bb60) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7ff70f32b9c0) 0 + primary-for QGeoAreaMonitorSource (0x0x7ff70f20bb60) + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7ff70f20bc98) 0 + QGeoShape (0x0x7ff70f32ba80) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7ff70f32bd20) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7ff70f004060) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7ff70f004120) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7ff70effc068) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7ff70f0040c0) 0 + primary-for QGeoSatelliteInfoSource (0x0x7ff70effc068) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7ff70f0041e0) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7ff70effc0d0) 0 + QGeoShape (0x0x7ff70f0042a0) 0 + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7ff70f0046c0) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7ff70effc270) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7ff70effc2d8) 0 + primary-for QNmeaPositionInfoSource (0x0x7ff70effc270) + QObject (0x0x7ff70f004660) 0 + primary-for QGeoPositionInfoSource (0x0x7ff70effc2d8) + diff --git a/tests/auto/bic/data/QtPositioning.5.8.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.8.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..9c9d1d8 --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.8.0.linux-gcc-amd64.txt @@ -0,0 +1,4425 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7fe59698d300) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7fe5969d5a80) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7fe5969d5cc0) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7fe5969d5f00) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7fe596a03180) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7fe596a03300) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7fe596a036c0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7fe59468fe40) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7fe59468ff00) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7fe5946be2a0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7fe5946be360) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7fe5946be420) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7fe5946be4e0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7fe5946be780) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7fe5946be960) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fe5946bede0) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fe5946bee40) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fe594775ae0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fe594775b40) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fe594666a90) 0 empty + std::input_iterator_tag (0x0x7fe594775ba0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fe594666af8) 0 empty + std::forward_iterator_tag (0x0x7fe594666b60) 0 empty + std::input_iterator_tag (0x0x7fe594775c00) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fe594666bc8) 0 empty + std::bidirectional_iterator_tag (0x0x7fe594666c30) 0 empty + std::forward_iterator_tag (0x0x7fe594666c98) 0 empty + std::input_iterator_tag (0x0x7fe594775c60) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7fe5947b1900) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7fe5947b1960) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7fe5947b19c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fe5947b1a20) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fe5947b1a80) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7fe59448c5a0) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fe59448c7e0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fe59448c8a0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fe59448c900) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fe59448c9c0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fe59448ca20) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fe59448cea0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fe59448cf00) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fe59448cf60) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fe5947e9208) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7fe5945ce000) 0 nearly-empty + primary-for std::bad_exception (0x0x7fe5947e9208) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7fe5945ce060) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7fe5945ce0c0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fe5947e9410) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7fe5945ce4e0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fe5947e9410) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7fe5947e9478) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7fe5947e94e0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7fe5947e9478) + std::exception (0x0x7fe5945ce540) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fe5947e94e0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fe5945ce5a0) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7fe5942a31e0) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fe5942a3ea0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fe5942a3f00) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fe5940e4de0) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7fe5940e4e40) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fe5940e4f00) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fe5940e4f60) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fe59416a000) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fe59416a060) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fe59416a180) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fe59416a1e0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7fe59416a600) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fe59416a660) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7fe593fa1e40) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7fe593fa1ea0) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fe593c77e40) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fe593e16c60) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fe593ade0d0) 0 + std::iterator (0x0x7fe593e16d20) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fe593ade138) 0 + std::_Bit_iterator_base (0x0x7fe593ade1a0) 0 + std::iterator (0x0x7fe593e16d80) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fe593ade208) 0 + std::_Bit_iterator_base (0x0x7fe593ade270) 0 + std::iterator (0x0x7fe593e16de0) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7fe593c02c00) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7fe5939359c0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7fe593935960) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7fe5936be960) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7fe59228c420) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7fe59228c480) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fe59234a6c0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fe59234a720) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fe59234a780) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fe5923a1240) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fe5923a1540) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7fe5923a1ae0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7fe5923a0680) 0 + std::__atomic_flag_base (0x0x7fe5923a1b40) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fe5923a0dd0) 0 + QAtomicInteger (0x0x7fe5923a0e38) 0 + QBasicAtomicInteger (0x0x7fe591f412a0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fe591d5eb40) 0 empty + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fe591b94ba0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fe591b5f270) 0 + QGenericArgument (0x0x7fe591b94c00) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7fe591b94d80) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fe591b94e40) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fe59186eea0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fe59186ef00) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fe5919163c0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7fe591916480) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fe5919168a0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fe591916900) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fe591916960) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fe5919169c0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fe591916a20) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7fe591916de0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7fe591992820) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7fe591916ea0) 0 nearly-empty + primary-for std::logic_error (0x0x7fe591992820) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7fe591992888) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7fe5919928f0) 0 + primary-for std::domain_error (0x0x7fe591992888) + std::exception (0x0x7fe591916f00) 0 nearly-empty + primary-for std::logic_error (0x0x7fe5919928f0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7fe591992958) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7fe5919929c0) 0 + primary-for std::invalid_argument (0x0x7fe591992958) + std::exception (0x0x7fe591916f60) 0 nearly-empty + primary-for std::logic_error (0x0x7fe5919929c0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7fe591992a28) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7fe591992a90) 0 + primary-for std::length_error (0x0x7fe591992a28) + std::exception (0x0x7fe591a38000) 0 nearly-empty + primary-for std::logic_error (0x0x7fe591992a90) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7fe591992af8) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7fe591992b60) 0 + primary-for std::out_of_range (0x0x7fe591992af8) + std::exception (0x0x7fe591a38060) 0 nearly-empty + primary-for std::logic_error (0x0x7fe591992b60) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7fe591992bc8) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7fe591a380c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe591992bc8) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7fe591992c30) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7fe591992c98) 0 + primary-for std::range_error (0x0x7fe591992c30) + std::exception (0x0x7fe591a38120) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe591992c98) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7fe591992d00) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7fe591992d68) 0 + primary-for std::overflow_error (0x0x7fe591992d00) + std::exception (0x0x7fe591a38180) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe591992d68) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7fe591992dd0) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7fe591992e38) 0 + primary-for std::underflow_error (0x0x7fe591992dd0) + std::exception (0x0x7fe591a381e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe591992e38) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7fe591a38360) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7fe591a385a0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7fe591a38720) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7fe591678270) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7fe5916782d8) 0 + primary-for std::system_error (0x0x7fe591678270) + std::exception (0x0x7fe591a38960) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe5916782d8) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7fe591678ea0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7fe591678f08) 0 + primary-for std::ios_base::failure (0x0x7fe591678ea0) + std::runtime_error (0x0x7fe591678f70) 0 + primary-for std::system_error (0x0x7fe591678f08) + std::exception (0x0x7fe591a38c60) 0 nearly-empty + primary-for std::runtime_error (0x0x7fe591678f70) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fe591a38cc0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fe591a38d20) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fe591a38d80) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fe591a38c00) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fe591785540) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fe591785c00) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7fe59133e888 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7fe59133e958 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7fe59133ed00 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7fe59133edd0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7fe5913294e0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7fe591329540) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7fe5910b5960) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fe5910b5cc0) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7fe5911b20c0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7fe5911b2180) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7fe5911b2120) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7fe590f8a120) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7fe590f8af60) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7fe590d08660) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7fe590d086c0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fe590d08720) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7fe590d08ae0) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7fe590d08b40) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7fe590d7e340) 0 empty + QListData::NotIndirectLayout (0x0x7fe590d08ba0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7fe590af8af0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fe590d08c00) 0 empty + QListData::NotIndirectLayout (0x0x7fe590d08c60) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7fe590d7e3a8) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fe590d08cc0) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7fe590d08d20) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7fe590d08a80) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7fe590b6d900) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7fe5908a5ba0) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7fe5908a5b40) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7fe5908a4d68) 0 + QList (0x0x7fe5908a4dd0) 0 + QListSpecialMethods (0x0x7fe5908a5d80) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fe590920240) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fe590920660) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7fe590920cc0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7fe590920e40) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7fe590920f00) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7fe59091fe38) 0 + std::__uses_alloc_base (0x0x7fe590920ea0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7fe590755f60) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7fe5904541e0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7fe5904542a0) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7fe5904543c0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7fe590454540) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7fe590454900) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7fe590454a20) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fe59060f3c0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fe59060f900) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fe59060fcc0) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fe5903cfd80) 0 + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7fe5903cff00) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fe590042120) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fe5900420c0) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7fe5900426c0) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fe590042720) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fe5900427e0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fe5902abdd0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7fe590042780) 0 + primary-for QAbstractAnimation (0x0x7fe5902abdd0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fe5900428a0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fe5902abe38) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7fe590042840) 0 + primary-for QAnimationDriver (0x0x7fe5902abe38) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fe590042960) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fe5902abea0) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7fe590042900) 0 + primary-for QEventLoop (0x0x7fe5902abea0) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fe590042ae0) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fe590042ba0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fe590042c00) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fe5902ab9c0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7fe590042b40) 0 + primary-for QAbstractEventDispatcher (0x0x7fe5902ab9c0) + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7fe590042c60) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7fe590042ea0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7fe5901c62a0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7fe5901c6240) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fe5901c6300) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7fe5901c6ea0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7fe5901c6f60) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7fe5901c6f00) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7fe58ffa9000) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7fe5901c6e40) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7fe58fc37480) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7fe58fc377e0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7fe58fc37780) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7fe58fc378a0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7fe58fc37840) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fe58fa69300) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fe58fa69600) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fe58fb44660) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fe58fb43888) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7fe58fb44600) 0 + primary-for QAbstractItemModel (0x0x7fe58fb43888) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fe58fb449c0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fe58fb43a90) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7fe58fb43af8) 0 + primary-for QAbstractTableModel (0x0x7fe58fb43a90) + QObject (0x0x7fe58fb44960) 0 + primary-for QAbstractItemModel (0x0x7fe58fb43af8) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fe58fb44a80) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fe58fb43b60) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7fe58fb43bc8) 0 + primary-for QAbstractListModel (0x0x7fe58fb43b60) + QObject (0x0x7fe58fb44a20) 0 + primary-for QAbstractItemModel (0x0x7fe58fb43bc8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fe58fb44d20) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fe58fb44de0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fe58fb43d00) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7fe58fb43d68) 0 + primary-for QAbstractProxyModel (0x0x7fe58fb43d00) + QObject (0x0x7fe58fb44d80) 0 + primary-for QAbstractItemModel (0x0x7fe58fb43d68) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7fe58fb44ea0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7fe58fb43dd0) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7fe58fb44e40) 0 + primary-for QAbstractState (0x0x7fe58fb43dd0) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7fe58fb44f60) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7fe58fb43e38) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7fe58fb44f00) 0 + primary-for QAbstractTransition (0x0x7fe58fb43e38) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fe58f89d060) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fe58fb43ea0) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7fe58fb43f08) 0 + primary-for QAnimationGroup (0x0x7fe58fb43ea0) + QObject (0x0x7fe58f89d000) 0 + primary-for QAbstractAnimation (0x0x7fe58fb43f08) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fe58f89d540) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7fe58f89d840) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7fe58f89da80) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fe58f89de40) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fe58f8caf08) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7fe58f89dde0) 0 + primary-for QIODevice (0x0x7fe58f8caf08) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fe58f9ae060) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fe58f98a068) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7fe58f98a0d0) 0 + primary-for QBuffer (0x0x7fe58f98a068) + QObject (0x0x7fe58f9ae000) 0 + primary-for QIODevice (0x0x7fe58f98a0d0) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fe58f9ae120) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7fe58f9ae0c0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fe58f9ae2a0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fe58f9ae480) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fe58f9ae900) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fe58f9ae9c0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fe58f76ba80) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7fe58f76bf00) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7fe58f7a2208) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7fe58f76bf60) 0 + primary-for QTimerEvent (0x0x7fe58f7a2208) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7fe58f7a2270) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7fe58f7e9000) 0 + primary-for QChildEvent (0x0x7fe58f7a2270) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7fe58f7a23a8) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7fe58f7e91e0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fe58f7a23a8) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7fe58f7a2410) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7fe58f7e9240) 0 + primary-for QDeferredDeleteEvent (0x0x7fe58f7a2410) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fe58f7e9300) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fe58f7a2478) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7fe58f7e92a0) 0 + primary-for QCoreApplication (0x0x7fe58f7a2478) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fe58f7e9360) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7fe58f7e93c0) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fe58f7e9660) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fe58f7e96c0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7fe58f7e9780) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fe58f7e9960) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fe58f7e9c60) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7fe58f4fd180) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7fe58f4fd1e0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fe58f4fd120) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fe58f5ae000) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7fe58f2223c0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7fe58f368240) 0 empty + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7fe58f3682a0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fe58f0a9120) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fe58f0a9360) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fe58f0a95a0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fe58f0a9720) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7fe58f0a9ba0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fe58f0a9b40) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fe58eef1de0) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fe58eef1ea0) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fe58eef1f60) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fe58ef03b60) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7fe58ef03bc8) 0 + primary-for QFileDevice (0x0x7fe58ef03b60) + QObject (0x0x7fe58eef1f00) 0 + primary-for QIODevice (0x0x7fe58ef03bc8) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fe58efb1180) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fe58ef03d00) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7fe58ef03d68) 0 + primary-for QFile (0x0x7fe58ef03d00) + QIODevice (0x0x7fe58ef03dd0) 0 + primary-for QFileDevice (0x0x7fe58ef03d68) + QObject (0x0x7fe58efb1120) 0 + primary-for QIODevice (0x0x7fe58ef03dd0) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fe58efb1300) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fe58efb1780) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fe58efb1d20) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fe58efb1f00) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7fe58ed8d1e0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7fe58ed7cbc8) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7fe58ed7cc30) 0 + primary-for QEventTransition (0x0x7fe58ed7cbc8) + QObject (0x0x7fe58ed8d180) 0 + primary-for QAbstractTransition (0x0x7fe58ed7cc30) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fe58ed7cc98) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7fe58ed8d240) 0 nearly-empty + primary-for QException (0x0x7fe58ed7cc98) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7fe58ed7cd00) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7fe58ed7cd68) 0 nearly-empty + primary-for QUnhandledException (0x0x7fe58ed7cd00) + std::exception (0x0x7fe58ed8d2a0) 0 nearly-empty + primary-for QException (0x0x7fe58ed7cd68) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7fe58ed8d300) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fe58ed8d3c0) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fe58ed8d420) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fe58ed8d540) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fe58ed7cdd0) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7fe58ed8d4e0) 0 + primary-for QFileSelector (0x0x7fe58ed7cdd0) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fe58ed8d600) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fe58ed7ce38) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7fe58ed8d5a0) 0 + primary-for QFileSystemWatcher (0x0x7fe58ed7ce38) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7fe58ed8d6c0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7fe58ed7cea0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7fe58ed7cf08) 0 + primary-for QFinalState (0x0x7fe58ed7cea0) + QObject (0x0x7fe58ed8d660) 0 + primary-for QAbstractState (0x0x7fe58ed7cf08) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7fe58ed8d720) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fe58ed8d780) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fe58ea54068) 0 + QBasicMutex (0x0x7fe58ed8d9c0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7fe58ed8dd80) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fe58ed8de40) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fe58ed8dea0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fe58eaf7060) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fe58eaf7120) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fe58eaf7480) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fe58ea54c30) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7fe58eaf7420) 0 + primary-for QFutureWatcherBase (0x0x7fe58ea54c30) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7fe58eaf7600) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7fe58e7db068) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7fe58e7db0d0) 0 + primary-for QHistoryState (0x0x7fe58e7db068) + QObject (0x0x7fe58eaf75a0) 0 + primary-for QAbstractState (0x0x7fe58e7db0d0) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fe58eaf76c0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fe58e7db138) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7fe58e7db1a0) 0 + primary-for QIdentityProxyModel (0x0x7fe58e7db138) + QAbstractItemModel (0x0x7fe58e7db208) 0 + primary-for QAbstractProxyModel (0x0x7fe58e7db1a0) + QObject (0x0x7fe58eaf7660) 0 + primary-for QAbstractItemModel (0x0x7fe58e7db208) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fe58eaf7720) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fe58eaf7ae0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fe58e7db548) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7fe58eaf7a80) 0 + primary-for QItemSelectionModel (0x0x7fe58e7db548) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7fe58e7db750) 0 + QList (0x0x7fe58e7db7b8) 0 + QListSpecialMethods (0x0x7fe58eaf7d80) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7fe58e8c8300) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7fe58e8c8540) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7fe58e8c8600) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7fe58e8c8660) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7fe58e8c8720) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7fe58e8c8780) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7fe58e8c86c0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fe58e8c8840) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fe58e8c88a0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7fe58e8c8960) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7fe58e8c89c0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7fe58e8c8900) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fe58e8c8ba0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7fe58e7dbbc8) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7fe58e8c8b40) 0 + primary-for QLibrary (0x0x7fe58e7dbbc8) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7fe58e8c8d80) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7fe58e8c8d20) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fe58e6f5b40) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fe58e6f5ba0) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fe58e6f5ea0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fe58e7931e0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fe58e7934e0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7fe58e7937e0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fe58e793f60) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7fe58e4d6120) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fe58e4d60c0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fe58e4d62a0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fe58e4d65a0) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fe58e4d6900) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7fe58e4d6960) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7fe58e4d6c60) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fe58e217000) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7fe58e217060) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fe58e2173c0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fe58e7c58f0) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7fe58e217360) 0 + primary-for QMimeData (0x0x7fe58e7c58f0) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fe58e217420) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fe58e217780) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fe58e217840) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7fe58e7c5a90) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7fe58e2177e0) 0 + primary-for QObjectCleanupHandler (0x0x7fe58e7c5a90) + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fe58e217900) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fe58e7c5af8) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7fe58e7c5b60) 0 + primary-for QParallelAnimationGroup (0x0x7fe58e7c5af8) + QAbstractAnimation (0x0x7fe58e7c5bc8) 0 + primary-for QAnimationGroup (0x0x7fe58e7c5b60) + QObject (0x0x7fe58e2178a0) 0 + primary-for QAbstractAnimation (0x0x7fe58e7c5bc8) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fe58e2179c0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fe58e7c5c30) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7fe58e7c5c98) 0 + primary-for QPauseAnimation (0x0x7fe58e7c5c30) + QObject (0x0x7fe58e217960) 0 + primary-for QAbstractAnimation (0x0x7fe58e7c5c98) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7fe58e217ba0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fe58e217f00) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fe58e7c5e38) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7fe58e217ea0) 0 + primary-for QPluginLoader (0x0x7fe58e7c5e38) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7fe58e217f60) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7fe58e7c5ea0) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7fe58e2cb000) 0 nearly-empty + primary-for std::bad_cast (0x0x7fe58e7c5ea0) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7fe58e7c5f08) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7fe58e2cb060) 0 nearly-empty + primary-for std::bad_typeid (0x0x7fe58e7c5f08) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7fe58e03e1a0) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7fe58e04f120) 0 nearly-empty + primary-for std::bad_function_call (0x0x7fe58e03e1a0) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7fe58e04f1e0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7fe58e04f240) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7fe58e04f360) 0 + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fe58e04f840) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fe58e04fc00) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fe58e03ea90) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7fe58e03eaf8) 0 + primary-for QProcess (0x0x7fe58e03ea90) + QObject (0x0x7fe58e04fba0) 0 + primary-for QIODevice (0x0x7fe58e03eaf8) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fe58e04fcc0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fe58e03eb60) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7fe58e03ebc8) 0 + primary-for QVariantAnimation (0x0x7fe58e03eb60) + QObject (0x0x7fe58e04fc60) 0 + primary-for QAbstractAnimation (0x0x7fe58e03ebc8) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fe58e04fd80) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fe58e03ec98) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7fe58e03ed00) 0 + primary-for QPropertyAnimation (0x0x7fe58e03ec98) + QAbstractAnimation (0x0x7fe58e03ed68) 0 + primary-for QVariantAnimation (0x0x7fe58e03ed00) + QObject (0x0x7fe58e04fd20) 0 + primary-for QAbstractAnimation (0x0x7fe58e03ed68) + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fe58e04fe40) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fe58e199120) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fe58e199180) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fe58e1991e0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fe58e1995a0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fe58e199960) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fe58e199c60) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fe58e199f60) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fe58df99540) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fe58df998a0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fe58df99c00) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fe58df99d80) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fe58ddead68) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7fe58ddeadd0) 0 + primary-for QSaveFile (0x0x7fe58ddead68) + QIODevice (0x0x7fe58ddeae38) 0 + primary-for QFileDevice (0x0x7fe58ddeadd0) + QObject (0x0x7fe58df99d20) 0 + primary-for QIODevice (0x0x7fe58ddeae38) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fe58df99e40) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fe58df99f00) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fe58ddeaea0) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7fe58ddeaf08) 0 + primary-for QSequentialAnimationGroup (0x0x7fe58ddeaea0) + QAbstractAnimation (0x0x7fe58ddeaf70) 0 + primary-for QAnimationGroup (0x0x7fe58ddeaf08) + QObject (0x0x7fe58df99ea0) 0 + primary-for QAbstractAnimation (0x0x7fe58ddeaf70) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fe58dc7f000) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fe58dc7b000) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7fe58df99f60) 0 + primary-for QSettings (0x0x7fe58dc7b000) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fe58dc7f0c0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fe58dc7b068) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7fe58dc7f060) 0 + primary-for QSharedMemory (0x0x7fe58dc7b068) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fe58dc7f180) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fe58dc7b0d0) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7fe58dc7f120) 0 + primary-for QSignalMapper (0x0x7fe58dc7b0d0) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7fe58dc7f240) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7fe58dc7b138) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7fe58dc7b1a0) 0 + primary-for QSignalTransition (0x0x7fe58dc7b138) + QObject (0x0x7fe58dc7f1e0) 0 + primary-for QAbstractTransition (0x0x7fe58dc7b1a0) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fe58dc7f300) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fe58dc7b208) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7fe58dc7f2a0) 0 + primary-for QSocketNotifier (0x0x7fe58dc7b208) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fe58dc7f3c0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fe58dc7b270) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7fe58dc7b2d8) 0 + primary-for QSortFilterProxyModel (0x0x7fe58dc7b270) + QAbstractItemModel (0x0x7fe58dc7b340) 0 + primary-for QAbstractProxyModel (0x0x7fe58dc7b2d8) + QObject (0x0x7fe58dc7f360) 0 + primary-for QAbstractItemModel (0x0x7fe58dc7b340) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fe58dc7f5a0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7fe58dc7f780) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7fe58dc7b4e0) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7fe58dc7b548) 0 + primary-for QState (0x0x7fe58dc7b4e0) + QObject (0x0x7fe58dc7f720) 0 + primary-for QAbstractState (0x0x7fe58dc7b548) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7fe58dc7f8a0) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7fe58dc7b6e8) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7fe58dc7f900) 0 + primary-for QStateMachine::SignalEvent (0x0x7fe58dc7b6e8) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7fe58dc7b750) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7fe58dc7f960) 0 + primary-for QStateMachine::WrappedEvent (0x0x7fe58dc7b750) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7fe58dc7b5b0) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7fe58dc7b618) 0 + primary-for QStateMachine (0x0x7fe58dc7b5b0) + QAbstractState (0x0x7fe58dc7b680) 0 + primary-for QState (0x0x7fe58dc7b618) + QObject (0x0x7fe58dc7f840) 0 + primary-for QAbstractState (0x0x7fe58dc7b680) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fe58dc7f9c0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fe58dc7fe40) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fe58d9d5900) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7fe58da30208) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7fe58da30270) 0 + primary-for QStringListModel (0x0x7fe58da30208) + QAbstractItemModel (0x0x7fe58da302d8) 0 + primary-for QAbstractListModel (0x0x7fe58da30270) + QObject (0x0x7fe58d9d58a0) 0 + primary-for QAbstractItemModel (0x0x7fe58da302d8) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fe58d9d5960) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fe58d9d5a20) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fe58d9d5b40) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fe58da30340) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7fe58da303a8) 0 + primary-for QTemporaryFile (0x0x7fe58da30340) + QFileDevice (0x0x7fe58da30410) 0 + primary-for QFile (0x0x7fe58da303a8) + QIODevice (0x0x7fe58da30478) 0 + primary-for QFileDevice (0x0x7fe58da30410) + QObject (0x0x7fe58d9d5ae0) 0 + primary-for QIODevice (0x0x7fe58da30478) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7fe58d9d5ba0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7fe58d9d5d80) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7fe58d9d5d20) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7fe58d9d5f00) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7fe58d9d5f60) 0 + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fe58db15060) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fe58da30680) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7fe58db15000) 0 + primary-for QThread (0x0x7fe58da30680) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fe58db15120) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fe58da306e8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7fe58db150c0) 0 + primary-for QThreadPool (0x0x7fe58da306e8) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fe58db15180) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fe58db152a0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fe58da30750) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7fe58db15240) 0 + primary-for QTimeLine (0x0x7fe58da30750) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fe58db15360) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7fe58da307b8) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7fe58db15300) 0 + primary-for QTimer (0x0x7fe58da307b8) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7fe58dbaf180) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fe58dbaf120) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fe58dbaf7e0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fe58dba2958) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7fe58dbaf780) 0 + primary-for QTranslator (0x0x7fe58dba2958) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fe58dbaf900) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fe58d8e3f00) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fe58d9892a0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fe58d9895a0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7fe58d989600) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7fe58d626ba0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7fe58d6661a0) 0 + QVector (0x0x7fe58d696000) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fe58d696060) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7fe58d696360) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7fe58d696660) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fe58d696960) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fe58d6969c0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fe58d696de0) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7fe58d696f00) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7fe58d76a3c0) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7fe58d76a840) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7fe58d76acc0) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7fe58d76ad80) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7fe58d76ae40) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7fe58d666ea0) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7fe58d76ade0) 0 + primary-for QGeoPositionInfoSource (0x0x7fe58d666ea0) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7fe58d41e060) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7fe58d6664e0) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7fe58d41e000) 0 + primary-for QGeoAreaMonitorSource (0x0x7fe58d6664e0) + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7fe58d6666e8) 0 + QGeoShape (0x0x7fe58d41e0c0) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7fe58d41e4e0) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7fe58d41e960) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7fe58d41ea20) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7fe58d440208) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7fe58d41e9c0) 0 + primary-for QGeoSatelliteInfoSource (0x0x7fe58d440208) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7fe58d41eae0) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7fe58d440270) 0 + QGeoShape (0x0x7fe58d41eba0) 0 + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7fe58d4d2180) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7fe58d4404e0) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7fe58d440548) 0 + primary-for QNmeaPositionInfoSource (0x0x7fe58d4404e0) + QObject (0x0x7fe58d4d2120) 0 + primary-for QGeoPositionInfoSource (0x0x7fe58d440548) + diff --git a/tests/auto/bic/data/QtPositioning.5.9.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPositioning.5.9.0.linux-gcc-amd64.txt new file mode 100644 index 0000000..db5f7e8 --- /dev/null +++ b/tests/auto/bic/data/QtPositioning.5.9.0.linux-gcc-amd64.txt @@ -0,0 +1,4446 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7fd646d253c0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7fd646d6eb40) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7fd646d6ed80) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7fd646d9a000) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7fd646d9a240) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7fd646d9a3c0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7fd646d9a780) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7fd644a28f00) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7fd644a56000) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7fd644a56360) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7fd644a56420) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7fd644a564e0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7fd644a565a0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7fd644a56840) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7fd644a56a20) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fd644a56ea0) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fd644a56f00) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fd644b0eba0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fd644b0ec00) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fd6449fdbc8) 0 empty + std::input_iterator_tag (0x0x7fd644b0ec60) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fd6449fdc30) 0 empty + std::forward_iterator_tag (0x0x7fd6449fdc98) 0 empty + std::input_iterator_tag (0x0x7fd644b0ecc0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fd6449fdd00) 0 empty + std::bidirectional_iterator_tag (0x0x7fd6449fdd68) 0 empty + std::forward_iterator_tag (0x0x7fd6449fddd0) 0 empty + std::input_iterator_tag (0x0x7fd644b0ed20) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7fd644b3c9c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7fd644b3ca20) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7fd644b3ca80) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fd644b3cae0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fd644b3cb40) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7fd644822660) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fd6448228a0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fd644822960) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fd6448229c0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fd644822a80) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fd644822ae0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fd644822f60) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fd6448af000) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fd6448af060) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fd644b4d340) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7fd6448af0c0) 0 nearly-empty + primary-for std::bad_exception (0x0x7fd644b4d340) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7fd6448af120) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7fd6448af180) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fd644b4d548) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7fd6448af5a0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fd644b4d548) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7fd644b4d5b0) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7fd644b4d618) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7fd644b4d5b0) + std::exception (0x0x7fd6448af600) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fd644b4d618) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fd6448af660) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7fd6446342a0) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fd644634f60) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fd64446f000) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fd64446fea0) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7fd64446ff00) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fd644501000) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fd644501060) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fd6445010c0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fd644501120) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fd644501240) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fd6445012a0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7fd6445016c0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fd644501720) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7fd644337f00) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7fd644337f60) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fd64400ef00) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fd6441b0d20) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fd6441af208) 0 + std::iterator (0x0x7fd6441b0de0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fd6441af270) 0 + std::_Bit_iterator_base (0x0x7fd6441af2d8) 0 + std::iterator (0x0x7fd6441b0e40) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fd6441af340) 0 + std::_Bit_iterator_base (0x0x7fd6441af3a8) 0 + std::iterator (0x0x7fd6441b0ea0) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7fd643f5acc0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7fd643ccca80) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7fd643ccca20) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7fd643a38a20) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7fd6426244e0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7fd642624540) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fd6426f5060) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fd6426f50c0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fd6426f5120) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fd6426f5180) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fd6426f5420) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7fd6426f5960) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7fd642743208) 0 + std::__atomic_flag_base (0x0x7fd6426f59c0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fd642743958) 0 + QAtomicInteger (0x0x7fd6427439c0) 0 + QBasicAtomicInteger (0x0x7fd64231d120) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fd642191600) 0 empty + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fd641f87660) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fd641f29270) 0 + QGenericArgument (0x0x7fd641f876c0) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7fd641f87840) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fd641f87900) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fd641c4a960) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fd641c4a9c0) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fd641c4ac60) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7fd641c4ad20) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fd641d5b1e0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fd641d5b240) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fd641d5b2a0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fd641d5b300) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fd641d5b360) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7fd641d5b720) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7fd641d63888) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7fd641d5b7e0) 0 nearly-empty + primary-for std::logic_error (0x0x7fd641d63888) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7fd641d638f0) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7fd641d63958) 0 + primary-for std::domain_error (0x0x7fd641d638f0) + std::exception (0x0x7fd641d5b840) 0 nearly-empty + primary-for std::logic_error (0x0x7fd641d63958) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7fd641d639c0) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7fd641d63a28) 0 + primary-for std::invalid_argument (0x0x7fd641d639c0) + std::exception (0x0x7fd641d5b8a0) 0 nearly-empty + primary-for std::logic_error (0x0x7fd641d63a28) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7fd641d63a90) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7fd641d63af8) 0 + primary-for std::length_error (0x0x7fd641d63a90) + std::exception (0x0x7fd641d5b900) 0 nearly-empty + primary-for std::logic_error (0x0x7fd641d63af8) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7fd641d63b60) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7fd641d63bc8) 0 + primary-for std::out_of_range (0x0x7fd641d63b60) + std::exception (0x0x7fd641d5b960) 0 nearly-empty + primary-for std::logic_error (0x0x7fd641d63bc8) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7fd641d63c30) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7fd641d5b9c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd641d63c30) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7fd641d63c98) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7fd641d63d00) 0 + primary-for std::range_error (0x0x7fd641d63c98) + std::exception (0x0x7fd641d5ba20) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd641d63d00) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7fd641d63d68) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7fd641d63dd0) 0 + primary-for std::overflow_error (0x0x7fd641d63d68) + std::exception (0x0x7fd641d5ba80) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd641d63dd0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7fd641d63e38) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7fd641d63ea0) 0 + primary-for std::underflow_error (0x0x7fd641d63e38) + std::exception (0x0x7fd641d5bae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd641d63ea0) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7fd641d5bc60) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7fd641d5bea0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7fd641a4b060) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7fd641a472d8) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7fd641a47340) 0 + primary-for std::system_error (0x0x7fd641a472d8) + std::exception (0x0x7fd641a4b2a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd641a47340) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7fd641a47f08) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7fd641a47f70) 0 + primary-for std::ios_base::failure (0x0x7fd641a47f08) + std::runtime_error (0x0x7fd641ab2000) 0 + primary-for std::system_error (0x0x7fd641a47f70) + std::exception (0x0x7fd641a4b5a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fd641ab2000) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fd641a4b600) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fd641a4b660) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fd641a4b6c0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fd641a4b540) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fd641a4be40) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fd641bc2540) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7fd6417089c0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7fd641708a90 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7fd641708e38 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7fd641708f08 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7fd641957de0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7fd641957e40) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7fd6414b5300) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fd6414b5600) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7fd6414b5960) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7fd6414b5a20) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7fd6414b59c0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7fd6412e4a20) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7fd6410727e0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7fd641072d20) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7fd641072d80) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fd641072de0) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7fd640e3d1e0) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7fd640e3d240) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7fd641106478) 0 empty + QListData::NotIndirectLayout (0x0x7fd640e3d2a0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7fd640ed2af0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fd640e3d300) 0 empty + QListData::NotIndirectLayout (0x0x7fd640e3d360) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7fd6411064e0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fd640e3d3c0) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7fd640e3d420) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7fd640e3d180) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7fd640bfa000) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7fd640c7e240) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7fd640c7e1e0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7fd640c6df08) 0 + QList (0x0x7fd640c6df70) 0 + QListSpecialMethods (0x0x7fd640c7e420) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fd640c7e840) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fd640c7ec60) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7fd640a52300) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7fd640a52480) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7fd640a52540) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7fd640cd4888) 0 + std::__uses_alloc_base (0x0x7fd640a524e0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7fd6407fe5a0) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7fd6407fe7e0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7fd6407fe8a0) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7fd6407fe9c0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7fd6407feb40) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7fd6407fef60) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7fd6409530c0) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fd640953a20) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fd640953f00) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fd64062f2a0) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fd6403e7180) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7fd640464660) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7fd6405b04e0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7fd6405b0540) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fd6405b0720) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fd6405b06c0) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7fd6405b0e40) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fd6405b0ea0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fd6405b0f60) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fd6401ae888) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7fd6405b0f00) 0 + primary-for QAbstractAnimation (0x0x7fd6401ae888) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fd6402b2060) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fd6401ae8f0) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7fd6402b2000) 0 + primary-for QAnimationDriver (0x0x7fd6401ae8f0) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fd6402b2120) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fd6401ae958) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7fd6402b20c0) 0 + primary-for QEventLoop (0x0x7fd6401ae958) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fd6402b2300) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fd6402b23c0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fd6402b2420) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fd6401aea90) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7fd6402b2360) 0 + primary-for QAbstractEventDispatcher (0x0x7fd6401aea90) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7fd6402b2480) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7fd6401aeaf8) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7fd6402b24e0) 0 nearly-empty + primary-for std::bad_cast (0x0x7fd6401aeaf8) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7fd6401aeb60) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7fd6402b2540) 0 nearly-empty + primary-for std::bad_typeid (0x0x7fd6401aeb60) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7fd63ffc4d68) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7fd64008d600) 0 nearly-empty + primary-for std::bad_function_call (0x0x7fd63ffc4d68) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7fd64008d6c0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7fd64008d720) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7fd64008d840) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7fd64008dd20) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7fd64008dde0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7fd6401881e0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7fd640188180) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fd640188240) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7fd640188d80) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7fd640188e40) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7fd640188de0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7fd640188ea0) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7fd640188d20) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7fd63fc211e0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7fd63fc214e0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7fd63fc21480) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7fd63fc215a0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7fd63fc21540) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fd63fa78000) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fd63fa782a0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fd63fb1b2a0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fd63fb0bf08) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7fd63fb1b240) 0 + primary-for QAbstractItemModel (0x0x7fd63fb0bf08) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fd63fb1b600) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fd63fb75138) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7fd63fb751a0) 0 + primary-for QAbstractTableModel (0x0x7fd63fb75138) + QObject (0x0x7fd63fb1b5a0) 0 + primary-for QAbstractItemModel (0x0x7fd63fb751a0) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fd63fb1b6c0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fd63fb75208) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7fd63fb75270) 0 + primary-for QAbstractListModel (0x0x7fd63fb75208) + QObject (0x0x7fd63fb1b660) 0 + primary-for QAbstractItemModel (0x0x7fd63fb75270) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fd63fb1b960) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fd63fb1ba20) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fd63fb753a8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7fd63fb75410) 0 + primary-for QAbstractProxyModel (0x0x7fd63fb753a8) + QObject (0x0x7fd63fb1b9c0) 0 + primary-for QAbstractItemModel (0x0x7fd63fb75410) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7fd63fb1bae0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7fd63fb75478) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7fd63fb1ba80) 0 + primary-for QAbstractState (0x0x7fd63fb75478) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7fd63fb1bba0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7fd63fb754e0) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7fd63fb1bb40) 0 + primary-for QAbstractTransition (0x0x7fd63fb754e0) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fd63fb1bc60) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fd63fb75548) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7fd63fb755b0) 0 + primary-for QAnimationGroup (0x0x7fd63fb75548) + QObject (0x0x7fd63fb1bc00) 0 + primary-for QAbstractAnimation (0x0x7fd63fb755b0) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fd63f8b3180) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7fd63f8b3420) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7fd63f8b3660) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fd63f8b39c0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fd63f8af680) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7fd63f8b3960) 0 + primary-for QIODevice (0x0x7fd63f8af680) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fd63f8b3c00) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fd63f8af7b8) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7fd63f8af820) 0 + primary-for QBuffer (0x0x7fd63f8af7b8) + QObject (0x0x7fd63f8b3ba0) 0 + primary-for QIODevice (0x0x7fd63f8af820) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fd63f8b3cc0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7fd63f8b3c60) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7fd63f8b3de0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7fd63f8b3d80) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fd63f5d4000) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fd63f5d41e0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fd63f5d4660) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fd63f5d4720) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fd63f75c720) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7fd63f75cba0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7fd63f759bc8) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7fd63f75cc00) 0 + primary-for QTimerEvent (0x0x7fd63f759bc8) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7fd63f759c30) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7fd63f75cc60) 0 + primary-for QChildEvent (0x0x7fd63f759c30) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7fd63f759c98) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7fd63f75ccc0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fd63f759c98) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7fd63f759d00) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7fd63f75cd20) 0 + primary-for QDeferredDeleteEvent (0x0x7fd63f759d00) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fd63f75cde0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fd63f759d68) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7fd63f75cd80) 0 + primary-for QCoreApplication (0x0x7fd63f759d68) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fd63f75ce40) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7fd63f75cea0) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fd63f3e0180) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fd63f3e01e0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7fd63f3e02a0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fd63f3e0300) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fd63f3e05a0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7fd63f3e08a0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7fd63f3e0900) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fd63f3e0840) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fd63f56c6c0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7fd63f56c720) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fd63f2aa360) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fd63f2aa600) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fd63f2aa840) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fd63f2aa9c0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7fd63f2aae40) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fd63f2aade0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fd63f14f060) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fd63f14f120) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fd63f14f1e0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fd63f10dd00) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7fd63f10dd68) 0 + primary-for QFileDevice (0x0x7fd63f10dd00) + QObject (0x0x7fd63f14f180) 0 + primary-for QIODevice (0x0x7fd63f10dd68) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fd63f14f420) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fd63f10dea0) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7fd63f10df08) 0 + primary-for QFile (0x0x7fd63f10dea0) + QIODevice (0x0x7fd63f10df70) 0 + primary-for QFileDevice (0x0x7fd63f10df08) + QObject (0x0x7fd63f14f3c0) 0 + primary-for QIODevice (0x0x7fd63f10df70) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fd63f14f600) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fd63f14fa20) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fd63ee83420) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fd63ee83660) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7fd63eb9c8a0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7fd63eba5270) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7fd63eba52d8) 0 + primary-for QEventTransition (0x0x7fd63eba5270) + QObject (0x0x7fd63eb9c840) 0 + primary-for QAbstractTransition (0x0x7fd63eba52d8) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fd63eba5340) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7fd63eb9c900) 0 nearly-empty + primary-for QException (0x0x7fd63eba5340) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7fd63eba53a8) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7fd63eba5410) 0 nearly-empty + primary-for QUnhandledException (0x0x7fd63eba53a8) + std::exception (0x0x7fd63eb9c960) 0 nearly-empty + primary-for QException (0x0x7fd63eba5410) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7fd63eb9c9c0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fd63eb9ca80) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fd63eb9cae0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fd63eb9cc00) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fd63eba5478) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7fd63eb9cba0) 0 + primary-for QFileSelector (0x0x7fd63eba5478) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fd63eb9ccc0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fd63eba54e0) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7fd63eb9cc60) 0 + primary-for QFileSystemWatcher (0x0x7fd63eba54e0) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7fd63eb9cd80) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7fd63eba5548) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7fd63eba55b0) 0 + primary-for QFinalState (0x0x7fd63eba5548) + QObject (0x0x7fd63eb9cd20) 0 + primary-for QAbstractState (0x0x7fd63eba55b0) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7fd63eb9cde0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fd63eb9ce40) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fd63eba56e8) 0 + QBasicMutex (0x0x7fd63ec6f0c0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7fd63ec6f180) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fd63ec6f240) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fd63ec6f2a0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fd63ec6f3c0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fd63ec6f420) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fd63ec6f780) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fd63eba5af8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7fd63ec6f720) 0 + primary-for QFutureWatcherBase (0x0x7fd63eba5af8) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7fd63ec6f900) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7fd63eba5f08) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7fd63eba5f70) 0 + primary-for QHistoryState (0x0x7fd63eba5f08) + QObject (0x0x7fd63ec6f8a0) 0 + primary-for QAbstractState (0x0x7fd63eba5f70) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fd63ec6f9c0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fd63eba5750) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7fd63e9e8000) 0 + primary-for QIdentityProxyModel (0x0x7fd63eba5750) + QAbstractItemModel (0x0x7fd63e9e8068) 0 + primary-for QAbstractProxyModel (0x0x7fd63e9e8000) + QObject (0x0x7fd63ec6f960) 0 + primary-for QAbstractItemModel (0x0x7fd63e9e8068) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fd63ec6fa20) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fd63ec6fd80) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fd63e9e8410) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7fd63ec6fd20) 0 + primary-for QItemSelectionModel (0x0x7fd63e9e8410) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7fd63e9e8618) 0 + QList (0x0x7fd63e9e8680) 0 + QListSpecialMethods (0x0x7fd63ea860c0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7fd63ea865a0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7fd63ea86660) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7fd63ea86720) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7fd63ea86780) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7fd63ea86840) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7fd63ea868a0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7fd63ea867e0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fd63ea86960) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fd63ea869c0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7fd63ea86a80) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7fd63ea86ae0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7fd63ea86a20) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fd63ea86cc0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7fd63e9e8a28) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7fd63ea86c60) 0 + primary-for QLibrary (0x0x7fd63e9e8a28) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7fd63ea86f00) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7fd63ea86ea0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fd63e8dfc60) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fd63e8dfcc0) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fd63e8dff60) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fd63e57d240) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fd63e57d4e0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7fd63e57d780) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fd63e57df00) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7fd63e6ce0c0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fd63e6ce060) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fd63e6ce240) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fd63e6ce4e0) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fd63e6ce7e0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7fd63e6ce840) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7fd63e6ceae0) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fd63e6cede0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7fd63e6cee40) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fd63e414180) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fd63e5b4b60) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7fd63e414120) 0 + primary-for QMimeData (0x0x7fd63e5b4b60) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fd63e4141e0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fd63e4144e0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fd63e4145a0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7fd63e5b4d68) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7fd63e414540) 0 + primary-for QObjectCleanupHandler (0x0x7fd63e5b4d68) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7fd63e414600) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fd63e4146c0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fd63e5b4e38) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7fd63e5b4ea0) 0 + primary-for QParallelAnimationGroup (0x0x7fd63e5b4e38) + QAbstractAnimation (0x0x7fd63e5b4f08) 0 + primary-for QAnimationGroup (0x0x7fd63e5b4ea0) + QObject (0x0x7fd63e414660) 0 + primary-for QAbstractAnimation (0x0x7fd63e5b4f08) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fd63e414780) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fd63e5b4f70) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7fd63e5b4dd0) 0 + primary-for QPauseAnimation (0x0x7fd63e5b4f70) + QObject (0x0x7fd63e414720) 0 + primary-for QAbstractAnimation (0x0x7fd63e5b4dd0) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7fd63e414960) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fd63e414c60) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fd63e4b31a0) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7fd63e414c00) 0 + primary-for QPluginLoader (0x0x7fd63e4b31a0) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fd63e414cc0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fd63e4e1060) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fd63e4b33a8) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7fd63e4b3410) 0 + primary-for QProcess (0x0x7fd63e4b33a8) + QObject (0x0x7fd63e4e1000) 0 + primary-for QIODevice (0x0x7fd63e4b3410) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fd63e4e1120) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fd63e4b3478) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7fd63e4b34e0) 0 + primary-for QVariantAnimation (0x0x7fd63e4b3478) + QObject (0x0x7fd63e4e10c0) 0 + primary-for QAbstractAnimation (0x0x7fd63e4b34e0) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fd63e4e11e0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fd63e4b35b0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7fd63e4b3618) 0 + primary-for QPropertyAnimation (0x0x7fd63e4b35b0) + QAbstractAnimation (0x0x7fd63e4b3680) 0 + primary-for QVariantAnimation (0x0x7fd63e4b3618) + QObject (0x0x7fd63e4e1180) 0 + primary-for QAbstractAnimation (0x0x7fd63e4b3680) + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fd63e4e12a0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fd63e4e1540) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fd63e4e15a0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fd63e4e1600) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fd63e4e1960) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fd63e4e1cc0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fd63e4e1f60) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fd63e303240) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fd63e303840) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fd63e303b40) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fd63e303e40) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fd63e032000) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fd63e26e958) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7fd63e26e9c0) 0 + primary-for QSaveFile (0x0x7fd63e26e958) + QIODevice (0x0x7fd63e26ea28) 0 + primary-for QFileDevice (0x0x7fd63e26e9c0) + QObject (0x0x7fd63e303f60) 0 + primary-for QIODevice (0x0x7fd63e26ea28) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fd63e0320c0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fd63e032180) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fd63e26ea90) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7fd63e26eaf8) 0 + primary-for QSequentialAnimationGroup (0x0x7fd63e26ea90) + QAbstractAnimation (0x0x7fd63e26eb60) 0 + primary-for QAnimationGroup (0x0x7fd63e26eaf8) + QObject (0x0x7fd63e032120) 0 + primary-for QAbstractAnimation (0x0x7fd63e26eb60) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fd63e032240) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fd63e26ebc8) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7fd63e0321e0) 0 + primary-for QSettings (0x0x7fd63e26ebc8) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fd63e032300) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fd63e26ec30) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7fd63e0322a0) 0 + primary-for QSharedMemory (0x0x7fd63e26ec30) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fd63e0323c0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fd63e26ec98) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7fd63e032360) 0 + primary-for QSignalMapper (0x0x7fd63e26ec98) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7fd63e032480) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7fd63e26ed00) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7fd63e26ed68) 0 + primary-for QSignalTransition (0x0x7fd63e26ed00) + QObject (0x0x7fd63e032420) 0 + primary-for QAbstractTransition (0x0x7fd63e26ed68) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fd63e032540) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fd63e26edd0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7fd63e0324e0) 0 + primary-for QSocketNotifier (0x0x7fd63e26edd0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fd63e032600) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fd63e26ee38) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7fd63e26eea0) 0 + primary-for QSortFilterProxyModel (0x0x7fd63e26ee38) + QAbstractItemModel (0x0x7fd63e26ef08) 0 + primary-for QAbstractProxyModel (0x0x7fd63e26eea0) + QObject (0x0x7fd63e0325a0) 0 + primary-for QAbstractItemModel (0x0x7fd63e26ef08) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fd63e0327e0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7fd63e032a20) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7fd63e1030d0) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7fd63e103138) 0 + primary-for QState (0x0x7fd63e1030d0) + QObject (0x0x7fd63e0329c0) 0 + primary-for QAbstractState (0x0x7fd63e103138) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7fd63e032b40) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7fd63e1032d8) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7fd63e032ba0) 0 + primary-for QStateMachine::SignalEvent (0x0x7fd63e1032d8) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7fd63e103340) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7fd63e032c00) 0 + primary-for QStateMachine::WrappedEvent (0x0x7fd63e103340) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7fd63e1031a0) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7fd63e103208) 0 + primary-for QStateMachine (0x0x7fd63e1031a0) + QAbstractState (0x0x7fd63e103270) 0 + primary-for QState (0x0x7fd63e103208) + QObject (0x0x7fd63e032ae0) 0 + primary-for QAbstractState (0x0x7fd63e103270) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fd63e032c60) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fd63ddaa0c0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fd63ddaab40) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7fd63e103dd0) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7fd63e103e38) 0 + primary-for QStringListModel (0x0x7fd63e103dd0) + QAbstractItemModel (0x0x7fd63e103ea0) 0 + primary-for QAbstractListModel (0x0x7fd63e103e38) + QObject (0x0x7fd63ddaaae0) 0 + primary-for QAbstractItemModel (0x0x7fd63e103ea0) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fd63ddaaba0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fd63ddaac60) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fd63ddaad80) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fd63e103f08) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7fd63e103f70) 0 + primary-for QTemporaryFile (0x0x7fd63e103f08) + QFileDevice (0x0x7fd63de51000) 0 + primary-for QFile (0x0x7fd63e103f70) + QIODevice (0x0x7fd63de51068) 0 + primary-for QFileDevice (0x0x7fd63de51000) + QObject (0x0x7fd63ddaad20) 0 + primary-for QIODevice (0x0x7fd63de51068) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7fd63ddaade0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7fd63de9e060) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7fd63de9e000) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7fd63de9e240) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7fd63de9e2a0) 0 + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fd63de9e360) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fd63de51270) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7fd63de9e300) 0 + primary-for QThread (0x0x7fd63de51270) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fd63de9e420) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fd63de512d8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7fd63de9e3c0) 0 + primary-for QThreadPool (0x0x7fd63de512d8) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fd63de9e480) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fd63de9e5a0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fd63de51340) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7fd63de9e540) 0 + primary-for QTimeLine (0x0x7fd63de51340) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fd63de9e660) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7fd63de513a8) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7fd63de9e600) 0 + primary-for QTimer (0x0x7fd63de513a8) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7fd63db75480) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fd63db75420) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fd63db75a20) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fd63db7d618) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7fd63db759c0) 0 + primary-for QTranslator (0x0x7fd63db7d618) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fd63db75b40) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fd63dcdf240) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fd63dcdf540) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fd63dcdf7e0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7fd63dcdf840) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7fd63d9fdc60) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7fd63da00c30) 0 + QVector (0x0x7fd63da50060) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fd63da500c0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7fd63da50360) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7fd63da50600) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fd63da508a0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fd63da50900) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fd63da50a20) 0 + +Class QGeoAddress + size=8 align=8 + base size=8 base align=8 +QGeoAddress (0x0x7fd63da50b40) 0 + +Class QGeoCoordinate + size=8 align=8 + base size=8 base align=8 +QGeoCoordinate (0x0x7fd63da50f60) 0 + +Class QGeoShape + size=8 align=8 + base size=8 base align=8 +QGeoShape (0x0x7fd63db523c0) 0 + +Class QGeoAreaMonitorInfo + size=8 align=8 + base size=8 base align=8 +QGeoAreaMonitorInfo (0x0x7fd63db527e0) 0 + +Class QGeoPositionInfo + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfo (0x0x7fd63db528a0) 0 + +Class QGeoPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoPositionInfoSource::QPrivateSignal (0x0x7fd63db52960) 0 empty + +Vtable for QGeoPositionInfoSource +QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGeoPositionInfoSource) +16 (int (*)(...))QGeoPositionInfoSource::metaObject +24 (int (*)(...))QGeoPositionInfoSource::qt_metacast +32 (int (*)(...))QGeoPositionInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoPositionInfoSource (0x0x7fd63da81d00) 0 + vptr=((& QGeoPositionInfoSource::_ZTV22QGeoPositionInfoSource) + 16u) + QObject (0x0x7fd63db52900) 0 + primary-for QGeoPositionInfoSource (0x0x7fd63da81d00) + +Class QGeoAreaMonitorSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoAreaMonitorSource::QPrivateSignal (0x0x7fd63db52ba0) 0 empty + +Vtable for QGeoAreaMonitorSource +QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGeoAreaMonitorSource) +16 (int (*)(...))QGeoAreaMonitorSource::metaObject +24 (int (*)(...))QGeoAreaMonitorSource::qt_metacast +32 (int (*)(...))QGeoAreaMonitorSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoAreaMonitorSource::setPositionInfoSource +120 (int (*)(...))QGeoAreaMonitorSource::positionInfoSource +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QGeoAreaMonitorSource + size=24 align=8 + base size=24 base align=8 +QGeoAreaMonitorSource (0x0x7fd63da81e38) 0 + vptr=((& QGeoAreaMonitorSource::_ZTV21QGeoAreaMonitorSource) + 16u) + QObject (0x0x7fd63db52b40) 0 + primary-for QGeoAreaMonitorSource (0x0x7fd63da81e38) + +Class QGeoRectangle + size=8 align=8 + base size=8 base align=8 +QGeoRectangle (0x0x7fd63da81ea0) 0 + QGeoShape (0x0x7fd63db52c00) 0 + +Class QGeoCircle + size=8 align=8 + base size=8 base align=8 +QGeoCircle (0x0x7fd63d81b068) 0 + QGeoShape (0x0x7fd63d843120) 0 + +Class QGeoLocation + size=8 align=8 + base size=8 base align=8 +QGeoLocation (0x0x7fd63d8434e0) 0 + +Class QGeoPath + size=8 align=8 + base size=8 base align=8 +QGeoPath (0x0x7fd63d81b410) 0 + QGeoShape (0x0x7fd63d843900) 0 + +Class QGeoSatelliteInfo + size=8 align=8 + base size=8 base align=8 +QGeoSatelliteInfo (0x0x7fd63d843cc0) 0 + +Class QGeoSatelliteInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGeoSatelliteInfoSource::QPrivateSignal (0x0x7fd63d843d80) 0 empty + +Vtable for QGeoSatelliteInfoSource +QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGeoSatelliteInfoSource) +16 (int (*)(...))QGeoSatelliteInfoSource::metaObject +24 (int (*)(...))QGeoSatelliteInfoSource::qt_metacast +32 (int (*)(...))QGeoSatelliteInfoSource::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGeoSatelliteInfoSource::setUpdateInterval +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QGeoSatelliteInfoSource + size=24 align=8 + base size=24 base align=8 +QGeoSatelliteInfoSource (0x0x7fd63d81b618) 0 + vptr=((& QGeoSatelliteInfoSource::_ZTV23QGeoSatelliteInfoSource) + 16u) + QObject (0x0x7fd63d843d20) 0 + primary-for QGeoSatelliteInfoSource (0x0x7fd63d81b618) + +Vtable for QGeoPositionInfoSourceFactory +QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QGeoPositionInfoSourceFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QGeoPositionInfoSourceFactory + size=8 align=8 + base size=8 base align=8 +QGeoPositionInfoSourceFactory (0x0x7fd63d843e40) 0 nearly-empty + vptr=((& QGeoPositionInfoSourceFactory::_ZTV29QGeoPositionInfoSourceFactory) + 16u) + +Class QNmeaPositionInfoSource::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNmeaPositionInfoSource::QPrivateSignal (0x0x7fd63d843f60) 0 empty + +Vtable for QNmeaPositionInfoSource +QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QNmeaPositionInfoSource) +16 (int (*)(...))QNmeaPositionInfoSource::metaObject +24 (int (*)(...))QNmeaPositionInfoSource::qt_metacast +32 (int (*)(...))QNmeaPositionInfoSource::qt_metacall +40 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +48 (int (*)(...))QNmeaPositionInfoSource::~QNmeaPositionInfoSource +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNmeaPositionInfoSource::setUpdateInterval +120 (int (*)(...))QGeoPositionInfoSource::setPreferredPositioningMethods +128 (int (*)(...))QNmeaPositionInfoSource::lastKnownPosition +136 (int (*)(...))QNmeaPositionInfoSource::supportedPositioningMethods +144 (int (*)(...))QNmeaPositionInfoSource::minimumUpdateInterval +152 (int (*)(...))QNmeaPositionInfoSource::error +160 (int (*)(...))QNmeaPositionInfoSource::startUpdates +168 (int (*)(...))QNmeaPositionInfoSource::stopUpdates +176 (int (*)(...))QNmeaPositionInfoSource::requestUpdate +184 (int (*)(...))QNmeaPositionInfoSource::parsePosInfoFromNmeaData + +Class QNmeaPositionInfoSource + size=32 align=8 + base size=32 base align=8 +QNmeaPositionInfoSource (0x0x7fd63d81b680) 0 + vptr=((& QNmeaPositionInfoSource::_ZTV23QNmeaPositionInfoSource) + 16u) + QGeoPositionInfoSource (0x0x7fd63d81b6e8) 0 + primary-for QNmeaPositionInfoSource (0x0x7fd63d81b680) + QObject (0x0x7fd63d843f00) 0 + primary-for QGeoPositionInfoSource (0x0x7fd63d81b6e8) + diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt new file mode 100644 index 0000000..7b037a3 --- /dev/null +++ b/tests/auto/cmake/CMakeLists.txt @@ -0,0 +1,44 @@ +# This is an automatic test for the CMake configuration files. +# To run it manually, +# 1) mkdir build # Create a build directory +# 2) cd build +# 3) # Run cmake on this directory +# `$qt_prefix/bin/qt-cmake ..` or `cmake -DCMAKE_PREFIX_PATH=/path/to/qt ..` +# 4) ctest # Run ctest + +cmake_minimum_required(VERSION 3.16) +project(positioning_cmake_tests) +enable_testing() + +set(required_packages Core Positioning) + +# Setup the test when called as a completely standalone project. +if(TARGET Qt6::Core) + # Tests are built as part of the repository's build tree. + # Setup paths so that the Qt packages are found. + qt_internal_set_up_build_dir_package_paths() +endif() + +find_package(Qt6 REQUIRED COMPONENTS ${required_packages}) + +# Setup common test variables which were previously set by ctest_testcase_common.prf. +set(CMAKE_MODULES_UNDER_TEST "${required_packages}") + +foreach(qt_package ${CMAKE_MODULES_UNDER_TEST}) + set(package_name "${QT_CMAKE_EXPORT_NAMESPACE}${qt_package}") + if(${package_name}_FOUND) + set(CMAKE_${qt_package}_MODULE_MAJOR_VERSION "${${package_name}_VERSION_MAJOR}") + set(CMAKE_${qt_package}_MODULE_MINOR_VERSION "${${package_name}_VERSION_MINOR}") + set(CMAKE_${qt_package}_MODULE_PATCH_VERSION "${${package_name}_VERSION_PATCH}") + endif() +endforeach() + +include("${_Qt6CTestMacros}") + +set(module_includes + Positioning QGeoRectangle +) + +_qt_internal_test_module_includes( + ${module_includes} +) diff --git a/tests/auto/declarative_geolocation/CMakeLists.txt b/tests/auto/declarative_geolocation/CMakeLists.txt new file mode 100644 index 0000000..366884c --- /dev/null +++ b/tests/auto/declarative_geolocation/CMakeLists.txt @@ -0,0 +1,16 @@ +# special case begin + +# Collect test data + +qt_internal_add_test(tst_declarative_geolocation + QMLTEST + SOURCES + main.cpp + PUBLIC_LIBRARIES + Qt::Positioning + Qt::Quick + TESTDATA + tst_declarativegeolocation.qml +) + +# special case end diff --git a/tests/auto/declarative_geolocation/main.cpp b/tests/auto/declarative_geolocation/main.cpp new file mode 100644 index 0000000..548a1c2 --- /dev/null +++ b/tests/auto/declarative_geolocation/main.cpp @@ -0,0 +1,23 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +static void initializeLibraryPath() +{ +#if QT_CONFIG(library) + // Set custom path since CI doesn't install test plugins +#ifdef Q_OS_WIN + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#else + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../plugins")); +#endif +#endif +} + +Q_COREAPP_STARTUP_FUNCTION(initializeLibraryPath) + +QUICK_TEST_MAIN(declarative_geolocation) diff --git a/tests/auto/declarative_geolocation/tst_declarativegeolocation.qml b/tests/auto/declarative_geolocation/tst_declarativegeolocation.qml new file mode 100644 index 0000000..1a0b29b --- /dev/null +++ b/tests/auto/declarative_geolocation/tst_declarativegeolocation.qml @@ -0,0 +1,136 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick 2.0 +import QtTest 1.0 +import QtPositioning 6.2 + +Item { + id: testCase + + property var topLeft: QtPositioning.coordinate(1.0, 2.0) + property var bottomRight: QtPositioning.coordinate(2.0, 1.0) + property var centerPoint: QtPositioning.coordinate(1.5, 1.5) + + Location { + id: defaultConstructed + } + + Location { + id: location + } + + // Use property bindings insetead of signal spies + property var addressObserver: location.address + property int addressChangedCount: 0 + onAddressObserverChanged: { + ++addressChangedCount + } + + property var coordObserver: location.coordinate + property int coordChangedCount: 0 + onCoordObserverChanged: { + ++coordChangedCount + } + + property var shapeObserver: location.boundingShape + property int shapeChangedCount: 0 + onShapeObserverChanged: { + ++shapeChangedCount + } + + property var attrsObserver: location.extendedAttributes + property int attrsChangedCount: 0 + onAttrsObserverChanged: { + ++attrsChangedCount + } + + Address { + id: emptyAddress + } + + Address { + id: addr1 + country: "Germany" + city: "Berlin" + street: "Erich-Thilo-Str" + streetNumber: "10" + postalCode: "12489" + } + + Location { + id: completeLocation + address: addr1 + coordinate: centerPoint + boundingShape: QtPositioning.rectangle(topLeft, bottomRight) + } + + Location { + id: fromGeoLocation + } + + TestCase { + name: "DeclarativeGeoLocation" + + function test_default_construction() { + compare(defaultConstructed.address.address, emptyAddress.address) + compare(defaultConstructed.coordinate, QtPositioning.coordinate()) + compare(defaultConstructed.boundingShape, QtPositioning.shape()) + } + + function test_address_changed() { + addressChangedCount = 0 + location.address = addr1 + compare(addressChangedCount, 1) + compare(location.address.address, addr1.address) + } + + function test_coordinate_changed() { + var coord1 = QtPositioning.coordinate(1.0, 2.0) + var emptyCoord = QtPositioning.coordinate() + coordChangedCount = 0 + compare(location.coordinate, emptyCoord) + location.coordinate = coord1 + compare(coordChangedCount, 1) + compare(location.coordinate, coord1) + } + + function test_bounding_box_changed() { + var emptyShape = QtPositioning.shape() + shapeChangedCount = 0 + compare(location.boundingShape, emptyShape) + + var box = QtPositioning.rectangle(topLeft, bottomRight) + location.boundingShape = box + compare(shapeChangedCount, 1) + compare(QtPositioning.shapeToRectangle(location.boundingShape), box) + // verify that shape's boundingGeoRectangle() matches the box. + compare(location.boundingShape.boundingGeoRectangle(), box) + + var circle = QtPositioning.circle(centerPoint, 100) + location.boundingShape = circle + compare(shapeChangedCount, 2) + compare(QtPositioning.shapeToCircle(location.boundingShape), circle) + } + + function test_from_geolocation() { + fromGeoLocation.location = completeLocation.location + compare(fromGeoLocation.location, completeLocation.location) + compare(fromGeoLocation.address.address, completeLocation.address.address) + compare(fromGeoLocation.coordinate, completeLocation.coordinate) + compare(fromGeoLocation.boundingShape, completeLocation.boundingShape) + } + + function test_extended_attributes() { + attrsChangedCount = 0 + + var attributes = { "foo" : 42 } + location.extendedAttributes = attributes; + compare(location.extendedAttributes, attributes) + compare(attrsChangedCount, 1) + + attributes["bar"] = 41 + verify(location.extendedAttributes !== attributes) + } + } +} diff --git a/tests/auto/declarative_positioning_core/BLACKLIST b/tests/auto/declarative_positioning_core/BLACKLIST new file mode 100644 index 0000000..4bafd5e --- /dev/null +++ b/tests/auto/declarative_positioning_core/BLACKLIST @@ -0,0 +1,6 @@ +# QTBUG-59074 and QTBUG-93761: flaky test +[CoordinateAnimation::test_west_direction_coordinate_animation] +osx +# QTBUG-59074 and QTBUG-93761: flaky test +[CoordinateAnimation::test_east_direction_coordinate_animation] +osx diff --git a/tests/auto/declarative_positioning_core/CMakeLists.txt b/tests/auto/declarative_positioning_core/CMakeLists.txt new file mode 100644 index 0000000..dde86ea --- /dev/null +++ b/tests/auto/declarative_positioning_core/CMakeLists.txt @@ -0,0 +1,44 @@ +# Generated from declarative_positioning_core.pro. + +##################################################################### +## tst_declarative_positioning_core Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + *.qml) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_declarative_positioning_core + QMLTEST + SOURCES + main.cpp + factory.cpp + factory.h + PUBLIC_LIBRARIES + Qt::Positioning + Qt::Quick + TESTDATA ${test_data} +) + +qt_add_qml_module(tst_declarative_positioning_core + URI TestFactory + VERSION 1.0 + QML_FILES + tst_address.qml + tst_coordinate.qml + tst_geoshape.qml + tst_position.qml + tst_positionsource.qml + NO_RESOURCE_TARGET_PATH +) + +add_dependencies(tst_declarative_positioning_core QGeoPositionInfoSourceFactoryTestPlugin + DummyPluginForTestsFactoryPlugin) +if(ANDROID) + # We depend on 2 plugins, but they both will be installed in the same dir + set_target_properties(tst_declarative_positioning_core PROPERTIES + QT_ANDROID_EXTRA_PLUGINS "$" + ) +endif() diff --git a/tests/auto/declarative_positioning_core/factory.cpp b/tests/auto/declarative_positioning_core/factory.cpp new file mode 100644 index 0000000..ce38647 --- /dev/null +++ b/tests/auto/declarative_positioning_core/factory.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "factory.h" +#include +#include + +QT_BEGIN_NAMESPACE + +Factory::Factory(QObject *parent) : QObject(parent) +{ + +} + +QGeoShape Factory::createShape(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight) +{ + return QGeoRectangle(topLeft, bottomRight); +} + +QGeoShape Factory::createShape(const QGeoCoordinate ¢er, qreal radius) const +{ + return QGeoCircle(center, radius); +} + +QT_END_NAMESPACE diff --git a/tests/auto/declarative_positioning_core/factory.h b/tests/auto/declarative_positioning_core/factory.h new file mode 100644 index 0000000..f14d0c9 --- /dev/null +++ b/tests/auto/declarative_positioning_core/factory.h @@ -0,0 +1,30 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#ifndef FACTORY_H +#define FACTORY_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QGeoShape; +class QGeoCoordinate; + +class Factory : public QObject +{ + Q_OBJECT + QML_ELEMENT + +public: + explicit Factory(QObject *parent = nullptr); + + Q_INVOKABLE QGeoShape createShape(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight); + Q_INVOKABLE QGeoShape createShape(const QGeoCoordinate ¢er, qreal radius) const; +}; + +QT_END_NAMESPACE + +#endif // FACTORY_H diff --git a/tests/auto/declarative_positioning_core/main.cpp b/tests/auto/declarative_positioning_core/main.cpp new file mode 100644 index 0000000..4bf3153 --- /dev/null +++ b/tests/auto/declarative_positioning_core/main.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include + +static void initializeLibraryPath() +{ +#if QT_CONFIG(library) + // Set custom path since CI doesn't install test plugins +#ifdef Q_OS_WIN + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#else + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../plugins")); +#endif +#endif +} + +Q_COREAPP_STARTUP_FUNCTION(initializeLibraryPath) + +QUICK_TEST_MAIN(declarative_positioning_core) diff --git a/tests/auto/declarative_positioning_core/tst_address.qml b/tests/auto/declarative_positioning_core/tst_address.qml new file mode 100644 index 0000000..124635d --- /dev/null +++ b/tests/auto/declarative_positioning_core/tst_address.qml @@ -0,0 +1,70 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtTest 1.0 +import QtPositioning 6.2 + +TestCase { + id: testCase + + name: "Address" + + Address { + id: address + + street: "Evergreen Tce" + streetNumber: "742" + district: "Pressboard Estates" + city: "Springfield" + state: "Oregon" + postalCode: "8900" + country: "United States" + countryCode: "USA" + } + + function test_qmlAddressText() { + compare(address.isTextGenerated, true); + compare(address.text, "742 Evergreen Tce
    Springfield, Oregon 8900
    United States"); + var textChangedSpy = Qt.createQmlObject('import QtTest 1.0; SignalSpy {}', testCase, "SignalSpy"); + textChangedSpy.target = address; + textChangedSpy.signalName = "textChanged" + + var isTextGeneratedSpy = Qt.createQmlObject('import QtTest 1.0; SignalSpy {}', testCase, "SignalSpy"); + isTextGeneratedSpy.target = address + isTextGeneratedSpy.signalName = "isTextGeneratedChanged" + + address.countryCode = "FRA"; + compare(address.text, "742 Evergreen Tce
    8900 Springfield
    United States"); + compare(textChangedSpy.count, 1); + textChangedSpy.clear(); + compare(isTextGeneratedSpy.count, 0); + + address.countryCode = "DEU"; // the street number should go after the street name + compare(address.text, "Evergreen Tce 742
    8900 Springfield
    United States"); + compare(textChangedSpy.count, 1); + textChangedSpy.clear(); + compare(isTextGeneratedSpy.count, 0); + + address.text = "address label"; + compare(address.isTextGenerated, false); + compare(address.text, "address label"); + compare(textChangedSpy.count, 1); + textChangedSpy.clear(); + compare(isTextGeneratedSpy.count, 1); + isTextGeneratedSpy.clear(); + + address.countryCode = "USA"; + compare(address.text, "address label"); + compare(textChangedSpy.count, 0); + textChangedSpy.clear(); + compare(isTextGeneratedSpy.count, 0); + + address.text = ""; + compare(address.isTextGenerated, true); + compare(address.text, "742 Evergreen Tce
    Springfield, Oregon 8900
    United States"); + compare(textChangedSpy.count, 1); + textChangedSpy.clear(); + compare(isTextGeneratedSpy.count, 1); + isTextGeneratedSpy.clear(); + } +} diff --git a/tests/auto/declarative_positioning_core/tst_coordinate.qml b/tests/auto/declarative_positioning_core/tst_coordinate.qml new file mode 100644 index 0000000..29f48e2 --- /dev/null +++ b/tests/auto/declarative_positioning_core/tst_coordinate.qml @@ -0,0 +1,379 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick 2.0 +import QtTest 1.0 +import QtPositioning 6.2 + +Item { + id: item + + property var empty: QtPositioning.coordinate() + property var base: QtPositioning.coordinate(1.0, 1.0, 5.0) + property var zero: QtPositioning.coordinate(0, 0) + property var plusone: QtPositioning.coordinate(0, 1) + property var minusone: QtPositioning.coordinate(0, -1) + property var north: QtPositioning.coordinate(3, 0) + + SignalSpy { id: coordSpy; target: item; signalName: "baseChanged" } + + property var inside: QtPositioning.coordinate(0.5, 0.5) + property var outside: QtPositioning.coordinate(2, 2) + property var tl: QtPositioning.coordinate(1, 0) + property var br: QtPositioning.coordinate(0, 1) + property var box: QtPositioning.rectangle(tl, br) + + + Address { + id: validTestAddress + street: "Brandl St" + streetNumber: "53" + city: "Eight Mile Plains" + country: "Australia" + countryCode: "AUS" + } + + Location { + id: testLocation + coordinate: inside + boundingShape: box + address: validTestAddress + } + + Location { + id: invalidLocation + } + + + Item { + id: coordinateItem + property variant coordinate + property int animationDuration: 100 + property var coordinateList: [] + property int coordinateCount: 0 + + CoordinateAnimation { + id: coordinateAnimation + target: coordinateItem + property: "coordinate" + duration: coordinateItem.animationDuration + } + onCoordinateChanged: { + if (!coordinateList) { + coordinateList = [] + } + coordinateList[coordinateCount] = QtPositioning.coordinate(coordinate.latitude,coordinate.longitude) + coordinateCount++ + } + + SignalSpy { id: coordinateAnimationStartSpy; target: coordinateAnimation; signalName: "started" } + SignalSpy { id: coordinateAnimationStopSpy; target: coordinateAnimation; signalName: "stopped" } + SignalSpy { id: coordinateAnimationDirectionSpy; target: coordinateAnimation; signalName: "directionChanged" } + } + + TestCase { + name: "GeoLocation" + + function test_Location_complete() + { + compare (testLocation.coordinate.longitude, inside.longitude) + compare (testLocation.coordinate.latitude, inside.latitude) + + compare (testLocation.boundingShape.contains(inside), true) + compare (testLocation.boundingShape.contains(outside), false) + var shapeRectangle = testLocation.boundingShape.boundingGeoRectangle() + compare (shapeRectangle.bottomRight.longitude, br.longitude) + compare (shapeRectangle.bottomRight.latitude, br.latitude) + compare (shapeRectangle.topLeft.longitude, tl.longitude) + compare (shapeRectangle.topLeft.latitude, tl.latitude) + + compare (testLocation.address.country, "Australia") + compare (testLocation.address.countryCode, "AUS") + compare (testLocation.address.city, "Eight Mile Plains") + compare (testLocation.address.street, "Brandl St") + compare (testLocation.address.streetNumber, "53") + } + + function test_Location_invalid() + { + compare(invalidLocation.coordinate.isValid, false) + compare(invalidLocation.boundingShape.isEmpty, true) + compare(invalidLocation.boundingShape.isValid, false) + compare(invalidLocation.address.city, "") + } + } + + TestCase { + name: "Coordinate" + + function test_validity() + { + compare(empty.isValid, false) + + empty.longitude = 0.0; + empty.latitude = 0.0; + + compare(empty.isValid, true) + } + + function test_accessors() + { + compare(base.longitude, 1.0) + compare(base.latitude, 1.0) + compare(base.altitude, 5.0) + + coordSpy.clear() + + base.longitude = 2.0 + base.latitude = 3.0 + base.altitude = 6.0 + + compare(base.longitude, 2.0) + compare(base.latitude, 3.0) + compare(base.altitude, 6.0) + // changing individual properties does *not* trigger + // change notification + compare(coordSpy.count, 0) + + // updating the whole object *does* trigger change notification + base = QtPositioning.coordinate(3.0, 4.0, 5.0) + compare(base.latitude, 3.0) + compare(base.longitude, 4.0) + compare(base.altitude, 5.0) + compare(coordSpy.count, 1) + } + + function test_comparison_data() + { + return [ + { tag: "empty", coord1: empty, coord2: QtPositioning.coordinate(), result: true }, + { tag: "zero", coord1: zero, coord2: QtPositioning.coordinate(0, 0), result: true }, + { tag: "plusone", coord1: plusone, coord2: QtPositioning.coordinate(0, 1), result: true }, + { tag: "minusone", coord1: minusone, coord2: QtPositioning.coordinate(0, -1), result: true }, + { tag: "north", coord1: north, coord2: QtPositioning.coordinate(3, 0), result: true }, + { tag: "lat,long.alt", coord1: QtPositioning.coordinate(1.1, 2.2, 3.3), coord2: QtPositioning.coordinate(1.1, 2.2, 3.3), result: true }, + { tag: "not equal1", coord1: plusone, coord2: minusone, result: false }, + { tag: "not equal2", coord1: plusone, coord2: north, result: false } + ] + } + + function test_comparison(data) + { + compare(data.coord1 === data.coord2, data.result) + compare(data.coord1 !== data.coord2, !data.result) + compare(data.coord1 == data.coord2, data.result) + compare(data.coord1 != data.coord2, !data.result) + } + + function test_distance() + { + compare(zero.distanceTo(plusone), zero.distanceTo(minusone)) + compare(2*plusone.distanceTo(zero), plusone.distanceTo(minusone)) + compare(zero.distanceTo(plusone) > 0, true) + } + + function test_azimuth() + { + compare(zero.azimuthTo(north), 0) + compare(zero.azimuthTo(plusone), 90) + compare(zero.azimuthTo(minusone), 270) + compare(minusone.azimuthTo(plusone), 360 - plusone.azimuthTo(minusone)) + } + + function test_atDistanceAndAzimuth() + { + // 112km is approximately one degree of arc + + var coord_0d = zero.atDistanceAndAzimuth(112000, 0) + compare(coord_0d.latitude > 0.95, true) + compare(coord_0d.latitude < 1.05, true) + compare(coord_0d.longitude < 0.05, true) + compare(coord_0d.longitude > -0.05, true) + compare(zero.distanceTo(coord_0d), 112000) + compare(zero.azimuthTo(coord_0d), 0) + + var coord_90d = zero.atDistanceAndAzimuth(112000, 90) + compare(coord_90d.longitude > 0.95, true) + compare(coord_90d.longitude < 1.05, true) + compare(coord_90d.latitude < 0.05, true) + compare(coord_90d.latitude > -0.05, true) + compare(zero.distanceTo(coord_90d), 112000) + compare(zero.azimuthTo(coord_90d), 90) + + var coord_30d = zero.atDistanceAndAzimuth(20000, 30) + compare(coord_30d.longitude > 0, true) + compare(coord_30d.latitude > 0, true) + compare(zero.distanceTo(coord_30d), 20000) + compare(zero.azimuthTo(coord_30d), 30) + + var coord_30d2 = coord_30d.atDistanceAndAzimuth(200, 30) + compare(zero.distanceTo(coord_30d2), 20200) + } + } + + TestCase { + name: "CoordinateAnimation" + + function init() + { + coordinateAnimation.stop() + coordinateAnimationStartSpy.clear() + coordinateAnimationStopSpy.clear() + coordinateAnimationDirectionSpy.clear() + coordinateAnimation.from = QtPositioning.coordinate(50,50) + coordinateAnimation.to = QtPositioning.coordinate(50,50) + coordinateAnimation.direction = CoordinateAnimation.Shortest + coordinateItem.coordinate = QtPositioning.coordinate(50,50) + coordinateItem.coordinateList = [] + coordinateItem.coordinateCount = 0 + } + + function initTestCase() + { + compare(coordinateAnimation.direction, CoordinateAnimation.Shortest) + compare(coordinateAnimationDirectionSpy.count,0) + coordinateAnimation.direction = CoordinateAnimation.Shortest + compare(coordinateAnimationDirectionSpy.count,0) + coordinateAnimation.direction = CoordinateAnimation.West + compare(coordinateAnimationDirectionSpy.count,1) + coordinateAnimation.direction = CoordinateAnimation.East + compare(coordinateAnimationDirectionSpy.count,2) + } + + function toMercator(coord) + { + var p = QtPositioning.coordToMercator(coord) + var lat = p.y + var lon = p.x + return {'latitude': lat, 'longitude': lon}; + } + + function coordinate_animation(from, to, movingEast) + { + var fromMerc = toMercator(from) + var toMerc = toMercator(to) + var delta = (toMerc.latitude - fromMerc.latitude) / (toMerc.longitude - fromMerc.longitude) + + compare(coordinateItem.coordinateList.length, 0); + coordinateAnimation.from = from + coordinateAnimation.to = to + coordinateAnimation.start() + tryCompare(coordinateAnimationStartSpy,"count",1) + tryCompare(coordinateAnimationStopSpy,"count",1) + + //check correct start position + verify(coordinateItem.coordinateList.length != 0) + compare(coordinateItem.coordinateList[0], from) + //check correct end position + compare(coordinateItem.coordinateList[coordinateItem.coordinateList.length - 1],to) + + var i + var lastLongitude + for (i in coordinateItem.coordinateList) { + var coordinate = coordinateItem.coordinateList[i] + var mercCoordinate = toMercator(coordinate) + + //check that coordinates from the animation is along a straight line between from and to + var estimatedLatitude = fromMerc.latitude + (mercCoordinate.longitude - fromMerc.longitude) * delta + verify(mercCoordinate.latitude - estimatedLatitude < 0.00000000001); + + //check that each step has moved in the right direction + + if (lastLongitude) { + var errorMessage = "movingEast: " + movingEast + "; From: " + from + "; To: " + to + "; i: " + i + "; crdList: " + coordinateItem.coordinateList + if (movingEast) { + if (coordinate.longitude < 0 && lastLongitude > 0) + verify(coordinate.longitude + 360 > lastLongitude, errorMessage) + else + verify(coordinate.longitude > lastLongitude, errorMessage) + } else { + if (coordinate.longitude > 0 && lastLongitude < 0) + verify(coordinate.longitude < lastLongitude + 360, errorMessage) + else + verify(coordinate.longitude < lastLongitude, errorMessage) + } + } + lastLongitude = coordinate.longitude + } + } + + function test_default_coordinate_animation(data) + { + //shortest + coordinate_animation(data.from, data.to, data.east) + } + + function test_default_coordinate_animation_data() + { + return [ + { + from: QtPositioning.coordinate(58.0, 12.0), + to: QtPositioning.coordinate(62.0, 24.0), + east: true + }, + { + from: QtPositioning.coordinate(58.0, 24.0), + to: QtPositioning.coordinate(42.0, 12.0), + east: false + }, + // cross 0 + { + from: QtPositioning.coordinate(30, 10), + to: QtPositioning.coordinate(20, -10), + east: false + }, + { + from: QtPositioning.coordinate(30, -20), + to: QtPositioning.coordinate(20, 10), + east: true + }, + // cross 180 + { + from: QtPositioning.coordinate(30, 170), + to: QtPositioning.coordinate(30, -170), + east: true + }, + { + from: QtPositioning.coordinate(30, -170), + to: QtPositioning.coordinate(30, 170), + east: false + }, + ] + } + + function test_east_direction_coordinate_animation(data) + { + coordinateAnimation.direction = CoordinateAnimation.East + coordinate_animation(data.from, + data.to, + true) + } + + function test_east_direction_coordinate_animation_data() + { + return [ + { from: QtPositioning.coordinate(58.0,24.0), to: QtPositioning.coordinate(58.0,12.0) }, + { from: QtPositioning.coordinate(58.0,12.0), to: QtPositioning.coordinate(58.0,24.0) }, + ] + } + + + function test_west_direction_coordinate_animation(data) + { + coordinateAnimation.direction = CoordinateAnimation.West + coordinate_animation(data.from, + data.to, + false) + } + + function test_west_direction_coordinate_animation_data() + { + return [ + { from: QtPositioning.coordinate(58.0,24.0),to: QtPositioning.coordinate(58.0,12.0) }, + { from: QtPositioning.coordinate(58.0,12.0),to: QtPositioning.coordinate(58.0,24.0) }, + ] + } + + + } +} diff --git a/tests/auto/declarative_positioning_core/tst_geoshape.qml b/tests/auto/declarative_positioning_core/tst_geoshape.qml new file mode 100644 index 0000000..f6a3105 --- /dev/null +++ b/tests/auto/declarative_positioning_core/tst_geoshape.qml @@ -0,0 +1,275 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick 2.0 +import QtTest 1.0 +import QtPositioning 5.2 +import TestFactory 1.0 + +Item { + id: testCase + + property var coordinate1: QtPositioning.coordinate(1, 1) + property var coordinate2: QtPositioning.coordinate(2, 2) + property var coordinate3: QtPositioning.coordinate(80, 80) + + property var emptyCircle: QtPositioning.circle() + property var circle1: QtPositioning.circle(coordinate1, 200000) + + SignalSpy { id: circleChangedSpy; target: testCase; signalName: "emptyCircleChanged" } + + TestCase { + name: "Bounding circle" + function test_circle_defaults_and_setters() { + circleChangedSpy.clear(); + compare (emptyCircle.radius, -1) + compare (circle1.radius, 200000) + + emptyCircle.radius = 200 + compare(emptyCircle.radius, 200) + + emptyCircle.center = coordinate1 + compare(emptyCircle.center, coordinate1) + + emptyCircle.center = coordinate2 + compare(emptyCircle.center, coordinate2) + + emptyCircle = QtPositioning.circle(coordinate1, 200000) + compare(emptyCircle.center, coordinate1) + compare(emptyCircle.radius, 200000) + // signal is triggered only when we update the whole object + compare(circleChangedSpy.count, 1) + + compare(emptyCircle.contains(coordinate1), true); + compare(emptyCircle.contains(coordinate2), true); + compare(emptyCircle.contains(coordinate3), false); + } + } + + property var trace1 : [ QtPositioning.coordinate(43.773175, 11.255386), + QtPositioning.coordinate(43.773546 , 11.255372) ] + property var trace2 : [ QtPositioning.coordinate(43.773175, 11.255386), + QtPositioning.coordinate(43.773546 , 11.255372), + QtPositioning.coordinate(43.77453 , 11.255734) ] + + + // coordinate unit square + property var bl: QtPositioning.coordinate(0, 0) + property var tl: QtPositioning.coordinate(1, 0) + property var tr: QtPositioning.coordinate(1, 1) + property var br: QtPositioning.coordinate(0, 1) + property var ntr: QtPositioning.coordinate(3, 3) + + property var invalid: QtPositioning.coordinate(100, 190) + property var inside: QtPositioning.coordinate(0.5, 0.5) + property var outside: QtPositioning.coordinate(2, 2) + + property var box: QtPositioning.rectangle(tl, br) + + property var coordinates: [bl, tl, tr, br] + property var coordinates2: [bl, tl, tr, br, ntr] + property var coordinates3: [tr] + property var coordinates4: [invalid] + property var coordinates5: [] + + property var listBox: QtPositioning.rectangle(coordinates) + property var listBox2: QtPositioning.rectangle(coordinates2) + property var listBox3: QtPositioning.rectangle(coordinates3) + property var listBox4: QtPositioning.rectangle(coordinates4) + property var listBox5: QtPositioning.rectangle(coordinates5) + + property var widthBox: QtPositioning.rectangle(inside, 1, 1); + + // C++ auto test exists for basics of bounding box, testing here + // only added functionality + TestCase { + name: "Bounding box" + function test_box_defaults_and_setters() { + compare (box.bottomRight.longitude, br.longitude) // sanity + compare (box.contains(bl), true) + compare (box.contains(inside), true) + compare (box.contains(outside), false) + box.topRight = ntr + compare (box.contains(outside), true) + + compare (listBox.isValid, true) + compare (listBox.contains(outside), false) + compare (listBox2.contains(outside), true) + compare (listBox3.isValid, true) + compare (listBox3.isEmpty, true) + compare (listBox4.isValid, false) + compare (listBox5.isValid, false) + + compare (widthBox.contains(inside), true) + compare (widthBox.contains(outside), false) + } + } + + TestCase { + name: "Shape" + + function test_shape_comparison_data() { + return [ + { tag: "invalid shape", shape1: QtPositioning.shape(), shape2: QtPositioning.shape(), result: true }, + { tag: "box equal", shape1: box, shape2: QtPositioning.rectangle(tl, br), result: true }, + { tag: "box not equal", shape1: box, shape2: QtPositioning.rectangle([inside, outside]), result: false }, + { tag: "box invalid shape", rect1: box, shape2: QtPositioning.shape(), result: false }, + { tag: "invalid rectangle", shape1: QtPositioning.rectangle(), shape2: QtPositioning.rectangle(), result: true }, + { tag: "invalid rectangle2", shape1: QtPositioning.rectangle(), shape2: QtPositioning.shape(), result: false }, + { tag: "circle1 equal", shape1: circle1, shape2: QtPositioning.circle(coordinate1, 200000), result: true }, + { tag: "circle1 not equal", shape1: circle1, shape2: QtPositioning.circle(coordinate2, 2000), result: false }, + { tag: "circle1 invalid shape", shape1: circle1, shape2: QtPositioning.shape(), result: false }, + { tag: "invalid circle", shape1: QtPositioning.circle(), shape2: QtPositioning.circle(), result: true }, + { tag: "invalid circle2", shape1: QtPositioning.circle(), shape2: QtPositioning.shape(), result: false } + ] + } + + function test_shape_comparison(data) { + compare(data.shape1 === data.shape2, data.result) + compare(data.shape1 !== data.shape2, !data.result) + compare(data.shape1 == data.shape2, data.result) + compare(data.shape1 != data.shape2, !data.result) + } + } + + TestCase { + name: "Conversions" + + function test_shape_circle_conversions() { + var circle = QtPositioning.shapeToCircle(QtPositioning.shape()) + verify(!circle.isValid) + circle = QtPositioning.shapeToCircle(QtPositioning.circle()) + verify(!circle.isValid) + circle = QtPositioning.shapeToCircle(QtPositioning.circle(tl, 10000)) + verify(circle.isValid) + compare(circle.center, tl) + compare(circle.radius, 10000) + circle = QtPositioning.shapeToCircle(QtPositioning.rectangle()) + verify(!circle.isValid) + circle = QtPositioning.shapeToCircle(QtPositioning.rectangle(tl, br)) + verify(!circle.isValid) + circle = QtPositioning.shapeToCircle(listBox) + verify(!circle.isValid) + } + + function test_shape_rectangle_conversions() { + var rectangle = QtPositioning.shapeToRectangle(QtPositioning.shape()) + verify(!rectangle.isValid) + rectangle = QtPositioning.shapeToRectangle(QtPositioning.circle()) + verify(!rectangle.isValid) + rectangle = QtPositioning.shapeToRectangle(QtPositioning.circle(tl, 10000)) + verify(!rectangle.isValid) + rectangle = QtPositioning.shapeToRectangle(QtPositioning.rectangle()) + verify(!rectangle.isValid) + rectangle = QtPositioning.shapeToRectangle(QtPositioning.rectangle(tl, br)) + verify(rectangle.isValid) + compare(rectangle.topLeft, tl) + compare(rectangle.bottomRight, br) + rectangle = QtPositioning.shapeToRectangle(listBox) + verify(rectangle.isValid) + } + + function test_shape_path_conversions() { + var path = QtPositioning.shapeToPath(QtPositioning.shape()) + verify(!path.isValid) + path = QtPositioning.shapeToPath(QtPositioning.circle()) + verify(!path.isValid) + path = QtPositioning.shapeToPath(QtPositioning.circle(tl, 10000)) + verify(!path.isValid) + path = QtPositioning.shapeToPath(QtPositioning.rectangle()) + verify(!path.isValid) + path = QtPositioning.shapeToPath(QtPositioning.rectangle(tl, br)) + verify(!path.isValid) + + path = QtPositioning.shapeToPath(QtPositioning.path()) + verify(!path.isValid) + path = QtPositioning.shapeToPath(QtPositioning.path(trace1, 1)) + verify(path.isValid) + path = QtPositioning.shapeToPath(QtPositioning.path(trace2, 2)) + verify(path.isValid) + verify(path !== QtPositioning.shapeToPath(QtPositioning.path(trace1, 1))) + compare(path, QtPositioning.shapeToPath(QtPositioning.path(trace2, 2))) + } + + function test_shape_polygon_conversions() { + var polygon = QtPositioning.shapeToPolygon(QtPositioning.shape()) + verify(!polygon.isValid) + polygon = QtPositioning.shapeToPolygon(QtPositioning.circle()) + verify(!polygon.isValid) + polygon = QtPositioning.shapeToPolygon(QtPositioning.circle(tl, 10000)) + verify(polygon.isValid) // fixed, polygon copy constructor can now initialize from a circle. + polygon = QtPositioning.shapeToPolygon(QtPositioning.rectangle()) + verify(!polygon.isValid) + polygon = QtPositioning.shapeToPolygon(QtPositioning.rectangle(tl, br)) + verify(polygon.isValid) // fixed, polygon copy constructor can now initialize from a rectangle. + + polygon = QtPositioning.shapeToPolygon(QtPositioning.polygon()) + verify(!polygon.isValid) + polygon = QtPositioning.shapeToPolygon(QtPositioning.polygon(trace1)) + verify(!polygon.isValid) // polygon needs 3 coords at least + polygon = QtPositioning.shapeToPolygon(QtPositioning.polygon(trace2)) + verify(polygon.isValid) + verify(polygon !== QtPositioning.shapeToPolygon(QtPositioning.polygon(trace1))) + compare(polygon, QtPositioning.shapeToPolygon(QtPositioning.polygon(trace2))) + } + } + + TestCase { + name: "GeoPath path" + function test_qgeopath_path_operations() { + var geopath = QtPositioning.path() + + geopath.path = trace2 + compare(geopath.path.length, trace2.length) + + geopath.path = trace2 + geopath.path[0].longitude = 11.0 + compare(geopath.path.length, trace2.length) + compare(geopath.coordinateAt(0).latitude, trace2[0].latitude) + expectFail("", "Longitude comparison fails") + compare(geopath.coordinateAt(0).longitude, 11) + } + } + + TestCase { + name: "GeoPolygon path" + function test_qgeopolygon_path_operations() { + var geopolygon = QtPositioning.polygon() + + geopolygon.perimeter = trace2 + compare(geopolygon.perimeter.length, trace2.length) + + geopolygon.perimeter = trace2 + compare(geopolygon.perimeter.length, trace2.length) + compare(geopolygon.coordinateAt(0).latitude, trace2[0].latitude) + compare(geopolygon.coordinateAt(0).longitude, trace2[0].longitude) + } + } + + Factory { + id: factory + } + + TestCase { + name: "GeoShape factory" + function test_geoshape_factory_construction() { + // Both createShape() methods return QGeoShape. We check that + // invokable methods and properties are called for correct + // objects + var c0 = QtPositioning.coordinate(1.0, 1.0) + var c1 = QtPositioning.coordinate(1.0001, 1.0001) + var c2 = QtPositioning.coordinate(0.5, 0.5) + var circle = factory.createShape(c0, 100.0) + verify(circle.contains(c1)) + verify(!circle.contains(c2)) + compare(circle.center, c0) + + var rectangle = factory.createShape(QtPositioning.coordinate(1.0, 0.0), QtPositioning.coordinate(0.0, 1.0)) + verify(rectangle.contains(c2)) + verify(!rectangle.contains(c1)) + compare(rectangle.center, c2) + + verify(rectangle.center !== circle.center) + } + } +} diff --git a/tests/auto/declarative_positioning_core/tst_position.qml b/tests/auto/declarative_positioning_core/tst_position.qml new file mode 100644 index 0000000..4cdc212 --- /dev/null +++ b/tests/auto/declarative_positioning_core/tst_position.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick 2.0 +import QtTest 1.0 +import QtPositioning 5.3 + +TestCase { + id: testCase + + name: "Position" + + Position { id: defaultPosition } + + function test_defaults() { + compare(defaultPosition.latitudeValid, false); + compare(defaultPosition.longitudeValid, false); + compare(defaultPosition.altitudeValid, false); + compare(defaultPosition.speedValid, false); + compare(defaultPosition.horizontalAccuracyValid, false); + compare(defaultPosition.verticalAccuracyValid, false); + verify(!defaultPosition.directionValid); + verify(isNaN(defaultPosition.direction)); + verify(!defaultPosition.verticalSpeedValid); + verify(isNaN(defaultPosition.verticalSpeed)); + } +} diff --git a/tests/auto/declarative_positioning_core/tst_positionsource.qml b/tests/auto/declarative_positioning_core/tst_positionsource.qml new file mode 100644 index 0000000..18f84af --- /dev/null +++ b/tests/auto/declarative_positioning_core/tst_positionsource.qml @@ -0,0 +1,420 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick 2.0 +import QtTest 1.0 +import QtPositioning 5.14 + +TestCase { + id: testCase + + name: "PositionSource" + + PositionSource { id: defaultSource } + PositionSource + { + id: activeDefaultSource + active: true + } + + SignalSpy { id: defaultSourceSpy; target: defaultSource; signalName: "positionChanged" } + + function test_activeDefaultSource() { + wait(0); + verify(activeDefaultSource.name !== ""); + compare(activeDefaultSource.active, true); + } + + function test_invalidSource() { + activeDefaultSource.name = "invalid_positioning_source"; + verify(!activeDefaultSource.active); + verify(!activeDefaultSource.valid); + } + + function test_defaults() { + // at least the test.source plugin should be available + verify(defaultSource.name != ""); + compare(defaultSource.active, false); + } + + function test_inactive() { + defaultSourceSpy.clear(); + compare(defaultSourceSpy.count, 0); + wait(1000); + compare(defaultSourceSpy.count, 0); + } + + PositionSource { id: testSetSource; name: "nonexistent bogus plugin" } + SignalSpy { id: testingSourcePluginSpy; target: testSetSource; signalName: "nameChanged" } + + function test_setplugin() { + testingSourcePluginSpy.clear(); + + // On construction, if the provided source name is invalid, the default source will be + // used. Test that the source is valid as expected. + verify(testSetSource.name !== ""); + //we don't really know what the default source is named. + //It may not be "test.source" + var defaultSourceName = testSetSource.name; + verify(testSetSource.valid); + + // Test that setting name to "" will still use the default. + testSetSource.name = ""; + compare(testingSourcePluginSpy.count, 0); + compare(testSetSource.name, defaultSourceName); + verify(testSetSource.valid); + + testSetSource.name = "test.source"; + if (defaultSourceName === "test.source") + compare(testingSourcePluginSpy.count, 0); + compare(testSetSource.name, "test.source"); + verify(testSetSource.valid); + testingSourcePluginSpy.clear(); + + testSetSource.name = "bogus"; + compare(testingSourcePluginSpy.count, 1); + verify(!testSetSource.valid); + } + + PositionSource { id: testingSource; name: "test.source"; updateInterval: 1000 } + + PositionSource { + id: testingSourceWParams + name: "test.source" + updateInterval: 200 + PluginParameter { + id: altitudeParameter + name: "test.source.altitude" + value: 42.42 + } + } + + // use property bindings instead of SignalSpy + property bool directionWParamsValid: testingSourceWParams.position.directionValid + property int directionWParamsValidChangedCount: 0 + onDirectionWParamsValidChanged: { + ++directionWParamsValidChangedCount + } + + property real directionWParams: testingSourceWParams.position.direction + property int directionWParamsChangedCount: 0 + onDirectionWParamsChanged: { + ++directionWParamsChangedCount + } + + SignalSpy { id: updateSpyWParams; target: testingSourceWParams; signalName: "positionChanged" } + + PositionSource { id: testingSourceV1; name: "test.source"; updateInterval: 200 } + + // use property bindings instead of SignalSpy + property bool directionV1Valid: testingSourceV1.position.directionValid + property int directionV1ValidChangedCount: 0 + onDirectionV1ValidChanged: { + ++directionV1ValidChangedCount + } + + property real directionV1: testingSourceV1.position.direction + property int directionV1ChangedCount: 0 + onDirectionV1Changed: { + ++directionV1ChangedCount + } + + SignalSpy { id: updateSpyV1; target: testingSourceV1; signalName: "positionChanged" } + + function test_updateInterval() { + testingSource.updateInterval = 200; + compare(testingSource.updateInterval, 200); + testingSource.updateInterval = 300; + compare(testingSource.updateInterval, 300); + testingSource.updateInterval = 100; + compare(testingSource.updateInterval, 200); + } + + function test_preferredPositioningMethods() { + testingSource.preferredPositioningMethods = PositionSource.AllPositioningMethods; + compare(testingSource.preferredPositioningMethods, PositionSource.AllPositioningMethods); + testingSource.preferredPositioningMethods = PositionSource.SatellitePositioningMethods; + compare(testingSource.preferredPositioningMethods, PositionSource.SatellitePositioningMethods); + testingSource.preferredPositioningMethods = PositionSource.NonSatellitePositioningMethods; + compare(testingSource.preferredPositioningMethods, PositionSource.NonSatellitePositioningMethods); + } + + function test_updates() { + updateSpyV1.clear(); + + directionV1ChangedCount = 0 + directionV1ValidChangedCount = 0 + + testingSourceV1.active = true; + + tryCompare(updateSpyV1, "count", 1, 300); + compare(testingSourceV1.position.coordinate.longitude, 0.1); + compare(testingSourceV1.position.coordinate.latitude, 0.1); + compare(directionV1ValidChangedCount, 1) + compare(directionV1ChangedCount, 1) + fuzzyCompare(testingSourceV1.position.direction, 45, 0.1) + verify(!testingSourceV1.position.speedValid) + verify(isNaN(testingSourceV1.position.speed)) + + tryCompare(updateSpyV1, "count", 2, 300); + compare(testingSourceV1.position.coordinate.longitude, 0.2); + compare(testingSourceV1.position.coordinate.latitude, 0.2); + compare(directionV1ValidChangedCount, 1) + compare(directionV1ChangedCount, 2) + fuzzyCompare(testingSourceV1.position.direction, 45, 0.1) + verify(testingSourceV1.position.speedValid) + verify(testingSourceV1.position.speed > 10000) + + testingSourceV1.active = false; + wait(300); + compare(updateSpyV1.count, 2); + compare(testingSourceV1.position.coordinate.longitude, 0.2); + compare(testingSourceV1.position.coordinate.latitude, 0.2); + compare(directionV1ValidChangedCount, 1) + compare(directionV1ChangedCount, 2) + fuzzyCompare(testingSourceV1.position.direction, 45, 0.1) + verify(testingSourceV1.position.speedValid) + verify(testingSourceV1.position.speed > 10000) + } + + function test_updates_w_params() { + updateSpyWParams.clear(); + + directionWParamsChangedCount = 0 + directionWParamsValidChangedCount = 0 + compare(testingSourceWParams.backendProperty("altitude"), altitudeParameter.value) + testingSourceWParams.active = true; + + tryCompare(updateSpyWParams, "count", 1, 300); + compare(testingSourceWParams.position.coordinate.longitude, 0.1); + compare(testingSourceWParams.position.coordinate.latitude, 0.1); + compare(testingSourceWParams.position.coordinate.altitude, altitudeParameter.value); + compare(directionWParamsValidChangedCount, 1) + compare(directionWParamsChangedCount, 1) + fuzzyCompare(testingSourceWParams.position.direction, 45, 0.1) + verify(!testingSourceWParams.position.speedValid) + verify(isNaN(testingSourceWParams.position.speed)) + testingSourceWParams.setBackendProperty("altitude", 24.24) + + tryCompare(updateSpyWParams, "count", 2, 300); + compare(testingSourceWParams.position.coordinate.longitude, 0.2); + compare(testingSourceWParams.position.coordinate.latitude, 0.2); + compare(testingSourceWParams.position.coordinate.altitude, 24.24); + compare(directionWParamsValidChangedCount, 1) + compare(directionWParamsChangedCount, 2) + fuzzyCompare(testingSourceWParams.position.direction, 45, 0.1) + verify(testingSourceWParams.position.speedValid) + verify(testingSourceWParams.position.speed > 10000) + compare(testingSourceWParams.backendProperty("altitude"), 24.24) + + testingSourceWParams.active = false; + wait(300); + compare(updateSpyWParams.count, 2); + compare(testingSourceWParams.position.coordinate.longitude, 0.2); + compare(testingSourceWParams.position.coordinate.latitude, 0.2); + compare(testingSourceWParams.position.coordinate.altitude, 24.24); + compare(directionWParamsValidChangedCount, 1) + compare(directionWParamsChangedCount, 2) + fuzzyCompare(testingSourceWParams.position.direction, 45, 0.1) + verify(testingSourceWParams.position.speedValid) + verify(testingSourceWParams.position.speed > 10000) + } + + // tests for bindings + PositionSource { + id: testSourceForBindings + name: "test.source" + } + + property var positionObserver: testSourceForBindings.position + SignalSpy { + id: positionObserverSpy; target: testSourceForBindings; signalName: "positionChanged" + } + + property bool activeObserver: testSourceForBindings.active + SignalSpy { + id: activeObserverSpy; target: testSourceForBindings; signalName: "activeChanged" + } + + property bool validObserver: testSourceForBindings.valid + SignalSpy { + id: validObserverSpy; target: testSourceForBindings; signalName: "validityChanged" + } + + property int updateIntervalObserver: testSourceForBindings.updateInterval + SignalSpy { + id: updateIntervalObserverSpy; target: testSourceForBindings; signalName: "updateIntervalChanged" + } + + property int supportedMethodsObserver: testSourceForBindings.supportedPositioningMethods + SignalSpy { + id: supportedMethodsObserverSpy; target: testSourceForBindings; signalName: "supportedPositioningMethodsChanged" + } + + property int preferredMethodsObserver: testSourceForBindings.preferredPositioningMethods + SignalSpy { + id: preferredMethodsObserverSpy; + target: testSourceForBindings; + signalName: "preferredPositioningMethodsChanged" + } + + property int errorObserver: testSourceForBindings.sourceError + SignalSpy { + id: errorObserverSpy; target: testSourceForBindings; signalName: "sourceErrorChanged" + } + + property string nameObserver: testSourceForBindings.name + SignalSpy { + id: nameObserverSpy; target: testSourceForBindings; signalName: "nameChanged" + } + + function test_bindingsToPositionSource() { + positionObserverSpy.clear() + activeObserverSpy.clear() + validObserverSpy.clear() + updateIntervalObserverSpy.clear() + supportedMethodsObserverSpy.clear() + preferredMethodsObserverSpy.clear() + errorObserverSpy.clear() + nameObserverSpy.clear() + + verify(testSourceForBindings.valid) + compare(testSourceForBindings.supportedPositioningMethods, PositionSource.AllPositioningMethods) + + testSourceForBindings.preferredPositioningMethods = PositionSource.SatellitePositioningMethods + compare(preferredMethodsObserver, PositionSource.SatellitePositioningMethods) + compare(preferredMethodsObserverSpy.count, 1) + + testSourceForBindings.updateInterval = 210; + compare(updateIntervalObserver, 210) + compare(updateIntervalObserverSpy.count, 1) + + testSourceForBindings.start(); + compare(activeObserver, true) + compare(activeObserverSpy.count, 1) + + tryCompare(positionObserverSpy, "count", 1, 300); + verify(testSourceForBindings.position.coordinate !== QtPositioning.coordinate()) + + testSourceForBindings.update(50) // small timeout will result in an error + tryCompare(errorObserverSpy, "count", 1, 200) + compare(errorObserver, PositionSource.UpdateTimeoutError) + + var newSourceName = "some invalid name" + testSourceForBindings.name = newSourceName + + compare(validObserver, false) + compare(validObserverSpy.count, 1) + + compare(nameObserver, newSourceName) + compare(nameObserverSpy.count, 1) + + compare(supportedMethodsObserver, PositionSource.NoPositioningMethods) + compare(supportedMethodsObserverSpy.count, 1) + } + + property bool activeSetter: false + property string nameSetter: "test.source" + property int updateIntervalSetter: 200 + property int preferredMethodsSetter: PositionSource.NonSatellitePositioningMethods + + PositionSource { + id: sourceWithBindings + name: nameSetter + active: activeSetter + updateInterval: updateIntervalSetter + preferredPositioningMethods: preferredMethodsSetter + } + + function test_bindPositionSourceProperties() { + compare(sourceWithBindings.name, "test.source") + compare(sourceWithBindings.active, false) + compare(sourceWithBindings.updateInterval, 200) + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.NonSatellitePositioningMethods) + + updateIntervalSetter = 210; + preferredMethodsSetter = PositionSource.AllPositioningMethods + activeSetter = true + + wait(0) // to trigger event processing + + compare(sourceWithBindings.active, true) + compare(sourceWithBindings.updateInterval, 210) + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.AllPositioningMethods) + + activeSetter = false; + + compare(sourceWithBindings.active, false) + + // check how call to update() effects the binding + sourceWithBindings.update(updateIntervalSetter) + compare(sourceWithBindings.active, true) + + wait(300) + compare(sourceWithBindings.active, false) + + activeSetter = true; + wait(0) // to trigger event processing + // the binding is *not* broken by calling update() + compare(sourceWithBindings.active, true) + } + + function test_updateIntervalBindings() { + var updateIntervalSpy = Qt.createQmlObject('import QtTest; SignalSpy { }', testCase) + updateIntervalSpy.target = sourceWithBindings + updateIntervalSpy.signalName = "updateIntervalChanged" + verify(updateIntervalSpy.valid) + + nameSetter = "invalid name" + updateIntervalSetter = 100; + compare(sourceWithBindings.updateInterval, 100) + compare(updateIntervalSpy.count, 1) + + nameSetter = "test.source" + // "test.source" has a minimum update interval of 200 + compare(sourceWithBindings.updateInterval, 200) + compare(updateIntervalSpy.count, 2) + + nameSetter = "dummy.source" + // "dummy.source" has a minimum udpate interval of 100, so we expect + // the updateInterval to be set to 100 + compare(sourceWithBindings.updateInterval, 100) + compare(updateIntervalSpy.count, 3) + + // The binding still works + updateIntervalSetter = 110 + compare(sourceWithBindings.updateInterval, 110) + compare(updateIntervalSpy.count, 4) + } + + function test_preferredPositioningMethodsBindings() { + var preferredMethodsSpy = Qt.createQmlObject('import QtTest; SignalSpy { }', testCase) + preferredMethodsSpy.target = sourceWithBindings + preferredMethodsSpy.signalName = "preferredPositioningMethodsChanged" + verify(preferredMethodsSpy.valid) + + nameSetter = "invalid name" + preferredMethodsSetter = PositionSource.SatellitePositioningMethods + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.SatellitePositioningMethods) + compare(preferredMethodsSpy.count, 1) + + nameSetter = "dummy.source" + // "dummy.source" has only NonSatellitePositioningMethods, so we expect + // the value to be set to NonSatellitePositioningMethods (see + // QGeoPositionInfoSource::setPreferredPositioningMethods for details) + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.NonSatellitePositioningMethods) + compare(preferredMethodsSpy.count, 2) + + nameSetter = "test.source" + // "test.source" has all positioning methods, so we expect the value to + // be set to the desired SatellitePositioningMethods + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.SatellitePositioningMethods) + compare(preferredMethodsSpy.count, 3) + + // The binding still works + preferredMethodsSetter = PositionSource.AllPositioningMethods + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.AllPositioningMethods) + compare(preferredMethodsSpy.count, 4) + } + +} diff --git a/tests/auto/doublevectors/CMakeLists.txt b/tests/auto/doublevectors/CMakeLists.txt new file mode 100644 index 0000000..99aeef4 --- /dev/null +++ b/tests/auto/doublevectors/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from doublevectors.pro. + +##################################################################### +## tst_doublevectors Test: +##################################################################### + +qt_internal_add_test(tst_doublevectors + SOURCES + tst_doublevectors.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::PositioningPrivate +) + +#### Keys ignored in scope 1:.:.:doublevectors.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/doublevectors/tst_doublevectors.cpp b/tests/auto/doublevectors/tst_doublevectors.cpp new file mode 100644 index 0000000..8f4a677 --- /dev/null +++ b/tests/auto/doublevectors/tst_doublevectors.cpp @@ -0,0 +1,268 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +#include +#include + +QT_USE_NAMESPACE + +class tst_doubleVectors : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + // 2D + void constructor2dTest(); + void basicFunctions2dTest(); + void unaryOperator2dTest(); + void binaryOperator2dTest(); + + // 3D + void constructor3dTest(); + void basicFunctions3dTest(); + void unaryOperator3dTest(); + void binaryOperator3dTest(); +}; + +// DoubleVector2D + +void tst_doubleVectors::constructor2dTest() +{ + // empty constructor, since it sets to 0, we should check, in case people rely on it + QDoubleVector2D v1; + QCOMPARE(v1.x(), 0.0); + QCOMPARE(v1.y(), 0.0); + QCOMPARE(v1.isNull(), true); + v1 = QDoubleVector2D(1.1, -2.5); // assignment and constructor + QCOMPARE(v1.x(), 1.1); + QCOMPARE(v1.y(), -2.5); + QDoubleVector2D v2(v1); // copy constructor + QCOMPARE(v2.x(), 1.1); + QCOMPARE(v2.y(), -2.5); + const QDoubleVector3D v3d(2.2, 3.3, 4.4); + QDoubleVector2D v3(v3d); // constructor from 3d vector, just copies x and y + QCOMPARE(v3.x(), 2.2); + QCOMPARE(v3.y(), 3.3); + QCOMPARE(v3.isNull(), false); +} + +void tst_doubleVectors::basicFunctions2dTest() +{ + QDoubleVector2D v1; + v1.setX(3.0); + v1.setY(4.0); + QCOMPARE(v1.x(), 3.0); + QCOMPARE(v1.y(), 4.0); + QCOMPARE(v1.length(), 5.0); + QDoubleVector2D v2 = v1.normalized(); + QCOMPARE(v1.lengthSquared(), 25.0); + v1.normalize(); + QCOMPARE(v1.x(), 3.0/5.0); + QCOMPARE(v1.y(), 4.0/5.0); + QCOMPARE(v2.x(), 3.0/5.0); + QCOMPARE(v2.y(), 4.0/5.0); + + QDoubleVector3D v3d = v1.toVector3D(); + QCOMPARE(v3d.x(), 3.0/5.0); + QCOMPARE(v3d.y(), 4.0/5.0); + QCOMPARE(v3d.z(), 0.0); +} + +void tst_doubleVectors::unaryOperator2dTest() +{ + QDoubleVector2D v1(1.1, 2.2); + QDoubleVector2D v2 = -v1; + QCOMPARE(v2.x(), -1.1); + QCOMPARE(v2.y(), -2.2); + + v1 *= 2.0; + QCOMPARE(v1.x(), 2.2); + QCOMPARE(v1.y(), 4.4); + + v2 /= 2.0; + QCOMPARE(v2.x(), -0.55); + QCOMPARE(v2.y(), -1.1); + + v1 += v2; + QCOMPARE(v1.x(), 1.65); + QCOMPARE(v1.y(), 3.3); + + v1 -= v2; + QCOMPARE(v1.x(), 2.2); + QCOMPARE(v1.y(), 4.4); + + v1 *= v2; + QCOMPARE(v1.x(), -1.21); + QCOMPARE(v1.y(), -4.84); +} + +void tst_doubleVectors::binaryOperator2dTest() +{ + QDoubleVector2D v1(1.1, 2.2); + QDoubleVector2D v2(3.4, 4.4); + QDoubleVector2D v3 = v1 + v2; + QCOMPARE(v3.x(), 4.5); + QCOMPARE(v3.y(), 6.6); + + QDoubleVector2D v4 = v1 - v2; + QCOMPARE(v4.x(), -2.3); + QCOMPARE(v4.y(), -2.2); + + QDoubleVector2D v5 = v2 * 2; + QCOMPARE(v5.x(), 6.8); + QCOMPARE(v5.y(), 8.8); + + QDoubleVector2D v6 = 2 * v2; + QCOMPARE(v6.x(), 6.8); + QCOMPARE(v6.y(), 8.8); + + QDoubleVector2D v7 = v2 / 2; + QCOMPARE(v7.x(), 1.7); + QCOMPARE(v7.y(), 2.2); + + double d = QDoubleVector2D::dotProduct(v1, v2); + QCOMPARE(d, 13.42); + + QCOMPARE(v5 == v6, true); + QCOMPARE(v5 != v6, false); + QCOMPARE(v6 == v7, false); + QCOMPARE(v6 != v7, true); +} + + + +// DoubleVector3D + + +void tst_doubleVectors::constructor3dTest() +{ + // empty constructor, since it sets to 0, we should check, in case people rely on it + QDoubleVector3D v1; + QCOMPARE(v1.x(), 0.0); + QCOMPARE(v1.y(), 0.0); + QCOMPARE(v1.z(), 0.0); + QCOMPARE(v1.isNull(), true); + v1 = QDoubleVector3D(1.1, -2.5, 3.2); // assignment and constructor + QCOMPARE(v1.x(), 1.1); + QCOMPARE(v1.y(), -2.5); + QCOMPARE(v1.z(), 3.2); + QDoubleVector3D v2(v1); // copy constructor + QCOMPARE(v2.x(), 1.1); + QCOMPARE(v2.y(), -2.5); + QCOMPARE(v2.z(), 3.2); + const QDoubleVector2D v2d(2.2, 3.3); + QDoubleVector3D v3(v2d); // constructor from 3d vector, just copies x and y + QCOMPARE(v3.x(), 2.2); + QCOMPARE(v3.y(), 3.3); + QCOMPARE(v3.z(), 0.0); + QCOMPARE(v3.isNull(), false); + const QDoubleVector2D v2d2(2.2, 3.3); + QDoubleVector3D v4(v2d2, -13.6); // constructor from 2d vector + QCOMPARE(v4.x(), 2.2); + QCOMPARE(v4.y(), 3.3); + QCOMPARE(v4.z(), -13.6); +} + +void tst_doubleVectors::basicFunctions3dTest() +{ + QDoubleVector3D v1; + v1.setX(2.0); + v1.setY(3.0); + v1.setZ(6.0); + QCOMPARE(v1.x(), 2.0); + QCOMPARE(v1.y(), 3.0); + QCOMPARE(v1.z(), 6.0); + QCOMPARE(v1.length(), 7.0); + QDoubleVector3D v2 = v1.normalized(); + QCOMPARE(v1.lengthSquared(), 49.0); + v1.normalize(); + QCOMPARE(v1.x(), 2.0/7.0); + QCOMPARE(v1.y(), 3.0/7.0); + QCOMPARE(v1.z(), 6.0/7.0); + QCOMPARE(v2.x(), 2.0/7.0); + QCOMPARE(v2.y(), 3.0/7.0); + QCOMPARE(v2.z(), 6.0/7.0); + + QDoubleVector2D v2d = v1.toVector2D(); + QCOMPARE(v2d.x(), 2.0/7.0); + QCOMPARE(v2d.y(), 3.0/7.0); +} + +void tst_doubleVectors::unaryOperator3dTest() +{ + QDoubleVector3D v1(1.1, 2.2, 3.3); + QDoubleVector3D v2 = -v1; + QCOMPARE(v2.x(), -1.1); + QCOMPARE(v2.y(), -2.2); + QCOMPARE(v2.z(), -3.3); + + v1 *= 2.0; + QCOMPARE(v1.x(), 2.2); + QCOMPARE(v1.y(), 4.4); + QCOMPARE(v1.z(), 6.6); + + v2 /= 2.0; + QCOMPARE(v2.x(), -0.55); + QCOMPARE(v2.y(), -1.1); + QCOMPARE(v2.z(), -1.65); + + v1 += v2; + QCOMPARE(v1.x(), 1.65); + QCOMPARE(v1.y(), 3.3); + QCOMPARE(v1.z(), 4.95); + + v1 -= v2; + QCOMPARE(v1.x(), 2.2); + QCOMPARE(v1.y(), 4.4); + QCOMPARE(v1.z(), 6.6); + + v1 *= v2; + QCOMPARE(v1.x(), -1.21); + QCOMPARE(v1.y(), -4.84); + QCOMPARE(v1.z(), -10.89); +} + +void tst_doubleVectors::binaryOperator3dTest() +{ + QDoubleVector3D v1(1.1, 2.2, 3.3); + QDoubleVector3D v2(3.4, 4.4, 5.5); + QDoubleVector3D v3 = v1 + v2; + QCOMPARE(v3.x(), 4.5); + QCOMPARE(v3.y(), 6.6); + QCOMPARE(v3.z(), 8.8); + + QDoubleVector3D v4 = v1 - v2; + QCOMPARE(v4.x(), -2.3); + QCOMPARE(v4.y(), -2.2); + QCOMPARE(v4.z(), -2.2); + + QDoubleVector3D v5 = v2 * 2; + QCOMPARE(v5.x(), 6.8); + QCOMPARE(v5.y(), 8.8); + QCOMPARE(v5.z(), 11.0); + + QDoubleVector3D v6 = 2 * v2; + QCOMPARE(v6.x(), 6.8); + QCOMPARE(v6.y(), 8.8); + QCOMPARE(v6.z(), 11.0); + + QDoubleVector3D v7 = v2 / 2; + QCOMPARE(v7.x(), 1.7); + QCOMPARE(v7.y(), 2.2); + QCOMPARE(v7.z(), 2.75); + + double d = QDoubleVector3D::dotProduct(v1, v2); + QCOMPARE(d, 31.57); + + QCOMPARE(v5 == v6, true); + QCOMPARE(v5 != v6, false); + QCOMPARE(v6 == v7, false); + QCOMPARE(v6 != v7, true); +} + +QTEST_APPLESS_MAIN(tst_doubleVectors) + +#include "tst_doublevectors.moc" diff --git a/tests/auto/dummypositionplugin/CMakeLists.txt b/tests/auto/dummypositionplugin/CMakeLists.txt new file mode 100644 index 0000000..9c196f0 --- /dev/null +++ b/tests/auto/dummypositionplugin/CMakeLists.txt @@ -0,0 +1,21 @@ +# Generated from positionplugin.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryTest Plugin: +##################################################################### + +qt_internal_add_plugin(DummyPluginForTestsFactoryPlugin + OUTPUT_NAME qtposition_testplugin2 + CLASS_NAME DummyPluginForTestsFactory + PLUGIN_TYPE position + DEFAULT_IF FALSE + SOURCES + plugin.cpp + LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:positionplugin.pro:: +# OTHER_FILES = "plugin.json" +# PLUGIN_EXTENDS = "-" diff --git a/tests/auto/dummypositionplugin/plugin.cpp b/tests/auto/dummypositionplugin/plugin.cpp new file mode 100644 index 0000000..021c387 --- /dev/null +++ b/tests/auto/dummypositionplugin/plugin.cpp @@ -0,0 +1,130 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE + +// This is a dummy plugin that is created mostly to test some features of +// QDeclarativePositionSource. It does not provide any position updates. +// Use plugin from positionplugin subdirectory, if you need to simulate some +// positioning updates. + +class DummyPluginSource : public QGeoPositionInfoSource +{ + Q_OBJECT + +public: + DummyPluginSource(const QVariantMap ¶meters, QObject *parent = 0); + ~DummyPluginSource(); + + void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 5000) override; + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const override; + PositioningMethods supportedPositioningMethods() const override; + + void setUpdateInterval(int msec) override; + int minimumUpdateInterval() const override; + Error error() const override; + +private: + Error lastError = QGeoPositionInfoSource::NoError; +}; + +DummyPluginSource::DummyPluginSource(const QVariantMap ¶meters, QObject *parent) + : QGeoPositionInfoSource(parent) +{ + Q_UNUSED(parameters) +} + +QGeoPositionInfoSource::Error DummyPluginSource::error() const +{ + return lastError; +} + +void DummyPluginSource::setUpdateInterval(int msec) +{ + if (msec < minimumUpdateInterval()) + msec = minimumUpdateInterval(); + + QGeoPositionInfoSource::setUpdateInterval(msec); +} + +int DummyPluginSource::minimumUpdateInterval() const +{ + return 100; +} + +QGeoPositionInfo +DummyPluginSource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const +{ + Q_UNUSED(fromSatellitePositioningMethodsOnly); + return QGeoPositionInfo(); +} + +QGeoPositionInfoSource::PositioningMethods DummyPluginSource::supportedPositioningMethods() const +{ + return QGeoPositionInfoSource::NonSatellitePositioningMethods; +} + +void DummyPluginSource::startUpdates() +{ + lastError = QGeoPositionInfoSource::NoError; +} + +void DummyPluginSource::stopUpdates() { } + +void DummyPluginSource::requestUpdate(int timeout) +{ + lastError = QGeoPositionInfoSource::NoError; + if (timeout < minimumUpdateInterval()) { + lastError = QGeoPositionInfoSource::UpdateTimeoutError; + emit QGeoPositionInfoSource::errorOccurred(lastError); + } +} + +DummyPluginSource::~DummyPluginSource() { } + +class DummyPluginForTestsFactory : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) + +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, + const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, + const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +QGeoPositionInfoSource * +DummyPluginForTestsFactory::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + return new DummyPluginSource(parameters, parent); +} + +QGeoSatelliteInfoSource * +DummyPluginForTestsFactory::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent); + Q_UNUSED(parameters); + return nullptr; +} + +QGeoAreaMonitorSource *DummyPluginForTestsFactory::areaMonitor(QObject *parent, + const QVariantMap ¶meters) +{ + Q_UNUSED(parent); + Q_UNUSED(parameters); + return nullptr; +} + +#include "plugin.moc" diff --git a/tests/auto/dummypositionplugin/plugin.json b/tests/auto/dummypositionplugin/plugin.json new file mode 100644 index 0000000..61f2657 --- /dev/null +++ b/tests/auto/dummypositionplugin/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["dummy.source"], + "Provider": "dummy.source", + "Position": true, + "Satellite": false, + "Monitor": false, + "Priority": 1, + "Testable": true +} diff --git a/tests/auto/positionplugin/CMakeLists.txt b/tests/auto/positionplugin/CMakeLists.txt new file mode 100644 index 0000000..7e1f2ed --- /dev/null +++ b/tests/auto/positionplugin/CMakeLists.txt @@ -0,0 +1,21 @@ +# Generated from positionplugin.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryTest Plugin: +##################################################################### + +qt_internal_add_plugin(QGeoPositionInfoSourceFactoryTestPlugin + OUTPUT_NAME qtposition_testplugin + CLASS_NAME QGeoPositionInfoSourceFactoryTest + PLUGIN_TYPE position + DEFAULT_IF FALSE + SOURCES + plugin.cpp + LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:positionplugin.pro:: +# OTHER_FILES = "plugin.json" +# PLUGIN_EXTENDS = "-" diff --git a/tests/auto/positionplugin/plugin.cpp b/tests/auto/positionplugin/plugin.cpp new file mode 100644 index 0000000..8dc4923 --- /dev/null +++ b/tests/auto/positionplugin/plugin.cpp @@ -0,0 +1,223 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE + +class DummySourcePrivate; +class DummySource : public QGeoPositionInfoSource +{ + Q_OBJECT + +public: + DummySource(const QVariantMap ¶meters, QObject *parent=0); + ~DummySource(); + + void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 5000) override; + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const override; + PositioningMethods supportedPositioningMethods() const override; + + void setUpdateInterval(int msec) override; + int minimumUpdateInterval() const override; + Error error() const override; + + bool setBackendProperty(const QString &name, const QVariant &value) override; + QVariant backendProperty(const QString &name) const override; + +private: + QTimer *timer; + QTimer *timeoutTimer; + QTimer *singleTimer; + QGeoPositionInfo lastPosition; + QDateTime lastUpdateTime; + Error lastError = QGeoPositionInfoSource::NoError; + qreal altitude = 0.0; + +private slots: + void updatePosition(); + void doTimeout(); +}; + +DummySource::DummySource(const QVariantMap ¶meters, QObject *parent) : + QGeoPositionInfoSource(parent), + timer(new QTimer(this)), + timeoutTimer(new QTimer(this)), + singleTimer(new QTimer(this)), + lastPosition(QGeoCoordinate(0,0), QDateTime::currentDateTime()) +{ + if (parameters.contains(QStringLiteral("test.source.altitude"))) { + const qreal alti = parameters.value(QStringLiteral("test.source.altitude")).toReal(); + altitude = alti; + QGeoCoordinate crd = lastPosition.coordinate(); + crd.setAltitude(alti); + lastPosition.setCoordinate(crd); + } + timer->setInterval(200); + connect(timer, SIGNAL(timeout()), + this, SLOT(updatePosition())); + connect(singleTimer, SIGNAL(timeout()), + this, SLOT(updatePosition())); + connect(timeoutTimer, SIGNAL(timeout()), + this, SLOT(doTimeout())); +} + +QGeoPositionInfoSource::Error DummySource::error() const +{ + return lastError; +} + +bool DummySource::setBackendProperty(const QString &name, const QVariant &value) +{ + if (name == QStringLiteral("altitude")) { + altitude = value.toReal(); + return true; + } + return false; +} + +QVariant DummySource::backendProperty(const QString &name) const +{ + if (name == QStringLiteral("altitude")) + return altitude; + return QVariant(); +} + + +void DummySource::setUpdateInterval(int msec) +{ + const int minInterval = minimumUpdateInterval(); + if (msec == 0) { + timer->setInterval(minInterval); + } else if (msec < minInterval) { + msec = minInterval; + timer->setInterval(msec); + } else { + timer->setInterval(msec); + } + + QGeoPositionInfoSource::setUpdateInterval(msec); +} + +int DummySource::minimumUpdateInterval() const +{ + return 200; +} + +QGeoPositionInfo DummySource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const +{ + Q_UNUSED(fromSatellitePositioningMethodsOnly); + return lastPosition; +} + +QGeoPositionInfoSource::PositioningMethods DummySource::supportedPositioningMethods() const +{ + return QGeoPositionInfoSource::AllPositioningMethods; +} + +void DummySource::startUpdates() +{ + lastError = QGeoPositionInfoSource::NoError; + timer->start(); +} + +void DummySource::stopUpdates() +{ + timer->stop(); +} + +void DummySource::requestUpdate(int timeout) +{ + lastError = QGeoPositionInfoSource::NoError; + if (timeout == 0) + timeout = 5000; + if (timeout < 0) + timeout = 0; + + timeoutTimer->setInterval(timeout); + timeoutTimer->start(); + + if (timer->isActive()) { + timer->stop(); + timer->start(); + } + + singleTimer->setInterval(minimumUpdateInterval()); + singleTimer->start(); +} + +DummySource::~DummySource() +{} + +void DummySource::updatePosition() +{ + timeoutTimer->stop(); + singleTimer->stop(); + + const QDateTime now = QDateTime::currentDateTime(); + + QGeoCoordinate coord(lastPosition.coordinate().latitude() + 0.1, + lastPosition.coordinate().longitude() + 0.1, + altitude); + + QGeoPositionInfo info(coord, now); + info.setAttribute(QGeoPositionInfo::Direction, lastPosition.coordinate().azimuthTo(coord)); + if (lastUpdateTime.isValid()) { + double speed = lastPosition.coordinate().distanceTo(coord) / lastUpdateTime.msecsTo(now); + info.setAttribute(QGeoPositionInfo::GroundSpeed, 1000 * speed); + } + + lastUpdateTime = now; + lastPosition = info; + emit positionUpdated(info); +} + +void DummySource::doTimeout() +{ + timeoutTimer->stop(); + singleTimer->stop(); + lastError = QGeoPositionInfoSource::UpdateTimeoutError; + emit QGeoPositionInfoSource::errorOccurred(lastError); +} + + +class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) + +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + return new DummySource(parameters, parent); +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent); + Q_UNUSED(parameters); + return nullptr; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent); + Q_UNUSED(parameters); + return nullptr; +} + +#include "plugin.moc" diff --git a/tests/auto/positionplugin/plugin.json b/tests/auto/positionplugin/plugin.json new file mode 100644 index 0000000..4e7df0e --- /dev/null +++ b/tests/auto/positionplugin/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["test.source"], + "Provider": "test.source", + "Position": true, + "Satellite": false, + "Monitor": false, + "Priority": 2, + "Testable": true +} diff --git a/tests/auto/positionplugintest/CMakeLists.txt b/tests/auto/positionplugintest/CMakeLists.txt new file mode 100644 index 0000000..8251e40 --- /dev/null +++ b/tests/auto/positionplugintest/CMakeLists.txt @@ -0,0 +1,23 @@ +# Generated from positionplugintest.pro. + +##################################################################### +## tst_positionplugin Test: +##################################################################### + +qt_internal_add_test(tst_positionplugin + SOURCES + tst_positionplugin.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +add_dependencies(tst_positionplugin QGeoPositionInfoSourceFactoryTestPlugin) +if(ANDROID) + set_target_properties(tst_positionplugin PROPERTIES + QT_ANDROID_EXTRA_PLUGINS "$" + ) +endif() + +#### Keys ignored in scope 1:.:.:positionplugintest.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/positionplugintest/tst_positionplugin.cpp b/tests/auto/positionplugintest/tst_positionplugin.cpp new file mode 100644 index 0000000..dfa3927 --- /dev/null +++ b/tests/auto/positionplugintest/tst_positionplugin.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_PositionPlugin : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + + void availableSources(); + void create(); + void getUpdates(); +}; + +void tst_PositionPlugin::initTestCase() +{ +#if QT_CONFIG(library) + /* + * Set custom path since CI doesn't install test plugins + */ +#ifdef Q_OS_WIN + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#else + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../plugins")); +#endif +#endif +} + +void tst_PositionPlugin::availableSources() +{ + QVERIFY(QGeoPositionInfoSource::availableSources().contains("test.source")); + QVERIFY(!QGeoSatelliteInfoSource::availableSources().contains("test.source")); + QVERIFY(!QGeoAreaMonitorSource::availableSources().contains("test.source")); +} + +void tst_PositionPlugin::create() +{ + std::unique_ptr src = nullptr; + src.reset(QGeoPositionInfoSource::createSource("test.source", 0)); + QVERIFY(src != nullptr); + + QVERIFY(src->minimumUpdateInterval() == 200); + + src.reset(QGeoPositionInfoSource::createSource("invalid source that will never exist", 0)); + QVERIFY(src == 0); + + std::unique_ptr ssrc = nullptr; + ssrc.reset(QGeoSatelliteInfoSource::createSource("test.source", 0)); + QVERIFY(ssrc == nullptr); +} + +void tst_PositionPlugin::getUpdates() +{ + std::unique_ptr src(QGeoPositionInfoSource::createSource("test.source", 0)); + src->setUpdateInterval(200); + + QSignalSpy spy(src.get(), SIGNAL(positionUpdated(QGeoPositionInfo))); + src->startUpdates(); + QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 5000); + QCOMPARE(spy[0].size(), 1); + + QGeoPositionInfo info = qvariant_cast(spy[0][0]); + QCOMPARE(info.coordinate().latitude(), 0.1); + QCOMPARE(info.coordinate().longitude(), 0.1); +} + + + +QTEST_GUILESS_MAIN(tst_PositionPlugin) +#include "tst_positionplugin.moc" diff --git a/tests/auto/qdeclarativegeolocation/CMakeLists.txt b/tests/auto/qdeclarativegeolocation/CMakeLists.txt new file mode 100644 index 0000000..ebf6589 --- /dev/null +++ b/tests/auto/qdeclarativegeolocation/CMakeLists.txt @@ -0,0 +1,9 @@ +qt_internal_add_test(tst_qdeclarativegeolocation + SOURCES + tst_qdeclarativegeolocation.cpp + LIBRARIES + Qt::Core + Qt::Positioning + Qt::PositioningQuickPrivate + Qt::TestPrivate +) diff --git a/tests/auto/qdeclarativegeolocation/tst_qdeclarativegeolocation.cpp b/tests/auto/qdeclarativegeolocation/tst_qdeclarativegeolocation.cpp new file mode 100644 index 0000000..ca8bff7 --- /dev/null +++ b/tests/auto/qdeclarativegeolocation/tst_qdeclarativegeolocation.cpp @@ -0,0 +1,156 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_DeclarativeGeoLocation : public QObject +{ + Q_OBJECT + +private slots: + void locationProperty(); + void addressBinding(); + void coordinateBinding(); + void shapeBinding(); + void attributesBinding(); +}; + +void tst_DeclarativeGeoLocation::locationProperty() +{ + // This test calls setLocation() with different preconditions, providing + // coverage for different branches of the setLocation() method. + + QGeoAddress addr; + addr.setCountryCode("DEU"); + addr.setCountry("Germany"); + addr.setCity("Berlin"); + addr.setStreet("Erich-Thilo-Str"); + addr.setStreetNumber("10"); + addr.setPostalCode("12489"); + + const QGeoCoordinate c(52.43, 13.53); + + const QVariantMap attrs { { "string_proprty", "value" }, { "int_property", 5 } }; + + QGeoLocation loc1; + loc1.setAddress(addr); + loc1.setCoordinate(c); + loc1.setBoundingShape(QGeoCircle(c, 100)); + loc1.setExtendedAttributes(attrs); + + QDeclarativeGeoLocation location; + qsizetype addrChangedCount = 0; + qsizetype coordChangedCount = 0; + qsizetype shapeChangedCount = 0; + qsizetype attrChangedCount = 0; + + auto addrChangedHandler = location.bindableAddress().onValueChanged( + [&addrChangedCount]() { ++addrChangedCount; }); + Q_UNUSED(addrChangedHandler) + auto coordChangedHandler = location.bindableCoordinate().onValueChanged( + [&coordChangedCount]() { ++coordChangedCount; }); + Q_UNUSED(coordChangedHandler) + auto shapeChangedHandler = location.bindableBoundingShape().onValueChanged( + [&shapeChangedCount]() { ++shapeChangedCount; }); + Q_UNUSED(shapeChangedHandler) + auto attrChangedHandler = location.bindableExtendedAttributes().onValueChanged( + [&attrChangedCount]() { ++attrChangedCount; }); + Q_UNUSED(attrChangedHandler) + + // By default an empty m_address is created in the default constructor. + // So m_address contains a valid pointer, m_address->parent() == this. + location.setLocation(loc1); + QCOMPARE(addrChangedCount, 0); // the pointer didn't change + QCOMPARE(coordChangedCount, 1); + QCOMPARE(shapeChangedCount, 1); + QCOMPARE(attrChangedCount, 1); + QCOMPARE(location.location(), loc1); + QCOMPARE(location.address()->parent(), &location); + + // m_address contains a nullptr + location.setAddress(nullptr); + QVERIFY(!location.address()); + addrChangedCount = 0; + coordChangedCount = 0; + shapeChangedCount = 0; + attrChangedCount = 0; + + location.setLocation(loc1); + QCOMPARE(addrChangedCount, 1); // only the pointer has changed + QCOMPARE(coordChangedCount, 0); + QCOMPARE(shapeChangedCount, 0); + QCOMPARE(attrChangedCount, 0); + QCOMPARE(location.location(), loc1); + QCOMPARE(location.address()->parent(), &location); + + // m_address contains a valid pointer, m_address->parent() != this + QGeoAddress addr1; + addr1.setCountryCode("USA"); + addr1.setCountry("United States"); + addr1.setPostalCode("8900"); + addr1.setState("Oregon"); + addr1.setCity("Springfield"); + addr1.setDistrict("Pressboard Estates"); + addr1.setStreet("Evergreen Tce"); + addr1.setStreetNumber("742"); + + QDeclarativeGeoAddress geoAddr(addr1); + + location.setAddress(&geoAddr); + QVERIFY(location.address()); + QCOMPARE(location.address()->parent(), nullptr); + addrChangedCount = 0; + + location.setLocation(loc1); + QCOMPARE(addrChangedCount, 1); // only the pointer has changed + QCOMPARE(coordChangedCount, 0); + QCOMPARE(shapeChangedCount, 0); + QCOMPARE(attrChangedCount, 0); + QCOMPARE(location.location(), loc1); + QCOMPARE(location.address()->parent(), &location); +} + +void tst_DeclarativeGeoLocation::addressBinding() +{ + QDeclarativeGeoLocation location; + QDeclarativeGeoAddress addr1; + QDeclarativeGeoAddress addr2; + QTestPrivate::testReadWritePropertyBasics( + location, &addr1, &addr2, "address"); +} + +void tst_DeclarativeGeoLocation::coordinateBinding() +{ + QDeclarativeGeoLocation location; + const QGeoCoordinate c1(2.0, 1.0); + const QGeoCoordinate c2(1.0, 2.0); + QTestPrivate::testReadWritePropertyBasics( + location, c1, c2, "coordinate"); +} + +void tst_DeclarativeGeoLocation::shapeBinding() +{ + QDeclarativeGeoLocation location; + const QGeoCircle circle(QGeoCoordinate(2.0, 1.0), 10); + const QGeoRectangle rectangle(QGeoCoordinate(2.0, 1.0), QGeoCoordinate(1.0, 2.0)); + QTestPrivate::testReadWritePropertyBasics( + location, circle, rectangle, "boundingShape"); +} + +void tst_DeclarativeGeoLocation::attributesBinding() +{ + QDeclarativeGeoLocation location; + const QVariantMap m1 { { "string_proprty", "value" }, { "int_property", 5 } }; + const QVariantMap m2 { { "int_property", 10 }, { "double_property", 15.5 } }; + QTestPrivate::testReadWritePropertyBasics( + location, m1, m2, "extendedAttributes"); +} + +QTEST_APPLESS_MAIN(tst_DeclarativeGeoLocation) + +#include "tst_qdeclarativegeolocation.moc" diff --git a/tests/auto/qdeclarativeposition/CMakeLists.txt b/tests/auto/qdeclarativeposition/CMakeLists.txt new file mode 100644 index 0000000..f5c132c --- /dev/null +++ b/tests/auto/qdeclarativeposition/CMakeLists.txt @@ -0,0 +1,8 @@ +qt_internal_add_test(tst_qdeclarativeposition + SOURCES + tst_qdeclarativeposition.cpp + LIBRARIES + Qt::Core + Qt::PositioningQuickPrivate + Qt::TestPrivate +) diff --git a/tests/auto/qdeclarativeposition/tst_qdeclarativeposition.cpp b/tests/auto/qdeclarativeposition/tst_qdeclarativeposition.cpp new file mode 100644 index 0000000..79fd88d --- /dev/null +++ b/tests/auto/qdeclarativeposition/tst_qdeclarativeposition.cpp @@ -0,0 +1,219 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_QDeclarativePosition : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void init(); + + void latitudeValidBinding(); + void longitudeValidBinding(); + void altitudeValidBinding(); + void coordinateBinding(); + void timestampBinding(); + void speedBinding(); + void speedValidBinding(); + void horizontalAccuracyValidBinding(); + void horizontalAccuracyBinding(); + void verticalAccuracyValidBinding(); + void verticalAccuracyBinding(); + void directionValidBinding(); + void directionBinding(); + void verticalSpeedValidBinding(); + void verticalSpeedBinding(); + void magneticVariationValidBinding(); + void magneticVariationBinding(); + void directionAccuracyBinding(); + void directionAccuracyValidBinding(); + +private: + QDeclarativePosition m_declarativePosition; + QGeoPositionInfo m_positionInfo; + std::function m_mutatorFunc = nullptr; + std::function m_doubleComparator = nullptr; +}; + +void tst_QDeclarativePosition::initTestCase() +{ + m_mutatorFunc = [&]() { m_declarativePosition.setPosition(m_positionInfo); }; + m_doubleComparator = [](const double &lhs, const double &rhs) { + return (qIsNaN(lhs) && qIsNaN(rhs)) || qFuzzyCompare(lhs, rhs); + }; +} + +void tst_QDeclarativePosition::init() +{ + // reset position before each test + m_declarativePosition.setPosition(QGeoPositionInfo()); +} + +void tst_QDeclarativePosition::latitudeValidBinding() +{ + QCOMPARE(m_declarativePosition.isLatitudeValid(), false); + m_positionInfo.setCoordinate(QGeoCoordinate(1.0, 2.0)); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "latitudeValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::longitudeValidBinding() +{ + QCOMPARE(m_declarativePosition.isLongitudeValid(), false); + m_positionInfo.setCoordinate(QGeoCoordinate(1.0, 2.0)); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "longitudeValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::altitudeValidBinding() +{ + QCOMPARE(m_declarativePosition.isAltitudeValid(), false); + m_positionInfo.setCoordinate(QGeoCoordinate(1.0, 2.0, 3.0)); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "altitudeValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::coordinateBinding() +{ + QCOMPARE(m_declarativePosition.coordinate(), QGeoCoordinate()); + m_positionInfo.setCoordinate(QGeoCoordinate(1.0, 2.0, 3.0)); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, QGeoCoordinate(), QGeoCoordinate(1.0, 2.0, 3.0), "coordinate", + m_mutatorFunc); +} + +void tst_QDeclarativePosition::timestampBinding() +{ + QCOMPARE(m_declarativePosition.timestamp(), QDateTime()); + const auto timestamp = QDateTime::currentDateTimeUtc(); + m_positionInfo.setTimestamp(timestamp); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, QDateTime(), timestamp, "timestamp", m_mutatorFunc); +} + +void tst_QDeclarativePosition::speedBinding() +{ + QCOMPARE(m_declarativePosition.speed(), qQNaN()); + m_positionInfo.setAttribute(QGeoPositionInfo::GroundSpeed, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, qQNaN(), 10.0, "speed", m_mutatorFunc, m_doubleComparator); +} + +void tst_QDeclarativePosition::speedValidBinding() +{ + QCOMPARE(m_declarativePosition.isSpeedValid(), false); + m_positionInfo.setAttribute(QGeoPositionInfo::GroundSpeed, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "speedValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::horizontalAccuracyValidBinding() +{ + QCOMPARE(m_declarativePosition.isHorizontalAccuracyValid(), false); + m_positionInfo.setAttribute(QGeoPositionInfo::HorizontalAccuracy, 1.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "horizontalAccuracyValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::horizontalAccuracyBinding() +{ + QCOMPARE(m_declarativePosition.horizontalAccuracy(), qQNaN()); + m_positionInfo.setAttribute(QGeoPositionInfo::HorizontalAccuracy, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, qQNaN(), 10.0, "horizontalAccuracy", m_mutatorFunc, + m_doubleComparator); +} + +void tst_QDeclarativePosition::verticalAccuracyValidBinding() +{ + QCOMPARE(m_declarativePosition.isVerticalAccuracyValid(), false); + m_positionInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy, 1.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "verticalAccuracyValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::verticalAccuracyBinding() +{ + QCOMPARE(m_declarativePosition.verticalAccuracy(), qQNaN()); + m_positionInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, qQNaN(), 10.0, "verticalAccuracy", m_mutatorFunc, + m_doubleComparator); +} + +void tst_QDeclarativePosition::directionValidBinding() +{ + QCOMPARE(m_declarativePosition.isDirectionValid(), false); + m_positionInfo.setAttribute(QGeoPositionInfo::Direction, 1.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "directionValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::directionBinding() +{ + QCOMPARE(m_declarativePosition.direction(), qQNaN()); + m_positionInfo.setAttribute(QGeoPositionInfo::Direction, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, qQNaN(), 10.0, "direction", m_mutatorFunc, m_doubleComparator); +} + +void tst_QDeclarativePosition::verticalSpeedValidBinding() +{ + QCOMPARE(m_declarativePosition.isVerticalSpeedValid(), false); + m_positionInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, 1.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "verticalSpeedValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::verticalSpeedBinding() +{ + QCOMPARE(m_declarativePosition.verticalSpeed(), qQNaN()); + m_positionInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, qQNaN(), 10.0, "verticalSpeed", m_mutatorFunc, + m_doubleComparator); +} + +void tst_QDeclarativePosition::magneticVariationValidBinding() +{ + QCOMPARE(m_declarativePosition.isMagneticVariationValid(), false); + m_positionInfo.setAttribute(QGeoPositionInfo::MagneticVariation, 1.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "magneticVariationValid", m_mutatorFunc); +} + +void tst_QDeclarativePosition::magneticVariationBinding() +{ + QCOMPARE(m_declarativePosition.magneticVariation(), qQNaN()); + m_positionInfo.setAttribute(QGeoPositionInfo::MagneticVariation, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, qQNaN(), 10.0, "magneticVariation", m_mutatorFunc, + m_doubleComparator); +} + +void tst_QDeclarativePosition::directionAccuracyBinding() +{ + QCOMPARE(m_declarativePosition.directionAccuracy(), qQNaN()); + m_positionInfo.setAttribute(QGeoPositionInfo::DirectionAccuracy, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, qQNaN(), 10.0, "directionAccuracy", m_mutatorFunc, + m_doubleComparator); +} + +void tst_QDeclarativePosition::directionAccuracyValidBinding() +{ + QCOMPARE(m_declarativePosition.isDirectionAccuracyValid(), false); + m_positionInfo.setAttribute(QGeoPositionInfo::DirectionAccuracy, 10.0); + QTestPrivate::testReadOnlyPropertyBasics( + m_declarativePosition, false, true, "directionAccuracyValid", m_mutatorFunc); +} + +QTEST_GUILESS_MAIN(tst_QDeclarativePosition) +#include "tst_qdeclarativeposition.moc" diff --git a/tests/auto/qdeclarativepositionsource/BLACKLIST b/tests/auto/qdeclarativepositionsource/BLACKLIST new file mode 100644 index 0000000..11993cf --- /dev/null +++ b/tests/auto/qdeclarativepositionsource/BLACKLIST @@ -0,0 +1,49 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format +#QTBUG-101345 +[supportedMethodsBinding] +qnx +#QTBUG-101345 +[updateAfterStart] +qnx +#QTBUG-101345 +[stopAfterUpdate] +qnx +#QTBUG-101345 +[updateWithStartTimedOut] +qnx +#QTBUG-101345 +[startUpdateStopWithNoIntervals] +qnx +#QTBUG-101345 +[startStopAfterUpdate] +qnx +#QTBUG-101345 +[activeBindingBreak] +qnx +#QTBUG-101345 +[preferredMethodsOnSourceDependency] +qnx +#QTBUG-101345 +[updateTimedOut] +qnx +#QTBUG-101345 +[startBreaksActiveBinding] +qnx +#QTBUG-101345 +[positionBinding] +qnx +#QTBUG-101345 +[sourceErrorBinding] +qnx +#QTBUG-101345 +[intervalOnSourceDependency] +qnx +#QTBUG-101345 +[startAfterUpdate] +qnx +#QTBUG-101345 +[validBinding] +qnx +#QTBUG-101345 +[activeBinding] +qnx diff --git a/tests/auto/qdeclarativepositionsource/CMakeLists.txt b/tests/auto/qdeclarativepositionsource/CMakeLists.txt new file mode 100644 index 0000000..53e295f --- /dev/null +++ b/tests/auto/qdeclarativepositionsource/CMakeLists.txt @@ -0,0 +1,18 @@ +qt_internal_add_test(tst_qdeclarativepositionsource + SOURCES + tst_qdeclarativepositionsource.cpp + LIBRARIES + Qt::Core + Qt::Positioning + Qt::PositioningQuickPrivate + Qt::TestPrivate +) + +add_dependencies(tst_qdeclarativepositionsource QGeoPositionInfoSourceFactoryTestPlugin + DummyPluginForTestsFactoryPlugin) +if(ANDROID) + # We depend on 2 plugins, but they both will be installed in the same dir + set_target_properties(tst_qdeclarativepositionsource PROPERTIES + QT_ANDROID_EXTRA_PLUGINS "$" + ) +endif() diff --git a/tests/auto/qdeclarativepositionsource/tst_qdeclarativepositionsource.cpp b/tests/auto/qdeclarativepositionsource/tst_qdeclarativepositionsource.cpp new file mode 100644 index 0000000..0937c75 --- /dev/null +++ b/tests/auto/qdeclarativepositionsource/tst_qdeclarativepositionsource.cpp @@ -0,0 +1,509 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_DeclarativePositionSource : public QObject +{ + Q_OBJECT + +private slots: + void init(); + + void nameBinding(); + void supportedMethodsBinding(); + void sourceErrorBinding(); + void validBinding(); + void positionBinding(); + void activeBinding(); + void startBreaksActiveBinding(); + void activeBindingBreak(); + + void intervalOnSourceDependency(); + void preferredMethodsOnSourceDependency(); + + void updateAfterStart(); + void startAfterUpdate(); + void stopAfterUpdate(); + void startStopAfterUpdate(); + void updateTimedOut(); + void updateWithStartTimedOut(); + void startUpdateStopWithNoIntervals(); + +private: + std::unique_ptr m_positionSource = nullptr; +}; + +void tst_DeclarativePositionSource::init() +{ + // create a fresh instance of QDeclarativePositionSource before each test + m_positionSource.reset(new QDeclarativePositionSource); + m_positionSource->componentComplete(); // simulate QML loading +} + +void tst_DeclarativePositionSource::nameBinding() +{ + m_positionSource->setName("test.source"); + QTestPrivate::testReadWritePropertyBasics( + *m_positionSource.get(), "invalid source", "test.source", "name"); +} + +void tst_DeclarativePositionSource::supportedMethodsBinding() +{ + // Invalid source has no positioning methods. + // "test.source" has all positioning methods. + m_positionSource->setName("invalid name"); + QTestPrivate::testReadOnlyPropertyBasics( + *m_positionSource.get(), QDeclarativePositionSource::NoPositioningMethods, + QDeclarativePositionSource::AllPositioningMethods, "supportedPositioningMethods", + [&]() { m_positionSource->setName("test.source"); }); +} + +void tst_DeclarativePositionSource::sourceErrorBinding() +{ + // "dummy.source" has a minimum update interval of 100, and calling + // update() with a smaller timeout immediately result in a timeout error + m_positionSource->setName("dummy.source"); + QTestPrivate::testReadOnlyPropertyBasics( + *m_positionSource.get(), QDeclarativePositionSource::NoError, + QDeclarativePositionSource::UpdateTimeoutError, "sourceError", + [&]() { m_positionSource->update(10); }); + if (QTest::currentTestFailed()) + return; + + // Test that we can't bind sourceError to smth, as it's read-only + QProperty errorSetter; + m_positionSource->bindableSourceError().setBinding(Qt::makePropertyBinding(errorSetter)); + QCOMPARE(m_positionSource->bindableSourceError().hasBinding(), false); +} + +void tst_DeclarativePositionSource::validBinding() +{ + // Invalid source name results in no position source -> invalid object. + // Setting the name to "test.source" results in creating a new position + // source -> valid object + m_positionSource->setName("invalid name"); + QTestPrivate::testReadOnlyPropertyBasics( + *m_positionSource.get(), false, true, "valid", + [&]() { m_positionSource->setName("test.source"); }); +} + +static char *printPosition(const QDeclarativePosition *position) +{ + // For this test we need to print only coordinate, so that we get a nice + // error message if the below test fails. + QString str; + QDebug dbg(&str); + dbg << position->coordinate(); + const auto dataArray = str.toLatin1(); + const auto msgSize = dataArray.size() + 1; + char *msg = new char[msgSize]; + memset(msg, 0, msgSize); + qsnprintf(msg, msgSize, "%s", dataArray.constData()); + return msg; +} + +void tst_DeclarativePositionSource::positionBinding() +{ + // "test.source" udpates its position, starting from (0, 0) coordinate, and + // adding 0.1 lat and 0.1 log at every step + m_positionSource->setName("test.source"); + m_positionSource->setUpdateInterval(200); + const QGeoCoordinate c1(0.1, 0.1, 0); + const QGeoCoordinate c2(0.2, 0.2, 0); + m_positionSource->update(); + QTRY_COMPARE_WITH_TIMEOUT(m_positionSource->position()->coordinate(), c1, 5000); + + QGeoPositionInfo posInfo; + posInfo.setCoordinate(c1); + QDeclarativePosition pos1; + pos1.setPosition(posInfo); + + posInfo.setCoordinate(c2); + QDeclarativePosition pos2; + pos2.setPosition(posInfo); + + QTestPrivate::testReadOnlyPropertyBasics( + *m_positionSource.get(), &pos1, &pos2, "position", + [&]() { + QSignalSpy spy(m_positionSource.get(), + &QDeclarativePositionSource::positionChanged); + m_positionSource->update(); + // Wait for the update to happen. It should take around 200 ms, + // but we want to be on a safe side in case of high CI load. + QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 5000); + }, + [](const QDeclarativePosition *p1, const QDeclarativePosition *p2) { + return p1->coordinate() == p2->coordinate(); + }, + printPosition); + if (QTest::currentTestFailed()) + return; + + QProperty prop(nullptr); + m_positionSource->bindablePosition().setBinding(Qt::makePropertyBinding(prop)); + // We can't have bindings on read-only properties + QCOMPARE(m_positionSource->bindablePosition().hasBinding(), false); +} + +void tst_DeclarativePositionSource::activeBinding() +{ + // we can't use a common templated method to test active property, because + // setActive() uses QTimer::singleShot() to actually update the property + // state. + m_positionSource->setName("test.source"); + + QProperty activeObserver; + activeObserver.setBinding(m_positionSource->bindableActive().makeBinding()); + + QProperty activeLambdaObserver; + activeLambdaObserver.setBinding([&]() { return m_positionSource->isActive(); }); + + QSignalSpy activeSpy(m_positionSource.get(), &QDeclarativePositionSource::activeChanged); + + QCOMPARE(activeSpy.size(), 0); + QCOMPARE(activeObserver.value(), false); + QCOMPARE(activeLambdaObserver.value(), false); + + QProperty activeSetter(false); + m_positionSource->bindableActive().setBinding(Qt::makePropertyBinding(activeSetter)); + + activeSetter = true; + QTest::qWait(0); // to trigger singleShot timer in setActive + + QCOMPARE(activeSpy.size(), 1); + QCOMPARE(activeObserver.value(), true); + QCOMPARE(activeLambdaObserver.value(), true); + + activeSetter = false; + + QCOMPARE(activeSpy.size(), 2); + QCOMPARE(activeObserver.value(), false); + QCOMPARE(activeLambdaObserver.value(), false); + + // calling update() does not break the binding + m_positionSource->update(50); + QCOMPARE(activeSpy.size(), 3); + QCOMPARE(activeObserver.value(), true); + QCOMPARE(activeLambdaObserver.value(), true); + + QTRY_COMPARE_WITH_TIMEOUT(m_positionSource->sourceError(), + QDeclarativePositionSource::UpdateTimeoutError, 5000); + + QCOMPARE(activeSpy.size(), 4); + QCOMPARE(activeObserver.value(), false); + QCOMPARE(activeLambdaObserver.value(), false); + + activeSetter = true; + QTest::qWait(0); // to trigger singleShot timer in setActive + + QCOMPARE(activeSpy.size(), 5); + QCOMPARE(activeObserver.value(), true); + QCOMPARE(activeLambdaObserver.value(), true); + + // calling stop() will break the binding + m_positionSource->stop(); + + QCOMPARE(activeSpy.size(), 6); + QCOMPARE(m_positionSource->isActive(), false); + QCOMPARE(activeObserver.value(), false); + QCOMPARE(activeLambdaObserver.value(), false); + + activeSetter = false; + activeSetter = true; + QTest::qWait(0); // to trigger singleShot timer in setActive + + // nothing changed, as the binding is broken + QCOMPARE(activeSpy.size(), 6); + QCOMPARE(m_positionSource->isActive(), false); + QCOMPARE(activeObserver.value(), false); + QCOMPARE(activeLambdaObserver.value(), false); +} + +void tst_DeclarativePositionSource::startBreaksActiveBinding() +{ + m_positionSource->setName("test.source"); + QSignalSpy activeSpy(m_positionSource.get(), &QDeclarativePositionSource::activeChanged); + + QProperty activeSetter(true); + m_positionSource->bindableActive().setBinding(Qt::makePropertyBinding(activeSetter)); + + QTest::qWait(0); // to trigger singleShot timer in setActive + + QCOMPARE(m_positionSource->isActive(), true); + QCOMPARE(activeSpy.size(), 1); + QVERIFY(m_positionSource->bindableActive().hasBinding()); + + // Call start() explicitly, which should break the binding for 'active' + // property. + m_positionSource->start(); + activeSetter = false; // this should have no effect + QTest::qWait(0); // to trigger singleShot timer in setActive + + QCOMPARE(m_positionSource->isActive(), true); + QCOMPARE(activeSpy.size(), 1); + QVERIFY(!m_positionSource->bindableActive().hasBinding()); +} + +void tst_DeclarativePositionSource::activeBindingBreak() +{ + // This test checks a tricky scenario of breaking the binding for + // 'active' property. + // 0. active has a binding to some property Prop. + // 1. Prop is set to true => active = true => start getting position info. + // 2. Calling update() for a single update => the binding of active is not + // broken. + // 3. Calling stop() explicitly before the update() call is finished => + // the active binding is supposed to be broken, but the active state + // should still be true, because we have a pending update. + // 4. The pending update finishes => the active is set to false. + + m_positionSource->setName("test.source"); + + QProperty setter(false); + m_positionSource->bindableActive().setBinding(Qt::makePropertyBinding(setter)); + QVERIFY(m_positionSource->bindableActive().hasBinding()); + + setter = true; + QTest::qWait(0); // to trigger singleShot timer in setActive + QCOMPARE(m_positionSource->isActive(), true); + + QSignalSpy posSpy(m_positionSource.get(), &QDeclarativePositionSource::positionChanged); + QSignalSpy errSpy(m_positionSource.get(), &QDeclarativePositionSource::sourceErrorChanged); + m_positionSource->update(210); + + m_positionSource->stop(); + QVERIFY(!m_positionSource->bindableActive().hasBinding()); + QCOMPARE(m_positionSource->isActive(), true); + + // Wait for the single update to complete. It can be either position update + // or timeout. + QTRY_VERIFY_WITH_TIMEOUT(posSpy.size() > 0 || errSpy.size() > 0, 5000); + + QCOMPARE(m_positionSource->isActive(), false); + QVERIFY(!m_positionSource->bindableActive().hasBinding()); +} + +void tst_DeclarativePositionSource::intervalOnSourceDependency() +{ + // updateInterval can be modified if the new source does not support that + // large one, or implements some calculation + m_positionSource->setName("invalid_source"); // reset the source + + QSignalSpy intervalSpy(m_positionSource.get(), + &QDeclarativePositionSource::updateIntervalChanged); + + m_positionSource->setUpdateInterval(100); + QCOMPARE(m_positionSource->updateInterval(), 100); + QCOMPARE(intervalSpy.size(), 1); + + // "test.source" has a minimum update interval of 200 + m_positionSource->setName("test.source"); + QCOMPARE(m_positionSource->updateInterval(), 200); + QCOMPARE(intervalSpy.size(), 2); + + // "dummy.source" has a minimum update interval of 100, so we expect our + // desired interval to be applied + m_positionSource->setName("dummy.source"); + QCOMPARE(m_positionSource->updateInterval(), 100); + QCOMPARE(intervalSpy.size(), 3); +} + +void tst_DeclarativePositionSource::preferredMethodsOnSourceDependency() +{ + m_positionSource->setName("invalid_source"); // reset the source + + QSignalSpy methodsSpy(m_positionSource.get(), + &QDeclarativePositionSource::preferredPositioningMethodsChanged); + + m_positionSource->setPreferredPositioningMethods( + QDeclarativePositionSource::SatellitePositioningMethods); + QCOMPARE(m_positionSource->preferredPositioningMethods(), + QDeclarativePositionSource::SatellitePositioningMethods); + QCOMPARE(methodsSpy.size(), 1); + + // "dummy.source" has only non-satellite methods, so they will be used + m_positionSource->setName("dummy.source"); + QCOMPARE(m_positionSource->preferredPositioningMethods(), + QDeclarativePositionSource::NonSatellitePositioningMethods); + QCOMPARE(methodsSpy.size(), 2); + + // "test.source" has all positioning methods, so satellite will be used, + // as we initially wanted + m_positionSource->setName("test.source"); + QCOMPARE(m_positionSource->preferredPositioningMethods(), + QDeclarativePositionSource::SatellitePositioningMethods); + QCOMPARE(methodsSpy.size(), 3); +} + +void tst_DeclarativePositionSource::updateAfterStart() +{ + // When update() is called after start(), it should not invalidate any + // state. The active state must still be true when the single update() is + // completed. + + m_positionSource->setName("test.source"); + + QCOMPARE(m_positionSource->isActive(), false); + + m_positionSource->start(); + QCOMPARE(m_positionSource->isActive(), true); + + QSignalSpy posSpy(m_positionSource.get(), &QDeclarativePositionSource::positionChanged); + QSignalSpy errSpy(m_positionSource.get(), &QDeclarativePositionSource::sourceErrorChanged); + m_positionSource->update(210); + // Wait for the single update to complete. It can be either position update + // or timeout. + QTRY_VERIFY_WITH_TIMEOUT(posSpy.size() > 0 || errSpy.size() > 0, 5000); + QCOMPARE(m_positionSource->isActive(), true); + + m_positionSource->stop(); + QCOMPARE(m_positionSource->isActive(), false); +} + +void tst_DeclarativePositionSource::startAfterUpdate() +{ + // When start() is called after update(), the position source should remain + // active even when the signle update is completed. + + m_positionSource->setName("test.source"); + + QCOMPARE(m_positionSource->isActive(), false); + + QSignalSpy posSpy(m_positionSource.get(), &QDeclarativePositionSource::positionChanged); + QSignalSpy errSpy(m_positionSource.get(), &QDeclarativePositionSource::sourceErrorChanged); + m_positionSource->update(210); + QCOMPARE(m_positionSource->isActive(), true); + + m_positionSource->start(); + // Wait for the single update to complete. It can be either position update + // or timeout. + QTRY_VERIFY_WITH_TIMEOUT(posSpy.size() > 0 || errSpy.size() > 0, 5000); + QCOMPARE(m_positionSource->isActive(), true); + + m_positionSource->stop(); + QCOMPARE(m_positionSource->isActive(), false); +} + +void tst_DeclarativePositionSource::stopAfterUpdate() +{ + // When stop() is called after update(), and the update() is still in + // progress, the position source should remain active until the update() + // is completed. + + m_positionSource->setName("test.source"); + + QCOMPARE(m_positionSource->isActive(), false); + + QSignalSpy posSpy(m_positionSource.get(), &QDeclarativePositionSource::positionChanged); + QSignalSpy errSpy(m_positionSource.get(), &QDeclarativePositionSource::sourceErrorChanged); + m_positionSource->update(210); + QCOMPARE(m_positionSource->isActive(), true); + + m_positionSource->stop(); + QCOMPARE(m_positionSource->isActive(), true); + + // Wait for the single update to complete. It can be either position update + // or timeout. + QTRY_VERIFY_WITH_TIMEOUT(posSpy.size() > 0 || errSpy.size() > 0, 5000); + QCOMPARE(m_positionSource->isActive(), false); +} + +void tst_DeclarativePositionSource::startStopAfterUpdate() +{ + // Quite artificial example. Calling start() and stop() after update(), + // while still waiting for the update() to complete, should still result in + // the position source to be active until the update() is completed. + + m_positionSource->setName("test.source"); + + QCOMPARE(m_positionSource->isActive(), false); + + QSignalSpy posSpy(m_positionSource.get(), &QDeclarativePositionSource::positionChanged); + QSignalSpy errSpy(m_positionSource.get(), &QDeclarativePositionSource::sourceErrorChanged); + m_positionSource->update(210); + QCOMPARE(m_positionSource->isActive(), true); + + m_positionSource->start(); + m_positionSource->stop(); + + QCOMPARE(m_positionSource->isActive(), true); + + // Wait for the single update to complete. It can be either position update + // or timeout. + QTRY_VERIFY_WITH_TIMEOUT(posSpy.size() > 0 || errSpy.size() > 0, 5000); + QCOMPARE(m_positionSource->isActive(), false); +} + +void tst_DeclarativePositionSource::updateTimedOut() +{ + // This test checks that we reset to inactive state when the single update() + // request times out without providing the position info + + m_positionSource->setName("test.source"); + + QCOMPARE(m_positionSource->isActive(), false); + + m_positionSource->update(50); // too small timeout -> will return an error + QCOMPARE(m_positionSource->isActive(), true); + + QTRY_COMPARE_WITH_TIMEOUT(m_positionSource->sourceError(), + QDeclarativePositionSource::UpdateTimeoutError, 5000); + QCOMPARE(m_positionSource->isActive(), false); +} + +void tst_DeclarativePositionSource::updateWithStartTimedOut() +{ + // This test checks that if single update() times out, but the regular + // updates are running, we still remain in active state. + + m_positionSource->setName("test.source"); + + QCOMPARE(m_positionSource->isActive(), false); + + m_positionSource->start(); + + m_positionSource->update(50); // too small timeout -> will return an error + QCOMPARE(m_positionSource->isActive(), true); + + QTRY_COMPARE_WITH_TIMEOUT(m_positionSource->sourceError(), + QDeclarativePositionSource::UpdateTimeoutError, 5000); + QCOMPARE(m_positionSource->isActive(), true); + + m_positionSource->stop(); + QCOMPARE(m_positionSource->isActive(), false); +} + +void tst_DeclarativePositionSource::startUpdateStopWithNoIntervals() +{ + // This test checks that a sequence of calls start() -> update() -> stop() + // without any waits between them will result in expected behavior. + // Specifically, the position source should remain active until it gets + // the position response. + + m_positionSource->setName("test.source"); + + QCOMPARE(m_positionSource->isActive(), false); + + m_positionSource->start(); + QSignalSpy posSpy(m_positionSource.get(), &QDeclarativePositionSource::positionChanged); + QSignalSpy errSpy(m_positionSource.get(), &QDeclarativePositionSource::sourceErrorChanged); + m_positionSource->update(210); + QCOMPARE(m_positionSource->isActive(), true); + m_positionSource->stop(); + QCOMPARE(m_positionSource->isActive(), true); + + // Wait for the single update to complete. It can be either position update + // or timeout. + QTRY_VERIFY_WITH_TIMEOUT(posSpy.size() > 0 || errSpy.size() > 0, 5000); + QCOMPARE(m_positionSource->isActive(), false); +} + +QTEST_MAIN(tst_DeclarativePositionSource) + +#include "tst_qdeclarativepositionsource.moc" diff --git a/tests/auto/qgeoaddress/CMakeLists.txt b/tests/auto/qgeoaddress/CMakeLists.txt new file mode 100644 index 0000000..48969d5 --- /dev/null +++ b/tests/auto/qgeoaddress/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from qgeoaddress.pro. + +##################################################################### +## tst_qgeoaddress Test: +##################################################################### + +qt_internal_add_test(tst_qgeoaddress + SOURCES + tst_qgeoaddress.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:qgeoaddress.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qgeoaddress/tst_qgeoaddress.cpp b/tests/auto/qgeoaddress/tst_qgeoaddress.cpp new file mode 100644 index 0000000..921176c --- /dev/null +++ b/tests/auto/qgeoaddress/tst_qgeoaddress.cpp @@ -0,0 +1,622 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +#include + +QT_USE_NAMESPACE + +class tst_QGeoAddress : public QObject +{ + Q_OBJECT + +public: + tst_QGeoAddress(); + +private Q_SLOTS: + void constructorTest(); + void moveConstructTest(); + void moveAssignTest(); + void textTest(); + void cityTest(); + void countryCodeTest(); + void countryTest(); + void countyTest(); + void districtTest(); + void postalCodeTest(); + void stateTest(); + void streetTest(); + void streetNumberTest(); + void generatedText(); + void generatedText_data(); + void operatorsTest(); + void emptyClearTest(); + void hashingTest(); + void hashingTest_data(); +}; + +tst_QGeoAddress::tst_QGeoAddress() +{ +} + +void tst_QGeoAddress::constructorTest() +{ + QGeoAddress testObj; + + testObj.setStreet("testId"); + auto testObjPtr = std::make_unique(testObj); + QVERIFY2(testObjPtr != NULL, "Copy constructor - null"); + QVERIFY2(*testObjPtr == testObj, "Copy constructor - compare"); +} + +void tst_QGeoAddress::moveConstructTest() +{ + QGeoAddress address; + address.setCountry("country"); + address.setCity("city"); + address.setPostalCode("postcode"); + address.setStreet("street"); + address.setStreetNumber("number"); + + const QGeoAddress addressCopy = address; + QCOMPARE(QGeoAddress(std::move(address)), addressCopy); +} + +void tst_QGeoAddress::moveAssignTest() +{ + QGeoAddress address; + address.setCountry("country"); + address.setCity("city"); + address.setPostalCode("postcode"); + address.setStreet("street"); + address.setStreetNumber("number"); + + QGeoAddress addressCopy = address; + + QGeoAddress otherAddress; + otherAddress = std::move(address); + QCOMPARE(otherAddress, addressCopy); + + // Check that (move)assigning to a moved-from object is fine + address = std::move(addressCopy); + QCOMPARE(address, otherAddress); +} + +void tst_QGeoAddress::textTest() +{ + QGeoAddress address; + QVERIFY(address.text().isEmpty()); + address.setText(QStringLiteral("123 Fake Street\nSpringfield")); + QCOMPARE(address.text(), QStringLiteral("123 Fake Street\nSpringfield")); +} + +void tst_QGeoAddress::cityTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.city() == QString(), "Wrong default value"); + testObj.setCity("testText"); + QVERIFY2(testObj.city() == "testText", "Wrong value returned"); +} + +void tst_QGeoAddress::countryCodeTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.countryCode() == QString(), "Wrong default value"); + testObj.setCountryCode("testText"); + QVERIFY2(testObj.countryCode() == "testText", "Wrong value returned"); +} + +void tst_QGeoAddress::countryTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.country() == QString(), "Wrong default value"); + testObj.setCountry("testText"); + QVERIFY2(testObj.country() == "testText", "Wrong value returned"); +} + +void tst_QGeoAddress::countyTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.county() == QString(), "Wrong default value"); + testObj.setCounty("testText"); + QVERIFY2(testObj.county() == "testText", "Wrong value returned"); +} + +void tst_QGeoAddress::districtTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.district() == QString(), "Wrong default value"); + testObj.setDistrict("testText"); + QVERIFY2(testObj.district() == "testText", "Wrong value returned"); +} + +void tst_QGeoAddress::postalCodeTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.postalCode() == QString(), "Wrong default value"); + testObj.setPostalCode("testText"); + QVERIFY2(testObj.postalCode() == "testText", "Wrong value returned"); +} + +void tst_QGeoAddress::stateTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.state() == QString(), "Wrong default value"); + testObj.setState("testText"); + QVERIFY2(testObj.state() == "testText", "Wrong value returned"); +} + +void tst_QGeoAddress::streetTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.street() == QString(), "Wrong default value"); + testObj.setStreet("testText"); + QVERIFY2(testObj.street() == "testText", "Wrong value returned"); +} + +void tst_QGeoAddress::streetNumberTest() +{ + QGeoAddress testObj; + QVERIFY2(testObj.streetNumber() == QString(), "Wrong default value"); + const auto streetNumber = QStringLiteral("some street number"); + testObj.setStreetNumber(streetNumber); + QVERIFY2(testObj.streetNumber() == streetNumber, "Wrong value returned"); +} + +void tst_QGeoAddress::generatedText() +{ + QFETCH(QString, countryCode); + QFETCH(QString, expectedPostalCodeOnly); + QFETCH(QString, expectedFullAddress); + + QGeoAddress streetOnly; + streetOnly.setStreet("street"); + streetOnly.setCountryCode(countryCode); + + QCOMPARE(streetOnly.text(), QStringLiteral("street")); + + QGeoAddress cityOnly; + cityOnly.setCity("city"); + cityOnly.setCountryCode(countryCode); + if (countryCode == QLatin1String("CYM") || countryCode == QLatin1String("IRL")) + QCOMPARE(cityOnly.text(), QString()); + else + QCOMPARE(cityOnly.text(), QStringLiteral("city")); + + QGeoAddress postalCodeOnly; + postalCodeOnly.setPostalCode("postcode"); + postalCodeOnly.setCountryCode(countryCode); + QCOMPARE(postalCodeOnly.text(), expectedPostalCodeOnly); + + QGeoAddress fullAddress; + fullAddress.setStreet("street"); + fullAddress.setStreetNumber("number"); + fullAddress.setDistrict("district"); + fullAddress.setPostalCode("postcode"); + fullAddress.setCity("city"); + fullAddress.setState("state"); + fullAddress.setCountry("country"); + fullAddress.setCountryCode(countryCode); + + QCOMPARE(fullAddress.text(), expectedFullAddress); +} + +void tst_QGeoAddress::generatedText_data() +{ + QTest::addColumn("countryCode"); + QTest::addColumn("expectedPostalCodeOnly"); + QTest::addColumn("expectedFullAddress"); + + QTest::newRow("Albania") << QString::fromLatin1("ALB") + << QString::fromLatin1("postcode") /* postal code only */ + << QString::fromLatin1("street number
    " /* full address */ + "postcode, city
    " + "country"); + + QTest::newRow("Andorra") << QString::fromLatin1("AND") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode city
    " + "country"); + QTest::newRow("United Arab Emirates") << QString::fromLatin1("ARE") + << QString() + << QString::fromLatin1("street number
    " + "district city
    " + "country"); + QTest::newRow("Australia") << QString::fromLatin1("AUS") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "district state postcode
    " + "country"); + QTest::newRow("Austria") << QString::fromLatin1("AUT") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode city
    " + "country"); + QTest::newRow("Bahamas") << QString::fromLatin1("BHS") + << QString() + << QString::fromLatin1("street number
    " + "district city
    " + "country"); + QTest::newRow("Bahrain") << QString::fromLatin1("BHR") + << QString() + << QString::fromLatin1("street number
    " + "district, city, state
    " + "country"); + QTest::newRow("Brazil") << QString::fromLatin1("BRA") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "district city-state postcode
    " + "country"); + QTest::newRow("Brunei Darussalam") << QString::fromLatin1("BRN") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "district city postcode
    " + "country"); + QTest::newRow("Canada") << QString::fromLatin1("CAN") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "city, state postcode
    " + "country"); + QTest::newRow("China") << QString::fromLatin1("CHN") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number, city
    " + "postcode state
    " + "country"); + QTest::newRow("Chile") << QString::fromLatin1("CHL") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode district, city, state
    " + "country"); + QTest::newRow("Cayman Islands") << QString::fromLatin1("CYM") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "state postcode
    " + "country"); + QTest::newRow("France") << QString::fromLatin1("FRA") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "postcode city
    " + "country"); + + QTest::newRow("United Kingdom") << QString::fromLatin1("GBR") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "district, city, postcode
    " + "country"); + QTest::newRow("Gibraltar") << QString::fromLatin1("GIB") + << QString() + << QString::fromLatin1("number street
    " + "city
    " + "country"); + QTest::newRow("Guadeloupe") << QString::fromLatin1("GLP") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode city
    " + "country"); + QTest::newRow("French Guiana") << QString::fromLatin1("GUF") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "postcode city
    " + "country"); + QTest::newRow("Hong Kong") << QString::fromLatin1("HKG") + << QString() + << QString::fromLatin1("number street
    " + "district
    " + "city"); + QTest::newRow("India") << QString::fromLatin1("IND") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "city postcode state
    " + "country"); + QTest::newRow("Indonesia") << QString::fromLatin1("IDN") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "city, postcode
    " + "country"); + QTest::newRow("Ireland") << QString::fromLatin1("IRL") + << QString() + << QString::fromLatin1("number street
    " + "district, state
    " + "country"); + QTest::newRow("Italy") << QString::fromLatin1("ITA") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode city
    " + "country"); + QTest::newRow("Jersey") << QString::fromLatin1("JEY") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "city, postcode
    " + "country"); + QTest::newRow("Jordan") << QString::fromLatin1("JOR") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "district city postcode
    " + "country"); + QTest::newRow("Kuwait") << QString::fromLatin1("KWT") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode, district, city
    " + "country"); + QTest::newRow("Latvia") << QString::fromLatin1("LVA") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "city, postcode
    " + "country"); + QTest::newRow("Lebanon") << QString::fromLatin1("LBN") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "district city postcode
    " + "country"); + QTest::newRow("Luxembourg") << QString::fromLatin1("LUX") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "postcode city
    " + "country"); + QTest::newRow("Malta") << QString::fromLatin1("MLT") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "city postcode
    " + "country"); + QTest::newRow("Monaco") << QString::fromLatin1("MCO") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "postcode city
    " + "country"); + QTest::newRow("Mexico") << QString::fromLatin1("MEX") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "district
    " + "postcode city, state
    " + "country"); + QTest::newRow("Martinique") << QString::fromLatin1("MTQ") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode, city
    " + "country"); + QTest::newRow("Malaysia") << QString::fromLatin1("MYS") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "postcode city
    " + "state
    " + "country"); + QTest::newRow("New Zealand") << QString::fromLatin1("NZL") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "district city postcode
    " + "country"); + QTest::newRow("Oman") << QString::fromLatin1("OMN") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "district, postcode, city, country"); + QTest::newRow("Puerto Rico") << QString::fromLatin1("PRI") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "district, city, state, postcode
    " + "country"); + QTest::newRow("Qatar") << QString::fromLatin1("QAT") + << QString() + << QString::fromLatin1("street number
    " + "district city, country"); + QTest::newRow("Reunion") << QString::fromLatin1("REU") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "postcode city
    " + "country"); + QTest::newRow("Russian Federation") << QString::fromLatin1("RUS") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode city
    " + "country"); + QTest::newRow("Saudi Arabia") << QString::fromLatin1("SAU") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street district
    " + "city postcode
    " + "country"); + QTest::newRow("Singapore") << QString::fromLatin1("SGP") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "city postcode
    " + "country"); + QTest::newRow("Marino") << QString::fromLatin1("SMR") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode city
    " + "country"); + QTest::newRow("Taiwan") << QString::fromLatin1("TWN") + << QString() + << QString::fromLatin1("street number, district, city
    " + "country"); + QTest::newRow("Thailand") << QString::fromLatin1("THA") + << QString("postcode") + << QString::fromLatin1("street number
    " + "district, city postcode
    " + "country"); + QTest::newRow("Turkey") << QString::fromLatin1("TUR") + << QString("postcode") + << QString::fromLatin1("street number
    " + "postcode district, city
    " + "country"); + QTest::newRow("Ukraine") << QString::fromLatin1("UKR") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "city postcode
    " + "country"); + QTest::newRow("United States") << QString::fromLatin1("USA") + << QString::fromLatin1("postcode") + << QString::fromLatin1("number street
    " + "city, state postcode
    " + "country"); + QTest::newRow("Virgin Islands, US") << QString::fromLatin1("VIR") + << QString("postcode") + << QString::fromLatin1("number street
    " + "city, state postcode
    " + "country"); + QTest::newRow("Vatican City State") << QString::fromLatin1("VAT") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode city
    " + "country"); + QTest::newRow("Venezuela") << QString::fromLatin1("VEN") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "city postcode, state
    " + "country"); + QTest::newRow("South Africa") << QString::fromLatin1("ZAF") + << QString() + << QString::fromLatin1("street number
    " + "district, city
    " + "country"); + QTest::newRow("Finland") << QString::fromLatin1("FIN") + << QString::fromLatin1("postcode") + << QString::fromLatin1("street number
    " + "postcode city
    " + "country"); +} + +void tst_QGeoAddress::operatorsTest() +{ + QGeoAddress testObj; + testObj.setStreet("testValue"); + QGeoAddress testObj2; + testObj2 = testObj; + QVERIFY2(testObj == testObj2, "Not copied correctly"); + testObj2.setCountry("testValue2"); + QVERIFY2(testObj != testObj2, "Object should be different"); +} + +void tst_QGeoAddress::emptyClearTest() +{ + QGeoAddress testObj; + QVERIFY(testObj.isEmpty()); + + testObj.setCountry(QStringLiteral("country")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setCountryCode(QStringLiteral("countryCode")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setState(QStringLiteral("state")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setCounty(QStringLiteral("county")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setCity(QStringLiteral("city")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setDistrict(QStringLiteral("district")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setPostalCode(QStringLiteral("postalCode")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setStreet(QStringLiteral("street")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setStreetNumber(QStringLiteral("street number")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + testObj.setText(QStringLiteral("formatted address")); + QVERIFY(!testObj.isEmpty()); + testObj.clear(); + + QVERIFY(testObj.isEmpty()); +} + +void tst_QGeoAddress::hashingTest() +{ + QFETCH(QGeoAddress, leftAddress); + QFETCH(QGeoAddress, rightAddress); + QFETCH(bool, result); + + const size_t leftHash = qHash(leftAddress); + const size_t rightHash = qHash(rightAddress); + QCOMPARE(leftHash == rightHash, result); +} + +void tst_QGeoAddress::hashingTest_data() +{ + QTest::addColumn("leftAddress"); + QTest::addColumn("rightAddress"); + QTest::addColumn("result"); + + QGeoAddress leftAddress; + QGeoAddress rightAddress; + + QTest::newRow("empty") << leftAddress << rightAddress << true; + // country + leftAddress.setCountry("country"); + QTest::newRow("different country") << leftAddress << rightAddress << false; + rightAddress.setCountry("country"); + QTest::newRow("same country") << leftAddress << rightAddress << true; + // country code + leftAddress.setCountryCode("country code"); + QTest::newRow("different code") << leftAddress << rightAddress << false; + rightAddress.setCountryCode("country code"); + QTest::newRow("same code") << leftAddress << rightAddress << true; + // state + leftAddress.setState("state"); + QTest::newRow("different state") << leftAddress << rightAddress << false; + rightAddress.setState("state"); + QTest::newRow("same state") << leftAddress << rightAddress << true; + // county + leftAddress.setCounty("county"); + QTest::newRow("different county") << leftAddress << rightAddress << false; + rightAddress.setCounty("county"); + QTest::newRow("same county") << leftAddress << rightAddress << true; + // city + leftAddress.setCity("city"); + QTest::newRow("different city") << leftAddress << rightAddress << false; + rightAddress.setCity("city"); + QTest::newRow("same city") << leftAddress << rightAddress << true; + // district + leftAddress.setDistrict("district"); + QTest::newRow("different district") << leftAddress << rightAddress << false; + rightAddress.setDistrict("district"); + QTest::newRow("same district") << leftAddress << rightAddress << true; + // street + leftAddress.setStreet("street"); + QTest::newRow("different street") << leftAddress << rightAddress << false; + rightAddress.setStreet("street"); + QTest::newRow("same street") << leftAddress << rightAddress << true; + // street number + leftAddress.setStreetNumber("number"); + QTest::newRow("different number") << leftAddress << rightAddress << false; + rightAddress.setStreetNumber("number"); + QTest::newRow("same number") << leftAddress << rightAddress << true; + // postal code + leftAddress.setPostalCode("postal code"); + QTest::newRow("different postcode") << leftAddress << rightAddress << false; + rightAddress.setPostalCode("postal code"); + QTest::newRow("same postcode") << leftAddress << rightAddress << true; + // custom text + leftAddress.setText("some custom text"); + QTest::newRow("different custom text") << leftAddress << rightAddress << false; + rightAddress.setText("some custom text"); + QTest::newRow("same custom text") << leftAddress << rightAddress << true; + + // empty with custom text + leftAddress.clear(); + leftAddress.setText("some custom text"); + rightAddress.clear(); + QTest::newRow("empty with different custom text") << leftAddress << rightAddress << false; + rightAddress.setText("some custom text"); + QTest::newRow("empty with same custom text") << leftAddress << rightAddress << true; +} + +QTEST_APPLESS_MAIN(tst_QGeoAddress) + +#include "tst_qgeoaddress.moc" diff --git a/tests/auto/qgeoareamonitor/CMakeLists.txt b/tests/auto/qgeoareamonitor/CMakeLists.txt new file mode 100644 index 0000000..dd04f37 --- /dev/null +++ b/tests/auto/qgeoareamonitor/CMakeLists.txt @@ -0,0 +1,33 @@ +# Generated from qgeoareamonitor.pro. + +##################################################################### +## tst_qgeoareamonitor Test: +##################################################################### + +list(APPEND test_data "simplelog.txt") + +qt_internal_add_test(tst_qgeoareamonitor + SOURCES + logfilepositionsource.cpp logfilepositionsource.h + positionconsumerthread.cpp positionconsumerthread.h + tst_qgeoareamonitor.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning + TESTDATA ${test_data} +) + +# QGeoAreaMonitor positionpoll plugin requires the presence of a +# QGeoPositionInfoSource object. It could be provided by android position +# plugin, but that plugin is not loaded for unit-tests, so we have to explicitly +# use a test position plugin. +add_dependencies(tst_qgeoareamonitor QGeoPositionInfoSourceFactoryTestPlugin) +if(ANDROID) + set_target_properties(tst_qgeoareamonitor PROPERTIES + QT_ANDROID_EXTRA_PLUGINS "$" + ) +endif() + +#### Keys ignored in scope 1:.:.:qgeoareamonitor.pro:: +# OTHER_FILES = "*.txt" +# TEMPLATE = "app" diff --git a/tests/auto/qgeoareamonitor/logfilepositionsource.cpp b/tests/auto/qgeoareamonitor/logfilepositionsource.cpp new file mode 100644 index 0000000..c14418c --- /dev/null +++ b/tests/auto/qgeoareamonitor/logfilepositionsource.cpp @@ -0,0 +1,107 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include "logfilepositionsource.h" + +LogFilePositionSource::LogFilePositionSource(const QList &data, QObject *parent) + : QGeoPositionInfoSource(parent), + timer(new QTimer(this)), + lines(data) +{ + connect(timer, SIGNAL(timeout()), this, SLOT(readNextPosition())); + + if (lines.isEmpty()) + qWarning() << "Error: the input data is empty!"; + else + index = 0; // ready to read +} + +QGeoPositionInfo LogFilePositionSource::lastKnownPosition(bool /*fromSatellitePositioningMethodsOnly*/) const +{ + return lastPosition; +} + +LogFilePositionSource::PositioningMethods LogFilePositionSource::supportedPositioningMethods() const +{ + return AllPositioningMethods; +} + +int LogFilePositionSource::minimumUpdateInterval() const +{ + return 50; +} + +void LogFilePositionSource::startUpdates() +{ + lastError = QGeoPositionInfoSource::NoError; + int interval = updateInterval(); + if (interval < minimumUpdateInterval()) + interval = minimumUpdateInterval(); + + if (!timer->isActive()) { + if (QMetaObject::invokeMethod(timer, "start", Q_ARG(int, interval))) + emit updatesStarted(); + } +} + +void LogFilePositionSource::stopUpdates() +{ + if (timer->isActive()) { + if (QMetaObject::invokeMethod(timer, "stop")) + emit updatesStopped(); + } +} + +void LogFilePositionSource::requestUpdate(int /*timeout*/) +{ + // For simplicity, ignore timeout - assume that if data is not available + // now, no data will be added to the file later + lastError = QGeoPositionInfoSource::NoError; + if (canReadLine()) { + readNextPosition(); + } else { + lastError = QGeoPositionInfoSource::UpdateTimeoutError; + emit errorOccurred(lastError); + } +} + +void LogFilePositionSource::readNextPosition() +{ + if (canReadLine()) { + const QByteArray line = lines.at(index); + if (!line.isEmpty()) { + QList data = line.split(' '); + double latitude; + double longitude; + bool hasLatitude = false; + bool hasLongitude = false; + QDateTime timestamp = QDateTime::fromString(QString(data.value(0)), Qt::ISODate); + latitude = data.value(1).toDouble(&hasLatitude); + longitude = data.value(2).toDouble(&hasLongitude); + + if (hasLatitude && hasLongitude && timestamp.isValid()) { + QGeoCoordinate coordinate(latitude, longitude); + QGeoPositionInfo info(coordinate, timestamp); + if (info.isValid()) { + lastPosition = info; + emit positionUpdated(info); + } + } + } + index++; + } else if (!noDataEmitted) { + emit noDataLeft(); + noDataEmitted = true; + } +} + +bool LogFilePositionSource::canReadLine() const +{ + return (index >= 0) && (index < lines.size()); +} + +QGeoPositionInfoSource::Error LogFilePositionSource::error() const +{ + return lastError; +} diff --git a/tests/auto/qgeoareamonitor/logfilepositionsource.h b/tests/auto/qgeoareamonitor/logfilepositionsource.h new file mode 100644 index 0000000..593c664 --- /dev/null +++ b/tests/auto/qgeoareamonitor/logfilepositionsource.h @@ -0,0 +1,56 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef LOGFILEPOSITIONSOURCE_H +#define LOGFILEPOSITIONSOURCE_H + +#include + +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +class LogFilePositionSource : public QGeoPositionInfoSource +{ + Q_OBJECT +public: + // This class is optimized to reduce the file IO. + // Initially it was reading the file line-by-line. + // It does not modify the data, so it was optimized to just hold the + // const reference to the pre-existing data, that can now be read once + // for all the instances of this class (for example, during the + // initTestCase() call). + LogFilePositionSource(const QList &data, QObject *parent = 0); + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override; + + PositioningMethods supportedPositioningMethods() const override; + int minimumUpdateInterval() const override; + Error error() const override; + +signals: + void noDataLeft(); + void updatesStarted(); + void updatesStopped(); + +public slots: + virtual void startUpdates() override; + virtual void stopUpdates() override; + + virtual void requestUpdate(int timeout = 5000) override; + +private slots: + void readNextPosition(); + +private: + bool canReadLine() const; + + QTimer *timer; + QGeoPositionInfo lastPosition; + Error lastError = QGeoPositionInfoSource::NoError; + const QList &lines; + qsizetype index = -1; + bool noDataEmitted = false; +}; + +#endif diff --git a/tests/auto/qgeoareamonitor/positionconsumerthread.cpp b/tests/auto/qgeoareamonitor/positionconsumerthread.cpp new file mode 100644 index 0000000..be073de --- /dev/null +++ b/tests/auto/qgeoareamonitor/positionconsumerthread.cpp @@ -0,0 +1,48 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include "positionconsumerthread.h" + +PositionConsumerThread::PositionConsumerThread(QGeoAreaMonitorSource *source, QObject *parent) + : QThread(parent), m_source(source) +{ +} + +PositionConsumerThread::~PositionConsumerThread() +{ + stopProcessing(); + wait(); +} + +int PositionConsumerThread::detectedEnterCount() const +{ + QMutexLocker locker(&m_mutex); + return m_detectedEnterCount; +} + +int PositionConsumerThread::detectedExitCount() const +{ + QMutexLocker locker(&m_mutex); + return m_detectedExitCount; +} + +void PositionConsumerThread::stopProcessing() +{ + m_mutex.lock(); + m_waitCondition.wakeOne(); + m_mutex.unlock(); +} + +void PositionConsumerThread::run() +{ + QSignalSpy enterSpy(m_source, &QGeoAreaMonitorSource::areaEntered); + QSignalSpy exitSpy(m_source, &QGeoAreaMonitorSource::areaExited); + + m_mutex.lock(); + m_waitCondition.wait(&m_mutex); + m_detectedEnterCount = enterSpy.size(); + m_detectedExitCount = exitSpy.size(); + m_mutex.unlock(); +} diff --git a/tests/auto/qgeoareamonitor/positionconsumerthread.h b/tests/auto/qgeoareamonitor/positionconsumerthread.h new file mode 100644 index 0000000..f98193e --- /dev/null +++ b/tests/auto/qgeoareamonitor/positionconsumerthread.h @@ -0,0 +1,49 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef POSITIONCONSUMERTHREAD_H +#define POSITIONCONSUMERTHREAD_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QGeoAreaMonitorSource; +QT_END_NAMESPACE + +// This class is created to test the behavior of QGeoAreaMonitorPolling class, +// that reimplements the connectNotify() and disconnetNotify() methods, by +// triggering these methods from multiple threads. +// The thread creates two QSignalSpy instances, that connect to the signals of +// QGeoAreaMonitorSource. Once constructed, they trigger connectNotify(). +// Once destroyed, they trigger disconnectNotify. +// With the previous implementation of these overridden methods, that could lead +// to a deadlock in a rare case. +class PositionConsumerThread : public QThread +{ + Q_OBJECT +public: + explicit PositionConsumerThread(QGeoAreaMonitorSource *source, QObject *parent = nullptr); + ~PositionConsumerThread(); + + int detectedEnterCount() const; + int detectedExitCount() const; + +public slots: + void stopProcessing(); + +protected: + void run() override; + +private: + QGeoAreaMonitorSource *m_source; + + int m_detectedEnterCount = 0; + int m_detectedExitCount = 0; + + mutable QMutex m_mutex; + QWaitCondition m_waitCondition; +}; + +#endif // POSITIONCONSUMERTHREAD_H diff --git a/tests/auto/qgeoareamonitor/simplelog.txt b/tests/auto/qgeoareamonitor/simplelog.txt new file mode 100644 index 0000000..5a14fb8 --- /dev/null +++ b/tests/auto/qgeoareamonitor/simplelog.txt @@ -0,0 +1,87 @@ +2009-08-24T22:24:34 -27.54 153.090718 +2009-08-24T22:24:35 -27.55 153.090718 +2009-08-24T22:24:36 -27.56 153.090718 +2009-08-24T22:24:37 -27.57 153.090718 +2009-08-24T22:24:38 -27.58 153.090783 +2009-08-24T22:24:39 -27.59 153.090845 +2009-08-24T22:24:40 -27.60 153.090908 +2009-08-24T22:24:41 -27.61 153.090971 +2009-08-24T22:24:42 -27.62 153.091036 +2009-08-24T22:24:43 -27.63 153.091102 +2009-08-24T22:24:44 -27.64 153.091167 +2009-08-24T22:24:45 -27.65 153.091232 +2009-08-24T22:24:46 -27.65 153.091298 +2009-08-24T22:24:47 -27.65 153.091366 +2009-08-24T22:24:48 -27.65 153.091435 +2009-08-24T22:24:49 -27.66 153.091507 +2009-08-24T22:24:50 -27.67 153.091581 +2009-08-24T22:24:51 -27.68 153.091654 +2009-08-24T22:24:52 -27.69 153.091729 +2009-08-24T22:24:53 -27.70 153.091800 +2009-08-24T22:24:54 -27.71 153.091870 +2009-08-24T22:24:55 -27.72 153.091940 +2009-08-24T22:24:56 -27.73 153.092010 +2009-08-24T22:24:57 -27.74 153.092078 +2009-08-24T22:24:58 -27.75 153.092144 +2009-08-24T22:24:59 -27.78 153.092218 +2009-08-24T22:25:00 -27.79 153.092308 +2009-08-24T22:25:01 -27.80 153.092415 +2009-08-24T22:25:02 -27.81 153.092530 +2009-08-24T22:25:03 -27.82 153.092648 +2009-08-24T22:25:04 -27.83 153.092763 +2009-08-24T22:25:05 -27.84 153.092879 +2009-08-24T22:25:06 -27.85 153.092990 +2009-08-24T22:25:07 -27.84 153.093099 +2009-08-24T22:25:08 -27.83 153.093204 +2009-08-24T22:25:09 -27.82 153.093303 +2009-08-24T22:25:10 -27.81 153.093396 +2009-08-24T22:25:11 -27.80 153.093484 +2009-08-24T22:25:12 -27.79 153.093568 +2009-08-24T22:25:13 -27.78 153.093647 +2009-08-24T22:25:14 -27.77 153.093727 +2009-08-24T22:25:15 -27.76 153.093810 +2009-08-24T22:25:16 -27.75 153.093896 +2009-08-24T22:25:17 -27.74 153.093984 +2009-08-24T22:25:18 -27.72 153.094074 +2009-08-24T22:25:19 -27.70 153.094168 +2009-08-24T22:25:20 -27.71 153.094267 +2009-08-24T22:25:21 -27.69 153.094370 +2009-08-24T22:25:22 -27.68 153.094474 +2009-08-24T22:25:23 -27.67 153.094581 +2009-08-24T22:25:24 -27.66 153.094688 +2009-08-24T22:25:25 -27.65 153.094796 +2009-08-24T22:25:26 -27.64 153.094905 +2009-08-24T22:25:27 -27.63 153.095012 +2009-08-24T22:25:28 -27.62 153.095121 +2009-08-24T22:25:29 -27.61 153.095231 +2009-08-24T22:25:30 -27.60 153.095340 +2009-08-24T22:25:31 -27.59 153.095449 +2009-08-24T22:25:32 -27.58 153.095558 +2009-08-24T22:25:33 -27.57 153.095667 +2009-08-24T22:25:34 -27.56 153.095776 +2009-08-24T22:25:35 -27.55 153.095885 +2009-08-24T22:25:36 -27.54 153.095995 +2009-08-24T22:25:37 -27.53 153.096109 +2009-08-24T22:25:38 -27.52 153.096226 +2009-08-24T22:25:39 -27.51 153.096337 +2009-08-24T22:25:40 -27.50 153.096441 +2009-08-24T22:25:41 -27.49 153.096537 +2009-08-24T22:25:42 -27.48 153.096628 +2009-08-24T22:25:43 -27.47 153.096714 +2009-08-24T22:25:44 -27.46 153.096795 +2009-08-24T22:25:45 -27.45 153.096847 +2009-08-24T22:25:46 -27.44 153.096855 +2009-08-24T22:25:47 -27.43 153.096873 +2009-08-24T22:25:48 -27.42 153.096875 +2009-08-24T22:25:49 -27.41 153.096878 +2009-08-24T22:25:50 -27.40 153.096880 +2009-08-24T22:25:51 -27.39 153.096880 +2009-08-24T22:25:52 -27.38 153.096881 +2009-08-24T22:25:53 -27.37 153.096882 +2009-08-24T22:25:54 -27.36 153.096883 +2009-08-24T22:25:55 -27.35 153.096883 +2009-08-24T22:25:56 -27.34 153.096883 +2009-08-24T22:25:57 -27.33 153.096890 +2009-08-24T22:25:58 -27.32 153.096919 +2009-08-24T22:25:59 -27.31 153.096985 +2009-08-24T22:26:00 -27.30 153.097060 diff --git a/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp b/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp new file mode 100644 index 0000000..8501fa3 --- /dev/null +++ b/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp @@ -0,0 +1,952 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "logfilepositionsource.h" +#include "positionconsumerthread.h" + +QT_USE_NAMESPACE +#define UPDATE_INTERVAL 50 + +QString tst_qgeoareamonitorinfo_debug; + +void tst_qgeoareamonitorinfo_messageHandler(QtMsgType type, + const QMessageLogContext &, + const QString &msg) +{ + switch (type) { + case QtDebugMsg : + tst_qgeoareamonitorinfo_debug = msg; + break; + default: + break; + } +} + +static QList readFileData(const QString &fileName) +{ + QList data; + QFile logFile(fileName); + if (logFile.open(QIODevice::ReadOnly)) { + data = logFile.readAll().split('\n'); + logFile.close(); + } else { + qWarning() << "Error: cannot open source file" << logFile.fileName(); + } + return data; +} + +class DummyMonitorSource : public QGeoAreaMonitorSource +{ + Q_OBJECT +public: + static const QString kTestProperty; + + DummyMonitorSource(QObject *parent = nullptr) : QGeoAreaMonitorSource(parent) + {} + + Error error() const override + { + return NoError; + } + AreaMonitorFeatures supportedAreaMonitorFeatures() const override + { + return AnyAreaMonitorFeature; + } + + bool startMonitoring(const QGeoAreaMonitorInfo &monitor) override + { + Q_UNUSED(monitor); + return false; + } + bool stopMonitoring(const QGeoAreaMonitorInfo &monitor) override + { + Q_UNUSED(monitor); + return false; + } + bool requestUpdate(const QGeoAreaMonitorInfo &monitor, const char *signal) override + { + Q_UNUSED(monitor); + Q_UNUSED(signal); + return false; + } + + QList activeMonitors() const override + { + return {}; + } + QList activeMonitors(const QGeoShape &lookupArea) const override + { + Q_UNUSED(lookupArea); + return {}; + } + + bool setBackendProperty(const QString &name, const QVariant &value) override + { + if (name == kTestProperty) { + m_testPropertyValue = value.toInt(); + return true; + } + return false; + } + QVariant backendProperty(const QString &name) const override + { + if (name == kTestProperty) + return m_testPropertyValue; + return QVariant(); + } + +private: + int m_testPropertyValue = 0; +}; + +const QString DummyMonitorSource::kTestProperty = "TestProperty"; + +class tst_QGeoAreaMonitorSource : public QObject +{ + Q_OBJECT + +private: + QList m_fileData; + +private slots: + void initTestCase() + { +#if QT_CONFIG(library) + /* + * Set custom path since CI doesn't install plugins + */ +#ifdef Q_OS_WIN + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#else + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../plugins")); +#endif +#endif + qRegisterMetaType(); + m_fileData = readFileData(QFINDTESTDATA("simplelog.txt")); + } + + void init() + { + } + + void cleanup() + { + std::unique_ptr obj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + + QList list = obj->activeMonitors(); + if (list.size() > 0) { + //cleanup installed monitors + foreach (const QGeoAreaMonitorInfo& info, list) { + QVERIFY(obj->stopMonitoring(info)); + } + } + QVERIFY(obj->activeMonitors().size() == 0); + } + + void cleanupTestCase() + { + } + + void tst_monitor() + { + QGeoAreaMonitorInfo defaultMonitor; + QVERIFY(defaultMonitor.name().isEmpty()); + QVERIFY(!defaultMonitor.identifier().isEmpty()); + QCOMPARE(defaultMonitor.isPersistent(), false); + QVERIFY(!defaultMonitor.area().isValid()); + QVERIFY(!defaultMonitor.isValid()); + QCOMPARE(defaultMonitor.expiration(), QDateTime()); + QCOMPARE(defaultMonitor.notificationParameters(), QVariantMap()); + + std::unique_ptr obj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + QVERIFY(!obj->startMonitoring(defaultMonitor)); + QCOMPARE(obj->activeMonitors().size(), 0); + QVERIFY(!obj->requestUpdate(defaultMonitor, + SIGNAL(areaEntered(QGeoMonitorInfo,QGeoAreaPositionInfo)))); + + //copy constructor based + QGeoAreaMonitorInfo copy(defaultMonitor); + QVERIFY(copy.name().isEmpty()); + QCOMPARE(copy.identifier(), defaultMonitor.identifier()); + QVERIFY(copy == defaultMonitor); + QVERIFY(!(copy != defaultMonitor)); + QCOMPARE(copy.isPersistent(), false); + + copy.setName(QString("my name")); + QCOMPARE(copy.name(), QString("my name")); + + + QDateTime now = QDateTime::currentDateTime().addSecs(1000); //little bit in the future + copy.setExpiration(now); + QVERIFY(copy != defaultMonitor); + QCOMPARE(copy.expiration(), now); + + QCOMPARE(copy.isPersistent(), defaultMonitor.isPersistent()); + copy.setPersistent(true); + QCOMPARE(copy.isPersistent(), true); + QCOMPARE(defaultMonitor.isPersistent(), false); + copy.setPersistent(false); + + QVERIFY(copy.area() == defaultMonitor.area()); + QVERIFY(!copy.area().isValid()); + copy.setArea(QGeoCircle(QGeoCoordinate(1, 2), 4)); + QVERIFY(copy.area().isValid()); + QVERIFY(copy.area() != defaultMonitor.area()); + QVERIFY(copy.area().contains(QGeoCoordinate(1, 2))); + + QVERIFY(copy.notificationParameters().isEmpty()); + QVariantMap map; + map.insert(QString("MyKey"), QVariant(123)); + copy.setNotificationParameters(map); + QVERIFY(!copy.notificationParameters().isEmpty()); + QCOMPARE(copy.notificationParameters().value(QString("MyKey")).toInt(), 123); + QCOMPARE(defaultMonitor.notificationParameters().value(QString("MyKey")).toInt(), 0); + + QCOMPARE(defaultMonitor.identifier(), copy.identifier()); + + //assignment operator based + QGeoAreaMonitorInfo assignmentCopy; + assignmentCopy = copy; + QVERIFY(copy == assignmentCopy); + QVERIFY(assignmentCopy != defaultMonitor); + + QVERIFY(assignmentCopy.area().contains(QGeoCoordinate(1, 2))); + QCOMPARE(assignmentCopy.expiration(), now); + QCOMPARE(assignmentCopy.isPersistent(), false); + QCOMPARE(assignmentCopy.notificationParameters().value(QString("MyKey")).toInt(), 123); + QCOMPARE(defaultMonitor.identifier(), assignmentCopy.identifier()); + QCOMPARE(assignmentCopy.name(), QString("my name")); + + //validity checks for requestUpdate() + obj.reset(QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + QCOMPARE(obj->activeMonitors().size(), 0); + //reference -> should work + QVERIFY(obj->requestUpdate(copy, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)))); + QCOMPARE(obj->activeMonitors().size(), 1); + //replaces areaEntered single shot + QVERIFY(obj->requestUpdate(copy, SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)))); + QCOMPARE(obj->activeMonitors().size(), 1); + //replaces areaExited single shot + QVERIFY(obj->startMonitoring(copy)); + QCOMPARE(obj->activeMonitors().size(), 1); + + + //invalid signal + QVERIFY(!obj->requestUpdate(copy, 0)); + QCOMPARE(obj->activeMonitors().size(), 1); + + //signal that doesn't exist + QVERIFY(!obj->requestUpdate(copy, SIGNAL(areaEntered(QGeoMonitor)))); + QCOMPARE(obj->activeMonitors().size(), 1); + + QVERIFY(!obj->requestUpdate(copy, "SIGNAL(areaEntered(QGeoMonitor))")); + QCOMPARE(obj->activeMonitors().size(), 1); + + //ensure that we cannot add a persistent monitor to a source + //that doesn't support persistence + QGeoAreaMonitorInfo persistenceMonitor(copy); + persistenceMonitor.setPersistent(obj->supportedAreaMonitorFeatures() & QGeoAreaMonitorSource::PersistentAreaMonitorFeature); + persistenceMonitor.setPersistent(!persistenceMonitor.isPersistent()); + + QVERIFY(!obj->requestUpdate(persistenceMonitor, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)))); + QCOMPARE(obj->activeMonitors().size(), 1); + QVERIFY(!obj->startMonitoring(persistenceMonitor)); + QCOMPARE(obj->activeMonitors().size(), 1); + + //ensure that persistence was only reason for rejection + persistenceMonitor.setPersistent(!persistenceMonitor.isPersistent()); + QVERIFY(obj->startMonitoring(persistenceMonitor)); + //persistenceMonitor is copy of already added monitor + //the last call was an update + QCOMPARE(obj->activeMonitors().size(), 1); + } + + void tst_monitor_move_semantics() + { + QGeoAreaMonitorInfo info1("test"); + info1.setArea(QGeoCircle(QGeoCoordinate(1.0, 1.0), 100)); + info1.setExpiration(QDateTime::currentDateTimeUtc()); + QGeoAreaMonitorInfo infoCopy(info1); + + QGeoAreaMonitorInfo info2(std::move(info1)); + QCOMPARE(info2, infoCopy); + + QGeoAreaMonitorInfo info3; + info3.setName("name"); + info3.setArea(QGeoRectangle(QGeoCoordinate(1, 2), QGeoCoordinate(2, 1))); + info3.setPersistent(true); + infoCopy = info3; + + // check that (move)assigning to the moved-from object is ok + info1 = std::move(info3); + QCOMPARE(info1, infoCopy); + + // The moved-from object info3 will go out of scope and will be + // destroyed here, so we also implicitly check that moved-from object's + // destructor is called without any issues. + } + + void tst_monitorValid() + { + QGeoAreaMonitorInfo mon; + QVERIFY(!mon.isValid()); + QCOMPARE(mon.name(), QString()); + QCOMPARE(mon.area().isValid(), false); + + QGeoAreaMonitorInfo mon2 = mon; + QVERIFY(!mon2.isValid()); + + QGeoShape invalidShape; + QGeoCircle emptyCircle(QGeoCoordinate(0,1), 0); + QGeoCircle validCircle(QGeoCoordinate(0,1), 1); + + //all invalid since no name set yet + mon2.setArea(invalidShape); + QVERIFY(mon2.area() == invalidShape); + QVERIFY(!mon2.isValid()); + + mon2.setArea(emptyCircle); + QVERIFY(mon2.area() == emptyCircle); + QVERIFY(!mon2.isValid()); + + mon2.setArea(validCircle); + QVERIFY(mon2.area() == validCircle); + QVERIFY(!mon2.isValid()); + + //valid since name and non-empy shape has been set + QGeoAreaMonitorInfo validMonitor("TestMonitor"); + QVERIFY(validMonitor.name() == QString("TestMonitor")); + QVERIFY(!validMonitor.isValid()); + + validMonitor.setArea(invalidShape); + QVERIFY(validMonitor.area() == invalidShape); + QVERIFY(!validMonitor.isValid()); + + validMonitor.setArea(emptyCircle); + QVERIFY(validMonitor.area() == emptyCircle); + QVERIFY(!validMonitor.isValid()); + + validMonitor.setArea(validCircle); + QVERIFY(validCircle == validMonitor.area()); + QVERIFY(validMonitor.isValid()); + } + + void tst_monitorStreaming() + { + QByteArray container; + QDataStream stream(&container, QIODevice::ReadWrite); + + QGeoAreaMonitorInfo monitor("someName"); + monitor.setArea(QGeoCircle(QGeoCoordinate(1,3), 5.4)); + const QDateTime expirationTime = QDateTime::currentDateTime().addSecs(60); + monitor.setExpiration(expirationTime); + monitor.setPersistent(true); + const QVariantMap params { {"string_param", "some string"}, + {"int_param", 1}, {"double_param", 3.5} }; + monitor.setNotificationParameters(params); + QVERIFY(monitor.isValid()); + QCOMPARE(monitor.name(), QString("someName")); + QCOMPARE(monitor.expiration(), expirationTime); + QVERIFY(monitor.isPersistent()); + QCOMPARE(monitor.notificationParameters(), params); + + QGeoAreaMonitorInfo target; + QVERIFY(!target.isValid()); + QVERIFY(target.name().isEmpty()); + + QVERIFY(target != monitor); + + stream << monitor; + stream.device()->seek(0); + stream >> target; + + QVERIFY(target == monitor); + QVERIFY(target.isValid()); + QCOMPARE(target.name(), QString("someName")); + QVERIFY(target.area() == QGeoCircle(QGeoCoordinate(1,3), 5.4)); + QCOMPARE(target.expiration(), expirationTime); + QVERIFY(target.isPersistent()); + QCOMPARE(target.notificationParameters(), params); + } + + void tst_createDefaultSource() + { + std::unique_ptr parent(new QObject); + + // Have to use a raw pointer here, because otherwise we'd end up + // deleting the obj twice when deleting the parent + QGeoAreaMonitorSource *obj = QGeoAreaMonitorSource::createDefaultSource(parent.get()); + QVERIFY(obj != nullptr); + QVERIFY(obj->parent() == parent.get()); + delete obj; + + const QStringList monitors = QGeoAreaMonitorSource::availableSources(); + QVERIFY(!monitors.isEmpty()); + QVERIFY(monitors.contains(QStringLiteral("positionpoll"))); + + obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), parent.get()); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + parent.reset(); + + // using a smart pointer will cause a double delete here + obj = QGeoAreaMonitorSource::createSource(QStringLiteral("randomNonExistingName"), 0); + QVERIFY(obj == nullptr); + } + + void tst_activeMonitors() + { + std::unique_ptr obj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + + // using this -> no need for smart pointer + LogFilePositionSource *source = new LogFilePositionSource(m_fileData, this); + source->setUpdateInterval(UPDATE_INTERVAL); + obj->setPositionInfoSource(source); + QCOMPARE(obj->positionInfoSource(), source); + + + QVERIFY(obj->activeMonitors().isEmpty()); + + QGeoAreaMonitorInfo mon("Monitor_Circle"); + mon.setArea(QGeoCircle(QGeoCoordinate(1,1), 1000)); + QVERIFY(obj->startMonitoring(mon)); + + QGeoAreaMonitorInfo mon2("Monitor_rectangle_below"); + QGeoRectangle r_below(QGeoCoordinate(1,1),2,2); + mon2.setArea(r_below); + QVERIFY(obj->startMonitoring(mon2)); + + QGeoAreaMonitorInfo mon3("Monitor_rectangle_above"); + QGeoRectangle r_above(QGeoCoordinate(2,1),2,2); + mon3.setArea(r_above); + QVERIFY(obj->startMonitoring(mon3)); + + QList results = obj->activeMonitors(); + QCOMPARE(results.size(), 3); + foreach (const QGeoAreaMonitorInfo& info, results) { + QVERIFY(info == mon || info == mon2 || info == mon3); + } + + results = obj->activeMonitors(QGeoShape()); + QCOMPARE(results.size(), 0); + + results = obj->activeMonitors(QGeoRectangle(QGeoCoordinate(1,1),0.2, 0.2)); + QCOMPARE(results.size(), 2); + foreach (const QGeoAreaMonitorInfo& info, results) { + QVERIFY(info == mon || info == mon2); + } + + results = obj->activeMonitors(QGeoCircle(QGeoCoordinate(1,1),1000)); + QCOMPARE(results.size(), 2); + foreach (const QGeoAreaMonitorInfo& info, results) { + QVERIFY(info == mon || info == mon2); + } + + results = obj->activeMonitors(QGeoCircle(QGeoCoordinate(2,1),1000)); + QCOMPARE(results.size(), 1); + foreach (const QGeoAreaMonitorInfo& info, results) { + QVERIFY(info == mon3); + } + + //same as above except that we use a different monitor source object instance + //all monitor objects of same type share same active monitors + std::unique_ptr secondObj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(secondObj != nullptr); + QCOMPARE(secondObj->sourceName(), QStringLiteral("positionpoll")); + + results = secondObj->activeMonitors(); + QCOMPARE(results.size(), 3); + foreach (const QGeoAreaMonitorInfo& info, results) { + QVERIFY(info == mon || info == mon2 || info == mon3); + } + + results = secondObj->activeMonitors(QGeoShape()); + QCOMPARE(results.size(), 0); + + results = secondObj->activeMonitors(QGeoRectangle(QGeoCoordinate(1,1),0.2, 0.2)); + QCOMPARE(results.size(), 2); + foreach (const QGeoAreaMonitorInfo& info, results) { + QVERIFY(info == mon || info == mon2); + } + + results = secondObj->activeMonitors(QGeoCircle(QGeoCoordinate(1,1),1000)); + QCOMPARE(results.size(), 2); + foreach (const QGeoAreaMonitorInfo& info, results) { + QVERIFY(info == mon || info == mon2); + } + + results = secondObj->activeMonitors(QGeoCircle(QGeoCoordinate(2,1),1000)); + QCOMPARE(results.size(), 1); + foreach (const QGeoAreaMonitorInfo& info, results) { + QVERIFY(info == mon3); + } + } + + void tst_testExpiryTimeout() + { + std::unique_ptr obj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + + std::unique_ptr secondObj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(secondObj != nullptr); + QCOMPARE(secondObj->sourceName(), QStringLiteral("positionpoll")); + + // using this -> no need for smart pointer + LogFilePositionSource *source = new LogFilePositionSource(m_fileData, this); + source->setUpdateInterval(UPDATE_INTERVAL); + obj->setPositionInfoSource(source); + + //Singleton pattern behind QGeoAreaMonitorSource ensures same position info source + QCOMPARE(obj->positionInfoSource(), source); + QCOMPARE(secondObj->positionInfoSource(), source); + + QSignalSpy expirySpy(obj.get(), SIGNAL(monitorExpired(QGeoAreaMonitorInfo))); + QSignalSpy expirySpy2(secondObj.get(), SIGNAL(monitorExpired(QGeoAreaMonitorInfo))); + + QDateTime now = QDateTime::currentDateTime(); + + const int monitorCount = 4; + for (int i = 1; i <= monitorCount; i++) { + QGeoAreaMonitorInfo mon(QString::number(i)); + mon.setArea(QGeoRectangle(QGeoCoordinate(i,i), i, i)); + mon.setExpiration(now.addSecs(i*2)); + QVERIFY(mon.isValid()); + QVERIFY(obj->startMonitoring(mon)); + } + + + + QCOMPARE(obj->activeMonitors().size(), monitorCount); + QCOMPARE(secondObj->activeMonitors().size(), monitorCount); + + QGeoAreaMonitorInfo info("InvalidExpiry"); + info.setArea(QGeoRectangle(QGeoCoordinate(10,10), 1, 1 )); + QVERIFY(info.isValid()); + info.setExpiration(now.addSecs(-1000)); + QVERIFY(info.expiration() < now); + QVERIFY(!obj->startMonitoring(info)); + QCOMPARE(obj->activeMonitors().size(), monitorCount); + QVERIFY(!obj->requestUpdate(info, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)))); + QCOMPARE(obj->activeMonitors().size(), monitorCount); + + for (int i = 1; i <= monitorCount; i++) { + QTRY_VERIFY_WITH_TIMEOUT(expirySpy.size() == 1, 3000); //each expiry within 2 s + QGeoAreaMonitorInfo mon = expirySpy.takeFirst().at(0).value(); + QCOMPARE(obj->activeMonitors().size(), monitorCount-i); + QCOMPARE(mon.name(), QString::number(i)); + } + + QCOMPARE(expirySpy2.size(), monitorCount); + QCOMPARE(secondObj->activeMonitors().size(), 0); //all monitors expired + for (int i = 1; i <= monitorCount; i++) { + QGeoAreaMonitorInfo mon = expirySpy2.takeFirst().at(0).value(); + QCOMPARE(mon.name(), QString::number(i)); + } + } + + void tst_enteredExitedSignal() + { + std::unique_ptr obj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + obj->setObjectName("firstObject"); + QSignalSpy enteredSpy(obj.get(), + SIGNAL(areaEntered(QGeoAreaMonitorInfo, QGeoPositionInfo))); + QSignalSpy exitedSpy(obj.get(), SIGNAL(areaExited(QGeoAreaMonitorInfo, QGeoPositionInfo))); + + // using this -> no need for smart pointer + LogFilePositionSource *source = new LogFilePositionSource(m_fileData, this); + source->setUpdateInterval(UPDATE_INTERVAL); + obj->setPositionInfoSource(source); + QCOMPARE(obj->positionInfoSource(), source); + + std::unique_ptr secondObj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(secondObj != nullptr); + QCOMPARE(secondObj->sourceName(), QStringLiteral("positionpoll")); + QSignalSpy enteredSpy2(secondObj.get(), + SIGNAL(areaEntered(QGeoAreaMonitorInfo, QGeoPositionInfo))); + QSignalSpy exitedSpy2(secondObj.get(), + SIGNAL(areaExited(QGeoAreaMonitorInfo, QGeoPositionInfo))); + secondObj->setObjectName("secondObject"); + + QGeoAreaMonitorInfo infoRectangle("Rectangle"); + infoRectangle.setArea(QGeoRectangle(QGeoCoordinate(-27.65, 153.093), 0.2, 0.2)); + QVERIFY(infoRectangle.isValid()); + QVERIFY(obj->startMonitoring(infoRectangle)); + + QGeoAreaMonitorInfo infoCircle("Circle"); + infoCircle.setArea(QGeoCircle(QGeoCoordinate(-27.70, 153.093),10000)); + QVERIFY(infoCircle.isValid()); + QVERIFY(obj->startMonitoring(infoCircle)); + + QGeoAreaMonitorInfo singleShot_enter("SingleShot_on_Entered"); + singleShot_enter.setArea(QGeoRectangle(QGeoCoordinate(-27.67, 153.093), 0.2, 0.2)); + QVERIFY(singleShot_enter.isValid()); + QVERIFY(obj->requestUpdate(singleShot_enter, + SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)))); + + QGeoAreaMonitorInfo singleShot_exit("SingleShot_on_Exited"); + singleShot_exit.setArea(QGeoRectangle(QGeoCoordinate(-27.70, 153.093), 0.2, 0.2)); + QVERIFY(singleShot_exit.isValid()); + QVERIFY(obj->requestUpdate(singleShot_exit, + SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)))); + + QVERIFY(obj->activeMonitors().size() == 4); //all monitors active + QVERIFY(secondObj->activeMonitors().size() == 4); //all monitors active + + static const int Number_Of_Entered_Events = 6; + static const int Number_Of_Exited_Events = 5; + //takes 87 (lines)*50(timeout)/1000 seconds to finish + QTRY_VERIFY_WITH_TIMEOUT(enteredSpy.size() == Number_Of_Entered_Events, 5000); + QTRY_VERIFY_WITH_TIMEOUT(exitedSpy.size() == Number_Of_Exited_Events, 5000); + QCOMPARE(enteredSpy.size(), Number_Of_Entered_Events); + QCOMPARE(exitedSpy.size(), Number_Of_Exited_Events); + + QList monitorsInExpectedEnteredEventOrder; + monitorsInExpectedEnteredEventOrder << infoRectangle << singleShot_enter << singleShot_exit + << infoCircle << infoCircle << infoRectangle; + + QList monitorsInExpectedExitedEventOrder; + monitorsInExpectedExitedEventOrder << infoRectangle << infoCircle + << singleShot_exit << infoCircle << infoRectangle; + + QList enteredEventCoordinateOrder; + enteredEventCoordinateOrder << QGeoCoordinate(-27.55, 153.090718) //infoRectangle + << QGeoCoordinate(-27.57, 153.090718) //singleshot_enter + << QGeoCoordinate(-27.60, 153.090908) //singleshot_exit + << QGeoCoordinate(-27.62, 153.091036) //infoCircle + << QGeoCoordinate(-27.78, 153.093647) //infoCircle + << QGeoCoordinate(-27.75, 153.093896);//infoRectangle + QCOMPARE(enteredEventCoordinateOrder.size(), Number_Of_Entered_Events); + QCOMPARE(monitorsInExpectedEnteredEventOrder.size(), Number_Of_Entered_Events); + + QList exitedEventCoordinateOrder; + exitedEventCoordinateOrder << QGeoCoordinate(-27.78, 153.092218) //infoRectangle + << QGeoCoordinate(-27.79, 153.092308) //infoCircle + << QGeoCoordinate(-27.81, 153.092530) //singleshot_exit + << QGeoCoordinate(-27.61, 153.095231) //infoCircle + << QGeoCoordinate(-27.54, 153.095995);//infoCircle + QCOMPARE(exitedEventCoordinateOrder.size(), Number_Of_Exited_Events); + QCOMPARE(monitorsInExpectedExitedEventOrder.size(), Number_Of_Exited_Events); + + //verify that both sources got the same signals + for (int i = 0; i < Number_Of_Entered_Events; i++) { + //first source + QGeoAreaMonitorInfo monInfo = enteredSpy.first().at(0).value(); + QGeoPositionInfo posInfo = enteredSpy.takeFirst().at(1).value(); + QVERIFY2(monInfo == monitorsInExpectedEnteredEventOrder.at(i), + qPrintable(QString::number(i) + ": " + monInfo.name())); + QVERIFY2(posInfo.coordinate() == enteredEventCoordinateOrder.at(i), + qPrintable(QString::number(i) + ". posInfo")); + + //reset info objects to avoid comparing the same + monInfo = QGeoAreaMonitorInfo(); + posInfo = QGeoPositionInfo(); + + //second source + monInfo = enteredSpy2.first().at(0).value(); + posInfo = enteredSpy2.takeFirst().at(1).value(); + QVERIFY2(monInfo == monitorsInExpectedEnteredEventOrder.at(i), + qPrintable(QString::number(i) + ": " + monInfo.name())); + QVERIFY2(posInfo.coordinate() == enteredEventCoordinateOrder.at(i), + qPrintable(QString::number(i) + ". posInfo")); + } + + for (int i = 0; i < Number_Of_Exited_Events; i++) { + //first source + QGeoAreaMonitorInfo monInfo = exitedSpy.first().at(0).value(); + QGeoPositionInfo posInfo = exitedSpy.takeFirst().at(1).value(); + QVERIFY2(monInfo == monitorsInExpectedExitedEventOrder.at(i), + qPrintable(QString::number(i) + ": " + monInfo.name())); + QVERIFY2(posInfo.coordinate() == exitedEventCoordinateOrder.at(i), + qPrintable(QString::number(i) + ". posInfo")); + + //reset info objects to avoid comparing the same + monInfo = QGeoAreaMonitorInfo(); + posInfo = QGeoPositionInfo(); + + //second source + monInfo = exitedSpy2.first().at(0).value(); + posInfo = exitedSpy2.takeFirst().at(1).value(); + QVERIFY2(monInfo == monitorsInExpectedExitedEventOrder.at(i), + qPrintable(QString::number(i) + ": " + monInfo.name())); + QVERIFY2(posInfo.coordinate() == exitedEventCoordinateOrder.at(i), + qPrintable(QString::number(i) + ". posInfo")); + } + + QCOMPARE(obj->activeMonitors().size(), 2); //single shot monitors have been removed + QCOMPARE(secondObj->activeMonitors().size(), 2); + } + + void tst_swapOfPositionSource() + { + std::unique_ptr obj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + obj->setObjectName("firstObject"); + QSignalSpy enteredSpy(obj.get(), + SIGNAL(areaEntered(QGeoAreaMonitorInfo, QGeoPositionInfo))); + QSignalSpy exitedSpy(obj.get(), SIGNAL(areaExited(QGeoAreaMonitorInfo, QGeoPositionInfo))); + + std::unique_ptr obj2( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj2 != nullptr); + QCOMPARE(obj2->sourceName(), QStringLiteral("positionpoll")); + obj2->setObjectName("secondObject"); + QSignalSpy enteredSpy2(obj2.get(), + SIGNAL(areaEntered(QGeoAreaMonitorInfo, QGeoPositionInfo))); + QSignalSpy exitedSpy2(obj2.get(), + SIGNAL(areaExited(QGeoAreaMonitorInfo, QGeoPositionInfo))); + + // using this -> no need for smart pointer + LogFilePositionSource *source = new LogFilePositionSource(m_fileData, this); + source->setUpdateInterval(UPDATE_INTERVAL); + source->setObjectName("FirstLogFileSource"); + + // using this -> no need for smart pointer + LogFilePositionSource *source2 = new LogFilePositionSource(m_fileData, this); + source2->setUpdateInterval(UPDATE_INTERVAL); + source2->setObjectName("SecondLogFileSource"); + + obj->setPositionInfoSource(source); + QCOMPARE(obj->positionInfoSource(), obj2->positionInfoSource()); + QCOMPARE(obj2->positionInfoSource(), source); + + QGeoAreaMonitorInfo infoRectangle("Rectangle"); + infoRectangle.setArea(QGeoRectangle(QGeoCoordinate(-27.70, 153.092), 0.2, 0.2)); + QVERIFY(infoRectangle.isValid()); + QVERIFY(obj->startMonitoring(infoRectangle)); + + QCOMPARE(obj->activeMonitors().size(), 1); + QCOMPARE(obj2->activeMonitors().size(), 1); + + QGeoCoordinate firstBorder(-27.6, 153.090908); + QGeoCoordinate secondBorder(-27.81, 153.092530); + + /***********************************/ + //1. trigger events on source (until areaExit + QTRY_VERIFY_WITH_TIMEOUT(exitedSpy.size() == 1, 5000); + QCOMPARE(enteredSpy.size(), enteredSpy2.size()); + QCOMPARE(exitedSpy.size(), exitedSpy2.size()); + + //compare entered event + QVERIFY(enteredSpy.first().at(0).value() == + enteredSpy2.first().at(0).value()); + QGeoPositionInfo info = enteredSpy.takeFirst().at(1).value(); + QVERIFY(info == enteredSpy2.takeFirst().at(1).value()); + QVERIFY(info.coordinate() == firstBorder); + //compare exit event + QVERIFY(exitedSpy.first().at(0).value() == + exitedSpy2.first().at(0).value()); + info = exitedSpy.takeFirst().at(1).value(); + QVERIFY(info == exitedSpy2.takeFirst().at(1).value()); + QVERIFY(info.coordinate() == secondBorder); + + QCOMPARE(exitedSpy.size(), 0); + QCOMPARE(enteredSpy.size(), 0); + QCOMPARE(exitedSpy2.size(), 0); + QCOMPARE(enteredSpy2.size(), 0); + + /***********************************/ + //2. change position source -> which restarts at beginning again + obj2->setPositionInfoSource(source2); + QCOMPARE(obj->positionInfoSource(), obj2->positionInfoSource()); + QCOMPARE(obj2->positionInfoSource(), source2); + + QTRY_VERIFY_WITH_TIMEOUT(exitedSpy.size() == 1, 5000); + QCOMPARE(enteredSpy.size(), enteredSpy2.size()); + QCOMPARE(exitedSpy.size(), exitedSpy2.size()); + + //compare entered event + QVERIFY(enteredSpy.first().at(0).value() == + enteredSpy2.first().at(0).value()); + info = enteredSpy.takeFirst().at(1).value(); + QVERIFY(info == enteredSpy2.takeFirst().at(1).value()); + QVERIFY(info.coordinate() == firstBorder); + //compare exit event + QVERIFY(exitedSpy.first().at(0).value() == + exitedSpy2.first().at(0).value()); + info = exitedSpy.takeFirst().at(1).value(); + QVERIFY(info == exitedSpy2.takeFirst().at(1).value()); + QVERIFY(info.coordinate() == secondBorder); + } + + void debug_data() + { + QTest::addColumn("info"); + QTest::addColumn("nextValue"); + QTest::addColumn("debugString"); + + QGeoAreaMonitorInfo info; + QTest::newRow("uninitialized") << info << 45 + << QString("QGeoAreaMonitorInfo(\"\", QGeoShape(Unknown), " + "persistent: false, expiry: QDateTime(Invalid)) 45"); + + info.setArea(QGeoRectangle()); + info.setPersistent(true); + info.setName("RectangleAreaMonitor"); + QTest::newRow("Rectangle Test") << info << 45 + << QString("QGeoAreaMonitorInfo(\"RectangleAreaMonitor\", QGeoShape(Rectangle), " + "persistent: true, expiry: QDateTime(Invalid)) 45"); + + info = QGeoAreaMonitorInfo(); + info.setArea(QGeoCircle()); + info.setPersistent(false); + info.setName("CircleAreaMonitor"); + QVariantMap map; + map.insert(QString("foobarKey"), QVariant(45)); //should be ignored + info.setNotificationParameters(map); + QTest::newRow("Circle Test") << info << 45 + << QString("QGeoAreaMonitorInfo(\"CircleAreaMonitor\", QGeoShape(Circle), " + "persistent: false, expiry: QDateTime(Invalid)) 45"); + + // we ignore any further QDateTime related changes to avoid depending on QDateTime related + // failures in case its QDebug string changes + } + + void debug() + { + QFETCH(QGeoAreaMonitorInfo, info); + QFETCH(int, nextValue); + QFETCH(QString, debugString); + + qInstallMessageHandler(tst_qgeoareamonitorinfo_messageHandler); + qDebug() << info << nextValue; + qInstallMessageHandler(0); + QCOMPARE(tst_qgeoareamonitorinfo_debug, debugString); + } + + void multipleThreads() + { + std::unique_ptr obj( + QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0)); + QVERIFY(obj != nullptr); + QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll")); + + QVERIFY(obj->activeMonitors().isEmpty()); + + LogFilePositionSource *source = new LogFilePositionSource(m_fileData, this); + source->setUpdateInterval(UPDATE_INTERVAL); + obj->setPositionInfoSource(source); + QCOMPARE(obj->positionInfoSource(), source); + + QSignalSpy noDataSpy(source, &LogFilePositionSource::noDataLeft); + QSignalSpy updatesStartedSpy(source, &LogFilePositionSource::updatesStarted); + QSignalSpy updatesStoppedSpy(source, &LogFilePositionSource::updatesStopped); + + // generate threads + const int threadCount = 10; + QList threads; + for (int i = 0; i < threadCount; ++i) { + auto threadObj = new PositionConsumerThread(obj.get(), this); + threadObj->start(); + threads.push_back(threadObj); + } + + // generate objects to monitor + QGeoAreaMonitorInfo infoRectangle("Rectangle"); + infoRectangle.setArea(QGeoRectangle(QGeoCoordinate(-27.65, 153.093), 0.2, 0.2)); + QVERIFY(infoRectangle.isValid()); + QVERIFY(obj->startMonitoring(infoRectangle)); + + QGeoAreaMonitorInfo infoCircle("Circle"); + infoCircle.setArea(QGeoCircle(QGeoCoordinate(-27.70, 153.093), 10000)); + QVERIFY(infoCircle.isValid()); + QVERIFY(obj->startMonitoring(infoCircle)); + + QGeoAreaMonitorInfo singleShot_enter("SingleShot_on_Entered"); + singleShot_enter.setArea(QGeoRectangle(QGeoCoordinate(-27.67, 153.093), 0.2, 0.2)); + QVERIFY(singleShot_enter.isValid()); + QVERIFY(obj->requestUpdate(singleShot_enter, + SIGNAL(areaEntered(QGeoAreaMonitorInfo, QGeoPositionInfo)))); + + QGeoAreaMonitorInfo singleShot_exit("SingleShot_on_Exited"); + singleShot_exit.setArea(QGeoRectangle(QGeoCoordinate(-27.70, 153.093), 0.2, 0.2)); + QVERIFY(singleShot_exit.isValid()); + QVERIFY(obj->requestUpdate(singleShot_exit, + SIGNAL(areaExited(QGeoAreaMonitorInfo, QGeoPositionInfo)))); + + // wait until we read all data + QTRY_COMPARE_WITH_TIMEOUT(noDataSpy.size(), 1, 5000); + + // first request all the threads to terminate + for (int i = 0; i < threadCount; ++i) + threads[i]->stopProcessing(); + + static const int Number_Of_Entered_Events = 6; + static const int Number_Of_Exited_Events = 5; + // wait until each thread is stopped, and compare the result values + for (int i = 0; i < threadCount; ++i) { + threads[i]->wait(); + QCOMPARE(threads[i]->detectedEnterCount(), Number_Of_Entered_Events); + QCOMPARE(threads[i]->detectedExitCount(), Number_Of_Exited_Events); + } + + // Verify that the source started and stopped updates only once. + // This is needed to check that the connection tracking logic in + // connectNotify()/disconnectNotify() is working properly. + QCOMPARE(updatesStartedSpy.size(), 1); + QCOMPARE(updatesStoppedSpy.size(), 1); + } + + void backendProperties() + { + std::unique_ptr obj = std::make_unique(); + + const QString invalidProperty = "SomePropertyName"; + + QCOMPARE(obj->backendProperty(DummyMonitorSource::kTestProperty), 0); + QCOMPARE(obj->backendProperty(invalidProperty), QVariant()); + + QVERIFY(obj->setBackendProperty(DummyMonitorSource::kTestProperty, 10)); + QVERIFY(!obj->setBackendProperty(invalidProperty, 15)); + + QCOMPARE(obj->backendProperty(DummyMonitorSource::kTestProperty), 10); + QCOMPARE(obj->backendProperty(invalidProperty), QVariant()); + } +}; + + +QTEST_GUILESS_MAIN(tst_QGeoAreaMonitorSource) +#include "tst_qgeoareamonitor.moc" diff --git a/tests/auto/qgeocircle/CMakeLists.txt b/tests/auto/qgeocircle/CMakeLists.txt new file mode 100644 index 0000000..18b1266 --- /dev/null +++ b/tests/auto/qgeocircle/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from qgeocircle.pro. + +##################################################################### +## tst_qgeocircle Test: +##################################################################### + +qt_internal_add_test(tst_qgeocircle + SOURCES + tst_qgeocircle.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:qgeocircle.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qgeocircle/tst_qgeocircle.cpp b/tests/auto/qgeocircle/tst_qgeocircle.cpp new file mode 100644 index 0000000..e320c25 --- /dev/null +++ b/tests/auto/qgeocircle/tst_qgeocircle.cpp @@ -0,0 +1,448 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_QGeoCircle : public QObject +{ + Q_OBJECT + +private slots: + void defaultConstructor(); + void centerRadiusConstructor(); + void assignment(); + + void comparison(); + void type(); + + void radius(); + void center(); + + void translate_data(); + void translate(); + + void valid_data(); + void valid(); + + void empty_data(); + void empty(); + + void contains_data(); + void contains(); + + void boundingGeoRectangle_data(); + void boundingGeoRectangle(); + + void extendCircle(); + void extendCircle_data(); + + void areaComparison(); + void areaComparison_data(); + + void boxComparison(); + void boxComparison_data(); + + void hashing(); +}; + +void tst_QGeoCircle::defaultConstructor() +{ + QGeoCircle c; + QVERIFY(!c.center().isValid()); + QCOMPARE(c.radius(), qreal(-1.0)); +} + +void tst_QGeoCircle::centerRadiusConstructor() +{ + QGeoCircle c(QGeoCoordinate(1,1), qreal(50.0)); + QCOMPARE(c.center(), QGeoCoordinate(1,1)); + QCOMPARE(c.radius(), qreal(50.0)); +} + +void tst_QGeoCircle::assignment() +{ + QGeoCircle c1 = QGeoCircle(QGeoCoordinate(10.0, 0.0), 20.0); + QGeoCircle c2 = QGeoCircle(QGeoCoordinate(20.0, 0.0), 30.0); + + QVERIFY(c1 != c2); + + c2 = c1; + QCOMPARE(c2.center(), QGeoCoordinate(10.0, 0.0)); + QCOMPARE(c2.radius(), 20.0); + QCOMPARE(c1, c2); + + c2.setCenter(QGeoCoordinate(30.0, 0.0)); + c2.setRadius(15.0); + QCOMPARE(c1.center(), QGeoCoordinate(10.0, 0.0)); + QCOMPARE(c1.radius(), 20.0); + + // Assign c1 to an area + QGeoShape area = c1; + QCOMPARE(area.type(), c1.type()); + QVERIFY(area == c1); + + // Assign the area back to a bounding circle + QGeoCircle ca = area; + QCOMPARE(ca.center(), c1.center()); + QCOMPARE(ca.radius(), c1.radius()); + + // Check that the copy is not modified when modifying the original. + c1.setCenter(QGeoCoordinate(15.0, 15.0)); + QVERIFY(ca.center() != c1.center()); + QVERIFY(ca != c1); +} + +void tst_QGeoCircle::comparison() +{ + QGeoCircle c1(QGeoCoordinate(1,1), qreal(50.0)); + QGeoCircle c2(QGeoCoordinate(1,1), qreal(50.0)); + QGeoCircle c3(QGeoCoordinate(1,1), qreal(35.0)); + QGeoCircle c4(QGeoCoordinate(1,2), qreal(50.0)); + + QVERIFY(c1 == c2); + QVERIFY(!(c1 != c2)); + + QVERIFY(!(c1 == c3)); + QVERIFY(c1 != c3); + + QVERIFY(!(c1 == c4)); + QVERIFY(c1 != c4); + + QVERIFY(!(c2 == c3)); + QVERIFY(c2 != c3); + + QGeoRectangle b1(QGeoCoordinate(20,20),QGeoCoordinate(10,30)); + QVERIFY(!(c1 == b1)); + QVERIFY(c1 != b1); + + QGeoShape *c2Ptr = &c2; + QVERIFY(c1 == *c2Ptr); + QVERIFY(!(c1 != *c2Ptr)); + + QGeoShape *c3Ptr = &c3; + QVERIFY(!(c1 == *c3Ptr)); + QVERIFY(c1 != *c3Ptr); +} + +void tst_QGeoCircle::type() +{ + QGeoCircle c; + QCOMPARE(c.type(), QGeoShape::CircleType); +} + +void tst_QGeoCircle::radius() +{ + QGeoCircle c; + c.setRadius(1.0); + QCOMPARE(c.radius(), qreal(1.0)); + c.setRadius(5.0); + QCOMPARE(c.radius(), qreal(5.0)); +} + +void tst_QGeoCircle::center() +{ + QGeoCircle c; + c.setCenter(QGeoCoordinate(1,1)); + QCOMPARE(c.center(), QGeoCoordinate(1,1)); + + QGeoShape shape = c; + QCOMPARE(shape.center(), c.center()); + + c.setCenter(QGeoCoordinate(5,10)); + QCOMPARE(c.center(), QGeoCoordinate(5,10)); +} + +void tst_QGeoCircle::translate_data() +{ + QTest::addColumn("center"); + QTest::addColumn("radius"); + QTest::addColumn("lat"); + QTest::addColumn("lon"); + QTest::addColumn("newCenter"); + + QTest::newRow("from 0,0") << QGeoCoordinate(0,0) << qreal(10.0) << + 5.0 << 5.0 << QGeoCoordinate(5.0, 5.0); + QTest::newRow("across 0,0") << QGeoCoordinate(-2, -2) << qreal(20.0) << + 5.0 << 5.0 << QGeoCoordinate(3.0, 3.0); + QTest::newRow("backwards across 0,0") << QGeoCoordinate(5,5) << qreal(50.0) + << -13.0 << 5.0 + << QGeoCoordinate(-8.0, 10.0); +} + +void tst_QGeoCircle::translate() +{ + QFETCH(QGeoCoordinate, center); + QFETCH(qreal, radius); + QFETCH(double, lat); + QFETCH(double, lon); + QFETCH(QGeoCoordinate, newCenter); + + QGeoCircle c(center, radius); + QGeoCircle d = c; + + c.translate(lat, lon); + + QCOMPARE(c.radius(), radius); + QCOMPARE(c.center(), newCenter); + + c = d.translated(lat, lon); + d.setRadius(1.0); + + QCOMPARE(c.radius(), radius); + QCOMPARE(d.center(), center); + QCOMPARE(c.center(), newCenter); +} + +void tst_QGeoCircle::valid_data() +{ + QTest::addColumn("center"); + QTest::addColumn("radius"); + QTest::addColumn("valid"); + + QTest::newRow("default") << QGeoCoordinate() << qreal(-1.0) << false; + QTest::newRow("empty coord") << QGeoCoordinate() << qreal(5.0) << false; + QTest::newRow("NaN coord") << QGeoCoordinate(500, 500) << qreal(5.0) << false; + QTest::newRow("bad radius") << QGeoCoordinate(10, 10) << qreal(-5.0) << false; + QTest::newRow("NaN radius") << QGeoCoordinate(10, 10) << qreal(qQNaN()) << false; + QTest::newRow("zero radius") << QGeoCoordinate(10, 10) << qreal(0.0) << true; + QTest::newRow("good") << QGeoCoordinate(10, 10) << qreal(5.0) << true; +} + +void tst_QGeoCircle::valid() +{ + QFETCH(QGeoCoordinate, center); + QFETCH(qreal, radius); + QFETCH(bool, valid); + + QGeoCircle c(center, radius); + QCOMPARE(c.isValid(), valid); + + QGeoShape area = c; + QCOMPARE(area.isValid(), valid); +} + +void tst_QGeoCircle::empty_data() +{ + QTest::addColumn("center"); + QTest::addColumn("radius"); + QTest::addColumn("empty"); + + QTest::newRow("default") << QGeoCoordinate() << qreal(-1.0) << true; + QTest::newRow("empty coord") << QGeoCoordinate() << qreal(5.0) << true; + QTest::newRow("NaN coord") << QGeoCoordinate(500, 500) << qreal(5.0) << true; + QTest::newRow("bad radius") << QGeoCoordinate(10, 10) << qreal(-5.0) << true; + QTest::newRow("NaN radius") << QGeoCoordinate(10, 10) << qreal(qQNaN()) << true; + QTest::newRow("zero radius") << QGeoCoordinate(10, 10) << qreal(0.0) << true; + QTest::newRow("good") << QGeoCoordinate(10, 10) << qreal(5.0) << false; +} + +void tst_QGeoCircle::empty() +{ + QFETCH(QGeoCoordinate, center); + QFETCH(qreal, radius); + QFETCH(bool, empty); + + QGeoCircle c(center, radius); + QCOMPARE(c.isEmpty(), empty); + + QGeoShape area = c; + QCOMPARE(area.isEmpty(), empty); +} + +void tst_QGeoCircle::contains_data() +{ + QTest::addColumn("center"); + QTest::addColumn("radius"); + QTest::addColumn("probe"); + QTest::addColumn("result"); + + QTest::newRow("own center") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1,1) << true; + QTest::newRow("over the hills") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(30, 40) << false; + QTest::newRow("at 0.5*radius") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00015374,1.00015274) << true; + QTest::newRow("at 0.99*radius") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00077538, 0.99955527) << true; + QTest::newRow("at 1.01*radius") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00071413, 0.99943423) << false; + // TODO: add tests for edge circle cases: cross 1 pole, cross both poles +} + +void tst_QGeoCircle::contains() +{ + QFETCH(QGeoCoordinate, center); + QFETCH(qreal, radius); + QFETCH(QGeoCoordinate, probe); + QFETCH(bool, result); + + QGeoCircle c(center, radius); + QCOMPARE(c.contains(probe), result); + + QGeoShape area = c; + QCOMPARE(area.contains(probe), result); +} + +void tst_QGeoCircle::boundingGeoRectangle_data() +{ + QTest::addColumn("center"); + QTest::addColumn("radius"); + QTest::addColumn("probe"); + QTest::addColumn("result"); + + QTest::newRow("own center") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1,1) << true; + QTest::newRow("over the hills") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(30, 40) << false; + QTest::newRow("at 0.5*radius") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00015374,1.00015274) << true; + QTest::newRow("at 0.99*radius") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00077538, 0.99955527) << true; + QTest::newRow("Outside the box") << QGeoCoordinate(1,1) << qreal(100.0) << + QGeoCoordinate(1.00071413, 0.99903423) << false; + // TODO: add tests for edge circle cases: cross 1 pole, cross both poles +} + +void tst_QGeoCircle::boundingGeoRectangle() +{ + QFETCH(QGeoCoordinate, center); + QFETCH(qreal, radius); + QFETCH(QGeoCoordinate, probe); + QFETCH(bool, result); + + QGeoCircle c(center, radius); + QGeoRectangle box = c.boundingGeoRectangle(); + QCOMPARE(box.contains(probe), result); +} + +void tst_QGeoCircle::extendCircle() +{ + QFETCH(QGeoCircle, circle); + QFETCH(QGeoCoordinate, coord); + QFETCH(bool, containsFirst); + QFETCH(bool, containsExtended); + + QCOMPARE(circle.contains(coord), containsFirst); + circle.extendCircle(coord); + QCOMPARE(circle.contains(coord), containsExtended); + +} + +void tst_QGeoCircle::extendCircle_data() +{ + QTest::addColumn("circle"); + QTest::addColumn("coord"); + QTest::addColumn("containsFirst"); + QTest::addColumn("containsExtended"); + + QGeoCoordinate co1(20.0, 20.0); + + QTest::newRow("own center") + << QGeoCircle(co1, 100) + << QGeoCoordinate(20.0, 20.0) + << true + << true; + QTest::newRow("inside") + << QGeoCircle(co1, 100) + << QGeoCoordinate(20.0001, 20.0001) + << true + << true; + QTest::newRow("far away") + << QGeoCircle(co1, 100) + << QGeoCoordinate(50.0001, 50.0001) + << false + << true; + QTest::newRow("invalid circle") + << QGeoCircle() + << QGeoCoordinate(20.0, 20.0) + << false + << false; + QTest::newRow("invalid coordinate") + << QGeoCircle(co1, 100) + << QGeoCoordinate(99.0, 190.0) + << false + << false; +} + +void tst_QGeoCircle::areaComparison_data() +{ + QTest::addColumn("area"); + QTest::addColumn("circle"); + QTest::addColumn("equal"); + + QGeoCircle c1(QGeoCoordinate(10.0, 0.0), 10.0); + QGeoCircle c2(QGeoCoordinate(20.0, 10.0), 20.0); + QGeoRectangle b(QGeoCoordinate(10.0, 0.0), QGeoCoordinate(0.0, 10.0)); + + QTest::newRow("default constructed") << QGeoShape() << QGeoCircle() << false; + QTest::newRow("c1 c1") << QGeoShape(c1) << c1 << true; + QTest::newRow("c1 c2") << QGeoShape(c1) << c2 << false; + QTest::newRow("c2 c1") << QGeoShape(c2) << c1 << false; + QTest::newRow("c2 c2") << QGeoShape(c2) << c2 << true; + QTest::newRow("b c1") << QGeoShape(b) << c1 << false; +} + +void tst_QGeoCircle::areaComparison() +{ + QFETCH(QGeoShape, area); + QFETCH(QGeoCircle, circle); + QFETCH(bool, equal); + + QCOMPARE((area == circle), equal); + QCOMPARE((area != circle), !equal); + + QCOMPARE((circle == area), equal); + QCOMPARE((circle != area), !equal); +} + +void tst_QGeoCircle::boxComparison_data() +{ + QTest::addColumn("box"); + QTest::addColumn("circle"); + QTest::addColumn("equal"); + + QGeoCircle c(QGeoCoordinate(10.0, 0.0), 10.0); + QGeoRectangle b(QGeoCoordinate(10.0, 0.0), QGeoCoordinate(0.0, 10.0)); + + QTest::newRow("default constructed") << QGeoRectangle() << QGeoCircle() << false; + QTest::newRow("b c") << b << c << false; +} + +void tst_QGeoCircle::boxComparison() +{ + QFETCH(QGeoRectangle, box); + QFETCH(QGeoCircle, circle); + QFETCH(bool, equal); + + QCOMPARE((box == circle), equal); + QCOMPARE((box != circle), !equal); + + QCOMPARE((circle == box), equal); + QCOMPARE((circle != box), !equal); +} + +void tst_QGeoCircle::hashing() +{ + const QGeoCircle circle(QGeoCoordinate(1, 1), 10); + const size_t circleHash = qHash(circle); + + QGeoCircle otherCenterCircle = circle; + otherCenterCircle.setCenter(QGeoCoordinate(1, 2)); + QVERIFY(qHash(otherCenterCircle) != circleHash); + + QGeoCircle otherRadiusCircle = circle; + otherRadiusCircle.setRadius(100); + QVERIFY(qHash(otherRadiusCircle) != circleHash); + + // Do not assign, so that they do not share same d_ptr + QGeoCircle similarCircle(QGeoCoordinate(1, 1), 10); + QCOMPARE(qHash(similarCircle), circleHash); +} + +QTEST_MAIN(tst_QGeoCircle) +#include "tst_qgeocircle.moc" diff --git a/tests/auto/qgeocoordinate/CMakeLists.txt b/tests/auto/qgeocoordinate/CMakeLists.txt new file mode 100644 index 0000000..dd216a0 --- /dev/null +++ b/tests/auto/qgeocoordinate/CMakeLists.txt @@ -0,0 +1,14 @@ +# Generated from qgeocoordinate.pro. + +##################################################################### +## tst_qgeocoordinate Test: +##################################################################### + +qt_internal_add_test(tst_qgeocoordinate + SOURCES + ../utils/qlocationtestutils.cpp ../utils/qlocationtestutils_p.h + tst_qgeocoordinate.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) diff --git a/tests/auto/qgeocoordinate/tst_qgeocoordinate.cpp b/tests/auto/qgeocoordinate/tst_qgeocoordinate.cpp new file mode 100644 index 0000000..0774f89 --- /dev/null +++ b/tests/auto/qgeocoordinate/tst_qgeocoordinate.cpp @@ -0,0 +1,975 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include "../utils/qlocationtestutils_p.h" + +#include +#include + +#include +#include + +#include + +QT_USE_NAMESPACE + +Q_DECLARE_METATYPE(QGeoCoordinate::CoordinateFormat) +Q_DECLARE_METATYPE(QGeoCoordinate::CoordinateType) + +static const QGeoCoordinate BRISBANE(-27.46758, 153.027892); +static const QGeoCoordinate MELBOURNE(-37.814251, 144.963169); +static const QGeoCoordinate LONDON(51.500152, -0.126236); +static const QGeoCoordinate NEW_YORK(40.71453, -74.00713); +static const QGeoCoordinate NORTH_POLE(90, 0); +static const QGeoCoordinate SOUTH_POLE(-90, 0); + +static const QChar DEGREES_SYMB(0x00B0); + + +QByteArray tst_qgeocoordinate_debug; + +void tst_qgeocoordinate_messageHandler(QtMsgType type, const QMessageLogContext &, const QString &msg) +{ + switch (type) { + case QtDebugMsg : + tst_qgeocoordinate_debug = msg.toLocal8Bit(); + break; + default: + break; + } +} + + +class tst_QGeoCoordinate : public QObject +{ + Q_OBJECT + +private: + enum TestDataType { + Latitude, + Longitude, + Altitude + }; + +private slots: + void initTestcase() + { + qRegisterMetaType(); + } + + void constructor() + { + QGeoCoordinate c; + QVERIFY(!c.isValid()); + QCOMPARE(c, QGeoCoordinate()); + } + + void constructor_lat_long() + { + QFETCH(double, latitude); + QFETCH(double, longitude); + QFETCH(QGeoCoordinate::CoordinateType, type); + + QGeoCoordinate c(latitude, longitude); + QCOMPARE(c.type(), type); + if (type != QGeoCoordinate::InvalidCoordinate) { + QVERIFY(c.isValid()); + QCOMPARE(c.latitude(), latitude); + QCOMPARE(c.longitude(), longitude); + } else { + QVERIFY(!c.isValid()); + QVERIFY(c.latitude() != latitude); + QVERIFY(c.longitude() != longitude); + } + } + + void constructor_lat_long_data() + { + QTest::addColumn("latitude"); + QTest::addColumn("longitude"); + QTest::addColumn("type"); + + QTest::newRow("both zero") << 0.0 << 0.0 << QGeoCoordinate::Coordinate2D; + QTest::newRow("both negative") << -1.0 << -1.0 << QGeoCoordinate::Coordinate2D; + QTest::newRow("both positive") << 1.0 << 1.0 << QGeoCoordinate::Coordinate2D; + QTest::newRow("latitude negative") << -1.0 << 1.0 << QGeoCoordinate::Coordinate2D; + QTest::newRow("longitude negative") << 1.0 << -1.0 << QGeoCoordinate::Coordinate2D; + + QTest::newRow("both too high") << 90.1 << 180.1 << QGeoCoordinate::InvalidCoordinate; + QTest::newRow("latitude too high") << 90.1 << 0.1 << QGeoCoordinate::InvalidCoordinate; + QTest::newRow("longitude too high") << 0.1 << 180.1 << QGeoCoordinate::InvalidCoordinate; + + QTest::newRow("both too low") << -90.1 << -180.1 << QGeoCoordinate::InvalidCoordinate; + QTest::newRow("latitude too low") << -90.1 << 0.1 << QGeoCoordinate::InvalidCoordinate; + QTest::newRow("longitude too low") << 0.1 << -180.1 << QGeoCoordinate::InvalidCoordinate; + + QTest::newRow("both not too high") << 90.0 << 180.0 << QGeoCoordinate::Coordinate2D; + QTest::newRow("both not too low") << -90.0 << -180.0 << QGeoCoordinate::Coordinate2D; + + QTest::newRow("latitude too high and longitude too low") << 90.1 << -180.1 << QGeoCoordinate::InvalidCoordinate; + QTest::newRow("latitude too low and longitude too high") << -90.1 << 180.1 << QGeoCoordinate::InvalidCoordinate; + } + + void constructor_lat_long_alt() + { + QFETCH(double, latitude); + QFETCH(double, longitude); + QFETCH(double, altitude); + QFETCH(QGeoCoordinate::CoordinateType, type); + + QGeoCoordinate c(latitude, longitude, altitude); + QCOMPARE(c.type(), type); + if (type != QGeoCoordinate::InvalidCoordinate) { + QCOMPARE(c.latitude(), latitude); + QCOMPARE(c.longitude(), longitude); + QCOMPARE(c.altitude(), altitude); + } else { + QVERIFY(!c.isValid()); + QVERIFY(c.latitude() != latitude); + QVERIFY(c.longitude() != longitude); + QVERIFY(c.altitude() != altitude); + } + } + + void constructor_lat_long_alt_data() + { + QTest::addColumn("latitude"); + QTest::addColumn("longitude"); + QTest::addColumn("altitude"); + QTest::addColumn("type"); + + QTest::newRow("all zero") << 0.0 << 0.0 << 0.0 << QGeoCoordinate::Coordinate3D; + QTest::newRow("all negative") << -1.0 << -1.0 << -2.0 << QGeoCoordinate::Coordinate3D; + QTest::newRow("all positive") << 1.0 << 1.0 << 4.0 << QGeoCoordinate::Coordinate3D; + + QTest::newRow("latitude negative") << -1.0 << 1.0 << 1.0 << QGeoCoordinate::Coordinate3D; + QTest::newRow("longitude negative") << 1.0 << -1.0 << 1.0 << QGeoCoordinate::Coordinate3D; + QTest::newRow("altitude negative") << 1.0 << 1.0 << -1.0 << QGeoCoordinate::Coordinate3D; + + QTest::newRow("altitude not too high") << 1.0 << 1.0 << DBL_MAX << QGeoCoordinate::Coordinate3D; + QTest::newRow("altitude not too low") << 1.0 << 1.0 << DBL_MIN << QGeoCoordinate::Coordinate3D; + + QTest::newRow("all not too high") << 90.0 << 180.0 << DBL_MAX << QGeoCoordinate::Coordinate3D; + QTest::newRow("all not too low") << -90.0 << -180.0 << DBL_MIN << QGeoCoordinate::Coordinate3D; + + QTest::newRow("all too high") << 90.1 << 180.1 << DBL_MAX << QGeoCoordinate::InvalidCoordinate; + QTest::newRow("all too low") << -90.1 << -180.1 << DBL_MIN << QGeoCoordinate::InvalidCoordinate; + } + + void copy_constructor() + { + QFETCH(QGeoCoordinate, c); + + QGeoCoordinate copy(c); + QCOMPARE(copy.type(), c.type()); + if (c.type() != QGeoCoordinate::InvalidCoordinate) { + QCOMPARE(copy.latitude(), c.latitude()); + QCOMPARE(copy.longitude(), c.longitude()); + if (c.type() == QGeoCoordinate::Coordinate3D) + QCOMPARE(copy.altitude(), c.altitude()); + } + } + + void copy_constructor_data() + { + QTest::addColumn("c"); + + QTest::newRow("no argument") << QGeoCoordinate(); + QTest::newRow("latitude, longitude arguments all zero") << QGeoCoordinate(0.0, 0.0); + + QTest::newRow("latitude, longitude arguments not too high") << QGeoCoordinate(90.0, 180.0); + QTest::newRow("latitude, longitude arguments not too low") << QGeoCoordinate(-90.0, -180.0); + QTest::newRow("latitude, longitude arguments too high") << QGeoCoordinate(90.1, 180.1); + QTest::newRow("latitude, longitude arguments too low") << QGeoCoordinate(-90.1, -180.1); + + QTest::newRow("latitude, longitude, altitude arguments all zero") << QGeoCoordinate(0.0, 0.0, 0.0); + QTest::newRow("latitude, longitude, altitude arguments not too high values") << QGeoCoordinate(90.0, 180.0, DBL_MAX); + QTest::newRow("latitude, longitude, altitude arguments not too low values") << QGeoCoordinate(-90.0, -180.0, DBL_MIN); + + QTest::newRow("latitude, longitude, altitude arguments too high latitude & longitude") << QGeoCoordinate(90.1, 180.1, DBL_MAX); + QTest::newRow("latitude, longitude, altitude arguments too low latitude & longitude") << QGeoCoordinate(-90.1, -180.1, DBL_MAX); + } + + void move_constructor() + { + QFETCH(QGeoCoordinate, c); + + const QGeoCoordinate coordinateCopy = c; + QCOMPARE(std::move(c), coordinateCopy); + } + + void move_constructor_data() + { + copy_constructor_data(); + } + + void destructor() + { + QGeoCoordinate *coordinate; + + coordinate = new QGeoCoordinate(); + delete coordinate; + + coordinate = new QGeoCoordinate(0.0, 0.0); + delete coordinate; + + coordinate = new QGeoCoordinate(0.0, 0.0, 0.0); + delete coordinate; + + coordinate = new QGeoCoordinate(90.0, 180.0); + delete coordinate; + + coordinate = new QGeoCoordinate(-90.0, -180.0); + delete coordinate; + + coordinate = new QGeoCoordinate(90.1, 180.1); + delete coordinate; + + coordinate = new QGeoCoordinate(-90.1, -180.1); + delete coordinate; + } + + void destructor2() + { + QFETCH(QGeoCoordinate, c); + QGeoCoordinate *coordinate = new QGeoCoordinate(c); + delete coordinate; + } + + void destructor2_data() + { + copy_constructor_data(); + } + + void assign() + { + QFETCH(QGeoCoordinate, c); + + QGeoCoordinate c1 = c; + QCOMPARE(c.type(), c1.type()); + if (c.isValid()) { + QCOMPARE(c.latitude(), c.latitude()); + QCOMPARE(c.longitude(), c.longitude()); + if (c.type() == QGeoCoordinate::Coordinate3D) + QCOMPARE(c.altitude(), c.altitude()); + } + } + + void assign_data() + { + copy_constructor_data(); + } + + void move_assign() + { + QFETCH(QGeoCoordinate, c); + + QGeoCoordinate copy = c; + + QGeoCoordinate otherCoordinate; + otherCoordinate = std::move(c); + QCOMPARE(otherCoordinate, copy); + + // check that (move)assinging to a moved-from object is fine + c = std::move(copy); + QCOMPARE(c, otherCoordinate); + } + + void move_assign_data() + { + copy_constructor_data(); + } + + void comparison() + { + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(bool, result); + + QCOMPARE(c1 == c2, result); + QVariant v1 = QVariant::fromValue(c1); + QVariant v2 = QVariant::fromValue(c2); + QCOMPARE(v2 == v1, result); + } + + void comparison_data() + { + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("result"); + + QTest::newRow("Invalid != BRISBANE") + << QGeoCoordinate(-190,-1000) << BRISBANE << false; + QTest::newRow("BRISBANE != MELBOURNE") + << BRISBANE << MELBOURNE << false; + QTest::newRow("equal") + << BRISBANE << BRISBANE << true; + QTest::newRow("LONDON != uninitialized data") + << LONDON << QGeoCoordinate() << false; + QTest::newRow("uninitialized data == uninitialized data") + << QGeoCoordinate() << QGeoCoordinate() << true; + QTest::newRow("invalid == same invalid") + << QGeoCoordinate(-190,-1000) << QGeoCoordinate(-190,-1000) << true; + QTest::newRow("invalid == different invalid") + << QGeoCoordinate(-190,-1000) << QGeoCoordinate(190,1000) << true; + QTest::newRow("valid != another valid") + << QGeoCoordinate(-90,-180) << QGeoCoordinate(-45,+45) << false; + QTest::newRow("valid == same valid") + << QGeoCoordinate(-90,-180) << QGeoCoordinate(-90,-180) << true; + QTest::newRow("different longitudes at north pole are equal") + << QGeoCoordinate(90, 0) << QGeoCoordinate(90, 45) << true; + QTest::newRow("different longitudes at south pole are equal") + << QGeoCoordinate(-90, 0) << QGeoCoordinate(-90, 45) << true; + } + + void type() + { + QFETCH(QGeoCoordinate, c); + QFETCH(QGeoCoordinate::CoordinateType, type); + + QCOMPARE(c.type(), type); + } + + void type_data() + { + QTest::addColumn("c"); + QTest::addColumn("type"); + + QGeoCoordinate c; + + QTest::newRow("no values set") << c << QGeoCoordinate::InvalidCoordinate; + + c.setAltitude(1.0); + QTest::newRow("only altitude is set") << c << QGeoCoordinate::InvalidCoordinate; + + c.setLongitude(1.0); + QTest::newRow("only latitude and altitude is set") << c << QGeoCoordinate::InvalidCoordinate; + + c.setLatitude(-1.0); + QTest::newRow("all valid: 3D Coordinate") << c << QGeoCoordinate::Coordinate3D; + + c.setLatitude(-90.1); + QTest::newRow("too low latitude and valid longitude") << c << QGeoCoordinate::InvalidCoordinate; + + c.setLongitude(-180.1); + c.setLatitude(90.0); + QTest::newRow("valid latitude and too low longitude") << c << QGeoCoordinate::InvalidCoordinate; + + c.setLatitude(90.1); + c.setLongitude(-180.0); + QTest::newRow("too high latitude and valid longitude") << c << QGeoCoordinate::InvalidCoordinate; + + c.setLatitude(-90.0); + c.setLongitude(180.1); + QTest::newRow("valid latitude and too high longitude") << c << QGeoCoordinate::InvalidCoordinate; + } + + void valid() + { + QFETCH(QGeoCoordinate, c); + QCOMPARE(c.isValid(), c.type() != QGeoCoordinate::InvalidCoordinate); + } + + void valid_data() + { + type_data(); + } + + void addDataValues(TestDataType type) + { + QTest::addColumn("value"); + QTest::addColumn("valid"); + + QTest::newRow("negative") << -1.0 << true; + QTest::newRow("zero") << 0.0 << true; + QTest::newRow("positive") << 1.0 << true; + + switch (type) { + case Latitude: + QTest::newRow("too low") << -90.1 << false; + QTest::newRow("not too low") << -90.0 << true; + QTest::newRow("not too hight") << 90.0 << true; + QTest::newRow("too high") << 90.1; + break; + case Longitude: + QTest::newRow("too low") << -180.1 << false; + QTest::newRow("not too low") << -180.0 << true; + QTest::newRow("not too hight") << 180.0 << true; + QTest::newRow("too high") << 180.1; + break; + case Altitude: + break; + } + } + + void latitude() + { + QFETCH(double, value); + QGeoCoordinate c; + c.setLatitude(value); + QCOMPARE(c.latitude(), value); + + QGeoCoordinate c2 = c; + QCOMPARE(c.latitude(), value); + QCOMPARE(c2, c); + } + void latitude_data() { addDataValues(Latitude); } + + void longitude() + { + QFETCH(double, value); + QGeoCoordinate c; + c.setLongitude(value); + QCOMPARE(c.longitude(), value); + + QGeoCoordinate c2 = c; + QCOMPARE(c.longitude(), value); + QCOMPARE(c2, c); + } + void longitude_data() { addDataValues(Longitude); } + + void altitude() + { + QFETCH(double, value); + QGeoCoordinate c; + c.setAltitude(value); + QCOMPARE(c.altitude(), value); + + QGeoCoordinate c2 = c; + QCOMPARE(c.altitude(), value); + QCOMPARE(c2, c); + } + void altitude_data() { addDataValues(Altitude); } + + void distanceTo() + { + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(qreal, distance); + + QCOMPARE(QString::number(c1.distanceTo(c2)), QString::number(distance)); + } + + void distanceTo_data() + { + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("distance"); + + QTest::newRow("invalid coord 1") + << QGeoCoordinate() << BRISBANE << qreal(0.0); + QTest::newRow("invalid coord 2") + << BRISBANE << QGeoCoordinate() << qreal(0.0); + QTest::newRow("brisbane -> melbourne") + << BRISBANE << MELBOURNE << qreal(1374820.1618767744); + QTest::newRow("london -> new york") + << LONDON << NEW_YORK << qreal(5570538.4987236429); + QTest::newRow("north pole -> south pole") + << NORTH_POLE << SOUTH_POLE << qreal(20015109.4154876769); + } + + void azimuthTo() + { + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(qreal, azimuth); + + qreal result = c1.azimuthTo(c2); + QVERIFY(result >= 0.0); + QVERIFY(result < 360.0); + QCOMPARE(QString::number(result), QString::number(azimuth)); + } + + void azimuthTo_data() + { + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("azimuth"); + + QTest::newRow("invalid coord 1") + << QGeoCoordinate() << BRISBANE << qreal(0.0); + QTest::newRow("invalid coord 2") + << BRISBANE << QGeoCoordinate() << qreal(0.0); + QTest::newRow("brisbane -> melbourne") + << BRISBANE << MELBOURNE << qreal(211.1717286649); + QTest::newRow("london -> new york") + << LONDON << NEW_YORK << qreal(288.3388804508); + QTest::newRow("north pole -> south pole") + << NORTH_POLE << SOUTH_POLE << qreal(180.0); + QTest::newRow("Almost 360degrees bearing") + << QGeoCoordinate(0.5,45.0,0.0) << QGeoCoordinate(0.5,-134.9999651,0.0) << qreal(359.998); + } + + void atDistanceAndAzimuth() + { + QFETCH(QGeoCoordinate, origin); + QFETCH(qreal, distance); + QFETCH(qreal, azimuth); + QFETCH(QGeoCoordinate, result); + + QCOMPARE(result, origin.atDistanceAndAzimuth(distance, azimuth)); + } + + void atDistanceAndAzimuth_data() + { + QTest::addColumn("origin"); + QTest::addColumn("distance"); + QTest::addColumn("azimuth"); + QTest::addColumn("result"); + + QTest::newRow("invalid coord") + << QGeoCoordinate() + << qreal(1000.0) + << qreal(10.0) + << QGeoCoordinate(); + if (sizeof(qreal) == sizeof(double)) { + QTest::newRow("brisbane -> melbourne") + << BRISBANE + << qreal(1374820.1618767744) + << qreal(211.1717286649) + << MELBOURNE; + QTest::newRow("london -> new york") + << LONDON + << qreal(5570538.4987236429) + << qreal(288.3388804508) + << NEW_YORK; + QTest::newRow("north pole -> south pole") + << NORTH_POLE + << qreal(20015109.4154876769) + << qreal(180.0) + << SOUTH_POLE; + } else { + QTest::newRow("brisbane -> melbourne") + << BRISBANE + << qreal(1374820.1618767744) + << qreal(211.1717286649) + << QGeoCoordinate(-37.8142515084775, 144.963170622944); + QTest::newRow("london -> new york") + << LONDON + << qreal(5570538.4987236429) + << qreal(288.3388804508) + << QGeoCoordinate(40.7145220608416, -74.0071216045375); + QTest::newRow("north pole -> south pole") + << NORTH_POLE + << qreal(20015109.4154876769) + << qreal(180.0) + << QGeoCoordinate(-89.9999947369857, -90.0); + } + } + + void degreesToString() + { + QFETCH(QGeoCoordinate, coord); + QFETCH(QGeoCoordinate::CoordinateFormat, format); + QFETCH(QString, string); + + QCOMPARE(coord.toString(format), string); + } + + void degreesToString_data() + { + QTest::addColumn("coord"); + QTest::addColumn("format"); + QTest::addColumn("string"); + + QGeoCoordinate northEast(27.46758, 153.027892); + QGeoCoordinate northEastWithAlt(27.46758, 153.027892, 28.23411); + QGeoCoordinate southEast(-27.46758, 153.027892); + QGeoCoordinate southEastWithAlt(-27.46758, 153.027892, 28.23411); + QGeoCoordinate northWest(27.46758, -153.027892); + QGeoCoordinate northWestWithAlt(27.46758, -153.027892, 28.23411); + QGeoCoordinate southWest(-27.46758, -153.027892); + QGeoCoordinate southWestWithAlt(-27.46758, -153.027892, 28.23411); + + QGeoCoordinate empty; + QGeoCoordinate toohigh(90.1, 180.1); + QGeoCoordinate toolow(-90.1, -180.1); + QGeoCoordinate zeroLatLong(0.0, 0.0); + QGeoCoordinate allZero(0.0, 0.0, 0.0); + + QTest::newRow("empty, dd, no hemisphere") + << empty << QGeoCoordinate::Degrees + << QString(); + QTest::newRow("empty, dd, hemisphere") + << empty << QGeoCoordinate::DegreesWithHemisphere + << QString(); + QTest::newRow("empty, dm, no hemisphere") + << empty << QGeoCoordinate::DegreesMinutes + << QString(); + QTest::newRow("empty, dm, hemisphere") + << empty << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString(); + QTest::newRow("empty, dms, no hemisphere") + << empty << QGeoCoordinate::DegreesMinutesSeconds + << QString(); + QTest::newRow("empty, dms, hemisphere") + << empty << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString(); + + QTest::newRow("too low, dd, no hemisphere") + << toolow << QGeoCoordinate::Degrees + << QString(); + QTest::newRow("too low, dd, hemisphere") + << toolow << QGeoCoordinate::DegreesWithHemisphere + << QString(); + QTest::newRow("too low, dm, no hemisphere") + << toolow << QGeoCoordinate::DegreesMinutes + << QString(); + QTest::newRow("too low, dm, hemisphere") + << toolow << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString(); + QTest::newRow("too low, dms, no hemisphere") + << toolow << QGeoCoordinate::DegreesMinutesSeconds + << QString(); + QTest::newRow("too low, dms, hemisphere") + << toolow << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString(); + + QTest::newRow("too high, dd, no hemisphere") + << toohigh << QGeoCoordinate::Degrees + << QString(); + QTest::newRow("too high, dd, hemisphere") + << toohigh << QGeoCoordinate::DegreesWithHemisphere + << QString(); + QTest::newRow("too high, dm, no hemisphere") + << toohigh << QGeoCoordinate::DegreesMinutes + << QString(); + QTest::newRow("too high, dm, hemisphere") + << toohigh << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString(); + QTest::newRow("too high, dms, no hemisphere") + << toohigh << QGeoCoordinate::DegreesMinutesSeconds + << QString(); + QTest::newRow("too high, dms, hemisphere") + << toohigh << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString(); + + QTest::newRow("zeroLatLong, dd, no hemisphere") + << zeroLatLong << QGeoCoordinate::Degrees + << QString("0.00000%1, 0.00000%1").arg(DEGREES_SYMB); + QTest::newRow("zeroLatLong, dd, hemisphere") + << zeroLatLong << QGeoCoordinate::DegreesWithHemisphere + << QString("0.00000%1, 0.00000%1").arg(DEGREES_SYMB); + QTest::newRow("zeroLatLong, dm, no hemisphere") + << zeroLatLong << QGeoCoordinate::DegreesMinutes + << QString("0%1 0.000', 0%1 0.000'").arg(DEGREES_SYMB); + QTest::newRow("zeroLatLong, dm, hemisphere") + << zeroLatLong << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("0%1 0.000', 0%1 0.000'").arg(DEGREES_SYMB); + QTest::newRow("zeroLatLong, dms, no hemisphere") + << zeroLatLong << QGeoCoordinate::DegreesMinutesSeconds + << QString("0%1 0' 0.0\", 0%1 0' 0.0\"").arg(DEGREES_SYMB); + QTest::newRow("zeroLatLong, dms, hemisphere") + << zeroLatLong << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("0%1 0' 0.0\", 0%1 0' 0.0\"").arg(DEGREES_SYMB); + + QTest::newRow("allZero, dd, no hemisphere") + << allZero << QGeoCoordinate::Degrees + << QString("0.00000%1, 0.00000%1, 0m").arg(DEGREES_SYMB); + QTest::newRow("allZero, dd, hemisphere") + << allZero << QGeoCoordinate::DegreesWithHemisphere + << QString("0.00000%1, 0.00000%1, 0m").arg(DEGREES_SYMB); + QTest::newRow("allZero, dm, no hemisphere") + << allZero << QGeoCoordinate::DegreesMinutes + << QString("0%1 0.000', 0%1 0.000', 0m").arg(DEGREES_SYMB); + QTest::newRow("allZero, dm, hemisphere") + << allZero << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("0%1 0.000', 0%1 0.000', 0m").arg(DEGREES_SYMB); + QTest::newRow("allZero, dms, no hemisphere") + << allZero << QGeoCoordinate::DegreesMinutesSeconds + << QString("0%1 0' 0.0\", 0%1 0' 0.0\", 0m").arg(DEGREES_SYMB); + QTest::newRow("allZero, dms, hemisphere") + << allZero << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("0%1 0' 0.0\", 0%1 0' 0.0\", 0m").arg(DEGREES_SYMB); + + QTest::newRow("NE, dd, no hemisphere") + << northEast << QGeoCoordinate::Degrees + << QString("27.46758%1, 153.02789%1").arg(DEGREES_SYMB); + QTest::newRow("NE, dd, hemisphere") + << northEast << QGeoCoordinate::DegreesWithHemisphere + << QString("27.46758%1 N, 153.02789%1 E").arg(DEGREES_SYMB); + QTest::newRow("NE, dm, no hemisphere") + << northEast << QGeoCoordinate::DegreesMinutes + << QString("27%1 28.055', 153%1 1.674'").arg(DEGREES_SYMB); + QTest::newRow("NE, dm, hemisphere") + << northEast << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("27%1 28.055' N, 153%1 1.674' E").arg(DEGREES_SYMB); + QTest::newRow("NE, dms, no hemisphere") + << northEast << QGeoCoordinate::DegreesMinutesSeconds + << QString("27%1 28' 3.3\", 153%1 1' 40.4\"").arg(DEGREES_SYMB); + QTest::newRow("NE, dms, hemisphere") + << northEast << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("27%1 28' 3.3\" N, 153%1 1' 40.4\" E").arg(DEGREES_SYMB); + + QTest::newRow("NE with alt, dd, no hemisphere") + << northEastWithAlt << QGeoCoordinate::Degrees + << QString("27.46758%1, 153.02789%1, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NE with alt, dd, hemisphere") + << northEastWithAlt << QGeoCoordinate::DegreesWithHemisphere + << QString("27.46758%1 N, 153.02789%1 E, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NE with alt, dm, no hemisphere") + << northEastWithAlt << QGeoCoordinate::DegreesMinutes + << QString("27%1 28.055', 153%1 1.674', 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NE with alt, dm, hemisphere") + << northEastWithAlt << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("27%1 28.055' N, 153%1 1.674' E, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NE with alt, dms, no hemisphere") + << northEastWithAlt << QGeoCoordinate::DegreesMinutesSeconds + << QString("27%1 28' 3.3\", 153%1 1' 40.4\", 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NE with alt, dms, hemisphere") + << northEastWithAlt << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("27%1 28' 3.3\" N, 153%1 1' 40.4\" E, 28.2341m").arg(DEGREES_SYMB); + + QTest::newRow("SE, dd, no hemisphere") + << southEast << QGeoCoordinate::Degrees + << QString("-27.46758%1, 153.02789%1").arg(DEGREES_SYMB); + QTest::newRow("SE, dd, hemisphere") + << southEast << QGeoCoordinate::DegreesWithHemisphere + << QString("27.46758%1 S, 153.02789%1 E").arg(DEGREES_SYMB); + QTest::newRow("SE, dm, no hemisphere") + << southEast << QGeoCoordinate::DegreesMinutes + << QString("-27%1 28.055', 153%1 1.674'").arg(DEGREES_SYMB); + QTest::newRow("SE, dm, hemisphere") + << southEast << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("27%1 28.055' S, 153%1 1.674' E").arg(DEGREES_SYMB); + QTest::newRow("SE, dms, no hemisphere") + << southEast << QGeoCoordinate::DegreesMinutesSeconds + << QString("-27%1 28' 3.3\", 153%1 1' 40.4\"").arg(DEGREES_SYMB); + QTest::newRow("SE, dms, hemisphere") + << southEast << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("27%1 28' 3.3\" S, 153%1 1' 40.4\" E").arg(DEGREES_SYMB); + + QTest::newRow("SE with alt, dd, no hemisphere, 28.2341m") + << southEastWithAlt << QGeoCoordinate::Degrees + << QString("-27.46758%1, 153.02789%1, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SE with alt, dd, hemisphere, 28.2341m") + << southEastWithAlt << QGeoCoordinate::DegreesWithHemisphere + << QString("27.46758%1 S, 153.02789%1 E, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SE with alt, dm, no hemisphere, 28.2341m") + << southEastWithAlt << QGeoCoordinate::DegreesMinutes + << QString("-27%1 28.055', 153%1 1.674', 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SE with alt, dm, hemisphere, 28.2341m") + << southEastWithAlt << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("27%1 28.055' S, 153%1 1.674' E, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SE with alt, dms, no hemisphere, 28.2341m") + << southEastWithAlt << QGeoCoordinate::DegreesMinutesSeconds + << QString("-27%1 28' 3.3\", 153%1 1' 40.4\", 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SE with alt, dms, hemisphere, 28.2341m") + << southEastWithAlt << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("27%1 28' 3.3\" S, 153%1 1' 40.4\" E, 28.2341m").arg(DEGREES_SYMB);; + + QTest::newRow("NW, dd, no hemisphere") + << northWest << QGeoCoordinate::Degrees + << QString("27.46758%1, -153.02789%1").arg(DEGREES_SYMB); + QTest::newRow("NW, dd, hemisphere") + << northWest << QGeoCoordinate::DegreesWithHemisphere + << QString("27.46758%1 N, 153.02789%1 W").arg(DEGREES_SYMB); + QTest::newRow("NW, dm, no hemisphere") + << northWest << QGeoCoordinate::DegreesMinutes + << QString("27%1 28.055', -153%1 1.674'").arg(DEGREES_SYMB); + QTest::newRow("NW, dm, hemisphere") + << northWest << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("27%1 28.055' N, 153%1 1.674' W").arg(DEGREES_SYMB); + QTest::newRow("NW, dms, no hemisphere") + << northWest << QGeoCoordinate::DegreesMinutesSeconds + << QString("27%1 28' 3.3\", -153%1 1' 40.4\"").arg(DEGREES_SYMB); + QTest::newRow("NW, dms, hemisphere") + << northWest << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("27%1 28' 3.3\" N, 153%1 1' 40.4\" W").arg(DEGREES_SYMB); + + QTest::newRow("NW with alt, dd, no hemisphere, 28.2341m") + << northWestWithAlt << QGeoCoordinate::Degrees + << QString("27.46758%1, -153.02789%1, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NW with alt, dd, hemisphere, 28.2341m") + << northWestWithAlt << QGeoCoordinate::DegreesWithHemisphere + << QString("27.46758%1 N, 153.02789%1 W, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NW with alt, dm, no hemisphere, 28.2341m") + << northWestWithAlt << QGeoCoordinate::DegreesMinutes + << QString("27%1 28.055', -153%1 1.674', 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NW with alt, dm, hemisphere, 28.2341m") + << northWestWithAlt << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("27%1 28.055' N, 153%1 1.674' W, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NW with alt, dms, no hemisphere, 28.2341m") + << northWestWithAlt << QGeoCoordinate::DegreesMinutesSeconds + << QString("27%1 28' 3.3\", -153%1 1' 40.4\", 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("NW with alt, dms, hemisphere, 28.2341m") + << northWestWithAlt << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("27%1 28' 3.3\" N, 153%1 1' 40.4\" W, 28.2341m").arg(DEGREES_SYMB); + + QTest::newRow("SW, dd, no hemisphere") + << southWest << QGeoCoordinate::Degrees + << QString("-27.46758%1, -153.02789%1").arg(DEGREES_SYMB); + QTest::newRow("SW, dd, hemisphere") + << southWest << QGeoCoordinate::DegreesWithHemisphere + << QString("27.46758%1 S, 153.02789%1 W").arg(DEGREES_SYMB); + QTest::newRow("SW, dm, no hemisphere") + << southWest << QGeoCoordinate::DegreesMinutes + << QString("-27%1 28.055', -153%1 1.674'").arg(DEGREES_SYMB); + QTest::newRow("SW, dm, hemisphere") + << southWest << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("27%1 28.055' S, 153%1 1.674' W").arg(DEGREES_SYMB); + QTest::newRow("SW, dms, no hemisphere") + << southWest << QGeoCoordinate::DegreesMinutesSeconds + << QString("-27%1 28' 3.3\", -153%1 1' 40.4\"").arg(DEGREES_SYMB); + QTest::newRow("SW, dms, hemisphere") + << southWest << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("27%1 28' 3.3\" S, 153%1 1' 40.4\" W").arg(DEGREES_SYMB); + + QTest::newRow("SW with alt, dd, no hemisphere, 28.2341m") + << southWestWithAlt << QGeoCoordinate::Degrees + << QString("-27.46758%1, -153.02789%1, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SW with alt, dd, hemisphere, 28.2341m") + << southWestWithAlt << QGeoCoordinate::DegreesWithHemisphere + << QString("27.46758%1 S, 153.02789%1 W, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SW with alt, dm, no hemisphere, 28.2341m") + << southWestWithAlt << QGeoCoordinate::DegreesMinutes + << QString("-27%1 28.055', -153%1 1.674', 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SW with alt, dm, hemisphere, 28.2341m") + << southWestWithAlt << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString("27%1 28.055' S, 153%1 1.674' W, 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SW with alt, dms, no hemisphere, 28.2341m") + << southWestWithAlt << QGeoCoordinate::DegreesMinutesSeconds + << QString("-27%1 28' 3.3\", -153%1 1' 40.4\", 28.2341m").arg(DEGREES_SYMB); + QTest::newRow("SW with alt, dms, hemisphere, 28.2341m") + << southWestWithAlt << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString("27%1 28' 3.3\" S, 153%1 1' 40.4\" W, 28.2341m").arg(DEGREES_SYMB); + + QTest::newRow("Wrap seconds to Minutes DMSH") + << QGeoCoordinate(1.1333333, 1.1333333) << QGeoCoordinate::DegreesMinutesSecondsWithHemisphere + << QString( "1%1 8' 0.0\" N, 1%1 8' 0.0\" E").arg(DEGREES_SYMB); + QTest::newRow("Wrap seconds to Minutes DMS") + << QGeoCoordinate(1.1333333, 1.1333333) << QGeoCoordinate::DegreesMinutesSeconds + << QString( "1%1 8' 0.0\", 1%1 8' 0.0\"").arg(DEGREES_SYMB); + QTest::newRow("Wrap minutes to Degrees DMH") + << QGeoCoordinate(1.999999, 1.999999) << QGeoCoordinate::DegreesMinutesWithHemisphere + << QString( "2%1 0.000' N, 2%1 0.000' E").arg(DEGREES_SYMB); + QTest::newRow("Wrap minutes to Degrees DM") + << QGeoCoordinate(1.999999, 1.999999) << QGeoCoordinate::DegreesMinutes + << QString( "2%1 0.000', 2%1 0.000'").arg(DEGREES_SYMB); + + QTest::newRow("Wrap seconds to minutes to Degrees DM -> above valid long/lat values") + << QGeoCoordinate(89.999999, 179.999999) << QGeoCoordinate::DegreesMinutesSeconds + << QString( "90%1 0' 0.0\", 180%1 0' 0.0\"").arg(DEGREES_SYMB); + + QTest::newRow("Seconds and minutes near valid long/lat values border") + << QGeoCoordinate(89.9999, 179.9999) << QGeoCoordinate::DegreesMinutesSeconds + << QString("89%1 59' 59.6\", 179%1 59' 59.6\"").arg(DEGREES_SYMB); + + QTest::newRow("Wrap minutes to Degrees DM ->above valid long/lat values") + << QGeoCoordinate(89.999999, 179.999999) << QGeoCoordinate::DegreesMinutes + << QString( "90%1 0.000', 180%1 0.000'").arg(DEGREES_SYMB); + + QTest::newRow("Minutes near valid long/lat values border") + << QGeoCoordinate(89.9999, 179.9999) << QGeoCoordinate::DegreesMinutes + << QString("89%1 59.994', 179%1 59.994'").arg(DEGREES_SYMB); + + QTest::newRow("Fix incorrect wrap minutes to degrees") + << QGeoCoordinate(0.995833, 0.995833) << QGeoCoordinate::DegreesMinutes + << QString("0%1 59.750', 0%1 59.750'").arg(DEGREES_SYMB); + + QTest::newRow("Fix incorrect wrap seconds to minutes") + << QGeoCoordinate(0.9832222, 0.9832222) << QGeoCoordinate::DegreesMinutesSeconds + << QString("0%1 58' 59.6\", 0%1 58' 59.6\"").arg(DEGREES_SYMB); + + } + + void datastream() + { + QFETCH(QGeoCoordinate, c); + + QByteArray ba; + QDataStream out(&ba, QIODevice::WriteOnly); + out << c; + + QDataStream in(&ba, QIODevice::ReadOnly); + QGeoCoordinate inCoord; + in >> inCoord; + QCOMPARE(inCoord, c); + } + + void datastream_data() + { + QTest::addColumn("c"); + + QTest::newRow("invalid") << QGeoCoordinate(); + QTest::newRow("valid lat, long") << BRISBANE; + QTest::newRow("valid lat, long, alt") << QGeoCoordinate(-1, -1, -1); + QTest::newRow("valid lat, long, alt again") << QGeoCoordinate(1, 1, 1); + } + + void debug() + { + QFETCH(QGeoCoordinate, c); + QFETCH(int, nextValue); + QFETCH(QByteArray, debugString); + + qInstallMessageHandler(tst_qgeocoordinate_messageHandler); + qDebug() << c << nextValue; + qInstallMessageHandler(0); + QCOMPARE(tst_qgeocoordinate_debug, debugString); + } + + void debug_data() + { + QTest::addColumn("c"); + QTest::addColumn("nextValue"); + QTest::addColumn("debugString"); + + QTest::newRow("uninitialized") << QGeoCoordinate() << 45 + << QByteArray("QGeoCoordinate(?, ?) 45"); + QTest::newRow("initialized without altitude") << BRISBANE << 45 + << (QString("QGeoCoordinate(%1, %2) 45").arg(BRISBANE.latitude(), 0, 'g', 9) + .arg(BRISBANE.longitude(), 0, 'g', 9)).toLatin1(); + QTest::newRow("invalid initialization") << QGeoCoordinate(-100,-200) << 45 + << QByteArray("QGeoCoordinate(?, ?) 45"); + QTest::newRow("initialized with altitude") << QGeoCoordinate(1,2,3) << 45 + << QByteArray("QGeoCoordinate(1, 2, 3) 45"); + QTest::newRow("extra long coordinates") << QGeoCoordinate(89.123412341, 179.123412341) + << 45 << QByteArray("QGeoCoordinate(89.123412341, 179.12341234) 45"); + } + + void hash() + { + uint s1 = qHash(QGeoCoordinate(1, 1, 2)); + uint s2 = qHash(QGeoCoordinate(2, 1, 1)); + uint s3 = qHash(QGeoCoordinate(1, 2, 1)); + uint s10 = qHash(QGeoCoordinate(0, 0, 2)); + uint s20 = qHash(QGeoCoordinate(2, 0, 0)); + uint s30 = qHash(QGeoCoordinate(0, 2, 0)); + uint s30NoAlt = qHash(QGeoCoordinate(0, 2)); + uint s30WithSeed = qHash(QGeoCoordinate(0, 2, 0), 1); + uint nullCoordinate = qHash(QGeoCoordinate()); + + uint north1 = qHash(QGeoCoordinate(90.0, 34.7, 0)); + uint north2 = qHash(QGeoCoordinate(90.0, 180, 0)); + + uint south1 = qHash(QGeoCoordinate(90.0, 67.7, 34.0)); + uint south2 = qHash(QGeoCoordinate(90.0, 111, 34.0)); + + QVERIFY(s1 != s2); + QVERIFY(s2 != s3); + QVERIFY(s1 != s3); + QVERIFY(s10 != s20); + QVERIFY(s20 != s30); + QVERIFY(s10 != s30); + QVERIFY(s30NoAlt != s30); + QVERIFY(s30WithSeed != s30); + + QVERIFY(nullCoordinate != s1); + QVERIFY(nullCoordinate != s2); + QVERIFY(nullCoordinate != s3); + QVERIFY(nullCoordinate != s10); + QVERIFY(nullCoordinate != s20); + QVERIFY(nullCoordinate != s30); + QVERIFY(nullCoordinate != s30NoAlt); + QVERIFY(nullCoordinate != s30WithSeed); + + QVERIFY(north1 == north2); + QVERIFY(south1 == south2); + } +}; + +QTEST_GUILESS_MAIN(tst_QGeoCoordinate) +#include "tst_qgeocoordinate.moc" diff --git a/tests/auto/qgeocoordinateobject/CMakeLists.txt b/tests/auto/qgeocoordinateobject/CMakeLists.txt new file mode 100644 index 0000000..b8af5b9 --- /dev/null +++ b/tests/auto/qgeocoordinateobject/CMakeLists.txt @@ -0,0 +1,8 @@ +qt_internal_add_test(tst_qgeocoordinateobject + SOURCES + tst_qgeocoordinateobject.cpp + LIBRARIES + Qt::Core + Qt::PositioningPrivate + Qt::TestPrivate +) diff --git a/tests/auto/qgeocoordinateobject/tst_qgeocoordinateobject.cpp b/tests/auto/qgeocoordinateobject/tst_qgeocoordinateobject.cpp new file mode 100644 index 0000000..df3c617 --- /dev/null +++ b/tests/auto/qgeocoordinateobject/tst_qgeocoordinateobject.cpp @@ -0,0 +1,74 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_QGeoCoordinateObject : public QObject +{ + Q_OBJECT +private slots: + void constructor(); + void equality(); + void equality_data(); + void coordinateBinding(); +}; + +void tst_QGeoCoordinateObject::constructor() +{ + QGeoCoordinateObject defaultConstructed; + QCOMPARE(defaultConstructed.coordinate(), QGeoCoordinate()); + + QGeoCoordinate c(1.0, 2.0, 3.0); + QGeoCoordinateObject co(c); + QCOMPARE(co.coordinate(), c); +} + +void tst_QGeoCoordinateObject::equality() +{ + QFETCH(QGeoCoordinate, lhs); + QFETCH(QGeoCoordinate, rhs); + QFETCH(bool, expectedResult); + + QGeoCoordinateObject leftObj(lhs); + QGeoCoordinateObject rightObj(rhs); + + QVERIFY(leftObj == lhs); + QVERIFY(rightObj == rhs); + + QCOMPARE(leftObj == rhs, expectedResult); + QCOMPARE(leftObj != rhs, !expectedResult); + QCOMPARE(rightObj == lhs, expectedResult); + QCOMPARE(rightObj != lhs, !expectedResult); + QCOMPARE(leftObj == rightObj, expectedResult); + QCOMPARE(leftObj != rightObj, !expectedResult); +} + +void tst_QGeoCoordinateObject::equality_data() +{ + QTest::addColumn("lhs"); + QTest::addColumn("rhs"); + QTest::addColumn("expectedResult"); + + QTest::newRow("two invalid") << QGeoCoordinate() << QGeoCoordinate() << true; + QTest::newRow("same valid") << QGeoCoordinate(1.0, 2.0, 3.0) << QGeoCoordinate(1.0, 2.0, 3.0) + << true; + QTest::newRow("invalid vs valid") << QGeoCoordinate() << QGeoCoordinate(1.0, 2.0, 3.0) << false; + QTest::newRow("different valid") + << QGeoCoordinate(1.0, 2.0, 3.0) << QGeoCoordinate(2.0, 3.0, 4.0) << false; +} + +void tst_QGeoCoordinateObject::coordinateBinding() +{ + QGeoCoordinateObject obj; + const QGeoCoordinate initial(1, 2, 3); + const QGeoCoordinate changed(4, 5, 6); + QTestPrivate::testReadWritePropertyBasics( + obj, initial, changed, "coordinate"); +} + +QTEST_GUILESS_MAIN(tst_QGeoCoordinateObject) +#include "tst_qgeocoordinateobject.moc" diff --git a/tests/auto/qgeolocation/CMakeLists.txt b/tests/auto/qgeolocation/CMakeLists.txt new file mode 100644 index 0000000..bb55161 --- /dev/null +++ b/tests/auto/qgeolocation/CMakeLists.txt @@ -0,0 +1,14 @@ +# Generated from qgeolocation.pro. + +##################################################################### +## tst_qgeolocation Test: +##################################################################### + +qt_internal_add_test(tst_qgeolocation + SOURCES + ../utils/qlocationtestutils.cpp ../utils/qlocationtestutils_p.h + tst_qgeolocation.cpp tst_qgeolocation.h + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) diff --git a/tests/auto/qgeolocation/tst_qgeolocation.cpp b/tests/auto/qgeolocation/tst_qgeolocation.cpp new file mode 100644 index 0000000..85542be --- /dev/null +++ b/tests/auto/qgeolocation/tst_qgeolocation.cpp @@ -0,0 +1,387 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "tst_qgeolocation.h" +#include +#include + +QT_USE_NAMESPACE + +tst_QGeoLocation::tst_QGeoLocation() +{ +} + +void tst_QGeoLocation::initTestCase() +{ + +} + +void tst_QGeoLocation::cleanupTestCase() +{ + +} + +void tst_QGeoLocation::init() +{ +} + +void tst_QGeoLocation::cleanup() +{ +} + +void tst_QGeoLocation::constructor() +{ + QCOMPARE(m_location.address(), m_address); + QCOMPARE(m_location.coordinate(), m_coordinate); + QCOMPARE(m_location.boundingShape(), m_viewport); + QCOMPARE(m_location.extendedAttributes(), m_extendedAttributes); +} + +void tst_QGeoLocation::copy_constructor() +{ + auto qgeolocationcopy = std::make_unique(m_location); + QCOMPARE(m_location, *qgeolocationcopy); +} + +void tst_QGeoLocation::move_constructor() +{ + QGeoAddress address; + address.setCity("Berlin"); + address.setCountry("Germany"); + address.setCountryCode("DEU"); + address.setDistrict("Adlershof"); + address.setPostalCode("12489"); + address.setStreet("Erich-Thilo-Strasse"); + + QGeoLocation location; + location.setAddress(address); + location.setCoordinate(QGeoCoordinate(1.3, 2.4, 3.1)); + location.setBoundingShape(QGeoCircle(QGeoCoordinate(1.3, 2.4), 100)); + + QGeoLocation locationCopy = location; + QCOMPARE(std::move(location), locationCopy); +} + +void tst_QGeoLocation::move_assignment() +{ + QGeoAddress address; + address.setCity("Berlin"); + address.setCountry("Germany"); + address.setCountryCode("DEU"); + address.setDistrict("Adlershof"); + address.setPostalCode("12489"); + address.setStreet("Erich-Thilo-Strasse"); + + QGeoLocation location; + location.setAddress(address); + location.setCoordinate(QGeoCoordinate(1.3, 2.4, 3.1)); + location.setBoundingShape(QGeoCircle(QGeoCoordinate(1.3, 2.4), 100)); + + QGeoLocation locationCopy = location; + + QGeoLocation otherLocation; + otherLocation = std::move(location); + QCOMPARE(otherLocation, locationCopy); + + // Check that (move)assignment to a moved-from object is fine + location = std::move(locationCopy); + QCOMPARE(location, otherLocation); +} + +void tst_QGeoLocation::destructor() +{ + QGeoLocation *qgeolocationcopy; + + qgeolocationcopy = new QGeoLocation(); + delete qgeolocationcopy; + + qgeolocationcopy = new QGeoLocation(m_location); + delete qgeolocationcopy; +} + +void tst_QGeoLocation::address() +{ + m_address.setCity("Berlin"); + m_address.setCountry("Germany"); + m_address.setCountryCode("DEU"); + m_address.setDistrict("Mitte"); + m_address.setPostalCode("10115"); + m_address.setStreet("Invalidenstrasse"); + + m_location.setAddress(m_address); + + QCOMPARE(m_location.address(),m_address); + + m_address.setPostalCode("10125"); + QVERIFY(m_location.address() != m_address); +} + +void tst_QGeoLocation::coordinate() +{ + m_coordinate.setLatitude(13.3851); + m_coordinate.setLongitude(52.5312); + m_coordinate.setAltitude(134.23); + + m_location.setCoordinate(m_coordinate); + + QCOMPARE(m_location.coordinate(), m_coordinate); + + m_coordinate.setAltitude(0); + QVERIFY(m_location.coordinate() != m_coordinate); +} + +void tst_QGeoLocation::viewport() +{ + m_coordinate.setLatitude(13.3851); + m_coordinate.setLongitude(52.5312); + + // rectangle bounding box + QGeoRectangle qgeoboundingboxcopy(m_coordinate, 0.4, 0.4); + m_location.setBoundingShape(qgeoboundingboxcopy); + + QCOMPARE(m_location.boundingShape(), qgeoboundingboxcopy); + // test that QGeoShape::boundingGeoRectangle() matches with + // the qgeoboundingboxcopy. It simplifies code porting + QCOMPARE(m_location.boundingShape().boundingGeoRectangle(), qgeoboundingboxcopy); + + qgeoboundingboxcopy.setHeight(1); + + QVERIFY(m_location.boundingShape() != qgeoboundingboxcopy); + + // circle bounding box + QGeoCircle circle(m_coordinate, 10); + m_location.setBoundingShape(circle); + + QCOMPARE(m_location.boundingShape(), circle); + + auto point = QGeoCoordinate(0.5, 0.5); + QVERIFY(!circle.contains(point)); + circle.extendCircle(point); + + QVERIFY(m_location.boundingShape() != circle); + QVERIFY(!m_location.boundingShape().contains(point)); + + // polygon bounding box + const QList points = {QGeoCoordinate(1.0, 1.0), QGeoCoordinate(1.0, 2.0), QGeoCoordinate(2.0, 2.0)}; + QGeoPolygon polygon(points); + + point = QGeoCoordinate(1.75, 1.25); + QVERIFY(!polygon.contains(point)); + + m_location.setBoundingShape(polygon); + QCOMPARE(m_location.boundingShape(), polygon); + + polygon.addCoordinate(QGeoCoordinate(2.0, 1.0)); + QVERIFY(m_location.boundingShape() != polygon); + QVERIFY(polygon.contains(point)); + QVERIFY(!m_location.boundingShape().contains(point)); +} + +void tst_QGeoLocation::extendedAttributes() +{ + m_extendedAttributes = QVariantMap({{ "foo" , 42 }}); + m_location.setExtendedAttributes(m_extendedAttributes); + QCOMPARE(m_location.extendedAttributes(), m_extendedAttributes); + + m_extendedAttributes["foo"] = 41; + QVERIFY(m_location.extendedAttributes() != m_extendedAttributes); +} + +void tst_QGeoLocation::operators() +{ + QGeoAddress qgeoaddresscopy; + qgeoaddresscopy.setCity("Berlin"); + qgeoaddresscopy.setCountry("Germany"); + qgeoaddresscopy.setCountryCode("DEU"); + + QGeoCoordinate qgeocoordinatecopy (32.324 , 41.324 , 24.55); + QVariantMap extendedAttributesCopy {{ "foo" , 42 }}; + + m_address.setCity("Madrid"); + m_address.setCountry("Spain"); + m_address.setCountryCode("SPA"); + + m_coordinate.setLatitude(21.3434); + m_coordinate.setLongitude(38.43443); + m_coordinate.setAltitude(634.21); + + m_extendedAttributes["foo"] = 43; + + m_location.setAddress(m_address); + m_location.setCoordinate(m_coordinate); + m_location.setExtendedAttributes(m_extendedAttributes); + + //Create a copy and see that they are the same + QGeoLocation qgeolocationcopy(m_location); + QVERIFY(m_location == qgeolocationcopy); + QVERIFY(!(m_location != qgeolocationcopy)); + + //Modify one and test if they are different + qgeolocationcopy.setAddress(qgeoaddresscopy); + QVERIFY(!(m_location == qgeolocationcopy)); + QVERIFY(m_location != qgeolocationcopy); + qgeolocationcopy.setAddress(m_address); + qgeolocationcopy.setCoordinate(qgeocoordinatecopy); + QVERIFY(!(m_location == qgeolocationcopy)); + QVERIFY(m_location != qgeolocationcopy); + qgeolocationcopy.setCoordinate(m_coordinate); + qgeolocationcopy.setExtendedAttributes(extendedAttributesCopy); + QVERIFY(!(m_location == qgeolocationcopy)); + QVERIFY(m_location != qgeolocationcopy); + + + //delete qgeolocationcopy; + //Asign and test that they are the same + qgeolocationcopy = m_location; + QVERIFY(m_location ==qgeolocationcopy); + QVERIFY(!(m_location != qgeolocationcopy)); +} + +void tst_QGeoLocation::comparison() +{ + QFETCH(QString, dataField); + + QGeoLocation location; + + //set address + QGeoAddress address; + address.setStreet("21 jump st"); + address.setCountry("USA"); + location.setAddress(address); + + //set coordinate + location.setCoordinate(QGeoCoordinate(5,10)); + + //set viewport + location.setBoundingShape(QGeoRectangle(QGeoCoordinate(5,5),0.4,0.4)); + + QGeoLocation otherLocation(location); + + if (dataField == "no change") { + QCOMPARE(location, otherLocation); + } else { + if (dataField == "address") { + QGeoAddress otherAddress; + otherAddress.setStreet("42 evergreen tce"); + otherAddress.setCountry("USA"); + otherLocation.setAddress(otherAddress); + } else if (dataField == "coordinate") { + otherLocation.setCoordinate(QGeoCoordinate(12,13)); + } else if (dataField == "viewport"){ + otherLocation.setBoundingShape(QGeoRectangle(QGeoCoordinate(1,2), 0.5,0.5)); + } else if (dataField == "extendedAttributes"){ + otherLocation.setExtendedAttributes(QVariantMap({{"foo", 44}})); + } else { + qFatal("Unknown data field to test"); + } + + QVERIFY(location != otherLocation); + } +} + +void tst_QGeoLocation::comparison_data() +{ + QTest::addColumn ("dataField"); + QTest::newRow("no change") << "no change"; + QTest::newRow("address") << "address"; + QTest::newRow("coordinate") << "coordinate"; + QTest::newRow("extendedAttributes") << "extendedAttributes"; +} + +void tst_QGeoLocation::isEmpty() +{ + QGeoAddress address; + address.setCity(QStringLiteral("Braunschweig")); + QVERIFY(!address.isEmpty()); + + QGeoRectangle boundingBox; + boundingBox.setTopLeft(QGeoCoordinate(1, -1)); + boundingBox.setBottomRight(QGeoCoordinate(-1, 1)); + QVERIFY(!boundingBox.isEmpty()); + + QVariantMap extendedAttributes({{"foo", 11}}); + + QGeoLocation location; + + QVERIFY(location.isEmpty()); + + // address + location.setAddress(address); + QVERIFY(!location.isEmpty()); + location.setAddress(QGeoAddress()); + QVERIFY(location.isEmpty()); + + // coordinate + location.setCoordinate(QGeoCoordinate(1, 2)); + QVERIFY(!location.isEmpty()); + location.setCoordinate(QGeoCoordinate()); + QVERIFY(location.isEmpty()); + + // bounding box + location.setBoundingShape(boundingBox); + QVERIFY(!location.isEmpty()); + location.setBoundingShape(QGeoRectangle()); + QVERIFY(location.isEmpty()); + + // extended attributes + location.setExtendedAttributes(extendedAttributes); + QVERIFY(!location.isEmpty()); + location.setExtendedAttributes(QVariantMap()); + QVERIFY(location.isEmpty()); +} + +void tst_QGeoLocation::hashing() +{ + QFETCH(QGeoLocation, leftLocation); + QFETCH(QGeoLocation, rightLocation); + QFETCH(bool, result); + + const size_t leftHash = qHash(leftLocation); + const size_t rightHash = qHash(rightLocation); + QCOMPARE(leftHash == rightHash, result); +} + +void tst_QGeoLocation::hashing_data() +{ + QTest::addColumn("leftLocation"); + QTest::addColumn("rightLocation"); + QTest::addColumn("result"); + + QTest::newRow("empty") << QGeoLocation() << QGeoLocation() << true; + + QGeoAddress address; + address.setCity("city"); + address.setPostalCode("1234"); + address.setDistrict("district"); + address.setStreet("street"); + address.setStreetNumber("12"); + + QGeoLocation leftLocation; + leftLocation.setAddress(address); + leftLocation.setCoordinate(QGeoCoordinate(1, 1)); + leftLocation.setBoundingShape(QGeoCircle(QGeoCoordinate(1, 1), 10)); + + // do not copy, so that they have different d_ptr's + QGeoLocation rightLocation; + rightLocation.setAddress(address); + rightLocation.setCoordinate(QGeoCoordinate(1, 1)); + rightLocation.setBoundingShape(QGeoCircle(QGeoCoordinate(1, 1), 10)); + + QTest::newRow("same locations") << leftLocation << rightLocation << true; + + QGeoLocation rightLocationCopy = rightLocation; + rightLocationCopy.setBoundingShape(QGeoRectangle(QGeoCoordinate(2, 0), QGeoCoordinate(0, 2))); + QTest::newRow("different shapes") << leftLocation << rightLocationCopy << false; + + rightLocationCopy = rightLocation; + rightLocationCopy.setCoordinate(QGeoCoordinate(2, 1)); + QTest::newRow("different coordinates") << leftLocation << rightLocationCopy << false; + + rightLocationCopy = rightLocation; + address.setState("state"); + rightLocationCopy.setAddress(address); + QTest::newRow("different addresses") << leftLocation << rightLocationCopy << false; +} + +QTEST_APPLESS_MAIN(tst_QGeoLocation); + diff --git a/tests/auto/qgeolocation/tst_qgeolocation.h b/tests/auto/qgeolocation/tst_qgeolocation.h new file mode 100644 index 0000000..1548c55 --- /dev/null +++ b/tests/auto/qgeolocation/tst_qgeolocation.h @@ -0,0 +1,65 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef TST_QGEOLOCATION_H +#define TST_QGEOLOCATION_H + +#include +#include +#include +#include + +#include "../utils/qlocationtestutils_p.h" +#include +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_QGeoLocation : public QObject +{ + Q_OBJECT + +public: + tst_QGeoLocation(); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + //Start Unit Tests for qgeolocation.h + void constructor(); + void copy_constructor(); + void move_constructor(); + void move_assignment(); + void destructor(); + void address(); + void coordinate(); + void viewport(); + void extendedAttributes(); + void operators(); + void comparison(); + void comparison_data(); + void isEmpty(); + void hashing(); + void hashing_data(); + //End Unit Tests for qgeolocation.h + +private: + QGeoLocation m_location; + + QGeoAddress m_address; + QGeoCoordinate m_coordinate; + QGeoShape m_viewport; + QVariantMap m_extendedAttributes; +}; + +Q_DECLARE_METATYPE( QGeoCoordinate::CoordinateFormat); +Q_DECLARE_METATYPE( QGeoCoordinate::CoordinateType); +Q_DECLARE_METATYPE( QList); + +#endif + diff --git a/tests/auto/qgeopath/CMakeLists.txt b/tests/auto/qgeopath/CMakeLists.txt new file mode 100644 index 0000000..b301c14 --- /dev/null +++ b/tests/auto/qgeopath/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from qgeopath.pro. + +##################################################################### +## tst_qgeopath Test: +##################################################################### + +qt_internal_add_test(tst_qgeopath + SOURCES + tst_qgeopath.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:qgeopath.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qgeopath/tst_qgeopath.cpp b/tests/auto/qgeopath/tst_qgeopath.cpp new file mode 100644 index 0000000..ac9d5fd --- /dev/null +++ b/tests/auto/qgeopath/tst_qgeopath.cpp @@ -0,0 +1,367 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_QGeoPath : public QObject +{ + Q_OBJECT + +private slots: + void defaultConstructor(); + void listConstructor(); + void assignment(); + + void comparison(); + void type(); + + void path(); + void width(); + void size(); + + void translate_data(); + void translate(); + + void valid_data(); + void valid(); + + void contains_data(); + void contains(); + + void boundingGeoRectangle_data(); + void boundingGeoRectangle(); + + void hashing(); +}; + +void tst_QGeoPath::defaultConstructor() +{ + QGeoPath p; + QVERIFY(!p.path().size()); + QCOMPARE(p.width(), qreal(0.0)); + QCOMPARE(p.length(), double(0.0)); +} + +void tst_QGeoPath::listConstructor() +{ + QList coords; + coords.append(QGeoCoordinate(1,1)); + coords.append(QGeoCoordinate(2,2)); + coords.append(QGeoCoordinate(3,0)); + + QGeoPath p(coords, 1.0); + QCOMPARE(p.width(), qreal(1.0)); + QCOMPARE(p.path().size(), 3); + + for (const QGeoCoordinate &c : coords) { + QCOMPARE(p.path().contains(c), true); + } +} + +void tst_QGeoPath::assignment() +{ + QGeoPath p1; + QList coords; + coords.append(QGeoCoordinate(1,1)); + coords.append(QGeoCoordinate(2,2)); + coords.append(QGeoCoordinate(3,0)); + QGeoPath p2(coords, 1.0); + + QVERIFY(p1 != p2); + + p1 = p2; + QCOMPARE(p1.path(), coords); + QCOMPARE(p1.width(), 1.0); + QCOMPARE(p1, p2); + + // Assign c1 to an area + QGeoShape area = p1; + QCOMPARE(area.type(), p1.type()); + QVERIFY(area == p1); + + // Assign the area back to a bounding circle + QGeoPath p3 = area; + QCOMPARE(p3.path(), coords); + QCOMPARE(p3.width(), 1.0); + + // Check that the copy is not modified when modifying the original. + p1.setWidth(2.0); + QVERIFY(p3.width() != p1.width()); + QVERIFY(p3 != p1); +} + +void tst_QGeoPath::comparison() +{ + QList coords; + coords.append(QGeoCoordinate(1,1)); + coords.append(QGeoCoordinate(2,2)); + coords.append(QGeoCoordinate(3,0)); + QList coords2; + coords2.append(QGeoCoordinate(3,1)); + coords2.append(QGeoCoordinate(4,2)); + coords2.append(QGeoCoordinate(3,0)); + QGeoPath c1(coords, qreal(50.0)); + QGeoPath c2(coords, qreal(50.0)); + QGeoPath c3(coords, qreal(35.0)); + QGeoPath c4(coords2, qreal(50.0)); + + QVERIFY(c1 == c2); + QVERIFY(!(c1 != c2)); + + QVERIFY(!(c1 == c3)); + QVERIFY(c1 != c3); + + QVERIFY(!(c1 == c4)); + QVERIFY(c1 != c4); + + QVERIFY(!(c2 == c3)); + QVERIFY(c2 != c3); + + QGeoRectangle b1(QGeoCoordinate(20,20),QGeoCoordinate(10,30)); + QVERIFY(!(c1 == b1)); + QVERIFY(c1 != b1); + + QGeoShape *c2Ptr = &c2; + QVERIFY(c1 == *c2Ptr); + QVERIFY(!(c1 != *c2Ptr)); + + QGeoShape *c3Ptr = &c3; + QVERIFY(!(c1 == *c3Ptr)); + QVERIFY(c1 != *c3Ptr); +} + +void tst_QGeoPath::type() +{ + QGeoPath c; + QCOMPARE(c.type(), QGeoShape::PathType); +} + +void tst_QGeoPath::path() +{ + QList coords; + coords.append(QGeoCoordinate(1,1)); + coords.append(QGeoCoordinate(2,2)); + coords.append(QGeoCoordinate(3,0)); + + QGeoPath p; + p.setPath(coords); + QCOMPARE(p.path().size(), 3); + + for (const QGeoCoordinate &c : coords) { + QCOMPARE(p.path().contains(c), true); + } + + p.clearPath(); + QCOMPARE(p.path().size(), 0); + QVERIFY(p.boundingGeoRectangle().isEmpty()); +} + +void tst_QGeoPath::width() +{ + QGeoPath p; + p.setWidth(10.0); + QCOMPARE(p.width(), qreal(10.0)); +} + +void tst_QGeoPath::size() +{ + QList coords; + + QGeoPath p1(coords, 3); + QCOMPARE(p1.size(), coords.size()); + + coords.append(QGeoCoordinate(1,1)); + QGeoPath p2(coords, 3); + QCOMPARE(p2.size(), coords.size()); + + coords.append(QGeoCoordinate(2,2)); + QGeoPath p3(coords, 3); + QCOMPARE(p3.size(), coords.size()); + + coords.append(QGeoCoordinate(3,0)); + QGeoPath p4(coords, 3); + QCOMPARE(p4.size(), coords.size()); + + p4.removeCoordinate(2); + QCOMPARE(p4.size(), coords.size() - 1); + + p4.removeCoordinate(coords.first()); + QCOMPARE(p4.size(), coords.size() - 2); +} + +void tst_QGeoPath::translate_data() +{ + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("c3"); + QTest::addColumn("lat"); + QTest::addColumn("lon"); + + QTest::newRow("Simple") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) << + QGeoCoordinate(3,0) << 5.0 << 4.0; + QTest::newRow("Backward") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) << + QGeoCoordinate(3,0) << -5.0 << -4.0; +} + +void tst_QGeoPath::translate() +{ + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(QGeoCoordinate, c3); + QFETCH(double, lat); + QFETCH(double, lon); + + QList coords; + coords.append(c1); + coords.append(c2); + coords.append(c3); + QGeoPath p(coords); + + p.translate(lat, lon); + + for (int i = 0; i < p.path().size(); i++) { + QCOMPARE(coords[i].latitude(), p.path()[i].latitude() - lat ); + QCOMPARE(coords[i].longitude(), p.path()[i].longitude() - lon ); + } +} + +void tst_QGeoPath::valid_data() +{ + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("c3"); + QTest::addColumn("width"); + QTest::addColumn("valid"); + + QTest::newRow("empty coords") << QGeoCoordinate() << QGeoCoordinate() << QGeoCoordinate() << qreal(5.0) << false; + QTest::newRow("invalid coord") << QGeoCoordinate(50, 50) << QGeoCoordinate(60, 60) << QGeoCoordinate(700, 700) << qreal(5.0) << false; + QTest::newRow("bad width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(-5.0) << true; + QTest::newRow("NaN width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(qQNaN()) << true; + QTest::newRow("zero width") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(0) << true; + QTest::newRow("good") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << qreal(5) << true; +} + +void tst_QGeoPath::valid() +{ + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(QGeoCoordinate, c3); + QFETCH(qreal, width); + QFETCH(bool, valid); + + QList coords; + coords.append(c1); + coords.append(c2); + coords.append(c3); + QGeoPath p(coords, width); + + QCOMPARE(p.isValid(), valid); + + QGeoShape area = p; + QCOMPARE(area.isValid(), valid); +} + +void tst_QGeoPath::contains_data() +{ + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("c3"); + QTest::addColumn("width"); + QTest::addColumn("probe"); + QTest::addColumn("result"); + + QList c; + c.append(QGeoCoordinate(1,1)); + c.append(QGeoCoordinate(2,2)); + c.append(QGeoCoordinate(3,0)); + + QTest::newRow("One of the points") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(2, 2) << true; + QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(0.8, 0.8) << false; + QTest::newRow("Not so far away and large line") << c[0] << c[1] << c[2] << 100000.0 << QGeoCoordinate(0.8, 0.8) << true; +} + +void tst_QGeoPath::contains() +{ + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(QGeoCoordinate, c3); + QFETCH(qreal, width); + QFETCH(QGeoCoordinate, probe); + QFETCH(bool, result); + + QList coords; + coords.append(c1); + coords.append(c2); + coords.append(c3); + QGeoPath p(coords, width); + + QCOMPARE(p.contains(probe), result); + + QGeoShape area = p; + QCOMPARE(area.contains(probe), result); +} + +void tst_QGeoPath::boundingGeoRectangle_data() +{ + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("c3"); + QTest::addColumn("width"); + QTest::addColumn("probe"); + QTest::addColumn("result"); + + QList c; + c.append(QGeoCoordinate(1,1)); + c.append(QGeoCoordinate(2,2)); + c.append(QGeoCoordinate(3,0)); + + QTest::newRow("One of the points") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(2, 2) << true; + QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << 0.0 << QGeoCoordinate(0, 0) << false; + QTest::newRow("Inside the bounds") << c[0] << c[1] << c[2] << 100.0 << QGeoCoordinate(1, 0) << true; + QTest::newRow("Inside the bounds") << c[0] << c[1] << c[2] << 100.0 << QGeoCoordinate(1.1, 0.1) << true; +} + +void tst_QGeoPath::boundingGeoRectangle() +{ + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(QGeoCoordinate, c3); + QFETCH(qreal, width); + QFETCH(QGeoCoordinate, probe); + QFETCH(bool, result); + + QList coords; + coords.append(c1); + coords.append(c2); + coords.append(c3); + QGeoPath p(coords, width); + + QGeoRectangle box = p.boundingGeoRectangle(); + QCOMPARE(box.contains(probe), result); +} + +void tst_QGeoPath::hashing() +{ + const QGeoPath path({ QGeoCoordinate(1, 1), QGeoCoordinate(1, 2), QGeoCoordinate(2, 5) }, 1.0); + const size_t pathHash = qHash(path); + + QGeoPath otherCoordsPath = path; + otherCoordsPath.addCoordinate(QGeoCoordinate(3, 5)); + QVERIFY(qHash(otherCoordsPath) != pathHash); + + QGeoPath otherWidthPath = path; + otherWidthPath.setWidth(1.5); + QVERIFY(qHash(otherWidthPath) != pathHash); + + // Do not assign, so that they do not share same d_ptr + QGeoPath similarPath({ QGeoCoordinate(1, 1), QGeoCoordinate(1, 2), QGeoCoordinate(2, 5) }, 1.0); + QCOMPARE(qHash(similarPath), pathHash); +} + +QTEST_MAIN(tst_QGeoPath) +#include "tst_qgeopath.moc" diff --git a/tests/auto/qgeopolygon/CMakeLists.txt b/tests/auto/qgeopolygon/CMakeLists.txt new file mode 100644 index 0000000..e38e2ca --- /dev/null +++ b/tests/auto/qgeopolygon/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from qgeopolygon.pro. + +##################################################################### +## tst_qgeopolygon Test: +##################################################################### + +qt_internal_add_test(tst_qgeopolygon + SOURCES + tst_qgeopolygon.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:qgeopolygon.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qgeopolygon/tst_qgeopolygon.cpp b/tests/auto/qgeopolygon/tst_qgeopolygon.cpp new file mode 100644 index 0000000..8c062e6 --- /dev/null +++ b/tests/auto/qgeopolygon/tst_qgeopolygon.cpp @@ -0,0 +1,384 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_QGeoPolygon : public QObject +{ + Q_OBJECT + +private slots: + void defaultConstructor(); + void listConstructor(); + void assignment(); + + void comparison(); + void type(); + + void path(); + void size(); + + void translate_data(); + void translate(); + + void valid_data(); + void valid(); + + void contains_data(); + void contains(); + + void containsAfterCopy(); + + void boundingGeoRectangle_data(); + void boundingGeoRectangle(); + + void hashing(); +}; + +void tst_QGeoPolygon::defaultConstructor() +{ + QGeoPolygon p; + QVERIFY(!p.perimeter().size()); + QVERIFY(!p.size()); + QVERIFY(!p.isValid()); + QVERIFY(p.isEmpty()); +} + +void tst_QGeoPolygon::listConstructor() +{ + QList coords; + coords.append(QGeoCoordinate(1,1)); + coords.append(QGeoCoordinate(2,2)); + QGeoPolygon p2(coords); + QCOMPARE(p2.perimeter().size(), 2); + QCOMPARE(p2.size(), 2); + QVERIFY(!p2.isValid()); // a polygon can't have only 2 coords + QVERIFY(!p2.isEmpty()); + + coords.append(QGeoCoordinate(3,0)); + + QGeoPolygon p(coords); + QCOMPARE(p.perimeter().size(), 3); + QCOMPARE(p.size(), 3); + QVERIFY(p.isValid()); + QVERIFY(!p.isEmpty()); + + + for (const QGeoCoordinate &c : coords) { + QCOMPARE(p.perimeter().contains(c), true); + QCOMPARE(p.containsCoordinate(c), true); + } +} + +void tst_QGeoPolygon::assignment() +{ + QGeoPolygon p1; + QList coords; + coords.append(QGeoCoordinate(1,1)); + coords.append(QGeoCoordinate(2,2)); + coords.append(QGeoCoordinate(3,0)); + QGeoPolygon p2(coords); + + QVERIFY(p1 != p2); + + p1 = p2; + QCOMPARE(p1.perimeter(), coords); + QCOMPARE(p1, p2); + + // Assign c1 to an area + QGeoShape area = p1; + QCOMPARE(area.type(), p1.type()); + QVERIFY(area == p1); + + // Assign the area back to a polygon + QGeoPolygon p3 = area; + QCOMPARE(p3.perimeter(), coords); + QVERIFY(p3 == p1); + + // Check that the copy is not modified when modifying the original. + p1.addCoordinate(QGeoCoordinate(4,0)); + QVERIFY(p3 != p1); +} + +void tst_QGeoPolygon::comparison() +{ + QList coords; + coords.append(QGeoCoordinate(1,1)); + coords.append(QGeoCoordinate(2,2)); + coords.append(QGeoCoordinate(3,0)); + QList coords2; + coords2.append(QGeoCoordinate(3,1)); + coords2.append(QGeoCoordinate(4,2)); + coords2.append(QGeoCoordinate(3,0)); + QGeoPolygon c1(coords); + QGeoPolygon c2(coords); + QGeoPolygon c3(coords2); + + QVERIFY(c1 == c2); + QVERIFY(!(c1 != c2)); + + QVERIFY(!(c1 == c3)); + QVERIFY(c1 != c3); + + QVERIFY(!(c2 == c3)); + QVERIFY(c2 != c3); + + QGeoRectangle b1(QGeoCoordinate(20,20),QGeoCoordinate(10,30)); + QVERIFY(!(c1 == b1)); + QVERIFY(c1 != b1); + + QGeoShape *c2Ptr = &c2; + QVERIFY(c1 == *c2Ptr); + QVERIFY(!(c1 != *c2Ptr)); + + QGeoShape *c3Ptr = &c3; + QVERIFY(!(c1 == *c3Ptr)); + QVERIFY(c1 != *c3Ptr); +} + +void tst_QGeoPolygon::type() +{ + QGeoPolygon c; + QCOMPARE(c.type(), QGeoShape::PolygonType); +} + +void tst_QGeoPolygon::path() +{ + QList coords; + coords.append(QGeoCoordinate(1,1)); + coords.append(QGeoCoordinate(2,2)); + coords.append(QGeoCoordinate(3,0)); + + QGeoPolygon p; + p.setPerimeter(coords); + QCOMPARE(p.perimeter().size(), 3); + QCOMPARE(p.size(), 3); + + for (const QGeoCoordinate &c : coords) { + QCOMPARE(p.perimeter().contains(c), true); + QCOMPARE(p.containsCoordinate(c), true); + } +} + +void tst_QGeoPolygon::size() +{ + QList coords; + + QGeoPolygon p1(coords); + QCOMPARE(p1.size(), coords.size()); + + coords.append(QGeoCoordinate(1,1)); + QGeoPolygon p2(coords); + QCOMPARE(p2.size(), coords.size()); + + coords.append(QGeoCoordinate(2,2)); + QGeoPolygon p3(coords); + QCOMPARE(p3.size(), coords.size()); + + coords.append(QGeoCoordinate(3,0)); + QGeoPolygon p4(coords); + QCOMPARE(p4.size(), coords.size()); + + p4.removeCoordinate(2); + QCOMPARE(p4.size(), coords.size() - 1); + + p4.removeCoordinate(coords.first()); + QCOMPARE(p4.size(), coords.size() - 2); +} + +void tst_QGeoPolygon::translate_data() +{ + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("c3"); + QTest::addColumn("lat"); + QTest::addColumn("lon"); + + QTest::newRow("Simple") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) << + QGeoCoordinate(3,0) << 5.0 << 4.0; + QTest::newRow("Backward") << QGeoCoordinate(1,1) << QGeoCoordinate(2,2) << + QGeoCoordinate(3,0) << -5.0 << -4.0; +} + +void tst_QGeoPolygon::translate() +{ + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(QGeoCoordinate, c3); + QFETCH(double, lat); + QFETCH(double, lon); + + QList coords; + coords.append(c1); + coords.append(c2); + coords.append(c3); + QGeoPolygon p(coords); + + p.translate(lat, lon); + + for (int i = 0; i < p.perimeter().size(); i++) { + QCOMPARE(coords[i].latitude(), p.perimeter()[i].latitude() - lat ); + QCOMPARE(coords[i].longitude(), p.perimeter()[i].longitude() - lon ); + } +} + +void tst_QGeoPolygon::valid_data() +{ + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("c3"); + QTest::addColumn("valid"); + + QTest::newRow("empty coords") << QGeoCoordinate() << QGeoCoordinate() << QGeoCoordinate() << false; + QTest::newRow("invalid coord") << QGeoCoordinate(50, 50) << QGeoCoordinate(60, 60) << QGeoCoordinate(700, 700) << false; + QTest::newRow("good") << QGeoCoordinate(10, 10) << QGeoCoordinate(11, 11) << QGeoCoordinate(10, 12) << true; +} + +void tst_QGeoPolygon::valid() +{ + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(QGeoCoordinate, c3); + QFETCH(bool, valid); + + QList coords; + coords.append(c1); + coords.append(c2); + coords.append(c3); + QGeoPolygon p(coords); + + QCOMPARE(p.isValid(), valid); + + QGeoShape area = p; + QCOMPARE(area.isValid(), valid); +} + +void tst_QGeoPolygon::contains_data() +{ + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("c3"); + QTest::addColumn("probe"); + QTest::addColumn("result"); + + QList c; + c.append(QGeoCoordinate(1,1)); + c.append(QGeoCoordinate(2,2)); + c.append(QGeoCoordinate(3,0)); + + QTest::newRow("One of the points") << c[0] << c[1] << c[2] << QGeoCoordinate(2, 2) << true; + QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << QGeoCoordinate(0.8, 0.8) << false; + QTest::newRow("Not so far away and large line") << c[0] << c[1] << c[2] << QGeoCoordinate(0.8, 0.8) << false; + QTest::newRow("Inside") << c[0] << c[1] << c[2] << QGeoCoordinate(2.0, 1.0) << true; +} + +void tst_QGeoPolygon::contains() +{ + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(QGeoCoordinate, c3); + QFETCH(QGeoCoordinate, probe); + QFETCH(bool, result); + + QList coords; + coords.append(c1); + coords.append(c2); + coords.append(c3); + QGeoPolygon p(coords); + + QCOMPARE(p.contains(probe), result); + + QGeoShape area = p; + QCOMPARE(area.contains(probe), result); +} + +void tst_QGeoPolygon::containsAfterCopy() +{ + // This test is to make sure that we copy the QClipperUtils in the + // QGeoPolygonPrivate correctly. + QList coords; + coords.append(QGeoCoordinate(1, 1)); + coords.append(QGeoCoordinate(2, 2)); + coords.append(QGeoCoordinate(3, 0)); + + const QGeoCoordinate testPoint(2.0, 1.0); + + QGeoPolygon p1(coords); + QVERIFY(p1.contains(testPoint)); + + QGeoPolygon p2 = p1; + QVERIFY(p2.contains(testPoint)); + + p2.translate(10, 10); // does not contain testPoint any more + QVERIFY(!p2.contains(testPoint)); + QVERIFY(p1.contains(testPoint)); + // This check is intentional! Needed to make sure that p1 does not modify + // the internals of p2 somehow. + QVERIFY(!p2.contains(testPoint)); +} + +void tst_QGeoPolygon::boundingGeoRectangle_data() +{ + QTest::addColumn("c1"); + QTest::addColumn("c2"); + QTest::addColumn("c3"); + QTest::addColumn("probe"); + QTest::addColumn("result"); + + QList c; + c.append(QGeoCoordinate(1,1)); + c.append(QGeoCoordinate(2,2)); + c.append(QGeoCoordinate(3,0)); + + QTest::newRow("One of the points") << c[0] << c[1] << c[2] << QGeoCoordinate(2, 2) << true; + QTest::newRow("Not so far away") << c[0] << c[1] << c[2] << QGeoCoordinate(0, 0) << false; + QTest::newRow("Inside the bounds") << c[0] << c[1] << c[2] << QGeoCoordinate(1, 0) << true; + QTest::newRow("Inside the bounds") << c[0] << c[1] << c[2] << QGeoCoordinate(1.1, 0.1) << true; +} + +void tst_QGeoPolygon::boundingGeoRectangle() +{ + QFETCH(QGeoCoordinate, c1); + QFETCH(QGeoCoordinate, c2); + QFETCH(QGeoCoordinate, c3); + QFETCH(QGeoCoordinate, probe); + QFETCH(bool, result); + + QList coords; + coords.append(c1); + coords.append(c2); + coords.append(c3); + QGeoPolygon p(coords); + + QGeoRectangle box = p.boundingGeoRectangle(); + QCOMPARE(box.contains(probe), result); +} + +void tst_QGeoPolygon::hashing() +{ + const QGeoPolygon polygon({ QGeoCoordinate(1, 1), QGeoCoordinate(2, 2), + QGeoCoordinate(3, 0) }); + const size_t polygonHash = qHash(polygon); + + QGeoPolygon otherCoordsPolygon = polygon; + otherCoordsPolygon.addCoordinate(QGeoCoordinate(4, 1)); + QVERIFY(qHash(otherCoordsPolygon) != polygonHash); + + QGeoPolygon otherHolesPolygon = polygon; + otherHolesPolygon.addHole({ QGeoCoordinate(1.1, 1), QGeoCoordinate(2, 1.8), + QGeoCoordinate(2, 1) }); + QVERIFY(qHash(otherHolesPolygon) != polygonHash); + + // Do not assign, so that they do not share same d_ptr + QGeoPolygon similarPolygon({ QGeoCoordinate(1, 1), QGeoCoordinate(2, 2), + QGeoCoordinate(3, 0) }); + QCOMPARE(qHash(similarPolygon), polygonHash); +} + +QTEST_MAIN(tst_QGeoPolygon) +#include "tst_qgeopolygon.moc" diff --git a/tests/auto/qgeopositioninfo/CMakeLists.txt b/tests/auto/qgeopositioninfo/CMakeLists.txt new file mode 100644 index 0000000..3ce93cf --- /dev/null +++ b/tests/auto/qgeopositioninfo/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from qgeopositioninfo.pro. + +##################################################################### +## tst_qgeopositioninfo Test: +##################################################################### + +qt_internal_add_test(tst_qgeopositioninfo + SOURCES + tst_qgeopositioninfo.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:qgeopositioninfo.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qgeopositioninfo/tst_qgeopositioninfo.cpp b/tests/auto/qgeopositioninfo/tst_qgeopositioninfo.cpp new file mode 100644 index 0000000..f92a13b --- /dev/null +++ b/tests/auto/qgeopositioninfo/tst_qgeopositioninfo.cpp @@ -0,0 +1,395 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include + +#include +#include +#include +#include +#include + +#include + +QT_USE_NAMESPACE + +Q_DECLARE_METATYPE(QGeoPositionInfo::Attribute) + +QByteArray tst_qgeopositioninfo_debug; + +void tst_qgeopositioninfo_messageHandler(QtMsgType type, const QMessageLogContext&, const QString &msg) +{ + switch (type) { + case QtDebugMsg : + tst_qgeopositioninfo_debug = msg.toLocal8Bit(); + break; + default: + break; + } +} + +QList tst_qgeopositioninfo_qrealTestValues() +{ + QList values; + + if (qreal(DBL_MIN) == DBL_MIN) + values << DBL_MIN; + + values << FLT_MIN; + values << -1.0 << 0.0 << 1.0; + values << FLT_MAX; + + if (qreal(DBL_MAX) == DBL_MAX) + values << DBL_MAX; + + return values; +} + +QList tst_qgeopositioninfo_getAttributes() +{ + QList attributes; + attributes << QGeoPositionInfo::Direction + << QGeoPositionInfo::GroundSpeed + << QGeoPositionInfo::VerticalSpeed + << QGeoPositionInfo::MagneticVariation + << QGeoPositionInfo::HorizontalAccuracy + << QGeoPositionInfo::VerticalAccuracy; + return attributes; +} + + +class tst_QGeoPositionInfo : public QObject +{ + Q_OBJECT + +private: + QGeoPositionInfo infoWithAttribute(QGeoPositionInfo::Attribute attribute, qreal value) + { + QGeoPositionInfo info; + info.setAttribute(attribute, value); + return info; + } + + void addTestData_info() + { + QTest::addColumn("info"); + + QTest::newRow("invalid") << QGeoPositionInfo(); + + QTest::newRow("coord") << QGeoPositionInfo(QGeoCoordinate(-27.3422,150.2342), QDateTime()); + QTest::newRow("datetime") << QGeoPositionInfo(QGeoCoordinate(), QDateTime::currentDateTime()); + + QList attributes = tst_qgeopositioninfo_getAttributes(); + QList values = tst_qgeopositioninfo_qrealTestValues(); + for (int i=0; i("coord"); + QTest::addColumn("dateTime"); + QTest::addColumn("valid"); + + QTest::newRow("both null") << QGeoCoordinate() << QDateTime() << false; + QTest::newRow("both valid") << QGeoCoordinate(1,1) << QDateTime::currentDateTime() << true; + QTest::newRow("valid coord") << QGeoCoordinate(1,1) << QDateTime() << false; + QTest::newRow("valid datetime") << QGeoCoordinate() << QDateTime::currentDateTime() << false; + QTest::newRow("valid time but not date == invalid") + << QGeoCoordinate() << QDateTime(QDate(), QTime::currentTime()) << false; + QTest::newRow("valid date but not time == valid due to QDateTime constructor") + << QGeoCoordinate() << QDateTime(QDate::currentDate(), QTime()) << false; + } + + void constructor_copy() + { + QFETCH(QGeoPositionInfo, info); + + QCOMPARE(QGeoPositionInfo(info), info); + } + + void constructor_copy_data() + { + addTestData_info(); + } + + void constructor_move() + { + QFETCH(QGeoPositionInfo, info); + QGeoPositionInfo infoCopy = info; + QCOMPARE(QGeoPositionInfo(std::move(info)), infoCopy); + // The moved-from object will go out of scope and will be destroyed + // here, so we also implicitly check that moved-from object's destructor + // is called without any issues. + } + + void constructor_move_data() + { + addTestData_info(); + } + + void operator_assign() + { + QFETCH(QGeoPositionInfo, info); + + QGeoPositionInfo info2; + info2 = info; + QCOMPARE(info2, info); + } + + void operator_assign_data() + { + addTestData_info(); + } + + void operator_move_assign() + { + QFETCH(QGeoPositionInfo, info); + QGeoPositionInfo infoCopy = info; + + QGeoPositionInfo obj; + obj = std::move(info); + QCOMPARE(obj, infoCopy); + + // check that (move)assigning to the moved-from object is ok + info = std::move(infoCopy); + QCOMPARE(info, obj); + } + + void operator_move_assign_data() + { + addTestData_info(); + } + + void operator_equals() + { + QFETCH(QGeoPositionInfo, info); + + QVERIFY(info == info); + if (info.isValid()) + QCOMPARE(info == QGeoPositionInfo(), false); + } + + void operator_equals_data() + { + addTestData_info(); + } + + void operator_notEquals() + { + QFETCH(QGeoPositionInfo, info); + + QCOMPARE(info != info, false); + if (info.isValid()) + QCOMPARE(info != QGeoPositionInfo(), true); + } + + void operator_notEquals_data() + { + addTestData_info(); + } + + void setDateTime() + { + QFETCH(QDateTime, dateTime); + + QGeoPositionInfo info; + info.setTimestamp(dateTime); + QCOMPARE(info.timestamp(), dateTime); + } + + void setDateTime_data() + { + QTest::addColumn("dateTime"); + QTest::newRow("invalid") << QDateTime(); + QTest::newRow("now") << QDateTime::currentDateTime(); + } + + void dateTime() + { + QGeoPositionInfo info; + QVERIFY(info.timestamp().isNull()); + } + + void setCoordinate() + { + + QFETCH(QGeoCoordinate, coord); + + QGeoPositionInfo info; + info.setCoordinate(coord); + QCOMPARE(info.coordinate(), coord); + } + + void setCoordinate_data() + { + QTest::addColumn("coord"); + + QTest::newRow("invalid") << QGeoCoordinate(); + QTest::newRow("valid") << QGeoCoordinate(30,30); + } + + void attribute() + { + QFETCH(QGeoPositionInfo::Attribute, attribute); + QFETCH(qreal, value); + + QGeoPositionInfo info; + QVERIFY(qIsNaN(info.attribute(attribute))); + + info.setAttribute(attribute, value); + QCOMPARE(info.attribute(attribute), value); + + info.removeAttribute(attribute); + QVERIFY(qIsNaN(info.attribute(attribute))); + } + + void attribute_data() + { + QTest::addColumn("attribute"); + QTest::addColumn("value"); + + QList attributes = tst_qgeopositioninfo_getAttributes(); + QList values = tst_qgeopositioninfo_qrealTestValues(); + for (int i=0; i> inInfo; + QCOMPARE(inInfo, info); + } + + void datastream_data() + { + addTestData_info(); + } + + void debug() + { + QFETCH(QGeoPositionInfo, info); + QFETCH(int, nextValue); + QFETCH(QByteArray, debugStringEnd); + + qInstallMessageHandler(tst_qgeopositioninfo_messageHandler); + qDebug() << info << nextValue; + qInstallMessageHandler(0); + + // use endsWith() so we don't depend on QDateTime's debug() implementation + QVERIFY2(tst_qgeopositioninfo_debug.endsWith(debugStringEnd), + qPrintable(QString::fromLatin1("'%1' does not end with '%2'"). + arg(QLatin1String(tst_qgeopositioninfo_debug), + QLatin1String(debugStringEnd)))); + } + + void debug_data() + { + QTest::addColumn("info"); + QTest::addColumn("nextValue"); + QTest::addColumn("debugStringEnd"); + + QTest::newRow("no values") << QGeoPositionInfo() << 40 + << QString("QGeoCoordinate(?, ?)) 40").toLatin1(); + + QGeoCoordinate coord(1, 1); + QTest::newRow("coord, time") << QGeoPositionInfo(coord, QDateTime::currentDateTime()) + << 40 << QByteArray("QGeoCoordinate(1, 1)) 40"); + + QGeoPositionInfo info; + info.setAttribute(QGeoPositionInfo::Direction, 1.1); + info.setAttribute(QGeoPositionInfo::GroundSpeed, 2.1); + info.setAttribute(QGeoPositionInfo::VerticalSpeed, 3.1); + info.setAttribute(QGeoPositionInfo::MagneticVariation, 4.1); + info.setAttribute(QGeoPositionInfo::HorizontalAccuracy, 5.1); + info.setAttribute(QGeoPositionInfo::VerticalAccuracy, 6.1); + QTest::newRow("all attributes") << info << 40 + << QByteArray("QGeoCoordinate(?, ?), Direction=1.1, GroundSpeed=2.1, VerticalSpeed=3.1, MagneticVariation=4.1, HorizontalAccuracy=5.1, VerticalAccuracy=6.1) 40"); + } +}; + + +QTEST_APPLESS_MAIN(tst_QGeoPositionInfo) +#include "tst_qgeopositioninfo.moc" diff --git a/tests/auto/qgeopositioninfosource/CMakeLists.txt b/tests/auto/qgeopositioninfosource/CMakeLists.txt new file mode 100644 index 0000000..462b64b --- /dev/null +++ b/tests/auto/qgeopositioninfosource/CMakeLists.txt @@ -0,0 +1,27 @@ +# Generated from qgeopositioninfosource.pro. + +##################################################################### +## tst_qgeopositioninfosource Test: +##################################################################### + +qt_internal_add_test(tst_qgeopositioninfosource + SOURCES + ../utils/qlocationtestutils.cpp ../utils/qlocationtestutils_p.h + testqgeopositioninfosource.cpp testqgeopositioninfosource_p.h + tst_qgeopositioninfosource.cpp + LIBRARIES + Qt::Core + Qt::Positioning + Qt::TestPrivate +) + +add_dependencies(tst_qgeopositioninfosource QGeoPositionInfoSourceFactoryTestPlugin) +if(ANDROID) + set_target_properties(tst_qgeopositioninfosource PROPERTIES + QT_ANDROID_EXTRA_PLUGINS "$" + ) +endif() + +#### Keys ignored in scope 1:.:.:qgeopositioninfosource.pro:: +# TEMPLATE = "app" +# testcase.timeout = "400" diff --git a/tests/auto/qgeopositioninfosource/testqgeopositioninfosource.cpp b/tests/auto/qgeopositioninfosource/testqgeopositioninfosource.cpp new file mode 100644 index 0000000..a50d680 --- /dev/null +++ b/tests/auto/qgeopositioninfosource/testqgeopositioninfosource.cpp @@ -0,0 +1,782 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "testqgeopositioninfosource_p.h" +#include "../utils/qlocationtestutils_p.h" + +Q_DECLARE_METATYPE(QGeoPositionInfoSource::PositioningMethod) +Q_DECLARE_METATYPE(QGeoPositionInfoSource::PositioningMethods) + +#define MAX_WAITING_TIME 50000 + +// Must provide a valid source, unless testing the source +// returned by QGeoPositionInfoSource::createDefaultSource() on a system +// that has no default source +#define CHECK_SOURCE_VALID { \ + if (!m_source) { \ + if (m_testingDefaultSource && QGeoPositionInfoSource::createDefaultSource(0) == 0) \ + QSKIP("No default position source on this system"); \ + else \ + QFAIL("createTestSource() must return a valid source!"); \ + } \ + } + +class MyPositionSource : public QGeoPositionInfoSource +{ + Q_OBJECT +public: + MyPositionSource(QObject *parent = 0) + : QGeoPositionInfoSource(parent) { + } + + QGeoPositionInfo lastKnownPosition(bool /*fromSatellitePositioningMethodsOnly = false*/) const override { + return QGeoPositionInfo(); + } + + void setSupportedPositioningMethods(PositioningMethods methods) { + m_methods = methods; + } + + virtual PositioningMethods supportedPositioningMethods() const override { + return m_methods; + } + virtual int minimumUpdateInterval() const override { + return 0; + } + + virtual void startUpdates() override {} + virtual void stopUpdates() override {} + + virtual void requestUpdate(int) override {} + + Error error() const override { return QGeoPositionInfoSource::NoError; } + +private: + PositioningMethods m_methods; +}; + +class DefaultSourceTest : public TestQGeoPositionInfoSource +{ + Q_OBJECT +protected: + QGeoPositionInfoSource *createTestSource() override { + return QGeoPositionInfoSource::createSource(QStringLiteral("test.source"), 0); + } +}; + + +TestQGeoPositionInfoSource::TestQGeoPositionInfoSource(QObject *parent) + : QObject(parent) +{ + m_testingDefaultSource = false; +#if QT_CONFIG(library) + /* + * Set custom path since CI doesn't install test plugins + */ +#ifdef Q_OS_WIN + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#else + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../plugins")); +#endif +#endif +} + +TestQGeoPositionInfoSource *TestQGeoPositionInfoSource::createDefaultSourceTest() +{ + DefaultSourceTest *test = new DefaultSourceTest; + test->m_testingDefaultSource = true; + return test; +} + +void TestQGeoPositionInfoSource::test_slot1() +{ +} + +void TestQGeoPositionInfoSource::test_slot2() +{ + m_testSlot2Called = true; +} + +void TestQGeoPositionInfoSource::base_initTestCase() +{ + +} + +void TestQGeoPositionInfoSource::base_init() +{ + m_source = createTestSource(); + m_testSlot2Called = false; +} + +void TestQGeoPositionInfoSource::base_cleanup() +{ + delete m_source; + m_source = 0; +} + +void TestQGeoPositionInfoSource::base_cleanupTestCase() +{ +} + +void TestQGeoPositionInfoSource::initTestCase() +{ + base_initTestCase(); +} + +void TestQGeoPositionInfoSource::init() +{ + base_init(); +} + +void TestQGeoPositionInfoSource::cleanup() +{ + base_cleanup(); +} + +void TestQGeoPositionInfoSource::cleanupTestCase() +{ + base_cleanupTestCase(); +} + +// TC_ID_3_x_1 +void TestQGeoPositionInfoSource::constructor_withParent() +{ + auto parent = std::make_unique(); + new MyPositionSource(parent.get()); +} + +// TC_ID_3_x_2 +void TestQGeoPositionInfoSource::constructor_noParent() +{ + MyPositionSource *obj = new MyPositionSource(); + delete obj; +} + +void TestQGeoPositionInfoSource::updateInterval() +{ + MyPositionSource s; + QCOMPARE(s.updateInterval(), 0); +} + +void TestQGeoPositionInfoSource::setPreferredPositioningMethods() +{ + QFETCH(QGeoPositionInfoSource::PositioningMethod, supported); + QFETCH(QGeoPositionInfoSource::PositioningMethod, preferred); + QFETCH(QGeoPositionInfoSource::PositioningMethod, resulting); + + MyPositionSource s; + s.setSupportedPositioningMethods(supported); + s.setPreferredPositioningMethods(preferred); + QCOMPARE(s.preferredPositioningMethods(), resulting); +} + +void TestQGeoPositionInfoSource::setPreferredPositioningMethods_data() +{ + QTest::addColumn("supported"); + QTest::addColumn("preferred"); + QTest::addColumn("resulting"); + + QTest::newRow("Sat supported, Sat preferred") + << QGeoPositionInfoSource::SatellitePositioningMethods + << QGeoPositionInfoSource::SatellitePositioningMethods + << QGeoPositionInfoSource::SatellitePositioningMethods; + QTest::newRow("Sat supported, Non-Sat preferred") + << QGeoPositionInfoSource::SatellitePositioningMethods + << QGeoPositionInfoSource::NonSatellitePositioningMethods + << QGeoPositionInfoSource::SatellitePositioningMethods; + QTest::newRow("Sat supported, All preferred") + << QGeoPositionInfoSource::SatellitePositioningMethods + << QGeoPositionInfoSource::AllPositioningMethods + << QGeoPositionInfoSource::SatellitePositioningMethods; + + QTest::newRow("Non-Sat supported, Sat preferred") + << QGeoPositionInfoSource::NonSatellitePositioningMethods + << QGeoPositionInfoSource::SatellitePositioningMethods + << QGeoPositionInfoSource::NonSatellitePositioningMethods; + QTest::newRow("Non-Sat supported, Non-Sat preferred") + << QGeoPositionInfoSource::NonSatellitePositioningMethods + << QGeoPositionInfoSource::NonSatellitePositioningMethods + << QGeoPositionInfoSource::NonSatellitePositioningMethods; + QTest::newRow("Non-Sat supported, All preferred") + << QGeoPositionInfoSource::NonSatellitePositioningMethods + << QGeoPositionInfoSource::AllPositioningMethods + << QGeoPositionInfoSource::NonSatellitePositioningMethods; + + QTest::newRow("All supported, Sat preferred") + << QGeoPositionInfoSource::AllPositioningMethods + << QGeoPositionInfoSource::SatellitePositioningMethods + << QGeoPositionInfoSource::SatellitePositioningMethods; + QTest::newRow("All supported, Non-Sat preferred") + << QGeoPositionInfoSource::AllPositioningMethods + << QGeoPositionInfoSource::NonSatellitePositioningMethods + << QGeoPositionInfoSource::NonSatellitePositioningMethods; + QTest::newRow("All supported, All preferred") + << QGeoPositionInfoSource::AllPositioningMethods + << QGeoPositionInfoSource::AllPositioningMethods + << QGeoPositionInfoSource::AllPositioningMethods; +} + +void TestQGeoPositionInfoSource::preferredPositioningMethods() +{ + MyPositionSource s; + QCOMPARE(s.preferredPositioningMethods(), 0); +} + +//TC_ID_3_x_1 : Create a position source with the given parent that reads from the system's default +// sources of location data +void TestQGeoPositionInfoSource::createDefaultSource() +{ + auto parent = std::make_unique(); + + // source will be deleted when parent goes out of scope + QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(parent.get()); + // now all platforms have the dummy plugin at least + QVERIFY(source != nullptr); +} + +void TestQGeoPositionInfoSource::setUpdateInterval() +{ + CHECK_SOURCE_VALID; + + QFETCH(int, interval); + QFETCH(int, expectedInterval); + + m_source->setUpdateInterval(interval); + QCOMPARE(m_source->updateInterval(), expectedInterval); +} + +void TestQGeoPositionInfoSource::setUpdateInterval_data() +{ + QTest::addColumn("interval"); + QTest::addColumn("expectedInterval"); + QGeoPositionInfoSource *source = createTestSource(); + int minUpdateInterval = source ? source->minimumUpdateInterval() : -1; + if (source) + delete source; + + QTest::newRow("0") << 0 << 0; + + if (minUpdateInterval > -1) { + QTest::newRow("INT_MIN") << INT_MIN << minUpdateInterval; + QTest::newRow("-1") << -1 << minUpdateInterval; + } + + if (minUpdateInterval > 0) { + QTest::newRow("more than minInterval") << minUpdateInterval + 1 << minUpdateInterval + 1; + QTest::newRow("equal to minInterval") << minUpdateInterval << minUpdateInterval; + } + + if (minUpdateInterval > 1) { + QTest::newRow("less then minInterval") << minUpdateInterval - 1 << minUpdateInterval; + QTest::newRow("in btw zero and minInterval") << 1 << minUpdateInterval; + } +} + +void TestQGeoPositionInfoSource::lastKnownPosition() +{ + CHECK_SOURCE_VALID; + QFETCH(QGeoPositionInfoSource::PositioningMethod, positioningMethod); + QFETCH(bool, lastKnownPositionArgument); + + if ((m_source->supportedPositioningMethods() & positioningMethod) == 0) + QSKIP("Not a supported positioning method for this position source"); + + m_source->setPreferredPositioningMethods(positioningMethod); + + QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy timeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->setUpdateInterval(1000); + m_source->startUpdates(); + + // Use QEventLoop instead of qWait() to ensure we stop as soon as a + // position is emitted (otherwise the lastKnownPosition() may have + // changed by the time it is checked) + QEventLoop loop; + QTimer timer; + //simulated CI tests will quickly return -> real GPS tests take 2 minutes for satellite systems + //use a 5 min timeout + timer.setInterval(300000); + connect(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), + &loop, SLOT(quit())); + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.start(); + loop.exec(); + + QVERIFY((spy.size() > 0) && (timeout.size() == 0)); + + QList list = spy.takeFirst(); + QGeoPositionInfo info = list.at(0).value(); + QGeoPositionInfo lastPositioninfo = m_source->lastKnownPosition(lastKnownPositionArgument); + + // lastPositioninfo is only gauranteed to be valid in all cases when only using satelite + // positioning methods or when lastKnownPositionArgument is false + if (!lastKnownPositionArgument || + positioningMethod == QGeoPositionInfoSource::SatellitePositioningMethods) { + QVERIFY(lastPositioninfo.isValid()); + } + + if (lastPositioninfo.isValid()) { + QCOMPARE(info.coordinate(), lastPositioninfo.coordinate()); + // On some CI machines the above evenloop code is not sufficient as positionUpdated + // still fires causing last know position and last update to be out of sync. + // To accommodate we check that the time stamps are no more than 1s apart + // ideally they should be the same + // doesn't work: QCOMPARE(info.timestamp(), lastPositioninfo.timestamp()); + const qint64 diff = qAbs(info.timestamp().msecsTo(lastPositioninfo.timestamp())); + QCOMPARE(diff < 1000, true); + + QCOMPARE(info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy), + lastPositioninfo.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)); + + if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) { + bool isNaN1 = qIsNaN(info.attribute(QGeoPositionInfo::HorizontalAccuracy)); + bool isNaN2 = qIsNaN(lastPositioninfo.attribute(QGeoPositionInfo::HorizontalAccuracy)); + QCOMPARE(isNaN1, isNaN2); + if (!isNaN1) { + QCOMPARE(qFuzzyCompare(info.attribute(QGeoPositionInfo::HorizontalAccuracy), + lastPositioninfo.attribute(QGeoPositionInfo::HorizontalAccuracy)), true); + } + } + + QCOMPARE(info.hasAttribute(QGeoPositionInfo::VerticalAccuracy), + lastPositioninfo.hasAttribute(QGeoPositionInfo::VerticalAccuracy)); + + if (info.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) { + bool isNaN1 = qIsNaN(info.attribute(QGeoPositionInfo::VerticalAccuracy)); + bool isNaN2 = qIsNaN(lastPositioninfo.attribute(QGeoPositionInfo::VerticalAccuracy)); + QCOMPARE(isNaN1, isNaN2); + if (!isNaN1) { + QCOMPARE(qFuzzyCompare(info.attribute(QGeoPositionInfo::VerticalAccuracy), + lastPositioninfo.attribute(QGeoPositionInfo::VerticalAccuracy)), true); + } + } + } + + m_source->stopUpdates(); +} + +void TestQGeoPositionInfoSource::lastKnownPosition_data() +{ + QTest::addColumn("positioningMethod"); + QTest::addColumn("lastKnownPositionArgument"); + + // no good way to determine on MeeGo what are supported. If we ask for all or non-satellites, we + // typically get geoclue-example provider, which is not suitable for this test. + QTest::newRow("all - false") << QGeoPositionInfoSource::AllPositioningMethods << false; + QTest::newRow("all - true") << QGeoPositionInfoSource::AllPositioningMethods << true; + QTest::newRow("satellite - false") << QGeoPositionInfoSource::SatellitePositioningMethods << false; + QTest::newRow("satellite - true") << QGeoPositionInfoSource::SatellitePositioningMethods << true; +} + +void TestQGeoPositionInfoSource::minimumUpdateInterval() +{ + CHECK_SOURCE_VALID; + + QVERIFY(m_source->minimumUpdateInterval() > 0); +} + +//TC_ID_3_x_1 +void TestQGeoPositionInfoSource::startUpdates_testIntervals() +{ + CHECK_SOURCE_VALID; + QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy timeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->setUpdateInterval(1000); + const int interval = 15000; + + m_source->startUpdates(); + + QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, interval); + for (int i = 0; i < 6; i++) { + QTRY_VERIFY_WITH_TIMEOUT((spy.size() == 1) && (timeout.size() == 0), interval); + spy.clear(); + } + + m_source->stopUpdates(); +} + + +void TestQGeoPositionInfoSource::startUpdates_testIntervalChangesWhileRunning() +{ + // There are two ways of dealing with an interval change, and we have left it system dependent. + // The interval can be changed will running or after the next update. + // WinCE uses the first method, S60 uses the second method. + + CHECK_SOURCE_VALID; + + QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy timeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->setUpdateInterval(0); + m_source->startUpdates(); + m_source->setUpdateInterval(0); + + QTRY_VERIFY_WITH_TIMEOUT(spy.size() > 0, 3000); + QCOMPARE(timeout.size(), 0); + spy.clear(); + + m_source->setUpdateInterval(1000); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() == 2) && (timeout.size() == 0), 15000); + spy.clear(); + + m_source->setUpdateInterval(2000); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() == 2) && (timeout.size() == 0), 30000); + spy.clear(); + + m_source->setUpdateInterval(1000); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() == 2) && (timeout.size() == 0), 15000); + spy.clear(); + + m_source->setUpdateInterval(1000); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() == 2) && (timeout.size() == 0), 15000); + spy.clear(); + + m_source->setUpdateInterval(0); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() > 0) && (timeout.size() == 0), 7000); + spy.clear(); + + m_source->setUpdateInterval(0); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() > 0) && (timeout.size() == 0), 7000); + spy.clear(); + + m_source->stopUpdates(); +} + +//TC_ID_3_x_2 +void TestQGeoPositionInfoSource::startUpdates_testDefaultInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy timeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->startUpdates(); + for (int i = 0; i < 3; i++) { + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() > 0) && (timeout.size() == 0), 7000); + spy.clear(); + } + m_source->stopUpdates(); +} + +//TC_ID_3_x_3 +void TestQGeoPositionInfoSource::startUpdates_testZeroInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy timeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->setUpdateInterval(0); + m_source->startUpdates(); + for (int i = 0; i < 3; i++) { + QTRY_VERIFY_WITH_TIMEOUT((spy.size() > 0) && (timeout.size() == 0), 7000); + spy.clear(); + } + m_source->stopUpdates(); +} + +void TestQGeoPositionInfoSource::startUpdates_moreThanOnce() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy timeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->setUpdateInterval(0); + m_source->startUpdates(); + + m_source->startUpdates(); // check there is no crash + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() > 0) && (timeout.size() == 0), 7000); + + m_source->startUpdates(); // check there is no crash + + m_source->stopUpdates(); +} + +//TC_ID_3_x_1 +void TestQGeoPositionInfoSource::stopUpdates() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy timeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->setUpdateInterval(1000); + m_source->startUpdates(); + for (int i = 0; i < 2; i++) { + QTRY_VERIFY_WITH_TIMEOUT((spy.size() > 0) && (timeout.size() == 0), 9500); + spy.clear(); + } + m_source->stopUpdates(); + QTest::qWait(2000); + QCOMPARE(spy.size(), 0); + spy.clear(); + + m_source->setUpdateInterval(0); + m_source->startUpdates(); + m_source->stopUpdates(); + QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 0, 9500); +} + +//TC_ID_3_x_2 +void TestQGeoPositionInfoSource::stopUpdates_withoutStart() +{ + CHECK_SOURCE_VALID; + m_source->stopUpdates(); // check there is no crash +} + +void TestQGeoPositionInfoSource::requestUpdate() +{ + CHECK_SOURCE_VALID; + QFETCH(int, timeout); + QSignalSpy spy(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->requestUpdate(timeout); + QTRY_COMPARE(spy.size(), 1); + const QList arguments = spy.takeFirst(); + const auto error = arguments.at(0).value(); + QCOMPARE(error, QGeoPositionInfoSource::UpdateTimeoutError); +} + +void TestQGeoPositionInfoSource::requestUpdate_data() +{ + QTest::addColumn("timeout"); + QTest::newRow("less than zero") << -1; //TC_ID_3_x_7 +} + +// TC_ID_3_x_1 : Create position source and call requestUpdate with valid timeout value +void TestQGeoPositionInfoSource::requestUpdate_validTimeout() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + // currently all the sources have a minimumUpdateInterval <= 1000 + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), 7000); +} + +void TestQGeoPositionInfoSource::requestUpdate_defaultTimeout() +{ + CHECK_SOURCE_VALID; + QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + m_source->requestUpdate(0); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), 7000); +} + +// TC_ID_3_x_2 : Create position source and call requestUpdate with a timeout less than +// minimumupdateInterval +void TestQGeoPositionInfoSource::requestUpdate_timeoutLessThanMinimumInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + m_source->requestUpdate(1); + + QTRY_COMPARE_WITH_TIMEOUT(spyTimeout.size(), 1, 1000); + const QList arguments = spyTimeout.takeFirst(); + const auto error = arguments.at(0).value(); + QCOMPARE(error, QGeoPositionInfoSource::UpdateTimeoutError); +} + +// TC_ID_3_x_3 : Call requestUpdate() with same value repeatedly +void TestQGeoPositionInfoSource::requestUpdate_repeatedCalls() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + // currently all the sources have a minimumUpdateInterval <= 1000 + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), 7000); + spyUpdate.clear(); + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), 7000); +} + +void TestQGeoPositionInfoSource::requestUpdate_overlappingCalls() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + // currently all the sources have a minimumUpdateInterval <= 1000 + m_source->requestUpdate(1500); + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), 7000); +} + +//TC_ID_3_x_4 +void TestQGeoPositionInfoSource::requestUpdateAfterStartUpdates_ZeroInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + m_source->setUpdateInterval(0); + m_source->startUpdates(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), 7000); + spyUpdate.clear(); + + m_source->requestUpdate(1500); + QTest::qWait(7000); + + QVERIFY((spyUpdate.size() > 0) && (spyTimeout.size() == 0)); + spyUpdate.clear(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), MAX_WAITING_TIME); + + m_source->stopUpdates(); +} + +void TestQGeoPositionInfoSource::requestUpdateAfterStartUpdates_SmallInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + m_source->setUpdateInterval(2000); + m_source->startUpdates(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() == 1) && (spyTimeout.size() == 0), 20000); + spyUpdate.clear(); + + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() == 1) && (spyTimeout.size() == 0), 7000); + spyUpdate.clear(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() == 1) && (spyTimeout.size() == 0), 20000); + + m_source->stopUpdates(); +} + +void TestQGeoPositionInfoSource::requestUpdateBeforeStartUpdates_ZeroInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + m_source->requestUpdate(1500); + + m_source->setUpdateInterval(0); + m_source->startUpdates(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() >= 2) && (spyTimeout.size() == 0), 14000); + spyUpdate.clear(); + + QTest::qWait(1500); + + QCOMPARE(spyTimeout.size(), 0); + + m_source->stopUpdates(); +} + +void TestQGeoPositionInfoSource::requestUpdateBeforeStartUpdates_SmallInterval() +{ + CHECK_SOURCE_VALID; + QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + m_source->requestUpdate(1500); + + m_source->setUpdateInterval(3000); + m_source->startUpdates(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), 7000); + spyUpdate.clear(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() > 0) && (spyTimeout.size() == 0), 20000); + + m_source->stopUpdates(); +} + +void TestQGeoPositionInfoSource::removeSlotForRequestTimeout() +{ + CHECK_SOURCE_VALID; + + bool i = connect(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error)), + this, SLOT(test_slot1())); + QVERIFY(i == true); + i = connect(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error)), + this, SLOT(test_slot2())); + QVERIFY(i == true); + i = disconnect(m_source, SIGNAL(errorOccurred(QGeoPositionInfoSource::Error)), + this, SLOT(test_slot1())); + QVERIFY(i == true); + + m_source->requestUpdate(-1); + QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 1000); +} + +void TestQGeoPositionInfoSource::removeSlotForPositionUpdated() +{ + CHECK_SOURCE_VALID; + + bool i = connect(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(test_slot1())); + QVERIFY(i == true); + i = connect(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(test_slot2())); + QVERIFY(i == true); + i = disconnect(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(test_slot1())); + QVERIFY(i == true); + + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 7000); +} + +void TestQGeoPositionInfoSource::updateIntervalBinding() +{ + auto parent = std::make_unique(); + // source will be deleted when parent goes out of scope + QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(parent.get()); + QVERIFY(source != nullptr); + + QTestPrivate::testReadWritePropertyBasics(*source, 1000, 2000, + "updateInterval"); +} + +void TestQGeoPositionInfoSource::preferredMethodsBinding() +{ + auto parent = std::make_unique(); + // source will be deleted when parent goes out of scope + QGeoPositionInfoSource *source = + QGeoPositionInfoSource::createSource("test.source", parent.get()); + QVERIFY(source != nullptr); + + QTestPrivate::testReadWritePropertyBasics( + *source, QGeoPositionInfoSource::SatellitePositioningMethods, + QGeoPositionInfoSource::AllPositioningMethods, "preferredPositioningMethods"); +} + +#include "testqgeopositioninfosource.moc" diff --git a/tests/auto/qgeopositioninfosource/testqgeopositioninfosource_p.h b/tests/auto/qgeopositioninfosource/testqgeopositioninfosource_p.h new file mode 100644 index 0000000..014ce16 --- /dev/null +++ b/tests/auto/qgeopositioninfosource/testqgeopositioninfosource_p.h @@ -0,0 +1,104 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef TESTQGEOPOSITIONINFOSOURCE_P_H +#define TESTQGEOPOSITIONINFOSOURCE_P_H + +#ifdef TST_GEOCLUEMOCK_ENABLED +#include "geocluemock.h" +#include +#endif + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QGeoPositionInfoSource; +QT_END_NAMESPACE + +class TestQGeoPositionInfoSource : public QObject +{ + Q_OBJECT + +public: + TestQGeoPositionInfoSource(QObject *parent = 0); + + static TestQGeoPositionInfoSource *createDefaultSourceTest(); + +public slots: + void test_slot1(); + void test_slot2(); + +protected: + virtual QGeoPositionInfoSource *createTestSource() = 0; + + // MUST be called by subclasses if they override respective test slots + void base_initTestCase(); + void base_init(); + void base_cleanup(); + void base_cleanupTestCase(); + +private slots: + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + void constructor_withParent(); + + void constructor_noParent(); + + void updateInterval(); + + void setPreferredPositioningMethods(); + void setPreferredPositioningMethods_data(); + + void preferredPositioningMethods(); + + void createDefaultSource(); + + void setUpdateInterval(); + void setUpdateInterval_data(); + + void lastKnownPosition(); + void lastKnownPosition_data(); + + void minimumUpdateInterval(); + + void startUpdates_testIntervals(); + void startUpdates_testIntervalChangesWhileRunning(); + void startUpdates_testDefaultInterval(); + void startUpdates_testZeroInterval(); + void startUpdates_moreThanOnce(); + + void stopUpdates(); + void stopUpdates_withoutStart(); + + void requestUpdate(); + void requestUpdate_data(); + + void requestUpdate_validTimeout(); + void requestUpdate_defaultTimeout(); + void requestUpdate_timeoutLessThanMinimumInterval(); + void requestUpdate_repeatedCalls(); + void requestUpdate_overlappingCalls(); + + void requestUpdateAfterStartUpdates_ZeroInterval(); + void requestUpdateAfterStartUpdates_SmallInterval(); + void requestUpdateBeforeStartUpdates_ZeroInterval(); + void requestUpdateBeforeStartUpdates_SmallInterval(); + + void removeSlotForRequestTimeout(); + void removeSlotForPositionUpdated(); + + void updateIntervalBinding(); + void preferredMethodsBinding(); + +private: + QGeoPositionInfoSource *m_source; + bool m_testingDefaultSource; + bool m_testSlot2Called; +}; + +#endif diff --git a/tests/auto/qgeopositioninfosource/tst_qgeopositioninfosource.cpp b/tests/auto/qgeopositioninfosource/tst_qgeopositioninfosource.cpp new file mode 100644 index 0000000..15f4c55 --- /dev/null +++ b/tests/auto/qgeopositioninfosource/tst_qgeopositioninfosource.cpp @@ -0,0 +1,12 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "testqgeopositioninfosource_p.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + std::unique_ptr test( + TestQGeoPositionInfoSource::createDefaultSourceTest()); + return QTest::qExec(test.get(), argc, argv); +} diff --git a/tests/auto/qgeorectangle/CMakeLists.txt b/tests/auto/qgeorectangle/CMakeLists.txt new file mode 100644 index 0000000..22c660b --- /dev/null +++ b/tests/auto/qgeorectangle/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from qgeorectangle.pro. + +##################################################################### +## tst_qgeorectangle Test: +##################################################################### + +qt_internal_add_test(tst_qgeorectangle + SOURCES + tst_qgeorectangle.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:qgeorectangle.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp new file mode 100644 index 0000000..7de2676 --- /dev/null +++ b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp @@ -0,0 +1,2394 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_QGeoRectangle : public QObject +{ + Q_OBJECT + +private slots: + void default_constructor(); + void center_constructor(); + void corner_constructor(); + void list_constructor(); + void copy_constructor(); + void assignment(); + void destructor(); + + void equality(); + void equality_data(); + + void isValid(); + void isValid_data(); + + void isEmpty(); + void isEmpty_data(); + + void corners(); + void corners_data(); + + void setCorners(); + + void width(); + void width_data(); + + void height(); + void height_data(); + + void center(); + void center_data(); + + void boundingGeoRectangle(); + void boundingGeoRectangle_data(); + + void containsCoord(); + void containsCoord_data(); + + void containsBoxAndIntersects(); + void containsBoxAndIntersects_data(); + + void translate(); + void translate_data(); + + void unite(); + void unite_data(); + + void extendRectangle(); + void extendRectangle_data(); + + void areaComparison(); + void areaComparison_data(); + + void circleComparison(); + void circleComparison_data(); + + void hashing(); +}; + +void tst_QGeoRectangle::default_constructor() +{ + QGeoRectangle box; + QCOMPARE(box.topLeft().isValid(), false); + QCOMPARE(box.bottomRight().isValid(), false); +} + +void tst_QGeoRectangle::center_constructor() +{ + QGeoRectangle b1 = QGeoRectangle(QGeoCoordinate(5.0, 5.0), 10.0, 10.0); + + QCOMPARE(b1.topLeft(), QGeoCoordinate(10.0, 0.0)); + QCOMPARE(b1.bottomRight(), QGeoCoordinate(0.0, 10.0)); +} + +void tst_QGeoRectangle::corner_constructor() +{ + QGeoRectangle b1 = QGeoRectangle(QGeoCoordinate(10.0, 0.0), + QGeoCoordinate(0.0, 10.0)); + + QCOMPARE(b1.topLeft(), QGeoCoordinate(10.0, 0.0)); + QCOMPARE(b1.bottomRight(), QGeoCoordinate(0.0, 10.0)); +} + +void tst_QGeoRectangle::list_constructor() +{ + QList coordinates; + QGeoRectangle b1 = QGeoRectangle(coordinates); + QCOMPARE(b1.isValid(), false); + + coordinates << QGeoCoordinate(10.0, 0.0); + b1 = QGeoRectangle(coordinates); + QCOMPARE(b1.isValid(), true); + QCOMPARE(b1.isEmpty(), true); + + coordinates << QGeoCoordinate(0.0, 10.0) << QGeoCoordinate(0.0, 5.0); + b1 = QGeoRectangle(coordinates); + QCOMPARE(b1.topLeft(), QGeoCoordinate(10.0,0.0)); + QCOMPARE(b1.bottomRight(), QGeoCoordinate(0.0, 10.0)); +} + +void tst_QGeoRectangle::copy_constructor() +{ + QGeoRectangle b1 = QGeoRectangle(QGeoCoordinate(10.0, 0.0), + QGeoCoordinate(0.0, 10.0)); + QGeoRectangle b2 = QGeoRectangle(b1); + + QCOMPARE(b2.topLeft(), QGeoCoordinate(10.0, 0.0)); + QCOMPARE(b2.bottomRight(), QGeoCoordinate(0.0, 10.0)); + + b2.setTopLeft(QGeoCoordinate(30.0, 0.0)); + b2.setBottomRight(QGeoCoordinate(0.0, 30.0)); + QCOMPARE(b1.topLeft(), QGeoCoordinate(10.0, 0.0)); + QCOMPARE(b1.bottomRight(), QGeoCoordinate(0.0, 10.0)); + + QGeoShape area; + QGeoRectangle areaBox(area); + QVERIFY(!areaBox.isValid()); + QVERIFY(areaBox.isEmpty()); + + QGeoCircle circle; + QGeoRectangle circleBox(circle); + QVERIFY(!circleBox.isValid()); + QVERIFY(circleBox.isEmpty()); +} + +void tst_QGeoRectangle::destructor() +{ + QGeoRectangle *box = new QGeoRectangle(); + delete box; + // checking for a crash +} + +void tst_QGeoRectangle::assignment() +{ + QGeoRectangle b1 = QGeoRectangle(QGeoCoordinate(10.0, 0.0), + QGeoCoordinate(0.0, 10.0)); + QGeoRectangle b2 = QGeoRectangle(QGeoCoordinate(20.0, 0.0), + QGeoCoordinate(0.0, 20.0)); + + QVERIFY(b1 != b2); + + b2 = b1; + QCOMPARE(b2.topLeft(), QGeoCoordinate(10.0, 0.0)); + QCOMPARE(b2.bottomRight(), QGeoCoordinate(0.0, 10.0)); + QCOMPARE(b1, b2); + + b2.setTopLeft(QGeoCoordinate(30.0, 0.0)); + b2.setBottomRight(QGeoCoordinate(0.0, 30.0)); + QCOMPARE(b1.topLeft(), QGeoCoordinate(10.0, 0.0)); + QCOMPARE(b1.bottomRight(), QGeoCoordinate(0.0, 10.0)); + + // Assign b1 to an area + QGeoShape area = b1; + QCOMPARE(area.type(), b1.type()); + QVERIFY(area == b1); + + // Assign the area back to a bounding box + QGeoRectangle ba = area; + QCOMPARE(ba.topLeft(), b1.topLeft()); + QCOMPARE(ba.bottomRight(), b1.bottomRight()); + + // Check that the copy is not modified when modifying the original. + b1.setTopLeft(QGeoCoordinate(80, 30)); + QVERIFY(ba.topLeft() != b1.topLeft()); + QVERIFY(ba != b1); +} + +void tst_QGeoRectangle::equality() +{ + QFETCH(QGeoRectangle, box1); + QFETCH(QGeoRectangle, box2); + QFETCH(QGeoShape, area1); + QFETCH(QGeoShape, area2); + QFETCH(bool, equal); + + // compare boxes + QCOMPARE((box1 == box2), equal); + QCOMPARE((box1 != box2), !equal); + + // compare areas + QCOMPARE((area1 == area2), equal); + QCOMPARE((area1 != area2), !equal); + + // compare area to box + QCOMPARE((area1 == box2), equal); + QCOMPARE((area1 != box2), !equal); + + // compare box to area + QCOMPARE((box1 == area2), equal); + QCOMPARE((box1 != area2), !equal); +} + +void tst_QGeoRectangle::equality_data() +{ + QTest::addColumn("box1"); + QTest::addColumn("box2"); + QTest::addColumn("area1"); + QTest::addColumn("area2"); + QTest::addColumn("equal"); + + QGeoCoordinate c1(10, 5); + QGeoCoordinate c2(5, 10); + QGeoCoordinate c3(20, 15); + QGeoCoordinate c4(15, 20); + + QGeoRectangle b1(c1, c2); + QGeoRectangle b2(c3, c4); + QGeoRectangle b3(c3, c2); + QGeoRectangle b4(c1, c3); + QGeoRectangle b5(c1, c2); + + QGeoShape a1(b1); + QGeoShape a2(b2); + QGeoShape a3(b3); + QGeoShape a4(b4); + QGeoShape a5(b5); + + QTest::newRow("all unequal") + << b1 << b2 << a1 << a2 << false; + QTest::newRow("top left unequal") + << b1 << b3 << a1 << a3 << false; + QTest::newRow("bottom right unequal") + << b1 << b4 << a1 << a4 << false; + QTest::newRow("equal") + << b1 << b5 << a1 << a5 << true; +} + +void tst_QGeoRectangle::isValid() +{ + QFETCH(QGeoRectangle, input); + QFETCH(bool, valid); + + QCOMPARE(input.isValid(), valid); + + QGeoShape area = input; + QCOMPARE(area.isValid(), valid); +} + +void tst_QGeoRectangle::isValid_data() +{ + QTest::addColumn("input"); + QTest::addColumn("valid"); + + QGeoCoordinate c0; + QGeoCoordinate c1(10, 5); + QGeoCoordinate c2(5, 10); + + QTest::newRow("both corners invalid") + << QGeoRectangle(c0, c0) << false; + QTest::newRow("top left corner invalid") + << QGeoRectangle(c0, c2) << false; + QTest::newRow("bottom right corner invalid") + << QGeoRectangle(c1, c0) << false; + QTest::newRow("height in wrong order") + << QGeoRectangle(c2, c1) << false; + QTest::newRow("both corners valid") + << QGeoRectangle(c1, c2) << true; +} + +void tst_QGeoRectangle::isEmpty() +{ + QFETCH(QGeoRectangle, input); + QFETCH(bool, empty); + + QCOMPARE(input.isEmpty(), empty); + + QGeoShape area = input; + QCOMPARE(area.isEmpty(), empty); +} + +void tst_QGeoRectangle::isEmpty_data() +{ + QTest::addColumn("input"); + QTest::addColumn("empty"); + + QGeoCoordinate c0; + QGeoCoordinate c1(10, 5); + QGeoCoordinate c2(5, 10); + QGeoCoordinate c3(10, 10); + + QTest::newRow("both corners invalid") + << QGeoRectangle(c0, c0) << true; + QTest::newRow("top left corner invalid") + << QGeoRectangle(c0, c2) << true; + QTest::newRow("bottom right corner invalid") + << QGeoRectangle(c1, c0) << true; + QTest::newRow("zero width") + << QGeoRectangle(c1, c3) << true; + QTest::newRow("zero height") + << QGeoRectangle(c3, c2) << true; + QTest::newRow("zero width and height") + << QGeoRectangle(c1, c1) << true; + QTest::newRow("non-zero width and height") + << QGeoRectangle(c1, c2) << false; +} + +void tst_QGeoRectangle::corners() +{ + QFETCH(QGeoRectangle, box); + QFETCH(QGeoCoordinate, topLeft); + QFETCH(QGeoCoordinate, topRight); + QFETCH(QGeoCoordinate, bottomLeft); + QFETCH(QGeoCoordinate, bottomRight); + + QCOMPARE(box.topLeft(), topLeft); + QCOMPARE(box.topRight(), topRight); + QCOMPARE(box.bottomLeft(), bottomLeft); + QCOMPARE(box.bottomRight(), bottomRight); +} + +void tst_QGeoRectangle::corners_data() +{ + QTest::addColumn("box"); + QTest::addColumn("topLeft"); + QTest::addColumn("topRight"); + QTest::addColumn("bottomLeft"); + QTest::addColumn("bottomRight"); + + QGeoCoordinate c0; + QGeoCoordinate tl(10, 5); + QGeoCoordinate br(5, 10); + QGeoCoordinate tr(10, 10); + QGeoCoordinate bl(5, 5); + + QTest::newRow("both invalid") + << QGeoRectangle(c0, c0) + << c0 + << c0 + << c0 + << c0; + QTest::newRow("top left invalid") + << QGeoRectangle(c0, br) + << c0 + << c0 + << c0 + << br; + QTest::newRow("bottom right invalid") + << QGeoRectangle(tl, c0) + << tl + << c0 + << c0 + << c0; + QTest::newRow("both valid") + << QGeoRectangle(tl, br) + << tl + << tr + << bl + << br; +} + +void tst_QGeoRectangle::setCorners() +{ + QGeoRectangle box(QGeoCoordinate(10.0, 0.0), + QGeoCoordinate(0.0, 10.0)); + + box.setTopLeft(QGeoCoordinate(20.0, -10.0)); + + QCOMPARE(box.topLeft(), QGeoCoordinate(20.0, -10.0)); + QCOMPARE(box.topRight(), QGeoCoordinate(20.0, 10.0)); + QCOMPARE(box.bottomLeft(), QGeoCoordinate(0.0, -10.0)); + QCOMPARE(box.bottomRight(), QGeoCoordinate(0.0, 10.0)); + + box.setTopRight(QGeoCoordinate(30.0, 20.0)); + + QCOMPARE(box.topLeft(), QGeoCoordinate(30.0, -10.0)); + QCOMPARE(box.topRight(), QGeoCoordinate(30.0, 20.0)); + QCOMPARE(box.bottomLeft(), QGeoCoordinate(0.0, -10.0)); + QCOMPARE(box.bottomRight(), QGeoCoordinate(0.0, 20.0)); + + box.setBottomRight(QGeoCoordinate(-10.0, 30.0)); + + QCOMPARE(box.topLeft(), QGeoCoordinate(30.0, -10.0)); + QCOMPARE(box.topRight(), QGeoCoordinate(30.0, 30.0)); + QCOMPARE(box.bottomLeft(), QGeoCoordinate(-10.0, -10.0)); + QCOMPARE(box.bottomRight(), QGeoCoordinate(-10.0, 30.0)); + + box.setBottomLeft(QGeoCoordinate(-20.0, -20.0)); + + QCOMPARE(box.topLeft(), QGeoCoordinate(30.0, -20.0)); + QCOMPARE(box.topRight(), QGeoCoordinate(30.0, 30.0)); + QCOMPARE(box.bottomLeft(), QGeoCoordinate(-20.0, -20.0)); + QCOMPARE(box.bottomRight(), QGeoCoordinate(-20.0, 30.0)); + + +} + +void tst_QGeoRectangle::width() +{ + QFETCH(QGeoRectangle, box); + QFETCH(double, oldWidth); + QFETCH(double, newWidth); + QFETCH(QGeoRectangle, newBox); + + if (qIsNaN(oldWidth)) + QVERIFY(qIsNaN(box.width())); + else + QCOMPARE(box.width(), oldWidth); + + box.setWidth(newWidth); + + QCOMPARE(box, newBox); +} + +void tst_QGeoRectangle::width_data() +{ + QTest::addColumn("box"); + QTest::addColumn("oldWidth"); + QTest::addColumn("newWidth"); + QTest::addColumn("newBox"); + + QTest::newRow("invalid box") + << QGeoRectangle() + << qQNaN() + << 100.0 + << QGeoRectangle(); + + QTest::newRow("0 width -> negative width") + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)) + << 0.0 + << -1.0 + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)); + + QTest::newRow("0 width -> 0 width") + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)) + << 0.0 + << 0.0 + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)); + + QTest::newRow("0 width -> non wrapping width") + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)) + << 0.0 + << 10.0 + << QGeoRectangle(QGeoCoordinate(10.0, 85.0), + QGeoCoordinate(5.0, 95.0)); + + QTest::newRow("0 width -> wrapping width positive") + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)) + << 0.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(10.0, -5.0), + QGeoCoordinate(5.0, -175.0)); + + QTest::newRow("0 width -> wrapping width negative") + << QGeoRectangle(QGeoCoordinate(10.0, -90.0), + QGeoCoordinate(5.0, -90.0)) + << 0.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, 5.0)); + + QTest::newRow("0 width -> 360 width") + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)) + << 0.0 + << 360.0 + << QGeoRectangle(QGeoCoordinate(10.0, -180.0), + QGeoCoordinate(5.0, 180.0)); + + QTest::newRow("0 width -> 360+ width") + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)) + << 0.0 + << 370.0 + << QGeoRectangle(QGeoCoordinate(10.0, -180.0), + QGeoCoordinate(5.0, 180.0)); + + QTest::newRow("non wrapping width -> negative width") + << QGeoRectangle(QGeoCoordinate(10.0, 85.0), + QGeoCoordinate(5.0, 95.0)) + << 10.0 + << -1.0 + << QGeoRectangle(QGeoCoordinate(10.0, 85.0), + QGeoCoordinate(5.0, 95.0)); + + QTest::newRow("non wrapping width -> 0 width") + << QGeoRectangle(QGeoCoordinate(10.0, 85.0), + QGeoCoordinate(5.0, 95.0)) + << 10.0 + << 0.0 + << QGeoRectangle(QGeoCoordinate(10.0, 90.0), + QGeoCoordinate(5.0, 90.0)); + + QTest::newRow("non wrapping width -> non wrapping width") + << QGeoRectangle(QGeoCoordinate(10.0, 85.0), + QGeoCoordinate(5.0, 95.0)) + << 10.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(10.0, 80.0), + QGeoCoordinate(5.0, 100.0)); + + QTest::newRow("non wrapping width -> wrapping width positive") + << QGeoRectangle(QGeoCoordinate(10.0, 85.0), + QGeoCoordinate(5.0, 95.0)) + << 10.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(10.0, -5.0), + QGeoCoordinate(5.0, -175.0)); + + QTest::newRow("non wrapping width -> wrapping width negative") + << QGeoRectangle(QGeoCoordinate(10.0, -95.0), + QGeoCoordinate(5.0, -85.0)) + << 10.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, 5.0)); + + QTest::newRow("non wrapping width -> 360 width") + << QGeoRectangle(QGeoCoordinate(10.0, 85.0), + QGeoCoordinate(5.0, 95.0)) + << 10.0 + << 360.0 + << QGeoRectangle(QGeoCoordinate(10.0, -180.0), + QGeoCoordinate(5.0, 180.0)); + + QTest::newRow("non wrapping width width -> 360+ width") + << QGeoRectangle(QGeoCoordinate(10.0, 85.0), + QGeoCoordinate(5.0, 95.0)) + << 10.0 + << 370.0 + << QGeoRectangle(QGeoCoordinate(10.0, -180.0), + QGeoCoordinate(5.0, 180.0)); + + QTest::newRow("wrapping width -> negative width") + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, -85.0)) + << 100.0 + << -1.0 + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, -85.0)); + + QTest::newRow("wrapping width -> 0 width") + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, -85.0)) + << 100.0 + << 0.0 + << QGeoRectangle(QGeoCoordinate(10.0, -135.0), + QGeoCoordinate(5.0, -135.0)); + + QTest::newRow("wrapping width -> non wrapping width") + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, -85.0)) + << 100.0 + << 80.0 + << QGeoRectangle(QGeoCoordinate(10.0, -175.0), + QGeoCoordinate(5.0, -95.0)); + + QTest::newRow("wrapping width -> wrapping width") + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, -85.0)) + << 100.0 + << 120.0 + << QGeoRectangle(QGeoCoordinate(10.0, 165.0), + QGeoCoordinate(5.0, -75.0)); + + QTest::newRow("wrapping width -> 360 width") + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, -85.0)) + << 100.0 + << 360.0 + << QGeoRectangle(QGeoCoordinate(10.0, -180.0), + QGeoCoordinate(5.0, 180.0)); + + QTest::newRow("wrapping width width -> 360+ width") + << QGeoRectangle(QGeoCoordinate(10.0, 175.0), + QGeoCoordinate(5.0, -85.0)) + << 100.0 + << 370.0 + << QGeoRectangle(QGeoCoordinate(10.0, -180.0), + QGeoCoordinate(5.0, 180.0)); +} + +void tst_QGeoRectangle::height() +{ + QFETCH(QGeoRectangle, box); + QFETCH(double, oldHeight); + QFETCH(double, newHeight); + QFETCH(QGeoRectangle, newBox); + + if (qIsNaN(oldHeight)) + QVERIFY(qIsNaN(box.height())); + else + QCOMPARE(box.height(), oldHeight); + + box.setHeight(newHeight); + QCOMPARE(box, newBox); +} + +void tst_QGeoRectangle::height_data() +{ + QTest::addColumn("box"); + QTest::addColumn("oldHeight"); + QTest::addColumn("newHeight"); + QTest::addColumn("newBox"); + + QTest::newRow("invalid box") + << QGeoRectangle() + << qQNaN() + << 100.0 + << QGeoRectangle(); + + QTest::newRow("0 height -> negative height") + << QGeoRectangle(QGeoCoordinate(10.0, 5.0), + QGeoCoordinate(10.0, 10.0)) + << 0.0 + << -1.0 + << QGeoRectangle(QGeoCoordinate(10.0, 5.0), + QGeoCoordinate(10.0, 10.0)); + + QTest::newRow("0 height -> 0 height") + << QGeoRectangle(QGeoCoordinate(10.0, 5.0), + QGeoCoordinate(10.0, 10.0)) + << 0.0 + << 0.0 + << QGeoRectangle(QGeoCoordinate(10.0, 5.0), + QGeoCoordinate(10.0, 10.0)); + + QTest::newRow("0 height -> non zero height") + << QGeoRectangle(QGeoCoordinate(10.0, 5.0), + QGeoCoordinate(10.0, 10.0)) + << 0.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(20.0, 5.0), + QGeoCoordinate(0.0, 10.0)); + + QTest::newRow("0 height -> squash top") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(70.0, 70.0)) + << 0.0 + << 60.0 + << QGeoRectangle(QGeoCoordinate(90.0, 30.0), + QGeoCoordinate(50.0, 70.0)); + + QTest::newRow("0 height -> squash bottom") + << QGeoRectangle(QGeoCoordinate(-70.0, 30.0), + QGeoCoordinate(-70.0, 70.0)) + << 0.0 + << 60.0 + << QGeoRectangle(QGeoCoordinate(-50.0, 30.0), + QGeoCoordinate(-90.0, 70.0)); + + QTest::newRow("0 height -> 180") + << QGeoRectangle(QGeoCoordinate(0.0, 5.0), + QGeoCoordinate(0.0, 10.0)) + << 0.0 + << 180.0 + << QGeoRectangle(QGeoCoordinate(90.0, 5.0), + QGeoCoordinate(-90.0, 10.0)); + + QTest::newRow("0 height -> 180 squash top") + << QGeoRectangle(QGeoCoordinate(20.0, 5.0), + QGeoCoordinate(20.0, 10.0)) + << 0.0 + << 180.0 + << QGeoRectangle(QGeoCoordinate(90.0, 5.0), + QGeoCoordinate(-50.0, 10.0)); + + QTest::newRow("0 height -> 180 squash bottom") + << QGeoRectangle(QGeoCoordinate(-20.0, 5.0), + QGeoCoordinate(-20.0, 10.0)) + << 0.0 + << 180.0 + << QGeoRectangle(QGeoCoordinate(50.0, 5.0), + QGeoCoordinate(-90.0, 10.0)); + + QTest::newRow("0 height -> 180+") + << QGeoRectangle(QGeoCoordinate(0.0, 5.0), + QGeoCoordinate(0.0, 10.0)) + << 0.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(90.0, 5.0), + QGeoCoordinate(-90.0, 10.0)); + + QTest::newRow("0 height -> 180+ squash top") + << QGeoRectangle(QGeoCoordinate(20.0, 5.0), + QGeoCoordinate(20.0, 10.0)) + << 0.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(90.0, 5.0), + QGeoCoordinate(-50.0, 10.0)); + + QTest::newRow("0 height -> 180+ squash bottom") + << QGeoRectangle(QGeoCoordinate(-20.0, 5.0), + QGeoCoordinate(-20.0, 10.0)) + << 0.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(50.0, 5.0), + QGeoCoordinate(-90.0, 10.0)); + + QTest::newRow("non zero height -> negative height") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << 40.0 + << -1.0 + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)); + + QTest::newRow("non zero height -> 0 height") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << 40.0 + << 0.0 + << QGeoRectangle(QGeoCoordinate(50.0, 30.0), + QGeoCoordinate(50.0, 70.0)); + + QTest::newRow("non zero height -> non zero height") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << 40.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(60.0, 30.0), + QGeoCoordinate(40.0, 70.0)); + + QTest::newRow("non zero height -> squash top") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << 40.0 + << 100.0 + << QGeoRectangle(QGeoCoordinate(90.0, 30.0), + QGeoCoordinate(10.0, 70.0)); + + QTest::newRow("non zero height -> squash bottom") + << QGeoRectangle(QGeoCoordinate(-30.0, 30.0), + QGeoCoordinate(-70.0, 70.0)) + << 40.0 + << 100.0 + << QGeoRectangle(QGeoCoordinate(-10.0, 30.0), + QGeoCoordinate(-90.0, 70.0)); + + QTest::newRow("non zero height -> 180") + << QGeoRectangle(QGeoCoordinate(20.0, 30.0), + QGeoCoordinate(-20.0, 70.0)) + << 40.0 + << 180.0 + << QGeoRectangle(QGeoCoordinate(90.0, 30.0), + QGeoCoordinate(-90.0, 70.0)); + + QTest::newRow("non zero height -> 180 squash top") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << 40.0 + << 180.0 + << QGeoRectangle(QGeoCoordinate(90.0, 30.0), + QGeoCoordinate(10.0, 70.0)); + + QTest::newRow("non zero height -> 180 squash bottom") + << QGeoRectangle(QGeoCoordinate(-30.0, 30.0), + QGeoCoordinate(-70.0, 70.0)) + << 40.0 + << 180.0 + << QGeoRectangle(QGeoCoordinate(-10.0, 30.0), + QGeoCoordinate(-90.0, 70.0)); + + QTest::newRow("non zero height -> 180+") + << QGeoRectangle(QGeoCoordinate(20.0, 30.0), + QGeoCoordinate(-20.0, 70.0)) + << 40.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(90.0, 30.0), + QGeoCoordinate(-90.0, 70.0)); + + QTest::newRow("non zero height -> 180+ squash top") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << 40.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(90.0, 30.0), + QGeoCoordinate(10.0, 70.0)); + + QTest::newRow("non zero height -> 180+ squash bottom") + << QGeoRectangle(QGeoCoordinate(-30.0, 30.0), + QGeoCoordinate(-70.0, 70.0)) + << 40.0 + << 190.0 + << QGeoRectangle(QGeoCoordinate(-10.0, 30.0), + QGeoCoordinate(-90.0, 70.0)); +} + +void tst_QGeoRectangle::center() +{ + QFETCH(QGeoRectangle, box); + QFETCH(QGeoCoordinate, oldCenter); + QFETCH(QGeoCoordinate, newCenter); + QFETCH(QGeoRectangle, newBox); + + QGeoShape shape = box; + QCOMPARE(box.center(), oldCenter); + QCOMPARE(shape.center(), oldCenter); + box.setCenter(newCenter); + QCOMPARE(box, newBox); +} + +void tst_QGeoRectangle::center_data() +{ + QTest::addColumn("box"); + QTest::addColumn("oldCenter"); + QTest::addColumn("newCenter"); + QTest::addColumn("newBox"); + + QTest::newRow("invalid") + << QGeoRectangle() + << QGeoCoordinate() + << QGeoCoordinate(0.0, 0.0) + << QGeoRectangle(QGeoCoordinate(0.0, 0.0), 0.0, 0.0); + + QTest::newRow("zero width") + << QGeoRectangle(QGeoCoordinate(10.0, 5.0), + QGeoCoordinate(5.0, 5.0)) + << QGeoCoordinate(7.5, 5.0) + << QGeoCoordinate(20.0, 20.0) + << QGeoRectangle(QGeoCoordinate(22.5, 20.0), + QGeoCoordinate(17.5, 20.0)); + + QTest::newRow("360 width") + << QGeoRectangle(QGeoCoordinate(10.0, -180.0), + QGeoCoordinate(5.0, 180.0)) + << QGeoCoordinate(7.5, 0.0) + << QGeoCoordinate(20.0, 20.0) + << QGeoRectangle(QGeoCoordinate(22.5, -180.0), + QGeoCoordinate(17.5, 180.0)); + + QTest::newRow("zero height") + << QGeoRectangle(QGeoCoordinate(5.0, 5.0), + QGeoCoordinate(5.0, 10.0)) + << QGeoCoordinate(5.0, 7.5) + << QGeoCoordinate(20.0, 20.0) + << QGeoRectangle(QGeoCoordinate(20.0, 17.5), + QGeoCoordinate(20.0, 22.5)); + + QTest::newRow("180 height -> move") + << QGeoRectangle(QGeoCoordinate(90.0, 5.0), + QGeoCoordinate(-90.0, 10.0)) + << QGeoCoordinate(0.0, 7.5) + << QGeoCoordinate(0.0, 20.0) + << QGeoRectangle(QGeoCoordinate(90.0, 17.5), + QGeoCoordinate(-90.0, 22.5)); + + QTest::newRow("180 height -> squash top") + << QGeoRectangle(QGeoCoordinate(90.0, 5.0), + QGeoCoordinate(-90.0, 10.0)) + << QGeoCoordinate(0.0, 7.5) + << QGeoCoordinate(-20.0, 20.0) + << QGeoRectangle(QGeoCoordinate(50.0, 17.5), + QGeoCoordinate(-90.0, 22.5)); + + QTest::newRow("180 height -> squash bottom") + << QGeoRectangle(QGeoCoordinate(90.0, 5.0), + QGeoCoordinate(-90.0, 10.0)) + << QGeoCoordinate(0.0, 7.5) + << QGeoCoordinate(20.0, 20.0) + << QGeoRectangle(QGeoCoordinate(90.0, 17.5), + QGeoCoordinate(-50.0, 22.5)); + + QTest::newRow("non wrapping -> non wrapping") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << QGeoCoordinate(50.0, 50.0) + << QGeoCoordinate(10.0, 10.0) + << QGeoRectangle(QGeoCoordinate(30.0, -10.0), + QGeoCoordinate(-10.0, 30.0)); + + QTest::newRow("non wrapping -> wrapping") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << QGeoCoordinate(50.0, 50.0) + << QGeoCoordinate(10.0, 170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-10.0, -170.0)); + + QTest::newRow("non wrapping -> squash top") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << QGeoCoordinate(50.0, 50.0) + << QGeoCoordinate(80.0, 50.0) + << QGeoRectangle(QGeoCoordinate(90.0, 30.0), + QGeoCoordinate(70.0, 70.0)); + + QTest::newRow("non wrapping -> squash bottom") + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)) + << QGeoCoordinate(50.0, 50.0) + << QGeoCoordinate(-80.0, 50.0) + << QGeoRectangle(QGeoCoordinate(-70.0, 30.0), + QGeoCoordinate(-90.0, 70.0)); + + QTest::newRow("wrapping -> non wrapping") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-10.0, -170.0)) + << QGeoCoordinate(10.0, 170.0) + << QGeoCoordinate(50.0, 50.0) + << QGeoRectangle(QGeoCoordinate(70.0, 30.0), + QGeoCoordinate(30.0, 70.0)); + + QTest::newRow("wrapping -> wrapping") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-10.0, -170.0)) + << QGeoCoordinate(10.0, 170.0) + << QGeoCoordinate(10.0, -170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 170.0), + QGeoCoordinate(-10.0, -150.0)); + + QTest::newRow("wrapping -> squash top") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-10.0, -170.0)) + << QGeoCoordinate(10.0, 170.0) + << QGeoCoordinate(80.0, 170.0) + << QGeoRectangle(QGeoCoordinate(90.0, 150.0), + QGeoCoordinate(70.0, -170.0)); + + QTest::newRow("wrapping -> squash bottom") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-10.0, -170.0)) + << QGeoCoordinate(10.0, 170.0) + << QGeoCoordinate(-80.0, 170.0) + << QGeoRectangle(QGeoCoordinate(-70.0, 150.0), + QGeoCoordinate(-90.0, -170.0)); +} + +void tst_QGeoRectangle::boundingGeoRectangle_data() +{ + QTest::addColumn("rectangle"); + + QGeoRectangle b1(QGeoCoordinate(70, 30), QGeoCoordinate(30, 70)); + QGeoRectangle b2(QGeoCoordinate(70, 150), QGeoCoordinate(30, -170)); + QGeoRectangle b3(QGeoCoordinate(90, 30), QGeoCoordinate(50, 70)); + QGeoRectangle b4(QGeoCoordinate(-50, 30), QGeoCoordinate(-90, 70)); + + QTest::newRow("Box 1") << b1; + QTest::newRow("Box 2") << b2; + QTest::newRow("Box 3") << b3; + QTest::newRow("Box 4") << b4; +} + +void tst_QGeoRectangle::boundingGeoRectangle() +{ + QFETCH(QGeoRectangle, rectangle); + + QGeoRectangle box = rectangle.boundingGeoRectangle(); + QCOMPARE(box, rectangle); +} + +void tst_QGeoRectangle::containsCoord() +{ + QFETCH(QGeoRectangle, box); + QFETCH(QGeoCoordinate, coord); + QFETCH(bool, contains); + + QCOMPARE(box.contains(coord), contains); + + QGeoShape area = box; + QCOMPARE(area.contains(coord), contains); +} + +void tst_QGeoRectangle::containsCoord_data() +{ + QTest::addColumn("box"); + QTest::addColumn("coord"); + QTest::addColumn("contains"); + + QGeoRectangle b1(QGeoCoordinate(70, 30), QGeoCoordinate(30, 70)); + + double lonLO1 = 20.0; + double lonL1 = 30.0; + double lonLI1 = 40.0; + double lonC1 = 50.0; + double lonRI1 = 60.0; + double lonR1 = 70.0; + double lonRO1 = 80.0; + + double latTO1 = 80.0; + double latT1 = 70.0; + double latTI1 = 60.0; + double latC1 = 50.0; + double latBI1 = 40.0; + double latB1 = 30.0; + double latBO1 = 20.0; + + QTest::newRow("non wrapped - in center") + << b1 << QGeoCoordinate(latC1, lonC1) << true; + QTest::newRow("non wrapped - left edge - inside") + << b1 << QGeoCoordinate(latC1, lonLI1) << true; + QTest::newRow("non wrapped - left edge") + << b1 << QGeoCoordinate(latC1, lonL1) << true; + QTest::newRow("non wrapped - left edge - outside") + << b1 << QGeoCoordinate(latC1, lonLO1) << false; + QTest::newRow("non wrapped - right edge - inside") + << b1 << QGeoCoordinate(latC1, lonRI1) << true; + QTest::newRow("non wrapped - right edge") + << b1 << QGeoCoordinate(latC1, lonR1) << true; + QTest::newRow("non wrapped - right edge - outside") + << b1 << QGeoCoordinate(latC1, lonRO1) << false; + QTest::newRow("non wrapped - top edge - inside") + << b1 << QGeoCoordinate(latTI1, lonC1) << true; + QTest::newRow("non wrapped - top edge") + << b1 << QGeoCoordinate(latT1, lonC1) << true; + QTest::newRow("non wrapped - top edge - outside") + << b1 << QGeoCoordinate(latTO1, lonC1) << false; + QTest::newRow("non wrapped - bottom edge - inside") + << b1 << QGeoCoordinate(latBI1, lonC1) << true; + QTest::newRow("non wrapped - bottom edge") + << b1 << QGeoCoordinate(latB1, lonC1) << true; + QTest::newRow("non wrapped - bottom edge - outside") + << b1 << QGeoCoordinate(latBO1, lonC1) << false; + QTest::newRow("non wrapped - top left - inside") + << b1 << QGeoCoordinate(latTI1, lonLI1) << true; + QTest::newRow("non wrapped - top left") + << b1 << QGeoCoordinate(latT1, lonL1) << true; + QTest::newRow("non wrapped - top left - outside") + << b1 << QGeoCoordinate(latTO1, lonLO1) << false; + QTest::newRow("non wrapped - top right - inside") + << b1 << QGeoCoordinate(latTI1, lonRI1) << true; + QTest::newRow("non wrapped - top right") + << b1 << QGeoCoordinate(latT1, lonR1) << true; + QTest::newRow("non wrapped - top right - outside") + << b1 << QGeoCoordinate(latTO1, lonRO1) << false; + QTest::newRow("non wrapped - bottom left - inside") + << b1 << QGeoCoordinate(latBI1, lonLI1) << true; + QTest::newRow("non wrapped - bottom left") + << b1 << QGeoCoordinate(latB1, lonL1) << true; + QTest::newRow("non wrapped - bottom left - outside") + << b1 << QGeoCoordinate(latBO1, lonLO1) << false; + QTest::newRow("non wrapped - bottom right - inside") + << b1 << QGeoCoordinate(latBI1, lonRI1) << true; + QTest::newRow("non wrapped - bottom right") + << b1 << QGeoCoordinate(latB1, lonR1) << true; + QTest::newRow("non wrapped - bottom right - outside") + << b1 << QGeoCoordinate(latBO1, lonRO1) << false; + + QGeoRectangle b2(QGeoCoordinate(70, 150), QGeoCoordinate(30, -170)); + + double lonLO2 = 140.0; + double lonL2 = 150.0; + double lonLI2 = 160.0; + double lonC2 = 170.0; + double lonRI2 = 180.0; + double lonR2 = -170.0; + double lonRO2 = -160.0; + + double latTO2 = 80.0; + double latT2 = 70.0; + double latTI2 = 60.0; + double latC2 = 50.0; + double latBI2 = 40.0; + double latB2 = 30.0; + double latBO2 = 20.0; + + QTest::newRow("wrapped - in center") + << b2 << QGeoCoordinate(latC2, lonC2) << true; + QTest::newRow("wrapped - left edge - inside") + << b2 << QGeoCoordinate(latC2, lonLI2) << true; + QTest::newRow("wrapped - left edge") + << b2 << QGeoCoordinate(latC2, lonL2) << true; + QTest::newRow("wrapped - left edge - outside") + << b2 << QGeoCoordinate(latC2, lonLO2) << false; + QTest::newRow("wrapped - right edge - inside") + << b2 << QGeoCoordinate(latC2, lonRI2) << true; + QTest::newRow("wrapped - right edge") + << b2 << QGeoCoordinate(latC2, lonR2) << true; + QTest::newRow("wrapped - right edge - outside") + << b2 << QGeoCoordinate(latC2, lonRO2) << false; + QTest::newRow("wrapped - top edge - inside") + << b2 << QGeoCoordinate(latTI2, lonC2) << true; + QTest::newRow("wrapped - top edge") + << b2 << QGeoCoordinate(latT2, lonC2) << true; + QTest::newRow("wrapped - top edge - outside") + << b2 << QGeoCoordinate(latTO2, lonC2) << false; + QTest::newRow("wrapped - bottom edge - inside") + << b2 << QGeoCoordinate(latBI2, lonC2) << true; + QTest::newRow("wrapped - bottom edge") + << b2 << QGeoCoordinate(latB2, lonC2) << true; + QTest::newRow("wrapped - bottom edge - outside") + << b2 << QGeoCoordinate(latBO2, lonC2) << false; + QTest::newRow("wrapped - top left - inside") + << b2 << QGeoCoordinate(latTI2, lonLI2) << true; + QTest::newRow("wrapped - top left") + << b2 << QGeoCoordinate(latT2, lonL2) << true; + QTest::newRow("wrapped - top left - outside") + << b2 << QGeoCoordinate(latTO2, lonLO2) << false; + QTest::newRow("wrapped - top right - inside") + << b2 << QGeoCoordinate(latTI2, lonRI2) << true; + QTest::newRow("wrapped - top right") + << b2 << QGeoCoordinate(latT2, lonR2) << true; + QTest::newRow("wrapped - top right - outside") + << b2 << QGeoCoordinate(latTO2, lonRO2) << false; + QTest::newRow("wrapped - bottom left - inside") + << b2 << QGeoCoordinate(latBI2, lonLI2) << true; + QTest::newRow("wrapped - bottom left") + << b2 << QGeoCoordinate(latB2, lonL2) << true; + QTest::newRow("wrapped - bottom left - outside") + << b2 << QGeoCoordinate(latBO2, lonLO2) << false; + QTest::newRow("wrapped - bottom right - inside") + << b2 << QGeoCoordinate(latBI2, lonRI2) << true; + QTest::newRow("wrapped - bottom right") + << b2 << QGeoCoordinate(latB2, lonR2) << true; + QTest::newRow("wrapped - bottom right - outside") + << b2 << QGeoCoordinate(latBO2, lonRO2) << false; + + QGeoRectangle b3(QGeoCoordinate(90, 30), QGeoCoordinate(50, 70)); + + double lonLO3 = 20.0; + double lonL3 = 30.0; + double lonLI3 = 40.0; + double lonC3 = 50.0; + double lonRI3 = 60.0; + double lonR3 = 70.0; + double lonRO3 = 80.0; + + double latT3 = 90.0; + double latTI3 = 80.0; + double latC3 = 70.0; + /* current unused: + double latBI3 = 60.0; + double latB3 = 50.0; + double latBO3 = 40.0; + */ + + QTest::newRow("north pole - in center") + << b3 << QGeoCoordinate(latC3, lonC3) << true; + QTest::newRow("north pole - left edge - inside") + << b3 << QGeoCoordinate(latC3, lonLI3) << true; + QTest::newRow("north pole - left edge") + << b3 << QGeoCoordinate(latC3, lonL3) << true; + QTest::newRow("north pole - left edge - outside") + << b3 << QGeoCoordinate(latC3, lonLO3) << false; + QTest::newRow("north pole - right edge - inside") + << b3 << QGeoCoordinate(latC3, lonRI3) << true; + QTest::newRow("north pole - right edge") + << b3 << QGeoCoordinate(latC3, lonR3) << true; + QTest::newRow("north pole - right edge - outside") + << b3 << QGeoCoordinate(latC3, lonRO3) << false; + QTest::newRow("north pole - top edge - inside") + << b3 << QGeoCoordinate(latTI3, lonC3) << true; + QTest::newRow("north pole - top edge") + << b3 << QGeoCoordinate(latT3, lonC3) << true; + QTest::newRow("north pole - top left - inside") + << b3 << QGeoCoordinate(latTI3, lonLI3) << true; + QTest::newRow("north pole - top left") + << b3 << QGeoCoordinate(latT3, lonL3) << true; + QTest::newRow("north pole - top left - outside") + << b3 << QGeoCoordinate(latT3, lonLO3) << true; + QTest::newRow("north pole - top right - inside") + << b3 << QGeoCoordinate(latTI3, lonRI3) << true; + QTest::newRow("north pole - top right") + << b3 << QGeoCoordinate(latT3, lonR3) << true; + QTest::newRow("north pole - top right - outside") + << b3 << QGeoCoordinate(latT3, lonRO3) << true; + + QGeoRectangle b4(QGeoCoordinate(-50, 30), QGeoCoordinate(-90, 70)); + + double lonLO4 = 20.0; + double lonL4 = 30.0; + double lonLI4 = 40.0; + double lonC4 = 50.0; + double lonRI4 = 60.0; + double lonR4 = 70.0; + double lonRO4 = 80.0; + + /* currently unused: + double latTO4 = -40.0; + double latT4 = -50.0; + double latTI4 = -60.0; + */ + double latC4 = -70.0; + double latBI4 = -80.0; + double latB4 = -90.0; + + QTest::newRow("south pole - in center") + << b4 << QGeoCoordinate(latC4, lonC4) << true; + QTest::newRow("south pole - left edge - inside") + << b4 << QGeoCoordinate(latC4, lonLI4) << true; + QTest::newRow("south pole - left edge") + << b4 << QGeoCoordinate(latC4, lonL4) << true; + QTest::newRow("south pole - left edge - outside") + << b4 << QGeoCoordinate(latC4, lonLO4) << false; + QTest::newRow("south pole - right edge - inside") + << b4 << QGeoCoordinate(latC4, lonRI4) << true; + QTest::newRow("south pole - right edge") + << b4 << QGeoCoordinate(latC4, lonR4) << true; + QTest::newRow("south pole - right edge - outside") + << b4 << QGeoCoordinate(latC4, lonRO4) << false; + QTest::newRow("south pole - bottom edge - inside") + << b4 << QGeoCoordinate(latBI4, lonC4) << true; + QTest::newRow("south pole - bottom edge") + << b4 << QGeoCoordinate(latB4, lonC4) << true; + QTest::newRow("south pole - bottom left - inside") + << b4 << QGeoCoordinate(latBI4, lonLI4) << true; + QTest::newRow("south pole - bottom left") + << b4 << QGeoCoordinate(latB4, lonL4) << true; + QTest::newRow("south pole - bottom left - outside") + << b4 << QGeoCoordinate(latB4, lonLO4) << true; + QTest::newRow("south pole - bottom right - inside") + << b4 << QGeoCoordinate(latBI4, lonRI4) << true; + QTest::newRow("south pole - bottom right") + << b4 << QGeoCoordinate(latB4, lonR4) << true; + QTest::newRow("south pole - bottom right - outside") + << b4 << QGeoCoordinate(latB4, lonRO4) << true; +} + +void tst_QGeoRectangle::containsBoxAndIntersects() +{ + QFETCH(QGeoRectangle, box1); + QFETCH(QGeoRectangle, box2); + QFETCH(bool, contains); + QFETCH(bool, intersects); + + QCOMPARE(box1.contains(box2), contains); + QCOMPARE(box1.intersects(box2), intersects); +} + +void tst_QGeoRectangle::containsBoxAndIntersects_data() +{ + QTest::addColumn("box1"); + QTest::addColumn("box2"); + QTest::addColumn("contains"); + QTest::addColumn("intersects"); + + QGeoRectangle b1(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)); + + QTest::newRow("non wrapped same") + << b1 + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << true << true; + + QTest::newRow("non wrapped smaller") + << b1 + << QGeoRectangle(QGeoCoordinate(20.0, -20.0), + QGeoCoordinate(-20.0, 20.0)) + << true << true; + + QTest::newRow("non wrapped larger") + << b1 + << QGeoRectangle(QGeoCoordinate(40.0, -40.0), + QGeoCoordinate(-40.0, 40.0)) + << false << true; + + QTest::newRow("non wrapped outside top") + << b1 + << QGeoRectangle(QGeoCoordinate(80.0, -30.0), + QGeoCoordinate(50.0, 30.0)) + << false << false; + + QTest::newRow("non wrapped outside bottom") + << b1 + << QGeoRectangle(QGeoCoordinate(-50.0, -30.0), + QGeoCoordinate(-80.0, 30.0)) + << false << false; + + QTest::newRow("non wrapped outside left") + << b1 + << QGeoRectangle(QGeoCoordinate(30.0, -80.0), + QGeoCoordinate(-30.0, -50.0)) + << false << false; + + QTest::newRow("non wrapped outside wrapped") + << b1 + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << false << false; + + QTest::newRow("non wrapped outside right") + << b1 + << QGeoRectangle(QGeoCoordinate(30.0, 50.0), + QGeoCoordinate(-30.0, 80.0)) + << false << false; + + QTest::newRow("non wrapped top left cross") + << b1 + << QGeoRectangle(QGeoCoordinate(40.0, -40.0), + QGeoCoordinate(20.0, -20.0)) + << false << true; + + QTest::newRow("non wrapped top cross") + << b1 + << QGeoRectangle(QGeoCoordinate(40.0, -10.0), + QGeoCoordinate(20.0, 10.0)) + << false << true; + + QTest::newRow("non wrapped top right cross") + << b1 + << QGeoRectangle(QGeoCoordinate(40.0, 20.0), + QGeoCoordinate(20.0, 40.0)) + << false << true; + + QTest::newRow("non wrapped left cross") + << b1 + << QGeoRectangle(QGeoCoordinate(10.0, -40.0), + QGeoCoordinate(-10.0, -20.0)) + << false << true; + + QTest::newRow("non wrapped right cross") + << b1 + << QGeoRectangle(QGeoCoordinate(10.0, 20.0), + QGeoCoordinate(-10.0, 40.0)) + << false << true; + + QTest::newRow("non wrapped bottom left cross") + << b1 + << QGeoRectangle(QGeoCoordinate(-20.0, -40.0), + QGeoCoordinate(-40.0, -20.0)) + << false << true; + + QTest::newRow("non wrapped bottom cross") + << b1 + << QGeoRectangle(QGeoCoordinate(-20.0, -10.0), + QGeoCoordinate(-40.0, 10.0)) + << false << true; + + QTest::newRow("non wrapped bottom right cross") + << b1 + << QGeoRectangle(QGeoCoordinate(-20.0, 20.0), + QGeoCoordinate(-40.0, 40.0)) + << false << true; + + QTest::newRow("non wrapped top left touch outside") + << b1 + << QGeoRectangle(QGeoCoordinate(50.0, -50.0), + QGeoCoordinate(30.0, -30.0)) + << false << true; + + QTest::newRow("non wrapped top touch outside") + << b1 + << QGeoRectangle(QGeoCoordinate(50.0, -10.0), + QGeoCoordinate(30.0, 10.0)) + << false << true; + + QTest::newRow("non wrapped top right touch outside") + << b1 + << QGeoRectangle(QGeoCoordinate(50.0, 30.0), + QGeoCoordinate(30.0, 50.0)) + << false << true; + + QTest::newRow("non wrapped left touch outside") + << b1 + << QGeoRectangle(QGeoCoordinate(10.0, -50.0), + QGeoCoordinate(-10.0, -30.0)) + << false << true; + + QTest::newRow("non wrapped right touch outside") + << b1 + << QGeoRectangle(QGeoCoordinate(10.0, 30.0), + QGeoCoordinate(-10.0, 50.0)) + << false << true; + + QTest::newRow("non wrapped bottom left touch outside") + << b1 + << QGeoRectangle(QGeoCoordinate(-30.0, -30.0), + QGeoCoordinate(-50.0, -50.0)) + << false << true; + + QTest::newRow("non wrapped bottom touch outside") + << b1 + << QGeoRectangle(QGeoCoordinate(-30.0, -10.0), + QGeoCoordinate(-50.0, 10.0)) + << false << true; + + QTest::newRow("non wrapped bottom right touch outside") + << b1 + << QGeoRectangle(QGeoCoordinate(-30.0, 30.0), + QGeoCoordinate(-50.0, 50.0)) + << false << true; + + QTest::newRow("non wrapped top left touch inside") + << b1 + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(10.0, -10.0)) + << true << true; + + QTest::newRow("non wrapped top touch inside") + << b1 + << QGeoRectangle(QGeoCoordinate(30.0, -10.0), + QGeoCoordinate(10.0, 10.0)) + << true << true; + + QTest::newRow("non wrapped top right touch inside") + << b1 + << QGeoRectangle(QGeoCoordinate(30.0, 10.0), + QGeoCoordinate(10.0, 30.0)) + << true << true; + + QTest::newRow("non wrapped left touch inside") + << b1 + << QGeoRectangle(QGeoCoordinate(10.0, -30.0), + QGeoCoordinate(-10.0, -10.0)) + << true << true; + + QTest::newRow("non wrapped right touch inside") + << b1 + << QGeoRectangle(QGeoCoordinate(10.0, 10.0), + QGeoCoordinate(-10.0, 30.0)) + << true << true; + + QTest::newRow("non wrapped bottom left touch inside") + << b1 + << QGeoRectangle(QGeoCoordinate(-10.0, -30.0), + QGeoCoordinate(-30.0, -10.0)) + << true << true; + + QTest::newRow("non wrapped bottom touch inside") + << b1 + << QGeoRectangle(QGeoCoordinate(-10.0, -10.0), + QGeoCoordinate(-30.0, 10.0)) + << true << true; + + QTest::newRow("non wrapped bottom right touch inside") + << b1 + << QGeoRectangle(QGeoCoordinate(-10.0, 10.0), + QGeoCoordinate(-30.0, 30.0)) + << true << true; + + QTest::newRow("non wrapped top lon strip") + << b1 + << QGeoRectangle(QGeoCoordinate(40.0, -40.0), + QGeoCoordinate(20.0, 40.0)) + << false << true; + + QTest::newRow("non wrapped center lon strip") + << b1 + << QGeoRectangle(QGeoCoordinate(10.0, -40.0), + QGeoCoordinate(-10.0, 40.0)) + << false << true; + + QTest::newRow("non wrapped bottom lon strip") + << b1 + << QGeoRectangle(QGeoCoordinate(-20.0, -40.0), + QGeoCoordinate(-40.0, 40.0)) + << false << true; + + QTest::newRow("non wrapped left lat strip") + << b1 + << QGeoRectangle(QGeoCoordinate(40.0, -40.0), + QGeoCoordinate(-40.0, -20.0)) + << false << true; + + QTest::newRow("non wrapped center lat strip") + << b1 + << QGeoRectangle(QGeoCoordinate(40.0, -10.0), + QGeoCoordinate(-40.0, 10.0)) + << false << true; + + QTest::newRow("non wrapped right lat strip") + << b1 + << QGeoRectangle(QGeoCoordinate(40.0, 20.0), + QGeoCoordinate(-40.0, 40.0)) + << false << true; + + QGeoRectangle b2(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)); + + QTest::newRow("wrapped same") + << b2 + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << true << true; + + QTest::newRow("wrapped smaller") + << b2 + << QGeoRectangle(QGeoCoordinate(20.0, 160.0), + QGeoCoordinate(-20.0, -160.0)) + << true << true; + + QTest::newRow("wrapped larger") + << b2 + << QGeoRectangle(QGeoCoordinate(40.0, 140.0), + QGeoCoordinate(-40.0, -140.0)) + << false << true; + + QTest::newRow("wrapped outside top") + << b2 + << QGeoRectangle(QGeoCoordinate(80.0, 150.0), + QGeoCoordinate(50.0, -150.0)) + << false << false; + + QTest::newRow("wrapped outside bottom") + << b2 + << QGeoRectangle(QGeoCoordinate(-50.0, 150.0), + QGeoCoordinate(-80.0, -150.0)) + << false << false; + + QTest::newRow("wrapped outside left") + << b2 + << QGeoRectangle(QGeoCoordinate(30.0, 70.0), + QGeoCoordinate(-30.0, 130.0)) + << false << false; + + QTest::newRow("wrapped outside right") + << b2 + << QGeoRectangle(QGeoCoordinate(30.0, -130.0), + QGeoCoordinate(-30.0, -70.0)) + << false << false; + + QTest::newRow("wrapped top left cross") + << b2 + << QGeoRectangle(QGeoCoordinate(40.0, 140.0), + QGeoCoordinate(20.0, 160.0)) + << false << true; + + QTest::newRow("wrapped top cross") + << b2 + << QGeoRectangle(QGeoCoordinate(40.0, 170.0), + QGeoCoordinate(20.0, -170.0)) + << false << true; + + QTest::newRow("wrapped top right cross") + << b2 + << QGeoRectangle(QGeoCoordinate(40.0, -160.0), + QGeoCoordinate(20.0, -140.0)) + << false << true; + + QTest::newRow("wrapped left cross") + << b2 + << QGeoRectangle(QGeoCoordinate(10.0, 140.0), + QGeoCoordinate(-10.0, 160.0)) + << false << true; + + QTest::newRow("wrapped right cross") + << b2 + << QGeoRectangle(QGeoCoordinate(10.0, -160.0), + QGeoCoordinate(-10.0, -140.0)) + << false << true; + + QTest::newRow("wrapped bottom left cross") + << b2 + << QGeoRectangle(QGeoCoordinate(-20.0, 140.0), + QGeoCoordinate(-40.0, 160.0)) + << false << true; + + QTest::newRow("wrapped bottom cross") + << b2 + << QGeoRectangle(QGeoCoordinate(-20.0, 170.0), + QGeoCoordinate(-40.0, -170.0)) + << false << true; + + QTest::newRow("wrapped bottom right cross") + << b2 + << QGeoRectangle(QGeoCoordinate(-20.0, -160.0), + QGeoCoordinate(-40.0, -140.0)) + << false << true; + + QTest::newRow("wrapped top left touch outside") + << b2 + << QGeoRectangle(QGeoCoordinate(50.0, 130.0), + QGeoCoordinate(30.0, 150.0)) + << false << true; + + QTest::newRow("wrapped top touch outside") + << b2 + << QGeoRectangle(QGeoCoordinate(50.0, 170.0), + QGeoCoordinate(30.0, -170.0)) + << false << true; + + QTest::newRow("wrapped top right touch outside") + << b2 + << QGeoRectangle(QGeoCoordinate(50.0, -150.0), + QGeoCoordinate(30.0, -130.0)) + << false << true; + + QTest::newRow("wrapped left touch outside") + << b2 + << QGeoRectangle(QGeoCoordinate(10.0, 130.0), + QGeoCoordinate(-10.0, 150.0)) + << false << true; + + QTest::newRow("wrapped right touch outside") + << b2 + << QGeoRectangle(QGeoCoordinate(10.0, -150.0), + QGeoCoordinate(-10.0, -130.0)) + << false << true; + + QTest::newRow("wrapped bottom left touch outside") + << b2 + << QGeoRectangle(QGeoCoordinate(-30.0, 150.0), + QGeoCoordinate(-50.0, 130.0)) + << false << true; + + QTest::newRow("wrapped bottom touch outside") + << b2 + << QGeoRectangle(QGeoCoordinate(-30.0, 170.0), + QGeoCoordinate(-50.0, -170.0)) + << false << true; + + QTest::newRow("wrapped bottom right touch outside") + << b2 + << QGeoRectangle(QGeoCoordinate(-30.0, -150.0), + QGeoCoordinate(-50.0, -130.0)) + << false << true; + + QTest::newRow("wrapped top left touch inside") + << b2 + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(10.0, 170.0)) + << true << true; + + QTest::newRow("wrapped top touch inside") + << b2 + << QGeoRectangle(QGeoCoordinate(30.0, 170.0), + QGeoCoordinate(10.0, -170.0)) + << true << true; + + QTest::newRow("wrapped top right touch inside") + << b2 + << QGeoRectangle(QGeoCoordinate(30.0, -170.0), + QGeoCoordinate(10.0, -150.0)) + << true << true; + + QTest::newRow("wrapped left touch inside") + << b2 + << QGeoRectangle(QGeoCoordinate(10.0, 150.0), + QGeoCoordinate(-10.0, 170.0)) + << true << true; + + QTest::newRow("wrapped right touch inside") + << b2 + << QGeoRectangle(QGeoCoordinate(10.0, -170.0), + QGeoCoordinate(-10.0, -150.0)) + << true << true; + + QTest::newRow("wrapped bottom left touch inside") + << b2 + << QGeoRectangle(QGeoCoordinate(-10.0, 150.0), + QGeoCoordinate(-30.0, 170.0)) + << true << true; + + QTest::newRow("wrapped bottom touch inside") + << b2 + << QGeoRectangle(QGeoCoordinate(-10.0, 170.0), + QGeoCoordinate(-30.0, -170.0)) + << true << true; + + QTest::newRow("wrapped bottom right touch inside") + << b2 + << QGeoRectangle(QGeoCoordinate(-10.0, -170.0), + QGeoCoordinate(-30.0, -150.0)) + << true << true; + + QTest::newRow("wrapped top lon strip") + << b2 + << QGeoRectangle(QGeoCoordinate(40.0, 140.0), + QGeoCoordinate(20.0, -140.0)) + << false << true; + + QTest::newRow("wrapped center lon strip") + << b2 + << QGeoRectangle(QGeoCoordinate(10.0, 140.0), + QGeoCoordinate(-10.0, -140.0)) + << false << true; + + QTest::newRow("wrapped bottom lon strip") + << b2 + << QGeoRectangle(QGeoCoordinate(-20.0, 140.0), + QGeoCoordinate(-40.0, -140.0)) + << false << true; + + QTest::newRow("wrapped left lat strip") + << b2 + << QGeoRectangle(QGeoCoordinate(40.0, 140.0), + QGeoCoordinate(-40.0, 160.0)) + << false << true; + + QTest::newRow("wrapped center lat strip") + << b2 + << QGeoRectangle(QGeoCoordinate(40.0, 170.0), + QGeoCoordinate(-40.0, -170.0)) + << false << true; + + QTest::newRow("wrapped right lat strip") + << b2 + << QGeoRectangle(QGeoCoordinate(40.0, -160.0), + QGeoCoordinate(-40.0, -140.0)) + << false << true; + + QTest::newRow("north pole touching") + << QGeoRectangle(QGeoCoordinate(90.0, 20.0), + QGeoCoordinate(40.0, 40.0)) + << QGeoRectangle(QGeoCoordinate(90.0, 60.0), + QGeoCoordinate(30.0, 80.0)) + << false << true; + + QTest::newRow("south pole touching") + << QGeoRectangle(QGeoCoordinate(40.0, 20.0), + QGeoCoordinate(-90.0, 40.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 60.0), + QGeoCoordinate(-90.0, 80.0)) + << false << true; +} + +void tst_QGeoRectangle::translate() +{ + QFETCH(QGeoRectangle, box); + QFETCH(double, degreesLatitude); + QFETCH(double, degreesLongitude); + QFETCH(QGeoRectangle, newBox); + + QGeoRectangle test = box.translated(degreesLatitude, degreesLongitude); + QCOMPARE(test, newBox); + box.translate(degreesLatitude, degreesLongitude); + QCOMPARE(box, newBox); + +} + +void tst_QGeoRectangle::translate_data() +{ + QTest::addColumn("box"); + QTest::addColumn("degreesLatitude"); + QTest::addColumn("degreesLongitude"); + QTest::addColumn("newBox"); + + QTest::newRow("invalid") + << QGeoRectangle() + << 20.0 + << 20.0 + << QGeoRectangle(); + + QTest::newRow("360 width") + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)) + << 20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(50.0, -180.0), + QGeoCoordinate(-10.0, 180.0)); + + QTest::newRow("180 height") + << QGeoRectangle(QGeoCoordinate(90.0, -30.0), + QGeoCoordinate(-90.0, 30.0)) + << 20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(90.0, -10.0), + QGeoCoordinate(-90.0, 50.0)); + + QTest::newRow("non wrapping -> non wrapping") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << 20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(50.0, -10.0), + QGeoCoordinate(-10.0, 50.0)); + + QTest::newRow("non wrapping -> wrapping") + << QGeoRectangle(QGeoCoordinate(30.0, 110.0), + QGeoCoordinate(-30.0, 170.0)) + << 20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(50.0, 130.0), + QGeoCoordinate(-10.0, -170.0)); + + QTest::newRow("non wrapping -> north clip") + << QGeoRectangle(QGeoCoordinate(80.0, -30.0), + QGeoCoordinate(20.0, 30.0)) + << 20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(90.0, -10.0), + QGeoCoordinate(30.0, 50.0)); + + QTest::newRow("non wrapping -> south clip") + << QGeoRectangle(QGeoCoordinate(-20.0, -30.0), + QGeoCoordinate(-80.0, 30.0)) + << -20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(-30.0, -10.0), + QGeoCoordinate(-90.0, 50.0)); + + QTest::newRow("wrapping -> non wrapping") + << QGeoRectangle(QGeoCoordinate(30.0, 130.0), + QGeoCoordinate(-30.0, -170.0)) + << 20.0 + << -20.0 + << QGeoRectangle(QGeoCoordinate(50.0, 110.0), + QGeoCoordinate(-10.0, 170.0)); + + QTest::newRow("wrapping -> wrapping") + << QGeoRectangle(QGeoCoordinate(30.0, 130.0), + QGeoCoordinate(-30.0, -170.0)) + << 20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(50.0, 150.0), + QGeoCoordinate(-10.0, -150.0)); + + QTest::newRow("wrapping -> north clip") + << QGeoRectangle(QGeoCoordinate(80.0, 130.0), + QGeoCoordinate(20.0, -170.0)) + << 20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(90.0, 150.0), + QGeoCoordinate(30.0, -150.0)); + + QTest::newRow("wrapping -> south clip") + << QGeoRectangle(QGeoCoordinate(-20.0, 130.0), + QGeoCoordinate(-80.0, -170.0)) + << -20.0 + << 20.0 + << QGeoRectangle(QGeoCoordinate(-30.0, 150.0), + QGeoCoordinate(-90.0, -150.0)); +} + +void tst_QGeoRectangle::unite() +{ + QFETCH(QGeoRectangle, in1); + QFETCH(QGeoRectangle, in2); + QFETCH(QGeoRectangle, out); + + QCOMPARE(in1.united(in2), out); + QCOMPARE(in2.united(in1), out); + + QCOMPARE(in1 | in2, out); + QCOMPARE(in2 | in1, out); + + QGeoRectangle united1 = QGeoRectangle(in1); + united1 |= in2; + QCOMPARE(united1, out); + + QGeoRectangle united2 = QGeoRectangle(in2); + united2 |= in1; + QCOMPARE(united2, out); +} + +void tst_QGeoRectangle::unite_data() +{ + QTest::addColumn("in1"); + QTest::addColumn("in2"); + QTest::addColumn("out"); + + QTest::newRow("central and taller") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(50.0, -30.0), + QGeoCoordinate(-50.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(50.0, -30.0), + QGeoCoordinate(-50.0, 30.0)); + + QTest::newRow("central and 180 high") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(90.0, -30.0), + QGeoCoordinate(-90.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(90.0, -30.0), + QGeoCoordinate(-90.0, 30.0)); + + QTest::newRow("central and non overlapping higher") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(60.0, -30.0), + QGeoCoordinate(50.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(60.0, -30.0), + QGeoCoordinate(-30.0, 30.0)); + + QTest::newRow("central and overlapping higher") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(60.0, -30.0), + QGeoCoordinate(0.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(60.0, -30.0), + QGeoCoordinate(-30.0, 30.0)); + + QTest::newRow("central and touching higher") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(60.0, -30.0), + QGeoCoordinate(30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(60.0, -30.0), + QGeoCoordinate(-30.0, 30.0)); + + QTest::newRow("central and non overlapping lower") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(-50.0, -30.0), + QGeoCoordinate(-60.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-60.0, 30.0)); + + QTest::newRow("central and overlapping lower") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(0.0, -30.0), + QGeoCoordinate(-60.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-60.0, 30.0)); + + QTest::newRow("central and touching lower") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(-30.0, -30.0), + QGeoCoordinate(-60.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-60.0, 30.0)); + + QTest::newRow("non wrapping central and wider") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -50.0), + QGeoCoordinate(-30.0, 50.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -50.0), + QGeoCoordinate(-30.0, 50.0)); + + QTest::newRow("non wrapping central and 360 width") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)); + + QTest::newRow("non wrapping central and non overlapping non wrapping left") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -110.0), + QGeoCoordinate(-30.0, -50.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -110.0), + QGeoCoordinate(-30.0, 30.0)); + + QTest::newRow("non wrapping central and overlapping non wrapping left") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -80.0), + QGeoCoordinate(-30.0, -20.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -80.0), + QGeoCoordinate(-30.0, 30.0)); + + QTest::newRow("non wrapping central and touching non wrapping left") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -90.0), + QGeoCoordinate(-30.0, -30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -90.0), + QGeoCoordinate(-30.0, 30.0)); + + QTest::newRow("non wrapping central and non overlapping non wrapping right") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 50.0), + QGeoCoordinate(-30.0, 110.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 110.0)); + + QTest::newRow("non wrapping central and overlapping non wrapping right") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 20.0), + QGeoCoordinate(-30.0, 80.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 80.0)); + + QTest::newRow("non wrapping central and touching non wrapping right") + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 30.0), + QGeoCoordinate(-30.0, 90.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 90.0)); + + QTest::newRow("wrapping and wider") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 130.0), + QGeoCoordinate(-30.0, -130.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 130.0), + QGeoCoordinate(-30.0, -130.0)); + + QTest::newRow("wrapping and 360 width") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)); + + QTest::newRow("wrapping and non overlapping right") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -130.0), + QGeoCoordinate(-30.0, -70.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -70.0)); + + QTest::newRow("wrapping and overlapping right") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -160.0), + QGeoCoordinate(-30.0, -70.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -70.0)); + + QTest::newRow("wrapping and touching right") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -150.0), + QGeoCoordinate(-30.0, -90.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -90.0)); + + QTest::newRow("wrapping and non overlapping left") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 70.0), + QGeoCoordinate(-30.0, 130.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 70.0), + QGeoCoordinate(-30.0, -150.0)); + + QTest::newRow("wrapping and overlapping left") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 100.0), + QGeoCoordinate(-30.0, 160.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 100.0), + QGeoCoordinate(-30.0, -150.0)); + + QTest::newRow("wrapping and touching left") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 90.0), + QGeoCoordinate(-30.0, 150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 90.0), + QGeoCoordinate(-30.0, -150.0)); + + QTest::newRow("wrapping and non overlapping center") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -30.0), + QGeoCoordinate(-30.0, 30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)); + + QTest::newRow("wrapping and overlapping center") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -160.0), + QGeoCoordinate(-30.0, 160.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)); + + QTest::newRow("wrapping and touching center") + << QGeoRectangle(QGeoCoordinate(30.0, 150.0), + QGeoCoordinate(-30.0, -150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -150.0), + QGeoCoordinate(-30.0, 150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)); + + QTest::newRow("wrapping and one containing other") + << QGeoRectangle(QGeoCoordinate(30.0, 40.0), + QGeoCoordinate(-30.0, -40.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, 170.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 40.0), + QGeoCoordinate(-30.0, -40.0)); + + QTest::newRow("small gap over zero line") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, -10.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 10.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)); + + QTest::newRow("small gap before zero line") + << QGeoRectangle(QGeoCoordinate(30.0, -40.0), + QGeoCoordinate(-30.0, -30.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, -10.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -40.0), + QGeoCoordinate(-30.0, -10.0)); + + QTest::newRow("small gap after zero line") + << QGeoRectangle(QGeoCoordinate(30.0, 10.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 30.0), + QGeoCoordinate(-30.0, 40.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 10.0), + QGeoCoordinate(-30.0, 40.0)); + + QTest::newRow("small gap over dateline") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, 170.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -170.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)); + + QTest::newRow("small gap before dateline") + << QGeoRectangle(QGeoCoordinate(30.0, 140.0), + QGeoCoordinate(-30.0, 150.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, 170.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 140.0), + QGeoCoordinate(-30.0, 170.0)); + + QTest::newRow("small gap after dateline") + << QGeoRectangle(QGeoCoordinate(30.0, -170.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -150.0), + QGeoCoordinate(-30.0, -140.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -170.0), + QGeoCoordinate(-30.0, -140.0)); + + QTest::newRow("90-degree inner gap over zero line") + << QGeoRectangle(QGeoCoordinate(30.0, -55.0), + QGeoCoordinate(-30.0, -45.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 45.0), + QGeoCoordinate(-30.0, 55.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -55.0), + QGeoCoordinate(-30.0, 55.0)); + + QTest::newRow("90-degree inner gap before zero line") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, -10.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -65.0), + QGeoCoordinate(-30.0, -55.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -65.0), + QGeoCoordinate(-30.0, -10.0)); + + QTest::newRow("90-degree inner gap after zero line") + << QGeoRectangle(QGeoCoordinate(30.0, 65.0), + QGeoCoordinate(-30.0, 75.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 10.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 10.0), + QGeoCoordinate(-30.0, 75.0)); + + QTest::newRow("90-degree inner gap over dateline") + << QGeoRectangle(QGeoCoordinate(30.0, 125.0), + QGeoCoordinate(-30.0, 135.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -135.0), + QGeoCoordinate(-30.0, -125.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 125.0), + QGeoCoordinate(-30.0, -125.0)); + + QTest::newRow("90-degree inner gap before dateline") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, 170.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 50.0), + QGeoCoordinate(-30.0, 60.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 50.0), + QGeoCoordinate(-30.0, 170.0)); + + QTest::newRow("90-degree inner gap after dateline") + << QGeoRectangle(QGeoCoordinate(30.0, -170.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -60.0), + QGeoCoordinate(-30.0, -50.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -170.0), + QGeoCoordinate(-30.0, -50.0)); + + QTest::newRow("180-degree inner gap centered on zero line") + << QGeoRectangle(QGeoCoordinate(30.0, -100.0), + QGeoCoordinate(-30.0, -90.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 90.0), + QGeoCoordinate(-30.0, 100.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 90.0), + QGeoCoordinate(-30.0, -90.0)); + + QTest::newRow("180-degree outer gap cenetered on zero line") + << QGeoRectangle(QGeoCoordinate(30.0, -90.0), + QGeoCoordinate(-30.0, -80.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 80.0), + QGeoCoordinate(-30.0, 90.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -90.0), + QGeoCoordinate(-30.0, 90.0)); + + QTest::newRow("180-degree shift centered on zero line") + << QGeoRectangle(QGeoCoordinate(30.0, -100.0), + QGeoCoordinate(-30.0, -80.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 80.0), + QGeoCoordinate(-30.0, 100.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)); + + QTest::newRow("180-degree inner gap centered on dateline") + << QGeoRectangle(QGeoCoordinate(30.0, 80.0), + QGeoCoordinate(-30.0, 90.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -90.0), + QGeoCoordinate(-30.0, -80.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -90.0), + QGeoCoordinate(-30.0, 90.0)); + + QTest::newRow("180-degree outer gap centered on dateline") + << QGeoRectangle(QGeoCoordinate(30.0, 90.0), + QGeoCoordinate(-30.0, 100.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -100.0), + QGeoCoordinate(-30.0, -90.0)) + << QGeoRectangle(QGeoCoordinate(30.0, 90.0), + QGeoCoordinate(-30.0, -90.0)); + + QTest::newRow("180-degree shift centered on dateline") + << QGeoRectangle(QGeoCoordinate(30.0, 80.0), + QGeoCoordinate(-30.0, 100.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -100.0), + QGeoCoordinate(-30.0, -80.0)) + << QGeoRectangle(QGeoCoordinate(30.0, -180.0), + QGeoCoordinate(-30.0, 180.0)); + + QTest::newRow("Small outer gap centered on dateline") + << QGeoRectangle(QGeoCoordinate(30, 160), QGeoCoordinate(-30, 170)) + << QGeoRectangle(QGeoCoordinate(30, -170), QGeoCoordinate(-30, 160)) + << QGeoRectangle(QGeoCoordinate(30, -170), QGeoCoordinate(-30, 170)); + + QTest::newRow("Overlapping over the dateline") + << QGeoRectangle(QGeoCoordinate(30, 160), QGeoCoordinate(-30, 170)) + << QGeoRectangle(QGeoCoordinate(30, 160), QGeoCoordinate(-30, -170)) + << QGeoRectangle(QGeoCoordinate(30, 160), QGeoCoordinate(-30, -170)); + + QTest::newRow("wrappinng, one containing other, overlapping center") + << QGeoRectangle(QGeoCoordinate(30, 170), QGeoCoordinate(-30, -30)) + << QGeoRectangle(QGeoCoordinate(30, -140), QGeoCoordinate(-30, -50)) + << QGeoRectangle(QGeoCoordinate(30, 170), QGeoCoordinate(-30, -30)); +} + + +void tst_QGeoRectangle::extendRectangle() +{ + QFETCH(QGeoRectangle, box); + QFETCH(QGeoCoordinate, coord); + QFETCH(QGeoRectangle, out); + + box.extendRectangle(coord); + QCOMPARE(box, out); +} + +void tst_QGeoRectangle::extendRectangle_data() +{ + QTest::addColumn("box"); + QTest::addColumn("coord"); + QTest::addColumn("out"); + + QTest::newRow("valid rect - invalid coordinate") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(100.0, 190.0) + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20)); + QTest::newRow("invalid rect - valid coordinate") + << QGeoRectangle() + << QGeoCoordinate(10.0, 10.0) + << QGeoRectangle(); + QTest::newRow("inside rect - not wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(10.0, 10.0) + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20)); + QTest::newRow("lat outside rect - not wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(40.0, 10.0) + << QGeoRectangle(QGeoCoordinate(40.0, -20.0), + QGeoCoordinate(-30.0, 20)); + QTest::newRow("positive lon outside rect - not wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(10.0, 40.0) + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 40)); + QTest::newRow("negative lon outside rect - not wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, -20.0), + QGeoCoordinate(-30.0, 20.0)) + << QGeoCoordinate(10.0, -40.0) + << QGeoRectangle(QGeoCoordinate(30.0, -40.0), + QGeoCoordinate(-30.0, 20.0)); + QTest::newRow("inside rect - wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoCoordinate(10.0, -170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)); + QTest::newRow("lat outside rect - wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoCoordinate(-40.0, -170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-40.0, -160.0)); + QTest::newRow("positive lon outside rect - wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoCoordinate(10.0, 140.0) + << QGeoRectangle(QGeoCoordinate(30.0, 140.0), + QGeoCoordinate(-30.0, -160.0)); + QTest::newRow("negative lon outside rect - wrapped") + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -160.0)) + << QGeoCoordinate(10.0, -140.0) + << QGeoRectangle(QGeoCoordinate(30.0, 160.0), + QGeoCoordinate(-30.0, -140.0)); + QTest::newRow("extending over 180 degree line eastward") + << QGeoRectangle(QGeoCoordinate(30.0, 130.0), + QGeoCoordinate(-30.0, 160.0)) + << QGeoCoordinate(10.0, -170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 130.0), + QGeoCoordinate(-30.0, -170)); + QTest::newRow("extending over -180 degree line westward") + << QGeoRectangle(QGeoCoordinate(30.0, -160.0), + QGeoCoordinate(-30.0, -130.0)) + << QGeoCoordinate(10.0, 170.0) + << QGeoRectangle(QGeoCoordinate(30.0, 170.0), + QGeoCoordinate(-30.0, -130)); +} + +void tst_QGeoRectangle::areaComparison_data() +{ + QTest::addColumn("area"); + QTest::addColumn("box"); + QTest::addColumn("equal"); + + QGeoRectangle b1(QGeoCoordinate(10.0, 0.0), QGeoCoordinate(0.0, 10.0)); + QGeoRectangle b2(QGeoCoordinate(20.0, 0.0), QGeoCoordinate(0.0, 20.0)); + QGeoCircle c(QGeoCoordinate(0.0, 0.0), 10); + + QTest::newRow("default constructed") << QGeoShape() << QGeoRectangle() << false; + QTest::newRow("b1 b1") << QGeoShape(b1) << b1 << true; + QTest::newRow("b1 b2") << QGeoShape(b1) << b2 << false; + QTest::newRow("b2 b1") << QGeoShape(b2) << b1 << false; + QTest::newRow("b2 b2") << QGeoShape(b2) << b2 << true; + QTest::newRow("c b1") << QGeoShape(c) << b1 << false; +} + +void tst_QGeoRectangle::areaComparison() +{ + QFETCH(QGeoShape, area); + QFETCH(QGeoRectangle, box); + QFETCH(bool, equal); + + QCOMPARE((area == box), equal); + QCOMPARE((area != box), !equal); + + QCOMPARE((box == area), equal); + QCOMPARE((box != area), !equal); +} + +void tst_QGeoRectangle::circleComparison_data() +{ + QTest::addColumn("circle"); + QTest::addColumn("box"); + QTest::addColumn("equal"); + + QGeoRectangle b(QGeoCoordinate(10.0, 0.0), QGeoCoordinate(0.0, 10.0)); + QGeoCircle c(QGeoCoordinate(0.0, 0.0), 10); + + QTest::newRow("default constructed") << QGeoCircle() << QGeoRectangle() << false; + QTest::newRow("c b") << c << b << false; +} + +void tst_QGeoRectangle::circleComparison() +{ + QFETCH(QGeoCircle, circle); + QFETCH(QGeoRectangle, box); + QFETCH(bool, equal); + + QCOMPARE((circle == box), equal); + QCOMPARE((circle != box), !equal); + + QCOMPARE((box == circle), equal); + QCOMPARE((box != circle), !equal); +} + +void tst_QGeoRectangle::hashing() +{ + const QGeoRectangle rectangle(QGeoCoordinate(10.0, 0.0), QGeoCoordinate(0.0, 10.0)); + const size_t rectangleHash = qHash(rectangle); + + QGeoRectangle otherTopLeftRectangle = rectangle; + otherTopLeftRectangle.setTopLeft(QGeoCoordinate(20.0, 0.0)); + QVERIFY(qHash(otherTopLeftRectangle) != rectangleHash); + + QGeoRectangle otherBottomRightRectangle = rectangle; + otherBottomRightRectangle.setBottomRight(QGeoCoordinate(0.0, 5.0)); + QVERIFY(qHash(otherBottomRightRectangle) != rectangleHash); + + // Do not assign, so that they do not share same d_ptr + QGeoRectangle similarRectangle(QGeoCoordinate(10.0, 0.0), QGeoCoordinate(0.0, 10.0)); + QCOMPARE(qHash(similarRectangle), rectangleHash); +} + +QTEST_MAIN(tst_QGeoRectangle) +#include "tst_qgeorectangle.moc" + diff --git a/tests/auto/qgeosatelliteinfo/CMakeLists.txt b/tests/auto/qgeosatelliteinfo/CMakeLists.txt new file mode 100644 index 0000000..b440055 --- /dev/null +++ b/tests/auto/qgeosatelliteinfo/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from qgeosatelliteinfo.pro. + +##################################################################### +## tst_qgeosatelliteinfo Test: +##################################################################### + +qt_internal_add_test(tst_qgeosatelliteinfo + SOURCES + tst_qgeosatelliteinfo.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:qgeosatelliteinfo.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qgeosatelliteinfo/tst_qgeosatelliteinfo.cpp b/tests/auto/qgeosatelliteinfo/tst_qgeosatelliteinfo.cpp new file mode 100644 index 0000000..4d333f4 --- /dev/null +++ b/tests/auto/qgeosatelliteinfo/tst_qgeosatelliteinfo.cpp @@ -0,0 +1,413 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include + +#include +#include +#include +#include + +#include +#include + +QT_USE_NAMESPACE +Q_DECLARE_METATYPE(QGeoSatelliteInfo::Attribute) + +QByteArray tst_qgeosatelliteinfo_debug; + +void tst_qgeosatelliteinfo_messageHandler(QtMsgType type, const QMessageLogContext &, const QString &msg) +{ + switch (type) { + case QtDebugMsg : + tst_qgeosatelliteinfo_debug = msg.toLocal8Bit(); + break; + default: + break; + } +} + + +QList tst_qgeosatelliteinfo_qrealTestValues() +{ + QList values; + + if (qreal(DBL_MIN) == DBL_MIN) + values << DBL_MIN; + + values << FLT_MIN; + values << -1.0 << 0.0 << 1.0; + values << FLT_MAX; + + if (qreal(DBL_MAX) == DBL_MAX) + values << DBL_MAX; + + return values; +} + +QList tst_qgeosatelliteinfo_intTestValues() +{ + QList values; + values << INT_MIN << -100 << 0 << 100 << INT_MAX; + return values; +} + +QList tst_qgeosatelliteinfo_getAttributes() +{ + QList attributes; + attributes << QGeoSatelliteInfo::Elevation + << QGeoSatelliteInfo::Azimuth; + return attributes; +} + + +class tst_QGeoSatelliteInfo : public QObject +{ + Q_OBJECT + +private: + QGeoSatelliteInfo updateWithAttribute(QGeoSatelliteInfo::Attribute attribute, qreal value) + { + QGeoSatelliteInfo info; + info.setAttribute(attribute, value); + return info; + } + + void addTestData_update() + { + QTest::addColumn("info"); + + QList intValues = tst_qgeosatelliteinfo_intTestValues(); + + for (int i=0; i attributes = tst_qgeosatelliteinfo_getAttributes(); + QList qrealValues = tst_qgeosatelliteinfo_qrealTestValues(); + for (int i=0; i attributes = tst_qgeosatelliteinfo_getAttributes(); + for (int i=0; i("signal"); + + QList intValues = tst_qgeosatelliteinfo_intTestValues(); + for (int i=0; i("satId"); + + QList intValues = tst_qgeosatelliteinfo_intTestValues(); + for (int i=0; i(system)); + QCOMPARE(info.satelliteSystem(), static_cast(system)); + } + + void setSatelliteSystem_data() + { + QTest::addColumn("system"); + + QTest::newRow("Sat system undefined") + << int(QGeoSatelliteInfo::Undefined); + QTest::newRow("Sat system GPS") + << int(QGeoSatelliteInfo::GPS); + QTest::newRow("Sat system GLONASS") + << int(QGeoSatelliteInfo::GLONASS); + } + + void attribute() + { + QFETCH(QGeoSatelliteInfo::Attribute, attribute); + QFETCH(qreal, value); + + QGeoSatelliteInfo u; + QCOMPARE(u.attribute(attribute), qreal(-1.0)); + + u.setAttribute(attribute, value); + QCOMPARE(u.attribute(attribute), value); + u.removeAttribute(attribute); + QCOMPARE(u.attribute(attribute), qreal(-1.0)); + } + + void attribute_data() + { + QTest::addColumn("attribute"); + QTest::addColumn("value"); + + QList props; + props << QGeoSatelliteInfo::Elevation + << QGeoSatelliteInfo::Azimuth; + for (int i=0; i> inInfo; + QCOMPARE(inInfo, info); + } + + void datastream_data() + { + addTestData_update(); + } + + void debug() + { + QFETCH(QGeoSatelliteInfo, info); + QFETCH(int, nextValue); + QFETCH(QByteArray, debugString); + + qInstallMessageHandler(tst_qgeosatelliteinfo_messageHandler); + qDebug() << info << nextValue; + qInstallMessageHandler(0); + QCOMPARE(QString(tst_qgeosatelliteinfo_debug), QString(debugString)); + } + + void debug_data() + { + QTest::addColumn("info"); + QTest::addColumn("nextValue"); + QTest::addColumn("debugString"); + + QGeoSatelliteInfo info; + + QTest::newRow("uninitialized") << info << 45 + << QByteArray("QGeoSatelliteInfo(system=0, satId=-1, signal-strength=-1) 45"); + + info = QGeoSatelliteInfo(); + info.setSignalStrength(1); + QTest::newRow("with SignalStrength") << info << 60 + << QByteArray("QGeoSatelliteInfo(system=0, satId=-1, signal-strength=1) 60"); + + info = QGeoSatelliteInfo(); + info.setSatelliteIdentifier(1); + QTest::newRow("with SatelliteIdentifier") << info << -1 + << QByteArray("QGeoSatelliteInfo(system=0, satId=1, signal-strength=-1) -1"); + + info = QGeoSatelliteInfo(); + info.setSatelliteSystem(QGeoSatelliteInfo::GPS); + QTest::newRow("with System GPS") << info << 1 + << QByteArray("QGeoSatelliteInfo(system=1, satId=-1, signal-strength=-1) 1"); + + info = QGeoSatelliteInfo(); + info.setSatelliteSystem(QGeoSatelliteInfo::GLONASS); + QTest::newRow("with System GLONASS") << info << 56 + << QByteArray("QGeoSatelliteInfo(system=2, satId=-1, signal-strength=-1) 56"); + + info = QGeoSatelliteInfo(); + info.setAttribute(QGeoSatelliteInfo::Elevation, 1.1); + QTest::newRow("with Elevation") << info << 0 + << QByteArray("QGeoSatelliteInfo(system=0, satId=-1, signal-strength=-1, Elevation=1.1) 0"); + + info = QGeoSatelliteInfo(); + info.setAttribute(QGeoSatelliteInfo::Azimuth, 1.1); + QTest::newRow("with Azimuth") << info << 45 + << QByteArray("QGeoSatelliteInfo(system=0, satId=-1, signal-strength=-1, Azimuth=1.1) 45"); + } +}; + + +QTEST_APPLESS_MAIN(tst_QGeoSatelliteInfo) +#include "tst_qgeosatelliteinfo.moc" diff --git a/tests/auto/qgeosatelliteinfosource/CMakeLists.txt b/tests/auto/qgeosatelliteinfosource/CMakeLists.txt new file mode 100644 index 0000000..3e2c64f --- /dev/null +++ b/tests/auto/qgeosatelliteinfosource/CMakeLists.txt @@ -0,0 +1,22 @@ +# Generated from qgeosatelliteinfosource.pro. + +##################################################################### +## tst_qgeosatelliteinfosource Binary: +##################################################################### + +qt_internal_add_test(tst_qgeosatelliteinfosource + SOURCES + ../utils/qlocationtestutils.cpp ../utils/qlocationtestutils_p.h + testqgeosatelliteinfosource.cpp testqgeosatelliteinfosource_p.h + tst_qgeosatelliteinfosource.cpp + LIBRARIES + Qt::Core + Qt::Positioning + Qt::TestPrivate +) + +#### Keys ignored in scope 1:.:.:qgeosatelliteinfosource.pro:: +# TEMPLATE = "app" + +## Scopes: +##################################################################### diff --git a/tests/auto/qgeosatelliteinfosource/testqgeosatelliteinfosource.cpp b/tests/auto/qgeosatelliteinfosource/testqgeosatelliteinfosource.cpp new file mode 100644 index 0000000..08a0f04 --- /dev/null +++ b/tests/auto/qgeosatelliteinfosource/testqgeosatelliteinfosource.cpp @@ -0,0 +1,741 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include + +#include +#include + +#include "testqgeosatelliteinfosource_p.h" +#include "../utils/qlocationtestutils_p.h" + +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QGeoSatelliteInfoSource::Error) + +#define MAX_WAITING_TIME 50000 + +// Must provide a valid source, unless testing the source +// returned by QGeoSatelliteInfoSource::createDefaultSource() on a system +// that has no default source +#define CHECK_SOURCE_VALID { \ + if (!m_source) { \ + if (m_testingDefaultSource && QGeoSatelliteInfoSource::createDefaultSource(0) == 0) \ + QSKIP("No default satellite source on this system"); \ + else \ + QFAIL("createTestSource() must return a valid source!"); \ + } \ + } + +class MySatelliteSource : public QGeoSatelliteInfoSource +{ + Q_OBJECT +public: + MySatelliteSource(QObject *parent = 0) + : QGeoSatelliteInfoSource(parent) { + } + virtual void startUpdates() override {} + virtual void stopUpdates() override {} + virtual void requestUpdate(int) override {} + virtual int minimumUpdateInterval() const override { + return 0; + } + Error error() const override { return QGeoSatelliteInfoSource::NoError; } +}; + + +class DefaultSourceTest : public TestQGeoSatelliteInfoSource +{ + Q_OBJECT +protected: + QGeoSatelliteInfoSource *createTestSource() override { + return QGeoSatelliteInfoSource::createDefaultSource(0); + } +}; + +TestQGeoSatelliteInfoSource::TestQGeoSatelliteInfoSource(QObject *parent) + : QObject(parent) +{ + qRegisterMetaType(); + + m_testingDefaultSource = false; +} + +TestQGeoSatelliteInfoSource *TestQGeoSatelliteInfoSource::createDefaultSourceTest() +{ + DefaultSourceTest *test = new DefaultSourceTest; + test->m_testingDefaultSource = true; + return test; +} + +void TestQGeoSatelliteInfoSource::base_initTestCase() +{ + qRegisterMetaType >(); +} + +void TestQGeoSatelliteInfoSource::base_init() +{ + m_source = createTestSource(); + m_testSlot2Called = false; +} + +void TestQGeoSatelliteInfoSource::base_cleanup() +{ + delete m_source; + m_source = 0; +} + +void TestQGeoSatelliteInfoSource::base_cleanupTestCase() +{ +} + +void TestQGeoSatelliteInfoSource::initTestCase() +{ + base_initTestCase(); +} + +void TestQGeoSatelliteInfoSource::init() +{ + base_init(); +} + +void TestQGeoSatelliteInfoSource::cleanup() +{ + base_cleanup(); +} + +void TestQGeoSatelliteInfoSource::cleanupTestCase() +{ + base_cleanupTestCase(); +} + +void TestQGeoSatelliteInfoSource::test_slot1() +{ +} + +void TestQGeoSatelliteInfoSource::test_slot2() +{ + m_testSlot2Called = true; +} + +void TestQGeoSatelliteInfoSource::constructor_withParent() +{ + auto parent = std::make_unique(); + new MySatelliteSource(parent.get()); +} + +void TestQGeoSatelliteInfoSource::constructor_noParent() +{ + MySatelliteSource *obj = new MySatelliteSource(); + delete obj; +} + +void TestQGeoSatelliteInfoSource::createDefaultSource() +{ + auto parent = std::make_unique(); + // source will be deleted by parent + QGeoSatelliteInfoSource *source = QGeoSatelliteInfoSource::createDefaultSource(parent.get()); + + // Check that default satellite source is successfully created. + if (!QGeoSatelliteInfoSource::availableSources().isEmpty()) + QVERIFY(source); + else + QVERIFY(!source); +} + +void TestQGeoSatelliteInfoSource::createDefaultSource_noParent() +{ + std::unique_ptr source( + QGeoSatelliteInfoSource::createDefaultSource(0)); + + // Check that default satellite source is successfully created. + if (!QGeoSatelliteInfoSource::availableSources().isEmpty()) + QVERIFY(source); + else + QVERIFY(!source); +} + +void TestQGeoSatelliteInfoSource::updateInterval() +{ + MySatelliteSource s; + QCOMPARE(s.updateInterval(), 0); +} + +void TestQGeoSatelliteInfoSource::setUpdateInterval() +{ + CHECK_SOURCE_VALID; + + QFETCH(int, interval); + QFETCH(int, expectedInterval); + + m_source->setUpdateInterval(interval); + QCOMPARE(m_source->updateInterval(), expectedInterval); +} + +void TestQGeoSatelliteInfoSource::setUpdateInterval_data() +{ + QTest::addColumn("interval"); + QTest::addColumn("expectedInterval"); + QGeoSatelliteInfoSource *source = createTestSource(); + int minUpdateInterval = source ? source->minimumUpdateInterval() : -1; + if (source) + delete source; + + QTest::newRow("0") << 0 << 0; + + if (minUpdateInterval > -1) { + QTest::newRow("INT_MIN") << INT_MIN << minUpdateInterval; + QTest::newRow("-1") << -1 << minUpdateInterval; + } + + if (minUpdateInterval > 0) { + QTest::newRow("more than minInterval") << minUpdateInterval + 1 << minUpdateInterval + 1; + QTest::newRow("equal to minInterval") << minUpdateInterval << minUpdateInterval; + } + + if (minUpdateInterval > 1) { + QTest::newRow("less then minInterval") << minUpdateInterval - 1 << minUpdateInterval; + QTest::newRow("in btw zero and minInterval") << 1 << minUpdateInterval; + } +} + +void TestQGeoSatelliteInfoSource::minimumUpdateInterval() +{ + CHECK_SOURCE_VALID; + + QVERIFY(m_source->minimumUpdateInterval() > 0); +} + +void TestQGeoSatelliteInfoSource::startUpdates_testIntervals() +{ + CHECK_SOURCE_VALID; + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->setUpdateInterval(1000); + const int interval = 10000; + + m_source->startUpdates(); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 1) && (spyUse.size() == 1), interval); + for (int i = 0; i < 6; i++) { + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 1) && (spyUse.size() == 1) && (errorSpy.size() == 0), interval); + spyView.clear(); + spyUse.clear(); + } + m_source->stopUpdates(); +} + + +void TestQGeoSatelliteInfoSource::startUpdates_testIntervalChangesWhileRunning() +{ + // There are two ways of dealing with an interval change, and we have left it system dependent. + // The interval can be changed will running or after the next update. + // WinCE uses the first method, S60 uses the second method. + + // The minimum interval on the symbian emulator is 5000 msecs, which is why the times in + // this test are as high as they are. + + CHECK_SOURCE_VALID; + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->setUpdateInterval(0); + m_source->startUpdates(); + m_source->setUpdateInterval(0); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() > 0) && (spyUse.size() > 0), 7000); + QCOMPARE(errorSpy.size(), 0); + spyView.clear(); + spyUse.clear(); + + m_source->setUpdateInterval(1000); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 2) && (spyUse.size() == 2) && (errorSpy.size() == 0), 15000); + spyView.clear(); + spyUse.clear(); + + m_source->setUpdateInterval(2000); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 2) && (spyUse.size() == 2) && (errorSpy.size() == 0), 30000); + spyView.clear(); + spyUse.clear(); + + m_source->setUpdateInterval(1000); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 2) && (spyUse.size() == 2) && (errorSpy.size() == 0), 15000); + spyView.clear(); + spyUse.clear(); + + m_source->setUpdateInterval(1000); + + QTRY_VERIFY_WITH_TIMEOUT( (spyView.size() == 2) && (spyUse.size() == 2) && (errorSpy.size() == 0), 15000); + spyView.clear(); + spyUse.clear(); + + m_source->setUpdateInterval(0); + + QTRY_VERIFY_WITH_TIMEOUT( (spyView.size() > 0 ) && (spyUse.size() > 0) && (errorSpy.size() == 0), 7000); + spyView.clear(); + spyUse.clear(); + + m_source->setUpdateInterval(0); + + QTRY_VERIFY_WITH_TIMEOUT( (spyView.size() > 0 ) && (spyUse.size() > 0) && (errorSpy.size() == 0), 7000); + spyView.clear(); + spyUse.clear(); + m_source->stopUpdates(); +} + +void TestQGeoSatelliteInfoSource::startUpdates_testDefaultInterval() +{ + CHECK_SOURCE_VALID; + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->startUpdates(); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + for (int i = 0; i < 3; i++) { + QTRY_VERIFY_WITH_TIMEOUT( (spyView.size() > 0 ) && (spyUse.size() > 0) && (errorSpy.size() == 0), 7000); + spyView.clear(); + spyUse.clear(); + } + m_source->stopUpdates(); +} + +void TestQGeoSatelliteInfoSource::startUpdates_testZeroInterval() +{ + CHECK_SOURCE_VALID; + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->setUpdateInterval(0); + m_source->startUpdates(); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + for (int i = 0; i < 3; i++) { + QTRY_VERIFY_WITH_TIMEOUT( (spyView.size() > 0 ) && (spyUse.size() > 0) && (errorSpy.size() == 0), 7000); + spyView.clear(); + spyUse.clear(); + } + m_source->stopUpdates(); +} + +void TestQGeoSatelliteInfoSource::startUpdates_moreThanOnce() +{ + CHECK_SOURCE_VALID; + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->setUpdateInterval(0); + m_source->startUpdates(); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + m_source->startUpdates(); // check there is no crash + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() > 0) && (spyUse.size() > 0), MAX_WAITING_TIME); + + m_source->startUpdates(); // check there is no crash + + m_source->stopUpdates(); +} + +void TestQGeoSatelliteInfoSource::stopUpdates() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->setUpdateInterval(1000); + m_source->startUpdates(); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + for (int i = 0; i < 2; i++) { + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 1) && (spyUse.size() == 1), 12000); + spyView.clear(); + spyUse.clear(); + } + + m_source->stopUpdates(); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 0) && (spyUse.size() == 0), 12000); +} + +void TestQGeoSatelliteInfoSource::stopUpdates_withoutStart() +{ + CHECK_SOURCE_VALID; + + m_source->stopUpdates(); // check there is no crash +} + +void TestQGeoSatelliteInfoSource::requestUpdate() +{ + CHECK_SOURCE_VALID; + + QFETCH(int, timeout); + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(timeout); + + if (!errorSpy.isEmpty()) { + // make sure that it's the UpdateTimeoutError + const auto error = errorSpy[0][0].value(); + QCOMPARE(error, QGeoSatelliteInfoSource::UpdateTimeoutError); + // errorSpy.clear(); // no need to clear the error, as we are expecting it + } + + // Geoclue may deliver update instantly if there is a satellite fix + QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty() || !spyView.isEmpty(), 10); + if (!errorSpy.isEmpty()) { + // make sure that it's the UpdateTimeoutError + const auto error = errorSpy[0][0].value(); + QCOMPARE(error, QGeoSatelliteInfoSource::UpdateTimeoutError); + } +} + +void TestQGeoSatelliteInfoSource::requestUpdate_data() +{ + QTest::addColumn("timeout"); + QTest::newRow("less than zero") << -1; + QTest::newRow("very small timeout") << 1; +} + +void TestQGeoSatelliteInfoSource::requestUpdate_validTimeout() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(1500); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + QTRY_VERIFY_WITH_TIMEOUT( + (spyView.size() == 1) && (spyUse.size() == 1 && (errorSpy.size()) == 0), 7000); +} + +void TestQGeoSatelliteInfoSource::requestUpdate_defaultTimeout() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(0); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + QTRY_VERIFY_WITH_TIMEOUT( + (spyView.size() == 1) && (spyUse.size() == 1 && (errorSpy.size()) == 0), + MAX_WAITING_TIME); +} + +void TestQGeoSatelliteInfoSource::requestUpdate_timeoutLessThanMinimumInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(1); + + QTRY_COMPARE_WITH_TIMEOUT(errorSpy.size(), 1, 1000); + const auto error = errorSpy[0][0].value(); + QCOMPARE(error, QGeoSatelliteInfoSource::UpdateTimeoutError); +} + +void TestQGeoSatelliteInfoSource::requestUpdate_repeatedCalls() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(1500); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 1) && (spyUse.size() == 1), 7000); + spyView.clear(); + spyUse.clear(); + + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 1) && (spyUse.size() == 1), 7000); +} + +void TestQGeoSatelliteInfoSource::requestUpdate_overlappingCalls() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(1500); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 1) && (spyUse.size() == 1), 7000); +} + +void TestQGeoSatelliteInfoSource::requestUpdate_overlappingCallsWithTimeout() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(0); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + m_source->requestUpdate(1); + + QTRY_COMPARE_WITH_TIMEOUT(errorSpy.size(), 0, 7000); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 1) && (spyUse.size() == 1), 7000); +} + +void TestQGeoSatelliteInfoSource::requestUpdateAfterStartUpdates_ZeroInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->setUpdateInterval(0); + m_source->startUpdates(); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() >= 1) && (spyUse.size() >= 1), MAX_WAITING_TIME); + spyView.clear(); + spyUse.clear(); + + m_source->requestUpdate(1500); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() >= 1) && (spyUse.size() >= 1) + && (errorSpy.size() == 0), 7000); + + spyView.clear(); + spyUse.clear(); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() >= 1) && (spyUse.size() >= 1), 12000); + + m_source->stopUpdates(); +} + +void TestQGeoSatelliteInfoSource::requestUpdateAfterStartUpdates_SmallInterval() +{ + CHECK_SOURCE_VALID; + + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->setUpdateInterval(3000); + m_source->requestUpdate(1500); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + m_source->startUpdates(); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() > 0) && (spyUse.size() > 0) + && (errorSpy.size() == 0), 7000); + + spyView.clear(); + spyUse.clear(); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() == 1) && (spyUse.size() == 1), 12000); + + m_source->stopUpdates(); +} + +void TestQGeoSatelliteInfoSource::requestUpdateBeforeStartUpdates_ZeroInterval() +{ + CHECK_SOURCE_VALID; + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(1500); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + m_source->setUpdateInterval(0); + m_source->startUpdates(); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() >= 2) && (spyUse.size() >= 2) && (errorSpy.size() == 0), 14000); + spyView.clear(); + spyUse.clear(); + + QTest::qWait(1500); + + QCOMPARE(errorSpy.size(), 0); + + m_source->stopUpdates(); +} + +void TestQGeoSatelliteInfoSource::requestUpdateBeforeStartUpdates_SmallInterval() +{ + CHECK_SOURCE_VALID; + QSignalSpy spyView(m_source, + SIGNAL(satellitesInViewUpdated(QList))); + QSignalSpy spyUse(m_source, + SIGNAL(satellitesInUseUpdated(QList))); + QSignalSpy errorSpy(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error))); + + m_source->requestUpdate(1500); + + if (!errorSpy.isEmpty()) + QSKIP("Error starting satellite updates."); + + m_source->setUpdateInterval(2000); + m_source->startUpdates(); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() > 0) && (spyUse.size() > 0) && (errorSpy.size() == 0), 7000); + spyView.clear(); + spyUse.clear(); + + QTRY_VERIFY_WITH_TIMEOUT((spyView.size() > 0) && (spyUse.size() > 0) && (errorSpy.size() == 0), 20000); + + m_source->stopUpdates(); +} + + + +void TestQGeoSatelliteInfoSource::removeSlotForRequestTimeout() +{ + CHECK_SOURCE_VALID; + + bool i = connect(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error)), + this, SLOT(test_slot1())); + QVERIFY(i==true); + i = connect(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error)), \ + this, SLOT(test_slot2())); + QVERIFY(i==true); + i = disconnect(m_source, SIGNAL(errorOccurred(QGeoSatelliteInfoSource::Error)), + this, SLOT(test_slot1())); + QVERIFY(i==true); + + m_source->requestUpdate(-1); + QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 1000); +} + +void TestQGeoSatelliteInfoSource::removeSlotForSatellitesInUseUpdated() +{ + CHECK_SOURCE_VALID; + + bool i = connect(m_source, SIGNAL(satellitesInUseUpdated(QList)), this, SLOT(test_slot1())); + QVERIFY(i == true); + i = connect(m_source, SIGNAL(satellitesInUseUpdated(QList)), this, SLOT(test_slot2())); + QVERIFY(i == true); + i = disconnect(m_source, SIGNAL(satellitesInUseUpdated(QList)), this, SLOT(test_slot1())); + QVERIFY(i == true); + + m_source->requestUpdate(1500); + + if (m_source->error() != QGeoSatelliteInfoSource::NoError) + QSKIP("Error starting satellite updates."); + + QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 7000); +} + +void TestQGeoSatelliteInfoSource::removeSlotForSatellitesInViewUpdated() +{ + CHECK_SOURCE_VALID; + + bool i = connect(m_source, SIGNAL(satellitesInViewUpdated(QList)), this, SLOT(test_slot1())); + QVERIFY(i == true); + i = connect(m_source, SIGNAL(satellitesInViewUpdated(QList)), this, SLOT(test_slot2())); + QVERIFY(i == true); + i = disconnect(m_source, SIGNAL(satellitesInViewUpdated(QList)), this, SLOT(test_slot1())); + QVERIFY(i == true); + + m_source->requestUpdate(1500); + + if (m_source->error() != QGeoSatelliteInfoSource::NoError) + QSKIP("Error starting satellite updates."); + + QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 7000); +} + +void TestQGeoSatelliteInfoSource::bindings() +{ + CHECK_SOURCE_VALID; + + QTestPrivate::testReadWritePropertyBasics(*m_source, 1000, 2000, + "updateInterval"); +} + +#include "testqgeosatelliteinfosource.moc" diff --git a/tests/auto/qgeosatelliteinfosource/testqgeosatelliteinfosource_p.h b/tests/auto/qgeosatelliteinfosource/testqgeosatelliteinfosource_p.h new file mode 100644 index 0000000..b73e8a4 --- /dev/null +++ b/tests/auto/qgeosatelliteinfosource/testqgeosatelliteinfosource_p.h @@ -0,0 +1,92 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef TESTQGEOSATELLITEINFOSOURCE_H +#define TESTQGEOSATELLITEINFOSOURCE_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QGeoSatelliteInfoSource; +QT_END_NAMESPACE + + +class TestQGeoSatelliteInfoSource : public QObject +{ + Q_OBJECT + +public: + TestQGeoSatelliteInfoSource(QObject *parent = 0); + + static TestQGeoSatelliteInfoSource *createDefaultSourceTest(); + +protected: + virtual QGeoSatelliteInfoSource *createTestSource() = 0; + + // MUST be called by subclasses if they override respective test slots + void base_initTestCase(); + void base_init(); + void base_cleanup(); + void base_cleanupTestCase(); + +public slots: + void test_slot1(); + void test_slot2(); + +private slots: + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + void constructor_withParent(); + void constructor_noParent(); + + void updateInterval(); + + void setUpdateInterval(); + void setUpdateInterval_data(); + + void minimumUpdateInterval(); + + void createDefaultSource(); + void createDefaultSource_noParent(); + + void startUpdates_testIntervals(); + void startUpdates_testIntervalChangesWhileRunning(); + void startUpdates_testDefaultInterval(); + void startUpdates_testZeroInterval(); + void startUpdates_moreThanOnce(); + void stopUpdates(); + void stopUpdates_withoutStart(); + + void requestUpdate(); + void requestUpdate_data(); + + void requestUpdate_validTimeout(); + void requestUpdate_defaultTimeout(); + void requestUpdate_timeoutLessThanMinimumInterval(); + void requestUpdate_repeatedCalls(); + void requestUpdate_overlappingCalls(); + void requestUpdate_overlappingCallsWithTimeout(); + + void requestUpdateAfterStartUpdates_ZeroInterval(); + void requestUpdateAfterStartUpdates_SmallInterval(); + void requestUpdateBeforeStartUpdates_ZeroInterval(); + void requestUpdateBeforeStartUpdates_SmallInterval(); + + void removeSlotForRequestTimeout(); + void removeSlotForSatellitesInUseUpdated(); + void removeSlotForSatellitesInViewUpdated(); + + void bindings(); + +private: + QGeoSatelliteInfoSource *m_source; + bool m_testingDefaultSource; + bool m_testSlot2Called; +}; + +#endif // #ifndef TESTQGEOSATELLITEINFOSOURCE_H diff --git a/tests/auto/qgeosatelliteinfosource/tst_qgeosatelliteinfosource.cpp b/tests/auto/qgeosatelliteinfosource/tst_qgeosatelliteinfosource.cpp new file mode 100644 index 0000000..054ae82 --- /dev/null +++ b/tests/auto/qgeosatelliteinfosource/tst_qgeosatelliteinfosource.cpp @@ -0,0 +1,12 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "testqgeosatelliteinfosource_p.h" +#include + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + std::unique_ptr test(TestQGeoSatelliteInfoSource::createDefaultSourceTest()); + return QTest::qExec(test.get(), argc, argv); +} diff --git a/tests/auto/qgeoshape/CMakeLists.txt b/tests/auto/qgeoshape/CMakeLists.txt new file mode 100644 index 0000000..a07a7e1 --- /dev/null +++ b/tests/auto/qgeoshape/CMakeLists.txt @@ -0,0 +1,14 @@ +# Generated from qgeoshape.pro. + +##################################################################### +## tst_qgeoshape Binary: +##################################################################### + +qt_internal_add_test(tst_qgeoshape + SOURCES + tst_qgeoshape.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning + Qt::Test +) diff --git a/tests/auto/qgeoshape/tst_qgeoshape.cpp b/tests/auto/qgeoshape/tst_qgeoshape.cpp new file mode 100644 index 0000000..bca2899 --- /dev/null +++ b/tests/auto/qgeoshape/tst_qgeoshape.cpp @@ -0,0 +1,218 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include +#include +#include +#include + +QString tst_qgeoshape_debug; + +void tst_qgeoshape_messageHandler(QtMsgType type, const QMessageLogContext&, + const QString &msg) +{ + switch (type) { + case QtDebugMsg : + tst_qgeoshape_debug = msg; + break; + default: + break; + } +} + +class tst_qgeoshape : public QObject +{ + Q_OBJECT + +private slots: + void testArea(); + void debug_data(); + void debug(); + void conversions(); + void serialization(); + void hashing(); +}; + +void tst_qgeoshape::testArea() +{ + QGeoShape area; + QVERIFY(!area.isValid()); + QVERIFY(area.isEmpty()); + QCOMPARE(area.type(), QGeoShape::UnknownType); + QVERIFY(!area.contains(QGeoCoordinate())); + + // QGeoShape never constructs a QGeoShapePrivate. Hence d_ptr is always 0. + + QGeoShape area2; + + QCOMPARE(area, area2); + + area = area2; + + QCOMPARE(area, area2); + + QGeoShape area3(area2); + + QCOMPARE(area2, area3); +} + +void tst_qgeoshape::debug_data() +{ + QTest::addColumn("shape"); + QTest::addColumn("nextValue"); + QTest::addColumn("debugString"); + + QTest::newRow("uninitialized") << QGeoShape() << 45 + << QString("QGeoShape(Unknown) 45"); + QTest::newRow("rectangle") << QGeoShape(QGeoRectangle()) << 45 + << QString("QGeoShape(Rectangle) 45"); + QTest::newRow("circle") << QGeoShape(QGeoCircle()) << 45 + << QString("QGeoShape(Circle) 45"); + QTest::newRow("polygon") << QGeoShape(QGeoPolygon()) << 45 + << QString("QGeoShape(Polygon) 45"); + QTest::newRow("path") << QGeoShape(QGeoPath()) << 45 + << QString("QGeoShape(Path) 45"); +} + + +void tst_qgeoshape::debug() +{ + QFETCH(QGeoShape, shape); + QFETCH(int, nextValue); + QFETCH(QString, debugString); + + qInstallMessageHandler(tst_qgeoshape_messageHandler); + qDebug() << shape << nextValue; + qInstallMessageHandler(0); + QCOMPARE(tst_qgeoshape_debug, debugString); +} + +void tst_qgeoshape::conversions() +{ + QVariant varShape = QVariant::fromValue(QGeoShape()); + QVariant varRect = QVariant::fromValue(QGeoRectangle( + QGeoCoordinate(1, 1), + QGeoCoordinate(2, 2))); + QVariant varCircle = QVariant::fromValue(QGeoCircle(QGeoCoordinate(3, 3), 1000)); + + QVERIFY(varShape.canConvert()); + QVERIFY(varShape.canConvert()); + QVERIFY(varShape.canConvert()); + QVERIFY(!varRect.canConvert()); + QVERIFY(varRect.canConvert()); + QVERIFY(varRect.canConvert()); + QVERIFY(varCircle.canConvert()); + QVERIFY(!varCircle.canConvert()); + QVERIFY(varCircle.canConvert()); +} + +void tst_qgeoshape::serialization() +{ + QByteArray data; + // empty shape + { + QGeoShape shape; + QDataStream writeStream(&data, QDataStream::WriteOnly); + writeStream << shape; + + QGeoShape otherShape; + QDataStream readStream(&data, QDataStream::ReadOnly); + readStream >> otherShape; + + QCOMPARE(otherShape, shape); + } + // circle + { + QGeoCircle circle(QGeoCoordinate(1.1, 2.2), 10.5); + QDataStream writeStream(&data, QDataStream::WriteOnly); + writeStream << circle; + + QGeoShape otherCircle; + QDataStream readStream(&data, QDataStream::ReadOnly); + readStream >> otherCircle; + + QCOMPARE(otherCircle, circle); + } + // rectangle + { + QGeoRectangle rectangle(QGeoCoordinate(30, 160), QGeoCoordinate(-30, 170)); + QDataStream writeStream(&data, QDataStream::WriteOnly); + writeStream << rectangle; + + QGeoShape otherRectangle; + QDataStream readStream(&data, QDataStream::ReadOnly); + readStream >> otherRectangle; + + QCOMPARE(otherRectangle, rectangle); + } + // polygon + { + QGeoPolygon polygon({ QGeoCoordinate(30, 160), + QGeoCoordinate(0, 170), + QGeoCoordinate(-30, 160) }); + QDataStream writeStream(&data, QDataStream::WriteOnly); + writeStream << polygon; + + QGeoShape otherPolygon; + QDataStream readStream(&data, QDataStream::ReadOnly); + readStream >> otherPolygon; + + QCOMPARE(otherPolygon, polygon); + } + // path + { + QGeoPath path({ QGeoCoordinate(30, 160), QGeoCoordinate(0, 170), + QGeoCoordinate(-30, 180) }, 0.5); + QDataStream writeStream(&data, QDataStream::WriteOnly); + writeStream << path; + + QGeoShape otherPath; + QDataStream readStream(&data, QDataStream::ReadOnly); + readStream >> otherPath; + + QCOMPARE(otherPath, path); + } +} + +void tst_qgeoshape::hashing() +{ + const size_t defaultShapeHash = qHash(QGeoShape()); + + const QGeoCircle circle(QGeoCoordinate(1, 2), 10); + const QGeoShape circleShape = circle; + const size_t circleShapeHash = qHash(circleShape); + QVERIFY(defaultShapeHash != circleShapeHash); + QCOMPARE(qHash(circle), circleShapeHash); + + const QGeoRectangle rectangle(QGeoCoordinate(30, 160), QGeoCoordinate(-30, 170)); + const QGeoShape rectangleShape = rectangle; + const size_t rectangleShapeHash = qHash(rectangleShape); + QVERIFY(defaultShapeHash != rectangleShapeHash); + QVERIFY(circleShapeHash != rectangleShapeHash); + QCOMPARE(qHash(rectangle), rectangleShapeHash); + + const QGeoPolygon polygon({ QGeoCoordinate(30, 160), QGeoCoordinate(0, 170), + QGeoCoordinate(-30, 160) }); + const QGeoShape polygonShape = polygon; + const size_t polygonShapeHash = qHash(polygonShape); + QVERIFY(defaultShapeHash != polygonShapeHash); + QVERIFY(circleShapeHash != polygonShapeHash); + QVERIFY(rectangleShapeHash != polygonShapeHash); + QCOMPARE(qHash(polygon), polygonShapeHash); + + const QGeoPath path({ QGeoCoordinate(30, 160), QGeoCoordinate(0, 170), + QGeoCoordinate(-30, 180) }, 0.5); + const QGeoShape pathShape = path; + const size_t pathShapeHash = qHash(pathShape); + QVERIFY(defaultShapeHash != pathShapeHash); + QVERIFY(circleShapeHash != pathShapeHash); + QVERIFY(rectangleShapeHash != pathShapeHash); + QVERIFY(polygonShapeHash != pathShapeHash); + QCOMPARE(qHash(path), pathShapeHash); +} + +QTEST_MAIN(tst_qgeoshape) +#include "tst_qgeoshape.moc" diff --git a/tests/auto/qnmeapositioninfosource/CMakeLists.txt b/tests/auto/qnmeapositioninfosource/CMakeLists.txt new file mode 100644 index 0000000..3a72497 --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/CMakeLists.txt @@ -0,0 +1,7 @@ +# Generated from qnmeapositioninfosource.pro. + +add_subdirectory(dummy) +add_subdirectory(realtime) +add_subdirectory(simulation) +add_subdirectory(realtime_generic) +add_subdirectory(simulation_generic) diff --git a/tests/auto/qnmeapositioninfosource/dummy/CMakeLists.txt b/tests/auto/qnmeapositioninfosource/dummy/CMakeLists.txt new file mode 100644 index 0000000..d152dc7 --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/dummy/CMakeLists.txt @@ -0,0 +1,23 @@ +# Generated from dummynmeapositioninfosource.pro. + +##################################################################### +## tst_dummynmeapositioninfosource Test: +##################################################################### + +qt_internal_add_test(tst_dummynmeapositioninfosource + SOURCES + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + ../../utils/qnmeaproxyfactory.cpp ../../utils/qnmeaproxyfactory.h + tst_dummynmeapositioninfosource.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + LIBRARIES + Qt::Core + Qt::Network + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:dummynmeapositioninfosource.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qnmeapositioninfosource/dummy/tst_dummynmeapositioninfosource.cpp b/tests/auto/qnmeapositioninfosource/dummy/tst_dummynmeapositioninfosource.cpp new file mode 100644 index 0000000..3c3e4fe --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/dummy/tst_dummynmeapositioninfosource.cpp @@ -0,0 +1,124 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include "../utils/qnmeaproxyfactory.h" +#include "../utils/qlocationtestutils_p.h" + +#include +#include +#include + +Q_DECLARE_METATYPE(QNmeaPositionInfoSource::UpdateMode) + +class DummyNmeaPositionInfoSource : public QNmeaPositionInfoSource +{ + Q_OBJECT + +public: + DummyNmeaPositionInfoSource(QNmeaPositionInfoSource::UpdateMode mode, QObject *parent = 0); + +protected: + bool parsePosInfoFromNmeaData(const char *data, + int size, + QGeoPositionInfo *posInfo, + bool *hasFix) override; + +private: + int callCount; +}; + +DummyNmeaPositionInfoSource::DummyNmeaPositionInfoSource(QNmeaPositionInfoSource::UpdateMode mode, QObject *parent) : + QNmeaPositionInfoSource(mode, parent), + callCount(0) +{ +} + +bool DummyNmeaPositionInfoSource::parsePosInfoFromNmeaData(const char* data, + int size, + QGeoPositionInfo *posInfo, + bool *hasFix) +{ + Q_UNUSED(data); + Q_UNUSED(size); + + posInfo->setCoordinate(QGeoCoordinate(callCount * 1.0, callCount * 1.0, callCount * 1.0)); + posInfo->setTimestamp(QDateTime::currentDateTimeUtc()); + *hasFix = true; + ++callCount; + + return true; +} + +class tst_DummyNmeaPositionInfoSource : public QObject +{ + Q_OBJECT + +public: + tst_DummyNmeaPositionInfoSource(); + +private slots: + void initTestCase(); + void testOverloadedParseFunction(); +}; + + +tst_DummyNmeaPositionInfoSource::tst_DummyNmeaPositionInfoSource() {} + +void tst_DummyNmeaPositionInfoSource::initTestCase() +{ + +} + +void tst_DummyNmeaPositionInfoSource::testOverloadedParseFunction() +{ + DummyNmeaPositionInfoSource source(QNmeaPositionInfoSource::RealTimeMode); + QNmeaProxyFactory factory; + // proxy is deleted by the source + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spy(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + + QGeoPositionInfo pos; + + proxy->source()->startUpdates(); + + proxy->feedBytes(QString("The parser converts\n").toLatin1()); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() == 1), 10000); + pos = spy.at(0).at(0).value(); + + QVERIFY((pos.coordinate().latitude() == 0.0) + && (pos.coordinate().longitude() == 0.0) + && (pos.coordinate().altitude() == 0.0)); + + spy.clear(); + + proxy->feedBytes(QString("any data it receives\n").toLatin1()); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() == 1), 10000); + pos = spy.at(0).at(0).value(); + + QVERIFY((pos.coordinate().latitude() == 1.0) + && (pos.coordinate().longitude() == 1.0) + && (pos.coordinate().altitude() == 1.0)); + + spy.clear(); + + proxy->feedBytes(QString("into positions\n").toLatin1()); + + QTRY_VERIFY_WITH_TIMEOUT((spy.size() == 1), 10000); + pos = spy.at(0).at(0).value(); + + QVERIFY((pos.coordinate().latitude() == 2.0) + && (pos.coordinate().longitude() == 2.0) + && (pos.coordinate().altitude() == 2.0)); + + spy.clear(); +} + +#include "tst_dummynmeapositioninfosource.moc" + +QTEST_GUILESS_MAIN(tst_DummyNmeaPositionInfoSource); diff --git a/tests/auto/qnmeapositioninfosource/realtime/CMakeLists.txt b/tests/auto/qnmeapositioninfosource/realtime/CMakeLists.txt new file mode 100644 index 0000000..4ca5f9a --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/realtime/CMakeLists.txt @@ -0,0 +1,26 @@ +# Generated from qnmeapositioninfosource_realtime.pro. + +##################################################################### +## tst_qnmeapositioninfosource_realtime Test: +##################################################################### + +qt_internal_add_test(tst_qnmeapositioninfosource_realtime + SOURCES + ../../qgeopositioninfosource/testqgeopositioninfosource.cpp ../../qgeopositioninfosource/testqgeopositioninfosource_p.h + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + ../../utils/qnmeaproxyfactory.cpp ../../utils/qnmeaproxyfactory.h + ../tst_qnmeapositioninfosource.cpp ../tst_qnmeapositioninfosource.h + tst_qnmeapositioninfosource_realtime.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + LIBRARIES + Qt::Core + Qt::Network + Qt::Positioning + Qt::TestPrivate +) + +#### Keys ignored in scope 1:.:.:qnmeapositioninfosource_realtime.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qnmeapositioninfosource/realtime/tst_qnmeapositioninfosource_realtime.cpp b/tests/auto/qnmeapositioninfosource/realtime/tst_qnmeapositioninfosource_realtime.cpp new file mode 100644 index 0000000..4586347 --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/realtime/tst_qnmeapositioninfosource_realtime.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include "tst_qnmeapositioninfosource.h" + +class tst_QNmeaPositionInfoSource_RealTime : public tst_QNmeaPositionInfoSource +{ + Q_OBJECT + +public: + tst_QNmeaPositionInfoSource_RealTime() + : tst_QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode) {} +}; + +#include "tst_qnmeapositioninfosource_realtime.moc" + +QTEST_GUILESS_MAIN(tst_QNmeaPositionInfoSource_RealTime); diff --git a/tests/auto/qnmeapositioninfosource/realtime_generic/CMakeLists.txt b/tests/auto/qnmeapositioninfosource/realtime_generic/CMakeLists.txt new file mode 100644 index 0000000..6efac25 --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/realtime_generic/CMakeLists.txt @@ -0,0 +1,37 @@ +# Generated from qnmeapositioninfosource_realtime_generic.pro. + +##################################################################### +## tst_qnmeapositioninfosource_realtime_generic Test: +##################################################################### + +qt_internal_add_test(tst_qnmeapositioninfosource_realtime_generic + SOURCES + ../../qgeopositioninfosource/testqgeopositioninfosource.cpp ../../qgeopositioninfosource/testqgeopositioninfosource_p.h + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + ../../utils/qnmeaproxyfactory.cpp ../../utils/qnmeaproxyfactory.h + ../tst_qnmeapositioninfosource.cpp ../tst_qnmeapositioninfosource.h + tst_qnmeapositioninfosource_realtime_generic.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + LIBRARIES + Qt::Core + Qt::Network + Qt::Positioning + Qt::TestPrivate +) + +# Default android position plugin is not loaded for unit-tests, so we have to +# explicitly use a test position plugin. +add_dependencies(tst_qnmeapositioninfosource_realtime_generic + QGeoPositionInfoSourceFactoryTestPlugin) +if(ANDROID) + set_target_properties(tst_qnmeapositioninfosource_realtime_generic PROPERTIES + QT_ANDROID_EXTRA_PLUGINS "$" + ) +endif() + +#### Keys ignored in scope 1:.:.:qnmeapositioninfosource_realtime_generic.pro:: +# TEMPLATE = "app" +# testcase.timeout = "400" diff --git a/tests/auto/qnmeapositioninfosource/realtime_generic/tst_qnmeapositioninfosource_realtime_generic.cpp b/tests/auto/qnmeapositioninfosource/realtime_generic/tst_qnmeapositioninfosource_realtime_generic.cpp new file mode 100644 index 0000000..6b24a4d --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/realtime_generic/tst_qnmeapositioninfosource_realtime_generic.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include "tst_qnmeapositioninfosource.h" + +class tst_QNmeaPositionInfoSource_RealTime_Generic : public TestQGeoPositionInfoSource +{ + Q_OBJECT + +public: + tst_QNmeaPositionInfoSource_RealTime_Generic() + { + m_factory = new QNmeaProxyFactory; +#if QT_CONFIG(library) + /* + * Set custom path since CI doesn't install test plugins + */ +#ifdef Q_OS_WIN + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#else + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#endif +#endif + } + + ~tst_QNmeaPositionInfoSource_RealTime_Generic() + { + delete m_factory; + } + +protected: + QGeoPositionInfoSource *createTestSource() override + { + QNmeaPositionInfoSource *source = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode); + QNmeaPositionInfoSourceProxy *proxy = static_cast( + m_factory->createPositionInfoSourceProxy(source)); + Feeder *feeder = new Feeder(source); + feeder->start(proxy); + return source; + } + +private: + QNmeaProxyFactory *m_factory; +}; + +#include "tst_qnmeapositioninfosource_realtime_generic.moc" + +QTEST_GUILESS_MAIN(tst_QNmeaPositionInfoSource_RealTime_Generic); diff --git a/tests/auto/qnmeapositioninfosource/simulation/CMakeLists.txt b/tests/auto/qnmeapositioninfosource/simulation/CMakeLists.txt new file mode 100644 index 0000000..f0ea5ce --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/simulation/CMakeLists.txt @@ -0,0 +1,26 @@ +# Generated from qnmeapositioninfosource_simulation.pro. + +##################################################################### +## tst_qnmeapositioninfosource_simulation Test: +##################################################################### + +qt_internal_add_test(tst_qnmeapositioninfosource_simulation + SOURCES + ../../qgeopositioninfosource/testqgeopositioninfosource.cpp ../../qgeopositioninfosource/testqgeopositioninfosource_p.h + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + ../../utils/qnmeaproxyfactory.cpp ../../utils/qnmeaproxyfactory.h + ../tst_qnmeapositioninfosource.cpp ../tst_qnmeapositioninfosource.h + tst_qnmeapositioninfosource_simulation.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + LIBRARIES + Qt::Core + Qt::Network + Qt::Positioning + Qt::TestPrivate +) + +#### Keys ignored in scope 1:.:.:qnmeapositioninfosource_simulation.pro:: +# TEMPLATE = "app" diff --git a/tests/auto/qnmeapositioninfosource/simulation/tst_qnmeapositioninfosource_simulation.cpp b/tests/auto/qnmeapositioninfosource/simulation/tst_qnmeapositioninfosource_simulation.cpp new file mode 100644 index 0000000..1da3fcd --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/simulation/tst_qnmeapositioninfosource_simulation.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include "tst_qnmeapositioninfosource.h" + +class tst_QNmeaPositionInfoSource_Simulation : public tst_QNmeaPositionInfoSource +{ + Q_OBJECT +public: + tst_QNmeaPositionInfoSource_Simulation() + : tst_QNmeaPositionInfoSource(QNmeaPositionInfoSource::SimulationMode) {} +}; + +#include "tst_qnmeapositioninfosource_simulation.moc" + +QTEST_GUILESS_MAIN(tst_QNmeaPositionInfoSource_Simulation); diff --git a/tests/auto/qnmeapositioninfosource/simulation_generic/CMakeLists.txt b/tests/auto/qnmeapositioninfosource/simulation_generic/CMakeLists.txt new file mode 100644 index 0000000..958ea90 --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/simulation_generic/CMakeLists.txt @@ -0,0 +1,41 @@ +# Generated from qnmeapositioninfosource_simulation_generic.pro. + +##################################################################### +## tst_qnmeapositioninfosource_simulation_generic Test: +##################################################################### + +# special case begin + +# Renamed the target due to problems with the maximum full path on +# Windows systems (which is 250 characters only) +qt_internal_add_test(tst_qnmeaposinfosource_sim_generic +# special case end + SOURCES + ../../qgeopositioninfosource/testqgeopositioninfosource.cpp ../../qgeopositioninfosource/testqgeopositioninfosource_p.h + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + ../../utils/qnmeaproxyfactory.cpp ../../utils/qnmeaproxyfactory.h + ../tst_qnmeapositioninfosource.cpp ../tst_qnmeapositioninfosource.h + tst_qnmeapositioninfosource_simulation_generic.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + LIBRARIES + Qt::Core + Qt::Network + Qt::Positioning + Qt::TestPrivate +) + +# Default android position plugin is not loaded for unit-tests, so we have to +# explicitly use a test position plugin. +add_dependencies(tst_qnmeaposinfosource_sim_generic QGeoPositionInfoSourceFactoryTestPlugin) +if(ANDROID) + set_target_properties(tst_qnmeaposinfosource_sim_generic PROPERTIES + QT_ANDROID_EXTRA_PLUGINS "$" + ) +endif() + +#### Keys ignored in scope 1:.:.:qnmeapositioninfosource_simulation_generic.pro:: +# TEMPLATE = "app" +# testcase.timeout = "400" diff --git a/tests/auto/qnmeapositioninfosource/simulation_generic/tst_qnmeapositioninfosource_simulation_generic.cpp b/tests/auto/qnmeapositioninfosource/simulation_generic/tst_qnmeapositioninfosource_simulation_generic.cpp new file mode 100644 index 0000000..e1052c9 --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/simulation_generic/tst_qnmeapositioninfosource_simulation_generic.cpp @@ -0,0 +1,39 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include "tst_qnmeapositioninfosource.h" + +class tst_QNmeaPositionInfoSource_Simulation_Generic : public TestQGeoPositionInfoSource +{ + Q_OBJECT +public: + tst_QNmeaPositionInfoSource_Simulation_Generic() + { +#if QT_CONFIG(library) + /* + * Set custom path since CI doesn't install test plugins + */ +#ifdef Q_OS_WIN + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#else + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + + QStringLiteral("/../../../../plugins")); +#endif +#endif + } + +protected: + QGeoPositionInfoSource *createTestSource() override + { + QNmeaPositionInfoSource *source = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::SimulationMode); + source->setDevice(new UnlimitedNmeaStream(source)); + return source; + } +}; + +#include "tst_qnmeapositioninfosource_simulation_generic.moc" + +QTEST_GUILESS_MAIN(tst_QNmeaPositionInfoSource_Simulation_Generic); diff --git a/tests/auto/qnmeapositioninfosource/tst_qnmeapositioninfosource.cpp b/tests/auto/qnmeapositioninfosource/tst_qnmeapositioninfosource.cpp new file mode 100644 index 0000000..d2965e1 --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/tst_qnmeapositioninfosource.cpp @@ -0,0 +1,591 @@ +// Copyright (C) 2016 Jolla Ltd. +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +//TESTED_COMPONENT=src/location + +#include "tst_qnmeapositioninfosource.h" + +#include +#include +#include + +#ifdef Q_OS_WIN + +// Windows seems to require longer timeouts and step length +// We override the standard QTestCase related macros + +#ifdef QTRY_COMPARE_WITH_TIMEOUT +#undef QTRY_COMPARE_WITH_TIMEOUT +#endif +#define QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, __timeout) \ +do { \ + const int __step = 100; \ + const int __timeoutValue = __timeout; \ + if ((__expr) != (__expected)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeoutValue && ((__expr) != (__expected)); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QCOMPARE(__expr, __expected); \ +} while (0) + +#ifdef QTRY_COMPARE +#undef QTRY_COMPARE +#endif +#define QTRY_COMPARE(__expr, __expected) QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, 10000) + +#endif + +tst_QNmeaPositionInfoSource::tst_QNmeaPositionInfoSource(QNmeaPositionInfoSource::UpdateMode mode, QObject *parent) + : QObject(parent), + m_mode(mode) +{ +} + +void tst_QNmeaPositionInfoSource::initTestCase() +{ + qRegisterMetaType(); +} + +void tst_QNmeaPositionInfoSource::constructor() +{ + QObject o; + QNmeaPositionInfoSource source(m_mode, &o); + QCOMPARE(source.updateMode(), m_mode); + QCOMPARE(source.parent(), &o); +} + +void tst_QNmeaPositionInfoSource::supportedPositioningMethods() +{ + QNmeaPositionInfoSource source(m_mode); + QCOMPARE(source.supportedPositioningMethods(), QNmeaPositionInfoSource::SatellitePositioningMethods); +} + +void tst_QNmeaPositionInfoSource::minimumUpdateInterval() +{ + QNmeaPositionInfoSource source(m_mode); + QCOMPARE(source.minimumUpdateInterval(), 2); +} + +void tst_QNmeaPositionInfoSource::userEquivalentRangeError() +{ + QNmeaPositionInfoSource source(m_mode); + QVERIFY(qIsNaN(source.userEquivalentRangeError())); + source.setUserEquivalentRangeError(5.1); + QVERIFY(qFuzzyCompare(source.userEquivalentRangeError(), 5.1)); +} + +void tst_QNmeaPositionInfoSource::setUpdateInterval_delayedUpdate() +{ + // If an update interval is set, and an update is not available at a + // particular interval, the source should emit the next update as soon + // as it becomes available + + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + // Android emulator is slow, so increase the update interval and all + // timeouts for it. +#ifndef Q_OS_ANDROID + constexpr int updateInterval = 500; + constexpr int waitInterval = 600; + constexpr int maxDelay = 400; +#else + constexpr int updateInterval = 1000; + constexpr int waitInterval = 1100; + constexpr int maxDelay = 900; +#endif + + QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + proxy->source()->setUpdateInterval(updateInterval); + proxy->source()->startUpdates(); + + QTest::qWait(waitInterval); + QDateTime now = QDateTime::currentDateTime(); + proxy->feedUpdate(now); + QTRY_COMPARE(spyUpdate.size(), 1); + + // should have gotten the update immediately, and not have needed to + // wait until the next interval + QVERIFY(now.time().msecsTo(QDateTime::currentDateTime().time()) < maxDelay); +} + +void tst_QNmeaPositionInfoSource::lastKnownPosition() +{ + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QCOMPARE(proxy->source()->lastKnownPosition(), QGeoPositionInfo()); + + // source may need requestUpdate() or startUpdates() to be called to + // trigger reading of data channel + QSignalSpy spyTimeout(proxy->source(), SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + proxy->source()->requestUpdate(proxy->source()->minimumUpdateInterval()); + QTRY_COMPARE(spyTimeout.size(), 1); + const QList arguments = spyTimeout.takeFirst(); + const auto error = arguments.at(0).value(); + QCOMPARE(error, QGeoPositionInfoSource::UpdateTimeoutError); + + // If an update is received and startUpdates() or requestUpdate() hasn't + // been called, it should still be available through lastKnownPosition() + QDateTime dt = QDateTime::currentDateTimeUtc(); + proxy->feedUpdate(dt); + QTRY_COMPARE(proxy->source()->lastKnownPosition().timestamp(), dt); + + QList dateTimes = createDateTimes(5); + for (int i=0; isource()->requestUpdate(); // Irrelevant for this test + proxy->feedUpdate(dateTimes[i]); + QTRY_COMPARE(proxy->source()->lastKnownPosition().timestamp(), dateTimes[i]); + } + + proxy->source()->startUpdates(); + // if dateTimes are older than before, they will be ignored. + dateTimes = createDateTimes(dateTimes.last().addMSecs(100), 5); + for (int i=0; ifeedUpdate(dateTimes[i]); + QTRY_COMPARE(proxy->source()->lastKnownPosition().timestamp(), dateTimes[i]); + } +} + +void tst_QNmeaPositionInfoSource::beginWithBufferedData() +{ + // In SimulationMode, data stored in the QIODevice is read when + // startUpdates() or requestUpdate() is called. + // In RealTimeMode, all existing data in the QIODevice is ignored - + // only new data will be read. + + QFETCH(QList, dateTimes); + QFETCH(UpdateTriggerMethod, trigger); + + QByteArray bytes; + for (int i=0; i().timestamp(), dateTimes[i]); + } else if (trigger == RequestUpdatesMethod) { + QTRY_COMPARE(spy.size(), 1); + QCOMPARE(spy.at(0).at(0).value().timestamp(), dateTimes.first()); + } + } +} + +void tst_QNmeaPositionInfoSource::beginWithBufferedData_data() +{ + QTest::addColumn >("dateTimes"); + QTest::addColumn("trigger"); + + QList dateTimes; + dateTimes << QDateTime::currentDateTime().toUTC(); + + QTest::newRow("startUpdates(), 1 update in buffer") << dateTimes << StartUpdatesMethod; + QTest::newRow("requestUpdate(), 1 update in buffer") << dateTimes << RequestUpdatesMethod; + + for (int i=1; i<3; i++) + dateTimes << dateTimes[0].addMSecs(i * 100); + QTest::newRow("startUpdates(), multiple updates in buffer") << dateTimes << StartUpdatesMethod; + QTest::newRow("requestUpdate(), multiple updates in buffer") << dateTimes << RequestUpdatesMethod; +} + +void tst_QNmeaPositionInfoSource::startUpdates() +{ + QFETCH(QList, dateTimes); + + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + proxy->source()->startUpdates(); + + for (int i=0; ifeedUpdate(dateTimes[i]); + QTRY_COMPARE(spyUpdate.size(), dateTimes.size()); +} + +void tst_QNmeaPositionInfoSource::startUpdates_data() +{ + QTest::addColumn >("dateTimes"); + + QTest::newRow("1 update") << createDateTimes(1); + QTest::newRow("2 updates") << createDateTimes(2); + QTest::newRow("10 updates") << createDateTimes(10); +} + +void tst_QNmeaPositionInfoSource::startUpdates_withTimeout() +{ + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(proxy->source(), SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + proxy->source()->setUpdateInterval(1000); + proxy->source()->startUpdates(); + + QDateTime dt = QDateTime::currentDateTimeUtc(); + + if (m_mode == QNmeaPositionInfoSource::SimulationMode) { + // the first sentence primes the simulation + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt).toLatin1()); + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addMSecs(10)).toLatin1()); + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addMSecs(1100)).toLatin1()); + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addMSecs(2200)).toLatin1()); + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(9)).toLatin1()); + + QElapsedTimer t; + t.start(); + + for (int j = 1; j < 4; ++j) { + QTRY_COMPARE(spyUpdate.size(), j); + QCOMPARE(spyTimeout.size(), 0); + int time = t.elapsed(); + QVERIFY((time > j*1000 - 300) && (time < j*1000 + 300)); + } + + spyUpdate.clear(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() == 0) && (spyTimeout.size() == 1), 7500); + const QList arguments = spyTimeout.takeFirst(); + const auto error = arguments.at(0).value(); + QCOMPARE(error, QGeoPositionInfoSource::UpdateTimeoutError); + spyTimeout.clear(); + + QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.size() == 1) && (spyTimeout.size() == 0), 7500); + + } else { + // dt + 900 + QTRY_VERIFY(spyUpdate.size() == 0 && spyTimeout.size() == 0); + + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(1)).toLatin1()); + // dt + 1200 + QTRY_VERIFY(spyUpdate.size() == 1 && spyTimeout.size() == 0); + spyUpdate.clear(); + + // dt + 1900 + QTRY_VERIFY(spyUpdate.size() == 0 && spyTimeout.size() == 0); + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(2)).toLatin1()); + + // dt + 2200 + QTRY_VERIFY(spyUpdate.size() == 1 && spyTimeout.size() == 0); + spyUpdate.clear(); + + // dt + 2900 + QTRY_VERIFY(spyUpdate.size() == 0 && spyTimeout.size() == 0); + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(3)).toLatin1()); + + // dt + 3200 + QTRY_VERIFY(spyUpdate.size() == 1 && spyTimeout.size() == 0); + spyUpdate.clear(); + + // dt + 6900 + QTRY_VERIFY(spyUpdate.size() == 0 && spyTimeout.size() == 1); + const QList arguments = spyTimeout.takeFirst(); + const auto error = arguments.at(0).value(); + QCOMPARE(error, QGeoPositionInfoSource::UpdateTimeoutError); + spyTimeout.clear(); + proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(7)).toLatin1()); + + // dt + 7200 + QTRY_VERIFY(spyUpdate.size() == 1 && spyTimeout.size() == 0); + spyUpdate.clear(); + } +} + +void tst_QNmeaPositionInfoSource::startUpdates_expectLatestUpdateOnly() +{ + // If startUpdates() is called and an interval has been set, if multiple' + // updates are in the buffer, only the latest update should be emitted + + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + proxy->source()->setUpdateInterval(500); + proxy->source()->startUpdates(); + + QList dateTimes = createDateTimes(3); + for (int i=0; ifeedUpdate(dateTimes[i]); + + QTRY_COMPARE(spyUpdate.size(), 1); + QCOMPARE(spyUpdate[0][0].value().timestamp(), dateTimes.last()); +} + +void tst_QNmeaPositionInfoSource::startUpdates_waitForValidDateTime() +{ + // Tests that the class does not emit an update until it receives a + // sentences with a valid date *and* time. All sentences before this + // should be ignored, and any sentences received after this that do + // not have a date should use the known date. + + QFETCH(QByteArray, bytes); + QFETCH(QList, dateTimes); + QFETCH(QList, expectHorizontalAccuracy); + QFETCH(QList, expectVerticalAccuracy); + + QNmeaPositionInfoSource source(m_mode); + source.setUserEquivalentRangeError(5.1); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spy(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + QObject::connect(proxy->source(), &QNmeaPositionInfoSource::positionUpdated, [](const QGeoPositionInfo &info) { + qDebug() << info.timestamp(); + }); + + proxy->source()->startUpdates(); + proxy->feedBytes(bytes); + QTest::qWait(1000); // default push delay is 20ms + QTRY_COMPARE(spy.size(), dateTimes.size()); + + for (int i=0; i(); + + QCOMPARE(pInfo.timestamp(), dateTimes[i]); + + // Generated GGA/GSA sentences have hard coded HDOP of 3.5, which corrisponds to a + // horizontal accuracy of 35.7, for the user equivalent range error of 5.1 set above. + QCOMPARE(pInfo.hasAttribute(QGeoPositionInfo::HorizontalAccuracy), + expectHorizontalAccuracy[i]); + if (pInfo.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) + QVERIFY(qFuzzyCompare(pInfo.attribute(QGeoPositionInfo::HorizontalAccuracy), 35.7)); + + // Generated GSA sentences have hard coded VDOP of 4.0, which corrisponds to a vertical + // accuracy of 40.8, for the user equivalent range error of 5.1 set above. + QCOMPARE(pInfo.hasAttribute(QGeoPositionInfo::VerticalAccuracy), + expectVerticalAccuracy[i]); + if (pInfo.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) + QVERIFY(qFuzzyCompare(pInfo.attribute(QGeoPositionInfo::VerticalAccuracy), 40.8)); + } +} + +void tst_QNmeaPositionInfoSource::startUpdates_waitForValidDateTime_data() +{ + QTest::addColumn("bytes"); + QTest::addColumn >("dateTimes"); + QTest::addColumn >("expectHorizontalAccuracy"); + QTest::addColumn >("expectVerticalAccuracy"); + + QDateTime dt = QDateTime::currentDateTime().toUTC(); + QByteArray bytes; + + // should only receive RMC sentence and the GGA sentence *after* it + bytes += QLocationTestUtils::createGgaSentence(dt.addMSecs(100).time()).toLatin1(); + bytes += QLocationTestUtils::createRmcSentence(dt.addMSecs(200)).toLatin1(); + bytes += QLocationTestUtils::createGgaSentence(dt.addMSecs(300).time()).toLatin1(); + // The first GGA does not have date, and there's no cached date to inject, so that update will be invalid + QTest::newRow("Feed GGA,RMC,GGA; expect RMC, second GGA only") + << bytes << (QList() << dt.addMSecs(200) << dt.addMSecs(300)) + << (QList() << true << true) // accuracies are currently cached and injected in QGeoPositionInfos that do not have it + << (QList() << false << false); + + // should not receive ZDA (has no coordinates) but should get the GGA + // sentence after it since it got the date/time from ZDA + bytes.clear(); + bytes += QLocationTestUtils::createGgaSentence(dt.addMSecs(100).time()).toLatin1(); + bytes += QLocationTestUtils::createZdaSentence(dt.addMSecs(200)).toLatin1(); + bytes += QLocationTestUtils::createGgaSentence(dt.addMSecs(300).time()).toLatin1(); + QTest::newRow("Feed GGA,ZDA,GGA; expect second GGA only") + << bytes << (QList() << dt.addMSecs(300)) + << (QList() << true) + << (QList() << false); + + // Feed ZDA,GGA,GSA,GGA; expect vertical accuracy from second GGA. + bytes.clear(); + bytes += QLocationTestUtils::createZdaSentence(dt.addMSecs(100)).toLatin1(); + bytes += QLocationTestUtils::createGgaSentence(dt.addMSecs(200).time()).toLatin1(); + bytes += QLocationTestUtils::createGsaSentence().toLatin1(); + bytes += QLocationTestUtils::createGgaSentence(dt.addMSecs(300).time()).toLatin1(); + if (m_mode == QNmeaPositionInfoSource::SimulationMode) { + QTest::newRow("Feed ZDA,GGA,GSA,GGA; expect vertical accuracy from second GGA") + << bytes << (QList() << dt.addMSecs(200) << dt.addMSecs(300)) + << (QList() << true << true) + << (QList() << true << true); // First GGA gets VDOP from GSA bundled into previous, as it has no timestamp, second GGA gets the cached value. + } + + if (m_mode == QNmeaPositionInfoSource::SimulationMode) { + // In sim m_mode, should ignore sentence with a date/time before the known date/time + // (in real time m_mode, everything is passed on regardless) + bytes.clear(); + bytes += QLocationTestUtils::createRmcSentence(dt.addMSecs(100)).toLatin1(); + bytes += QLocationTestUtils::createRmcSentence(dt.addMSecs(-200)).toLatin1(); + bytes += QLocationTestUtils::createRmcSentence(dt.addMSecs(200)).toLatin1(); + QTest::newRow("Feed good RMC, RMC with bad date/time, good RMC; expect first and third RMC only") + << bytes << (QList() << dt.addMSecs(100) << dt.addMSecs(200)) + << (QList() << false << false) + << (QList() << false << false); + } +} + +void tst_QNmeaPositionInfoSource::requestUpdate_waitForValidDateTime() +{ + QFETCH(QByteArray, bytes); + QFETCH(QList, dateTimes); + + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spy(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + proxy->source()->requestUpdate(); + + proxy->feedBytes(bytes); + QTRY_COMPARE(spy.size(), 1); + QCOMPARE(spy[0][0].value().timestamp(), dateTimes[0]); +} + +void tst_QNmeaPositionInfoSource::requestUpdate_waitForValidDateTime_data() +{ + startUpdates_waitForValidDateTime_data(); +} + +void tst_QNmeaPositionInfoSource::requestUpdate() +{ + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(proxy->source(), SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + QDateTime dt; + + proxy->source()->requestUpdate(100); + QTRY_COMPARE(spyTimeout.size(), 1); + auto error = spyTimeout[0][0].value(); + QCOMPARE(error, QGeoPositionInfoSource::UpdateTimeoutError); + spyTimeout.clear(); + + dt = QDateTime::currentDateTimeUtc(); + proxy->feedUpdate(dt); + proxy->source()->requestUpdate(); + QTRY_COMPARE(spyUpdate.size(), 1); + QCOMPARE(spyUpdate[0][0].value().timestamp(), dt); + QCOMPARE(spyTimeout.size(), 0); + spyUpdate.clear(); + + // delay the update and expect it to be emitted after 300ms + dt = QDateTime::currentDateTimeUtc(); + proxy->source()->requestUpdate(1000); + QTest::qWait(300); + proxy->feedUpdate(dt); + QTRY_COMPARE(spyUpdate.size(), 1); + QCOMPARE(spyUpdate[0][0].value().timestamp(), dt); + QCOMPARE(spyTimeout.size(), 0); + spyUpdate.clear(); + + // delay the update and expect errorOccurred() to be emitted + dt = QDateTime::currentDateTimeUtc(); + proxy->source()->requestUpdate(500); + QTest::qWait(1000); + proxy->feedUpdate(dt); + QCOMPARE(spyTimeout.size(), 1); + error = spyTimeout[0][0].value(); + QCOMPARE(error, QGeoPositionInfoSource::UpdateTimeoutError); + QCOMPARE(spyUpdate.size(), 0); + spyUpdate.clear(); +} + +void tst_QNmeaPositionInfoSource::requestUpdate_after_start() +{ + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + QSignalSpy spyTimeout(proxy->source(), SIGNAL(errorOccurred(QGeoPositionInfoSource::Error))); + + // Start updates with 500ms interval and requestUpdate() with 100ms + // timeout. Feed an update, and it should be emitted immediately due to + // the requestUpdate(). The update should not be emitted again after that + // (i.e. the startUpdates() interval should not cause it to be re-emitted). + + QDateTime dt = QDateTime::currentDateTimeUtc(); + proxy->source()->setUpdateInterval(500); + proxy->source()->startUpdates(); + proxy->source()->requestUpdate(100); + proxy->feedUpdate(dt); + QTRY_COMPARE(spyUpdate.size(), 1); + QCOMPARE(spyUpdate[0][0].value().timestamp(), dt); + QCOMPARE(spyTimeout.size(), 0); + spyUpdate.clear(); + + // Update has been emitted for requestUpdate(), shouldn't be emitted for startUpdates() + QTRY_COMPARE_WITH_TIMEOUT(spyUpdate.size(), 0, 1000); +} + +void tst_QNmeaPositionInfoSource::testWithBadNmea() +{ + QFETCH(QByteArray, bytes); + QFETCH(QList, dateTimes); + QFETCH(UpdateTriggerMethod, trigger); + + QNmeaPositionInfoSource source(m_mode); + QNmeaProxyFactory factory; + QNmeaPositionInfoSourceProxy *proxy = static_cast( + factory.createPositionInfoSourceProxy(&source)); + + QSignalSpy spy(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); + if (trigger == StartUpdatesMethod) + proxy->source()->startUpdates(); + else + proxy->source()->requestUpdate(); + + proxy->feedBytes(bytes); + QTRY_COMPARE(spy.size(), dateTimes.size()); + for (int i=0; i().timestamp(), dateTimes[i]); +} + +void tst_QNmeaPositionInfoSource::testWithBadNmea_data() +{ + QTest::addColumn("bytes"); + QTest::addColumn >("dateTimes"); + QTest::addColumn("trigger"); + + QDateTime firstDateTime = QDateTime::currentDateTimeUtc(); + QByteArray bad = QLocationTestUtils::createRmcSentence(firstDateTime.addSecs(1)).toLatin1(); + bad = bad.mid(bad.size()/2); + QDateTime lastDateTime = firstDateTime.addSecs(2); + + QByteArray bytes; + bytes += QLocationTestUtils::createRmcSentence(firstDateTime).toLatin1(); + bytes += bad; + bytes += QLocationTestUtils::createRmcSentence(lastDateTime).toLatin1(); + QTest::newRow("requestUpdate(), bad second sentence") << bytes + << (QList() << firstDateTime) << RequestUpdatesMethod; + QTest::newRow("startUpdates(), bad second sentence") << bytes + << (QList() << firstDateTime << lastDateTime) << StartUpdatesMethod; +} diff --git a/tests/auto/qnmeapositioninfosource/tst_qnmeapositioninfosource.h b/tests/auto/qnmeapositioninfosource/tst_qnmeapositioninfosource.h new file mode 100644 index 0000000..88f83dc --- /dev/null +++ b/tests/auto/qnmeapositioninfosource/tst_qnmeapositioninfosource.h @@ -0,0 +1,157 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "../qgeopositioninfosource/testqgeopositioninfosource_p.h" +#include "../utils/qnmeaproxyfactory.h" +#include "../utils/qlocationtestutils_p.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE +Q_DECLARE_METATYPE(QNmeaPositionInfoSource::UpdateMode) +Q_DECLARE_METATYPE(QList) + +class tst_QNmeaPositionInfoSource : public QObject +{ + Q_OBJECT + +public: + enum UpdateTriggerMethod + { + StartUpdatesMethod, + RequestUpdatesMethod + }; + + tst_QNmeaPositionInfoSource(QNmeaPositionInfoSource::UpdateMode mode, QObject *parent = 0); + +private: + QList createDateTimes(const QDateTime &dt, int count) const + { + QList dateTimes; + int interval = 100; + for (int i=0; i createDateTimes(int count) const + { + return createDateTimes(QDateTime::currentDateTime().toUTC(), count); + } + +private slots: + void initTestCase(); + + void constructor(); + + void supportedPositioningMethods(); + + void minimumUpdateInterval(); + + void userEquivalentRangeError(); + + void setUpdateInterval_delayedUpdate(); + + void lastKnownPosition(); + + void beginWithBufferedData(); + void beginWithBufferedData_data(); + + void startUpdates(); + void startUpdates_data(); + + void startUpdates_withTimeout(); + + void startUpdates_expectLatestUpdateOnly(); + + void startUpdates_waitForValidDateTime(); + void startUpdates_waitForValidDateTime_data(); + + void requestUpdate_waitForValidDateTime(); + void requestUpdate_waitForValidDateTime_data(); + + void requestUpdate(); + void requestUpdate_after_start(); + + void testWithBadNmea(); + void testWithBadNmea_data(); + +private: + QNmeaPositionInfoSource::UpdateMode m_mode; +}; + +Q_DECLARE_METATYPE(tst_QNmeaPositionInfoSource::UpdateTriggerMethod) + +//--------------------------------------------------- + +class Feeder : public QObject +{ + Q_OBJECT + +public: + Feeder(QObject *parent) + : QObject(parent) + { + } + + void start(QNmeaPositionInfoSourceProxy *proxy) + { + m_proxy = proxy; + QTimer *timer = new QTimer(this); + QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer->setInterval(proxy->source()->minimumUpdateInterval()*2); + timer->start(); + } + +public slots: + void timeout() + { + m_proxy->feedBytes(QLocationTestUtils::createRmcSentence(QDateTime::currentDateTime()).toLatin1()); + } + +private: + QNmeaPositionInfoSourceProxy *m_proxy; +}; + +//--------------------------------------------------- + + +class UnlimitedNmeaStream : public QIODevice +{ + Q_OBJECT + +public: + UnlimitedNmeaStream(QObject *parent) : QIODevice(parent) {} + +protected: + qint64 readData(char *data, qint64 maxSize) override + { + QByteArray bytes = QLocationTestUtils::createRmcSentence(QDateTime::currentDateTime()).toLatin1(); + qint64 sz = qMin(qint64(bytes.size()), maxSize); + memcpy(data, bytes.constData(), sz); + return sz; + } + + qint64 writeData(const char *, qint64) override + { + return -1; + } + + qint64 bytesAvailable() const override + { + return 1024 + QIODevice::bytesAvailable(); + } +}; diff --git a/tests/auto/qnmeasatelliteinfosource/CMakeLists.txt b/tests/auto/qnmeasatelliteinfosource/CMakeLists.txt new file mode 100644 index 0000000..865b782 --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(dummy) +add_subdirectory(generic_realtime) +add_subdirectory(generic_simulation) +add_subdirectory(nmea) diff --git a/tests/auto/qnmeasatelliteinfosource/dummy/CMakeLists.txt b/tests/auto/qnmeasatelliteinfosource/dummy/CMakeLists.txt new file mode 100644 index 0000000..f4a323e --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/dummy/CMakeLists.txt @@ -0,0 +1,16 @@ +# special case begin +qt_internal_add_test(tst_dummynmeasatelliteinfosource + SOURCES + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + ../../utils/qnmeaproxyfactory.cpp ../../utils/qnmeaproxyfactory.h + tst_dummynmeasatelliteinfosource.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + PUBLIC_LIBRARIES + Qt::Core + Qt::Network + Qt::Positioning +) +# special case end diff --git a/tests/auto/qnmeasatelliteinfosource/dummy/tst_dummynmeasatelliteinfosource.cpp b/tests/auto/qnmeasatelliteinfosource/dummy/tst_dummynmeasatelliteinfosource.cpp new file mode 100644 index 0000000..f7c8a59 --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/dummy/tst_dummynmeasatelliteinfosource.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include "../../utils/qnmeaproxyfactory.h" + +class DummyNmeaSatelliteInfoSource : public QNmeaSatelliteInfoSource +{ + Q_OBJECT + +public: + DummyNmeaSatelliteInfoSource(QObject *parent = 0); + +protected: + QGeoSatelliteInfo::SatelliteSystem parseSatellitesInUseFromNmea(const char *data, int size, + QList &pnrsInUse) override; + SatelliteInfoParseStatus parseSatelliteInfoFromNmea(const char *data, int size, + QList &infos, + QGeoSatelliteInfo::SatelliteSystem &system) override; +}; + +DummyNmeaSatelliteInfoSource::DummyNmeaSatelliteInfoSource(QObject *parent) + : QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode, parent) +{ +} + +QGeoSatelliteInfo::SatelliteSystem +DummyNmeaSatelliteInfoSource::parseSatellitesInUseFromNmea(const char *data, int size, + QList &pnrsInUse) +{ + // expected format: "USE:num1;num2;num3\n" + // example: "USE:1;3;4;7\n" + if (!data || !size) + return QGeoSatelliteInfo::Undefined; + + QString str = QLatin1String(data, size).toString(); + if (!str.startsWith("USE:")) + return QGeoSatelliteInfo::Undefined; + + const QStringList sl = str.mid(4).split(";", Qt::SkipEmptyParts); + + if (sl.empty()) + return QGeoSatelliteInfo::Undefined; + + for (const auto &str : sl) { + bool ok = false; + int value = str.toInt(&ok); + if (ok) { + pnrsInUse.push_back(value); + } + } + return QGeoSatelliteInfo::GPS; +} + +QNmeaSatelliteInfoSource::SatelliteInfoParseStatus +DummyNmeaSatelliteInfoSource::parseSatelliteInfoFromNmea(const char *data, int size, + QList &infos, + QGeoSatelliteInfo::SatelliteSystem &system) +{ + // expected format: "INFO:system,identifier;system,identifier;system,identifier\n" + // example: "INFO:1,5;1,7;1,15\n" + if (!data || !size) + return NotParsed; + + QString str = QLatin1String(data, size).toString(); + if (!str.startsWith("INFO:")) + return NotParsed; + + QStringList sat_infos = str.mid(5).split(";", Qt::SkipEmptyParts); + + if (sat_infos.empty()) + return NotParsed; + + for (const auto &sat_info : sat_infos) { + QStringList parameters = sat_info.split(",", Qt::SkipEmptyParts); + if (parameters.size() == 2) { + QGeoSatelliteInfo info; + info.setSatelliteSystem( + static_cast(parameters[0].toInt())); + info.setSatelliteIdentifier(parameters[1].toInt()); + infos.push_back(info); + } + } + + system = infos.isEmpty() ? QGeoSatelliteInfo::Undefined : infos.front().satelliteSystem(); + + return FullyParsed; +} + +class tst_DummyNmeaSatelliteInfoSource : public QObject +{ + Q_OBJECT + +private slots: + void testOverloadedParseFunction(); +}; + +void tst_DummyNmeaSatelliteInfoSource::testOverloadedParseFunction() +{ + DummyNmeaSatelliteInfoSource source; + QNmeaProxyFactory factory; + QScopedPointer proxy( + factory.createSatelliteInfoSourceProxy(&source)); + + QSignalSpy inUseSpy(proxy->source(), &QNmeaSatelliteInfoSource::satellitesInUseUpdated); + QSignalSpy inViewSpy(proxy->source(), &QNmeaSatelliteInfoSource::satellitesInViewUpdated); + + proxy->source()->startUpdates(); + + // first we need to send all satellites + proxy->feedBytes("INFO:1,5;1,7;1,15\n"); + // then - used ones + proxy->feedBytes("USE:5;15\n"); + + QTRY_VERIFY_WITH_TIMEOUT(inUseSpy.size() == 1, 10000); + QTRY_VERIFY_WITH_TIMEOUT(inViewSpy.size() == 1, 10000); + + QGeoSatelliteInfo info_1_5; + info_1_5.setSatelliteSystem(QGeoSatelliteInfo::GPS); + info_1_5.setSatelliteIdentifier(5); + + QGeoSatelliteInfo info_1_7; + info_1_7.setSatelliteSystem(QGeoSatelliteInfo::GPS); + info_1_7.setSatelliteIdentifier(7); + + QGeoSatelliteInfo info_1_15; + info_1_15.setSatelliteSystem(QGeoSatelliteInfo::GPS); + info_1_15.setSatelliteIdentifier(15); + + const QList desiredInView = { info_1_5, info_1_7, info_1_15 }; + const QList desiredInUse = { info_1_5, info_1_15 }; + + const QList inViewList = + inViewSpy.at(0).at(0).value>(); + const QList inUseList = + inUseSpy.at(0).at(0).value>(); + + QCOMPARE(inViewList, desiredInView); + QCOMPARE(inUseList, desiredInUse); +} + +#include "tst_dummynmeasatelliteinfosource.moc" + +QTEST_GUILESS_MAIN(tst_DummyNmeaSatelliteInfoSource); diff --git a/tests/auto/qnmeasatelliteinfosource/generic_realtime/CMakeLists.txt b/tests/auto/qnmeasatelliteinfosource/generic_realtime/CMakeLists.txt new file mode 100644 index 0000000..f465bc1 --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/generic_realtime/CMakeLists.txt @@ -0,0 +1,18 @@ +# special case begin +qt_internal_add_test(tst_nmeasatelliteinfosource_generic_rt + SOURCES + ../../qgeosatelliteinfosource/testqgeosatelliteinfosource.cpp ../../qgeosatelliteinfosource/testqgeosatelliteinfosource_p.h + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + ../../utils/qnmeaproxyfactory.cpp ../../utils/qnmeaproxyfactory.h + tst_nmeasatelliteinfosource_generic_rt.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + LIBRARIES + Qt::Core + Qt::Network + Qt::Positioning + Qt::TestPrivate +) +# special case end diff --git a/tests/auto/qnmeasatelliteinfosource/generic_realtime/tst_nmeasatelliteinfosource_generic_rt.cpp b/tests/auto/qnmeasatelliteinfosource/generic_realtime/tst_nmeasatelliteinfosource_generic_rt.cpp new file mode 100644 index 0000000..7d8dfbf --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/generic_realtime/tst_nmeasatelliteinfosource_generic_rt.cpp @@ -0,0 +1,68 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include "../../qgeosatelliteinfosource/testqgeosatelliteinfosource_p.h" +#include "../../utils/qnmeaproxyfactory.h" +#include "../../utils/qlocationtestutils_p.h" + +class Feeder : public QObject +{ + Q_OBJECT +public: + Feeder(QObject *parent) : QObject(parent) + { + } + + void start(QNmeaSatelliteInfoSourceProxy *proxy) + { + m_proxy = proxy; + QTimer *timer = new QTimer(this); + QObject::connect(timer, &QTimer::timeout, this, &Feeder::timeout); + timer->setInterval(proxy->source()->minimumUpdateInterval() * 2); + timer->start(); + } + +public slots: + void timeout() + { + // Here we need to provide different chunks of data, because the signals + // are emitted only when data changes. + if (has_data) { + m_proxy->feedBytes(QLocationTestUtils::createGsvLongSentence().toLatin1()); + m_proxy->feedBytes(QLocationTestUtils::createGsaLongSentence().toLatin1()); + } else { + m_proxy->feedBytes(QLocationTestUtils::createGsvSentence().toLatin1()); + m_proxy->feedBytes(QLocationTestUtils::createGsaSentence().toLatin1()); + } + has_data = !has_data; + } + +private: + QNmeaSatelliteInfoSourceProxy *m_proxy; + bool has_data = true; +}; + +class tst_QNmeaSatelliteInfoSource_Generic_Realtime : public TestQGeoSatelliteInfoSource +{ + Q_OBJECT +protected: + QGeoSatelliteInfoSource *createTestSource() override + { + QNmeaSatelliteInfoSource *source = + new QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode); + QNmeaSatelliteInfoSourceProxy *proxy = m_factory.createSatelliteInfoSourceProxy(source); + Feeder *feeder = new Feeder(source); + feeder->start(proxy); + return source; + } + +private: + QNmeaProxyFactory m_factory; +}; + +#include "tst_nmeasatelliteinfosource_generic_rt.moc" + +QTEST_GUILESS_MAIN(tst_QNmeaSatelliteInfoSource_Generic_Realtime) diff --git a/tests/auto/qnmeasatelliteinfosource/generic_simulation/CMakeLists.txt b/tests/auto/qnmeasatelliteinfosource/generic_simulation/CMakeLists.txt new file mode 100644 index 0000000..d86d506 --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/generic_simulation/CMakeLists.txt @@ -0,0 +1,18 @@ +# special case begin +qt_internal_add_test(tst_nmeasatelliteinfosource_generic_sim + SOURCES + ../../qgeosatelliteinfosource/testqgeosatelliteinfosource.cpp ../../qgeosatelliteinfosource/testqgeosatelliteinfosource_p.h + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + ../../utils/qnmeaproxyfactory.cpp ../../utils/qnmeaproxyfactory.h + tst_nmeasatelliteinfosource_generic_sim.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + LIBRARIES + Qt::Core + Qt::Network + Qt::Positioning + Qt::TestPrivate +) +# special case end diff --git a/tests/auto/qnmeasatelliteinfosource/generic_simulation/tst_nmeasatelliteinfosource_generic_sim.cpp b/tests/auto/qnmeasatelliteinfosource/generic_simulation/tst_nmeasatelliteinfosource_generic_sim.cpp new file mode 100644 index 0000000..bb9441f --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/generic_simulation/tst_nmeasatelliteinfosource_generic_sim.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include "../../qgeosatelliteinfosource/testqgeosatelliteinfosource_p.h" +#include "../../utils/qlocationtestutils_p.h" + +class UnlimitedNmeaStream : public QIODevice +{ + Q_OBJECT + +public: + UnlimitedNmeaStream(QObject *parent) : QIODevice(parent) {} + +protected: + qint64 readData(char *data, qint64 maxSize) override + { + if (maxSize == 0) + return 0; + QByteArray bytes; + if (genSatInView) { + increaseSatId(); + bytes = QLocationTestUtils::createGsvVariableSentence(satId).toLatin1(); + } else { + bytes = QLocationTestUtils::createGsaVariableSentence(satId).toLatin1(); + } + genSatInView = !genSatInView; + qint64 sz = qMin(qint64(bytes.size()), maxSize); + memcpy(data, bytes.constData(), sz); + return sz; + } + + qint64 writeData(const char *, qint64) override + { + return -1; + } + + qint64 bytesAvailable() const override + { + return 1024 + QIODevice::bytesAvailable(); + } + +private: + void increaseSatId() + { + if (++satId == 0) + satId = 1; + } + + quint8 satId = 0; + bool genSatInView = true; +}; + +class tst_QNmeaSatelliteInfoSource_Generic_Simulation : public TestQGeoSatelliteInfoSource +{ + Q_OBJECT +protected: + QGeoSatelliteInfoSource *createTestSource() override + { + QNmeaSatelliteInfoSource *source = + new QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::SimulationMode); + source->setDevice(new UnlimitedNmeaStream(source)); + return source; + } +}; + +#include "tst_nmeasatelliteinfosource_generic_sim.moc" + +QTEST_GUILESS_MAIN(tst_QNmeaSatelliteInfoSource_Generic_Simulation) diff --git a/tests/auto/qnmeasatelliteinfosource/nmea/CMakeLists.txt b/tests/auto/qnmeasatelliteinfosource/nmea/CMakeLists.txt new file mode 100644 index 0000000..28eafc9 --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/nmea/CMakeLists.txt @@ -0,0 +1,14 @@ +# special case begin +qt_internal_add_test(tst_nmeasatelliteinfosource + SOURCES + ../../utils/qlocationtestutils.cpp ../../utils/qlocationtestutils_p.h + tst_nmeasatelliteinfosource.cpp + DEFINES + QT_DISABLE_DEPRECATED_BEFORE=0 + INCLUDE_DIRECTORIES + .. + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) +# special case end diff --git a/tests/auto/qnmeasatelliteinfosource/nmea/tst_nmeasatelliteinfosource.cpp b/tests/auto/qnmeasatelliteinfosource/nmea/tst_nmeasatelliteinfosource.cpp new file mode 100644 index 0000000..ff9f86c --- /dev/null +++ b/tests/auto/qnmeasatelliteinfosource/nmea/tst_nmeasatelliteinfosource.cpp @@ -0,0 +1,531 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include +#include "../../utils/qlocationtestutils_p.h" + +class DataFeeder : public QIODevice +{ + Q_OBJECT +public: + DataFeeder(QNmeaSatelliteInfoSource *parent) + : QIODevice(parent), m_parentMode(parent->updateMode()) + { + } + + void setMessages(const QList &messages) + { + m_messages = messages; + m_canReadLine = true; + m_messageIndex = 0; + if (m_parentMode == QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode) + emit readyRead(); + } + +signals: + void messageSent(); + +protected: + qint64 readData(char *data, qint64 maxSize) override + { + if (maxSize == 0 || m_messageIndex < 0 || m_messageIndex >= m_messages.size()) + return 0; + + m_canReadLine = false; + + QByteArray bytes = m_messages.at(m_messageIndex); + qint64 sz = qMin(qint64(bytes.size()), maxSize); + memcpy(data, bytes.constData(), sz); + + m_messageIndex++; + + emit messageSent(); + QTimer::singleShot(10, this, &DataFeeder::onTimer); + + return sz; + } + + qint64 writeData(const char *, qint64) override { return -1; } + + qint64 bytesAvailable() const override { return 1024 + QIODevice::bytesAvailable(); } + + bool canReadLine() const override + { + return m_canReadLine && (m_messageIndex >= 0) && (m_messageIndex < m_messages.size()); + } + +private slots: + void onTimer() + { + m_canReadLine = true; + if (m_parentMode == QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode) + emit readyRead(); + } + +private: + QNmeaSatelliteInfoSource::UpdateMode m_parentMode; + QList m_messages; + qsizetype m_messageIndex = 0; + bool m_canReadLine = true; // To read each line separately +}; + +class tst_QNmeaSatelliteInfoSource : public QObject +{ + Q_OBJECT +private slots: + void backendProperty(); + void backendProperty_data(); + + void parseDataStream(); + void parseDataStream_data(); + +private: + QGeoSatelliteInfo createSatelliteInfo(QGeoSatelliteInfo::SatelliteSystem system, int id, + int snr); +}; + +void tst_QNmeaSatelliteInfoSource::backendProperty() +{ + QFETCH(int, simulationRate); + QFETCH(int, updateInterval); + QFETCH(QList, messages); + QFETCH(int, timeout); + QFETCH(int, desiredMessagesSent); + + QNmeaSatelliteInfoSource source(QNmeaSatelliteInfoSource::UpdateMode::SimulationMode); + auto feeder = new DataFeeder(&source); + source.setDevice(feeder); + + QSignalSpy messageSentSpy(feeder, &DataFeeder::messageSent); + QSignalSpy inViewSpy(&source, &QNmeaSatelliteInfoSource::satellitesInViewUpdated); + + source.setBackendProperty(QNmeaSatelliteInfoSource::SimulationUpdateInterval, simulationRate); + source.setUpdateInterval(updateInterval); + + source.startUpdates(); + feeder->setMessages(messages); + + QTRY_VERIFY_WITH_TIMEOUT(inViewSpy.size() == 1, timeout); + + QCOMPARE(source.backendProperty(QNmeaSatelliteInfoSource::SimulationUpdateInterval).toInt(), + simulationRate); + QCOMPARE(source.updateInterval(), updateInterval); + + QCOMPARE(messageSentSpy.size(), desiredMessagesSent); +} + +void tst_QNmeaSatelliteInfoSource::backendProperty_data() +{ + QTest::addColumn("simulationRate"); + QTest::addColumn("updateInterval"); + QTest::addColumn>("messages"); + QTest::addColumn("timeout"); + QTest::addColumn("desiredMessagesSent"); + + const auto simpleGpsGsvMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GPGSV,1,1,4,05,,,25,07,,,,08,,,,13,,,36*") + .toLatin1(); + + const QList msgs(10, simpleGpsGsvMessage); + + // here updateInterval should not be a multiple of simulationRate because + // this will make the test flacky due to timer precision. + QTest::addRow("Simulation rate smaller than updateInterval") << 200 << 500 << msgs << 550 << 2; + + QTest::addRow("Simulation rate larger than updateInterval") << 200 << 100 << msgs << 300 << 1; + + // Here we do not really have problems with timer precision, because even if + // the updateInterval() timer expires earlier, we will not get any update + // until the real data comes. + QTest::addRow("Simulation rate equals updateInterval") << 200 << 200 << msgs << 300 << 1; +} + +void tst_QNmeaSatelliteInfoSource::parseDataStream() +{ + QFETCH(QNmeaSatelliteInfoSource::UpdateMode, mode); + QFETCH(QList, messages); + QFETCH(QList, desiredInView); + QFETCH(QList, desiredInUse); + + QNmeaSatelliteInfoSource source(mode); + auto feeder = new DataFeeder(&source); + source.setDevice(feeder); + + QSignalSpy messageSentSpy(feeder, &DataFeeder::messageSent); + QSignalSpy inViewSpy(&source, &QNmeaSatelliteInfoSource::satellitesInViewUpdated); + QSignalSpy inUseSpy(&source, &QNmeaSatelliteInfoSource::satellitesInUseUpdated); + + source.startUpdates(); + feeder->setMessages(messages); + + QTRY_VERIFY_WITH_TIMEOUT(messageSentSpy.size() == messages.size(), 2000); + QVERIFY(!inViewSpy.isEmpty()); + QVERIFY(!inUseSpy.isEmpty()); + + const auto inView = inViewSpy.back().at(0).value>(); + QCOMPARE(inView, desiredInView); + + const auto inUse = inUseSpy.back().at(0).value>(); + QCOMPARE(inUse, desiredInUse); +} + +void tst_QNmeaSatelliteInfoSource::parseDataStream_data() +{ + QTest::addColumn("mode"); + QTest::addColumn>("messages"); + QTest::addColumn>("desiredInView"); + QTest::addColumn>("desiredInUse"); + + // We will use only satId and SNR, to simplify objects for comparison + + // one line GPS + const auto simpleGpsGsvMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GPGSV,1,1,4,05,,,25,07,,,,08,,,,13,,,36*") + .toLatin1(); + const auto simpleGpsGsaMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GPGSA,A,3,05,13,,,,,,,,,,,50.95,50.94,1.00*") + .toLatin1(); + + const auto simpleGpsInView = + QList { createSatelliteInfo(QGeoSatelliteInfo::GPS, 5, 25), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 7, -1), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 8, -1), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 13, 36) }; + const auto simpleGpsInUse = + QList { createSatelliteInfo(QGeoSatelliteInfo::GPS, 5, 25), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 13, 36) }; + + QTest::newRow("realtime GPS") << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { simpleGpsGsvMessage, simpleGpsGsaMessage } + << simpleGpsInView << simpleGpsInUse; + + QTest::newRow("simulation GPS") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { simpleGpsGsvMessage, simpleGpsGsaMessage } << simpleGpsInView + << simpleGpsInUse; + + // multi line GPS + const auto complexGpsGsvMessage1 = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GPGSV,2,1,8,05,,,22,07,,,,08,,,,13,,,18*") + .toLatin1(); + const auto complexGpsGsvMessage2 = + QLocationTestUtils::addNmeaChecksumAndBreaks("$GPGSV,2,2,8,14,,,,15,,,18,18,,,,20,,,*") + .toLatin1(); + const auto complexGpsGsaMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GPGSA,A,3,05,13,15,,,,,,,,,,50.95,50.94,1.00*") + .toLatin1(); + + const auto complexGpsInView = + QList { createSatelliteInfo(QGeoSatelliteInfo::GPS, 5, 22), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 7, -1), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 8, -1), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 13, 18), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 14, -1), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 15, 18), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 18, -1), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 20, -1) }; + const auto complexGpsInUse = + QList { createSatelliteInfo(QGeoSatelliteInfo::GPS, 5, 22), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 13, 18), + createSatelliteInfo(QGeoSatelliteInfo::GPS, 15, 18) }; + + QTest::newRow("realtime multi-line GPS") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { complexGpsGsvMessage1, complexGpsGsvMessage2, + complexGpsGsaMessage } + << complexGpsInView << complexGpsInUse; + + QTest::newRow("simulation multi-line GPS") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { complexGpsGsvMessage1, complexGpsGsvMessage2, + complexGpsGsaMessage } + << complexGpsInView << complexGpsInUse; + + // one line GPS & GLONASS + const auto simpleGlnsGsvMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GLGSV,1,1,4,65,,,,66,,,,71,,,20,72,,,28*") + .toLatin1(); + const auto gnSimpleGlnsGsaMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GNGSA,A,3,71,72,,,,,,,,,,,50.95,50.94,1.00*") + .toLatin1(); + const auto gnSimpleGpsGsaMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GNGSA,A,3,05,13,,,,,,,,,,,50.95,50.94,1.00*") + .toLatin1(); + + const auto simpleGlnsInView = + QList { createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 65, -1), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 66, -1), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 71, 20), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 72, 28) }; + const auto simpleGlnsInUse = + QList { createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 71, 20), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 72, 28) }; + + const auto simpleGpsGlnsInView = simpleGpsInView + simpleGlnsInView; + const auto simpleGpsGlnsInUse = simpleGpsInUse + simpleGlnsInUse; + + QTest::newRow("realtime GPS & GLONASS") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { simpleGpsGsvMessage, simpleGlnsGsvMessage, gnSimpleGpsGsaMessage, + gnSimpleGlnsGsaMessage } + << simpleGpsGlnsInView << simpleGpsGlnsInUse; + + QTest::newRow("simulation GPS & GLONASS") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { simpleGpsGsvMessage, simpleGlnsGsvMessage, gnSimpleGpsGsaMessage, + gnSimpleGlnsGsaMessage } + << simpleGpsGlnsInView << simpleGpsGlnsInUse; + + // multi line GPS & GLONASS + const auto complexGlnsGsvMessage1 = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GLGSV,3,1,10,65,,,,66,,,,71,,,20,72,,,28*") + .toLatin1(); + const auto complexGlnsGsvMessage2 = + QLocationTestUtils::addNmeaChecksumAndBreaks("$GLGSV,3,2,10,73,,,,74,,,,75,,,33,81,,,*") + .toLatin1(); + const auto complexGlnsGsvMessage3 = + QLocationTestUtils::addNmeaChecksumAndBreaks("$GLGSV,3,3,10,82,,,,83,,,*").toLatin1(); + const auto gnComplexGlnsGsaMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GNGSA,A,3,71,72,75,,,,,,,,,,50.95,50.94,1.00*") + .toLatin1(); + const auto gnComplexGpsGsaMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GNGSA,A,3,05,13,15,,,,,,,,,,50.95,50.94,1.00*") + .toLatin1(); + + const auto complexGlnsInView = + QList { createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 65, -1), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 66, -1), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 71, 20), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 72, 28), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 73, -1), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 74, -1), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 75, 33), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 81, -1), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 82, -1), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 83, -1) }; + const auto complexGlnsInUse = + QList { createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 71, 20), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 72, 28), + createSatelliteInfo(QGeoSatelliteInfo::GLONASS, 75, 33) }; + + const auto complexGpsGlnsInView = complexGpsInView + complexGlnsInView; + const auto complexGpsGlnsInUse = complexGpsInUse + complexGlnsInUse; + + QTest::newRow("realtime multi-line GPS & GLONASS") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { complexGpsGsvMessage1, complexGpsGsvMessage2, + complexGlnsGsvMessage1, complexGlnsGsvMessage2, + complexGlnsGsvMessage3, gnComplexGpsGsaMessage, + gnComplexGlnsGsaMessage } + << complexGpsGlnsInView << complexGpsGlnsInUse; + + QTest::newRow("simulation multi-line GPS & GLONASS") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { complexGpsGsvMessage1, complexGpsGsvMessage2, + complexGlnsGsvMessage1, complexGlnsGsvMessage2, + complexGlnsGsvMessage3, gnComplexGpsGsaMessage, + gnComplexGlnsGsaMessage } + << complexGpsGlnsInView << complexGpsGlnsInUse; + + // multi-line GPS & GLONASS: GSA before GSV + QTest::newRow("realtime multi-line GPS & GLONASS reverse") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { gnComplexGlnsGsaMessage, gnComplexGpsGsaMessage, + complexGlnsGsvMessage1, complexGlnsGsvMessage2, + complexGlnsGsvMessage3, complexGpsGsvMessage1, + complexGpsGsvMessage2 } + << complexGpsGlnsInView << complexGpsGlnsInUse; + + QTest::newRow("simulation multi-line GPS & GLONASS reverse") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { gnComplexGlnsGsaMessage, gnComplexGpsGsaMessage, + complexGlnsGsvMessage1, complexGlnsGsvMessage2, + complexGlnsGsvMessage3, complexGpsGsvMessage1, + complexGpsGsvMessage2 } + << complexGpsGlnsInView << complexGpsGlnsInUse; + + // multi-line GSP & GLONASS: mixed order + QTest::newRow("realtime multi-line GPS & GLONASS mixed") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { gnComplexGlnsGsaMessage, complexGlnsGsvMessage1, + complexGlnsGsvMessage2, complexGlnsGsvMessage3, + complexGpsGsvMessage1, complexGpsGsvMessage2, + gnComplexGpsGsaMessage } + << complexGpsGlnsInView << complexGpsGlnsInUse; + + QTest::newRow("realtime multi-line GPS & GLONASS mixed") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { gnComplexGlnsGsaMessage, complexGlnsGsvMessage1, + complexGlnsGsvMessage2, complexGlnsGsvMessage3, + complexGpsGsvMessage1, complexGpsGsvMessage2, + gnComplexGpsGsaMessage } + << complexGpsGlnsInView << complexGpsGlnsInUse; + + // one line GPS & GLONASS: empty GNGSA for GPS + const auto gnEmptyGpsGsaMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*") + .toLatin1(); + + QTest::newRow("realtime GSP & GLONASS: empty GSA for GPS") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { simpleGpsGsvMessage, simpleGlnsGsvMessage, + gnSimpleGlnsGsaMessage, gnEmptyGpsGsaMessage } + << simpleGpsGlnsInView << simpleGlnsInUse; + + QTest::newRow("simulation GSP & GLONASS: empty GSA for GPS") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { simpleGpsGsvMessage, simpleGlnsGsvMessage, + gnSimpleGlnsGsaMessage, gnEmptyGpsGsaMessage } + << simpleGpsGlnsInView << simpleGlnsInUse; + + // one line GPS & GLONASS: empty $GPGSV + const auto emptyGpsGsvMessage = + QLocationTestUtils::addNmeaChecksumAndBreaks("$GPGSV,1,1,0,,,,,,,,,,,,,,,,*") + .toLatin1(); + + QTest::newRow("realtime GPS & GLONASS: empty $GPGSV") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { emptyGpsGsvMessage, simpleGlnsGsvMessage, gnSimpleGlnsGsaMessage, + gnSimpleGpsGsaMessage } + << simpleGlnsInView << simpleGlnsInUse; + + QTest::newRow("simulation GPS & GLONASS: empty $GPGSV") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { emptyGpsGsvMessage, simpleGlnsGsvMessage, gnSimpleGlnsGsaMessage, + gnSimpleGpsGsaMessage } + << simpleGlnsInView << simpleGlnsInUse; + + // one line GPS & GLONASS: empty GNGSA in the middle + // In this test we send the following sequence: + // 1. $GPGSV - valid GPS in view + // 2. $GLGSV - valid GLONASS in view + // 3. $GNGSA - valid GPS in use + // 4. $GNGSA - valid GLONASS in use + // 5. $GPGSV - valid GPS in view + // 6. $GNGSA - empty GNGSA (meaning empty GPS) + // 7. $GPGSV - valid GPS in view: at this point GPS in use will be cleared + // As a result, we will see valid GPS & GLONASS in view, but only GLONASS + // in use. + + QTest::newRow("realtime GPS & GLONASS: empty $GNGSA in the middle") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { simpleGpsGsvMessage, simpleGlnsGsvMessage, + gnSimpleGpsGsaMessage, gnSimpleGlnsGsaMessage, + simpleGpsGsvMessage, gnEmptyGpsGsaMessage, + simpleGpsGsvMessage } + << simpleGpsGlnsInView << simpleGlnsInUse; + + QTest::newRow("simulation GPS & GLONASS: empty $GNGSA in the middle") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { simpleGpsGsvMessage, simpleGlnsGsvMessage, + gnSimpleGpsGsaMessage, gnSimpleGlnsGsaMessage, + simpleGpsGsvMessage, gnEmptyGpsGsaMessage, + simpleGpsGsvMessage } + << simpleGpsGlnsInView << simpleGlnsInUse; + + // BEIDOU signals for below test cases are just synthesized based on the + // NMEA protocol description. They were NEVER checked on real hardware, + // as we do not have one. + + // multi-line GPS, GLONASS & BEIDOU + const auto complexBduGsvMessage1 = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GBGSV,2,1,7,201,,,,202,,,,203,,,20,204,,,28*") + .toLatin1(); + const auto complexBduGsvMessage2 = + QLocationTestUtils::addNmeaChecksumAndBreaks("$GBGSV,2,2,7,205,,,,206,,,,207,,,33,,,,*") + .toLatin1(); + const auto gnComplexBduGsaMessage = QLocationTestUtils::addNmeaChecksumAndBreaks( + "$GNGSA,A,3,203,204,207,,,,,,,,,,50.95,50.94,1.00*") + .toLatin1(); + const auto complexBduInView = + QList { createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 201, -1), + createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 202, -1), + createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 203, 20), + createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 204, 28), + createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 205, -1), + createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 206, -1), + createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 207, 33) }; + const auto complexBduInUse = + QList { createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 203, 20), + createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 204, 28), + createSatelliteInfo(QGeoSatelliteInfo::BEIDOU, 207, 33) }; + + const auto complexGpsGlnsBduInView = complexGpsInView + complexGlnsInView + complexBduInView; + const auto complexGpsGlnsBduInUse = complexGpsInUse + complexGlnsInUse + complexBduInUse; + + QTest::newRow("realtime GPS, GLONASS & BEIDOU") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { complexGpsGsvMessage1, complexGpsGsvMessage2, + complexGlnsGsvMessage1, complexGlnsGsvMessage2, + complexGlnsGsvMessage3, complexBduGsvMessage1, + complexBduGsvMessage2, gnComplexGpsGsaMessage, + gnComplexGlnsGsaMessage, gnComplexBduGsaMessage } + << complexGpsGlnsBduInView << complexGpsGlnsBduInUse; + + QTest::newRow("simulation GPS, GLONASS & BEIDOU") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { complexGpsGsvMessage1, complexGpsGsvMessage2, + complexGlnsGsvMessage1, complexGlnsGsvMessage2, + complexGlnsGsvMessage3, complexBduGsvMessage1, + complexBduGsvMessage2, gnComplexGpsGsaMessage, + gnComplexGlnsGsaMessage, gnComplexBduGsaMessage } + << complexGpsGlnsBduInView << complexGpsGlnsBduInUse; + + // multi-line GPS, GLONASS & BEIDOU: GSA before GSV + QTest::newRow("realtime GPS, GLONASS & BEIDOU reverse") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { gnComplexGpsGsaMessage, gnComplexGlnsGsaMessage, + gnComplexBduGsaMessage, complexGpsGsvMessage1, + complexGpsGsvMessage2, complexGlnsGsvMessage1, + complexGlnsGsvMessage2, complexGlnsGsvMessage3, + complexBduGsvMessage1, complexBduGsvMessage2 } + << complexGpsGlnsBduInView << complexGpsGlnsBduInUse; + + QTest::newRow("simulation GPS, GLONASS & BEIDOU reverse") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { gnComplexGpsGsaMessage, gnComplexGlnsGsaMessage, + gnComplexBduGsaMessage, complexGpsGsvMessage1, + complexGpsGsvMessage2, complexGlnsGsvMessage1, + complexGlnsGsvMessage2, complexGlnsGsvMessage3, + complexBduGsvMessage1, complexBduGsvMessage2 } + << complexGpsGlnsBduInView << complexGpsGlnsBduInUse; + + // multi-line GPS, GLONASS & BEIDOU: mixed order + QTest::newRow("realtime GPS, GLONASS & BEIDOU mixed") + << QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode + << QList { gnComplexGpsGsaMessage, complexGlnsGsvMessage1, + complexGlnsGsvMessage2, complexGlnsGsvMessage3, + complexBduGsvMessage1, complexBduGsvMessage2, + gnComplexGlnsGsaMessage, gnComplexBduGsaMessage, + complexGpsGsvMessage1, complexGpsGsvMessage2 } + << complexGpsGlnsBduInView << complexGpsGlnsBduInUse; + + QTest::newRow("simulation GPS, GLONASS & BEIDOU mixed") + << QNmeaSatelliteInfoSource::UpdateMode::SimulationMode + << QList { gnComplexGpsGsaMessage, complexGlnsGsvMessage1, + complexGlnsGsvMessage2, complexGlnsGsvMessage3, + complexBduGsvMessage1, complexBduGsvMessage2, + gnComplexGlnsGsaMessage, gnComplexBduGsaMessage, + complexGpsGsvMessage1, complexGpsGsvMessage2 } + << complexGpsGlnsBduInView << complexGpsGlnsBduInUse; +} + +QGeoSatelliteInfo +tst_QNmeaSatelliteInfoSource::createSatelliteInfo(QGeoSatelliteInfo::SatelliteSystem system, int id, + int snr) +{ + QGeoSatelliteInfo info; + info.setSatelliteSystem(system); + info.setSatelliteIdentifier(id); + info.setSignalStrength(snr); + info.setAttribute(QGeoSatelliteInfo::Azimuth, 0.0); + info.setAttribute(QGeoSatelliteInfo::Elevation, 0.0); + return info; +} + +#include "tst_nmeasatelliteinfosource.moc" + +QTEST_GUILESS_MAIN(tst_QNmeaSatelliteInfoSource) diff --git a/tests/auto/qquickgeocoordinateanimation/CMakeLists.txt b/tests/auto/qquickgeocoordinateanimation/CMakeLists.txt new file mode 100644 index 0000000..81342b6 --- /dev/null +++ b/tests/auto/qquickgeocoordinateanimation/CMakeLists.txt @@ -0,0 +1,9 @@ +qt_internal_add_test(tst_qquickgeocoordinateanimation + SOURCES + tst_qquickgeocoordinateanimation.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning + Qt::PositioningQuickPrivate + Qt::TestPrivate +) diff --git a/tests/auto/qquickgeocoordinateanimation/tst_qquickgeocoordinateanimation.cpp b/tests/auto/qquickgeocoordinateanimation/tst_qquickgeocoordinateanimation.cpp new file mode 100644 index 0000000..630bc41 --- /dev/null +++ b/tests/auto/qquickgeocoordinateanimation/tst_qquickgeocoordinateanimation.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include +#include +#include + +QT_USE_NAMESPACE + +class tst_QuickGeoCoordinateAnimation : public QObject +{ + Q_OBJECT + +private slots: + void bindings(); +}; + +void tst_QuickGeoCoordinateAnimation::bindings() +{ + QQuickGeoCoordinateAnimation animation; + QTestPrivate::testReadWritePropertyBasics( + animation, QQuickGeoCoordinateAnimation::East, QQuickGeoCoordinateAnimation::West, + "direction"); +} + +QTEST_APPLESS_MAIN(tst_QuickGeoCoordinateAnimation) + +#include "tst_qquickgeocoordinateanimation.moc" diff --git a/tests/auto/utils/qlocationtestutils.cpp b/tests/auto/utils/qlocationtestutils.cpp new file mode 100644 index 0000000..d290898 --- /dev/null +++ b/tests/auto/utils/qlocationtestutils.cpp @@ -0,0 +1,89 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "qlocationtestutils_p.h" + +bool QLocationTestUtils::hasDefaultSource() +{ + return false; +} + +bool QLocationTestUtils::hasDefaultMonitor() +{ + return false; +} + +QString QLocationTestUtils::addNmeaChecksumAndBreaks(const QString &sentence) +{ + Q_ASSERT(sentence[0] == '$' && sentence[sentence.size()-1] == '*'); + + // XOR byte value of all characters between '$' and '*' + int result = 0; + for (int i=1; i(satId)); + return addNmeaChecksumAndBreaks(nmea); +} + +QString QLocationTestUtils::createGsvVariableSentence(quint8 satId) +{ + const QString nmea = QString("$GPGSV,1,1,1,%1,49,115,42,,,,,,,,,,,,*").arg(static_cast(satId)); + return addNmeaChecksumAndBreaks(nmea); +} diff --git a/tests/auto/utils/qlocationtestutils_p.h b/tests/auto/utils/qlocationtestutils_p.h new file mode 100644 index 0000000..67eef80 --- /dev/null +++ b/tests/auto/utils/qlocationtestutils_p.h @@ -0,0 +1,150 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef QLOCATIONTESTUTILS_P_H +#define QLOCATIONTESTUTILS_P_H + +#include +#include +#include + +namespace QLocationTestUtils +{ + bool hasDefaultSource(); + bool hasDefaultMonitor(); + + QString addNmeaChecksumAndBreaks(const QString &sentence); + + QString createRmcSentence(const QDateTime &dt); + QString createGgaSentence(const QTime &time); + QString createGgaSentence(int lat, int lng, const QTime &time); + QString createZdaSentence(const QDateTime &dt); + QString createGsaSentence(); + QString createGsvSentence(); + QString createGsaLongSentence(); + QString createGsvLongSentence(); + QString createGsaVariableSentence(quint8 satId); + QString createGsvVariableSentence(quint8 satId); + + //The purpose of compareEquality() is to test equality + //operators where it is expected that A == B. + template + bool compareEquality(const A &first, const B &second) { + if (first != second) { + qWarning() << "compareEquality() failed: first != second"; + return false; + } + + if (second != first) { + qWarning() << "compareEquality() failed: second != first"; + return false; + } + + if (!(first == second)) { + qWarning() << "compareEquality() failed: !(first == second)"; + return false; + } + + if (!(second == first)) { + qWarning() << "compareEquality() failed: !(second == first)"; + return false; + } + + return true; + } + + //The purpose of compareInequality() is to test equality + //operators where it is expected that A != B. + //Using !compareEquality(...) is not sufficient because + //only the first operator checked would end up being tested. + template + bool compareInequality(const A &first, const B &second) { + if (!(first != second)){ + qWarning() << "compareInequality() failed: !(first != second)"; + return false; + } + + if (!(second != first)) { + qWarning() << "compareInequality() failed: !(second != first)"; + return false; + } + + if (first == second) { + qWarning() << "compareInequality() failed: first == second)"; + return false; + } + + if (second == first) { + qWarning() << "compareInequality() failed: second == first"; + return false; + } + return true; + } + + // Tests conversions between sub and base classes + // TC (test case) must implement: + // SubClass initialSubObject(); + // bool checkType(const BaseClass &) + // void detach(BaseClass *) - calls a mutator method, but doesn't actually modify the + // property to something different. + // void setSubClassProperty(SubClass *) - sets a property in the subclass instance + template + void testConversion(TC *tc) { + SubClass sub = tc->initialSubObject(); + //check conversion from SubClass -> BaseClass + //using assignment operator + BaseClass base; + base = sub; + QVERIFY(QLocationTestUtils::compareEquality(base, sub)); + QVERIFY(tc->checkType(base)); + + //check comparing base classes + BaseClass base2; + base2 = sub; + QVERIFY(QLocationTestUtils::compareEquality(base, base2)); + + //check conversion from BaseClass -> SubClass + //using assignment operator + SubClass sub2; + sub2 = base; + QVERIFY(QLocationTestUtils::compareEquality(sub, sub2)); + QVERIFY(tc->checkType(sub2)); + + //check that equality still holds with detachment of underlying data pointer + tc->detach(&base); + sub2 = base; + QVERIFY(QLocationTestUtils::compareEquality(sub, sub2)); + QVERIFY(QLocationTestUtils::compareEquality(sub, base)); + QVERIFY(QLocationTestUtils::compareEquality(base, base2)); + + //check that comparing objects are not the same + //when an underlying subclass field has been modified + tc->setSubClassProperty(&sub2); + base2 = sub2; + QVERIFY(QLocationTestUtils::compareInequality(sub, sub2)); + QVERIFY(QLocationTestUtils::compareInequality(sub, base2)); + QVERIFY(QLocationTestUtils::compareInequality(base, base2)); + + //check conversion from SubClass -> BaseClass + //using copy constructor + BaseClass base3(sub); + QVERIFY(QLocationTestUtils::compareEquality(sub, base3)); + QVERIFY(QLocationTestUtils::compareEquality(base, base3)); + + //check conversion from BaseClass -> SubClass + //using copy constructor + SubClass sub3(base3); + QVERIFY(QLocationTestUtils::compareEquality(sub, sub3)); + + //check conversion to subclass using a default base class instance + BaseClass baseDefault; + SubClass subDefault; + SubClass sub4(baseDefault); + QVERIFY(QLocationTestUtils::compareEquality(sub4, subDefault)); + + SubClass sub5 = baseDefault; + QVERIFY(QLocationTestUtils::compareEquality(sub5, subDefault)); + } +}; + +#endif diff --git a/tests/auto/utils/qnmeaproxyfactory.cpp b/tests/auto/utils/qnmeaproxyfactory.cpp new file mode 100644 index 0000000..12d7c43 --- /dev/null +++ b/tests/auto/utils/qnmeaproxyfactory.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "qnmeaproxyfactory.h" +#include "qlocationtestutils_p.h" +#include +#include + +#include +#include +#include + +QNmeaPositionInfoSourceProxy::QNmeaPositionInfoSourceProxy(QNmeaPositionInfoSource *source, + QIODevice *outDevice) + : m_source(source), m_outDevice(outDevice) +{ +} + +QNmeaPositionInfoSourceProxy::~QNmeaPositionInfoSourceProxy() +{ + m_outDevice->close(); + delete m_outDevice; +} + +QGeoPositionInfoSource *QNmeaPositionInfoSourceProxy::source() const +{ + return m_source; +} + +void QNmeaPositionInfoSourceProxy::feedUpdate(const QDateTime &dt) +{ + m_outDevice->write(QLocationTestUtils::createRmcSentence(dt).toLatin1()); +} + +void QNmeaPositionInfoSourceProxy::feedBytes(const QByteArray &bytes) +{ + m_outDevice->write(bytes); +} + +QNmeaProxyFactory::QNmeaProxyFactory() : m_server(new QTcpServer(this)) +{ + bool b = m_server->listen(QHostAddress::LocalHost); + Q_ASSERT(b); +} + +QNmeaPositionInfoSourceProxy * +QNmeaProxyFactory::createPositionInfoSourceProxy(QNmeaPositionInfoSource *source) +{ + QTcpSocket *client = new QTcpSocket; + QIODevice *device = createServerConnection(client); + source->setDevice(device); + Q_ASSERT(source->device() != 0); + QNmeaPositionInfoSourceProxy *proxy = new QNmeaPositionInfoSourceProxy(source, client); + proxy->setParent(source); + return proxy; +} + +QNmeaSatelliteInfoSourceProxy * +QNmeaProxyFactory::createSatelliteInfoSourceProxy(QNmeaSatelliteInfoSource *source) +{ + QTcpSocket *client = new QTcpSocket; + QIODevice *device = createServerConnection(client); + source->setDevice(device); + Q_ASSERT(source->device() != 0); + QNmeaSatelliteInfoSourceProxy *proxy = new QNmeaSatelliteInfoSourceProxy(source, client); + proxy->setParent(source); + return proxy; +} + +QIODevice *QNmeaProxyFactory::createServerConnection(QTcpSocket *client) +{ + client->connectToHost(m_server->serverAddress(), m_server->serverPort()); + qDebug() << "listening on" << m_server->serverAddress() << m_server->serverPort(); + bool b = m_server->waitForNewConnection(15000); + if (!b) + qWarning() << "Server didin't receive new connection"; + b = client->waitForConnected(); + if (!b) + qWarning() << "Client could not connect to server"; + + QIODevice *device = m_server->nextPendingConnection(); + return device; +} + +QNmeaSatelliteInfoSourceProxy::QNmeaSatelliteInfoSourceProxy(QNmeaSatelliteInfoSource *source, + QIODevice *outDevice) + : m_source(source), m_outDevice(outDevice) +{ +} + +QNmeaSatelliteInfoSourceProxy::~QNmeaSatelliteInfoSourceProxy() +{ + m_outDevice->close(); + delete m_outDevice; +} + +QGeoSatelliteInfoSource *QNmeaSatelliteInfoSourceProxy::source() const +{ + return m_source; +} + +void QNmeaSatelliteInfoSourceProxy::feedBytes(const QByteArray &bytes) +{ + m_outDevice->write(bytes); +} diff --git a/tests/auto/utils/qnmeaproxyfactory.h b/tests/auto/utils/qnmeaproxyfactory.h new file mode 100644 index 0000000..be82ddc --- /dev/null +++ b/tests/auto/utils/qnmeaproxyfactory.h @@ -0,0 +1,71 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef QNMEAPROXYFACTORY_H +#define QNMEAPROXYFACTORY_H + +#include + +QT_BEGIN_NAMESPACE +class QTcpServer; +class QTcpSocket; +class QIODevice; +class QNmeaPositionInfoSource; +class QNmeaSatelliteInfoSource; +class QGeoPositionInfoSource; +class QGeoSatelliteInfoSource; +QT_END_NAMESPACE + +class QNmeaPositionInfoSourceProxy : public QObject +{ + Q_OBJECT +public: + QNmeaPositionInfoSourceProxy(QNmeaPositionInfoSource *source, QIODevice *outDevice); + ~QNmeaPositionInfoSourceProxy(); + + QGeoPositionInfoSource *source() const; + + void feedUpdate(const QDateTime &dt); + + void feedBytes(const QByteArray &bytes); + + int updateIntervalErrorMargin() const { return 50; } + +private: + QNmeaPositionInfoSource *m_source; + QIODevice *m_outDevice; +}; + +class QNmeaSatelliteInfoSourceProxy : public QObject +{ + Q_OBJECT +public: + QNmeaSatelliteInfoSourceProxy(QNmeaSatelliteInfoSource *source, QIODevice *outDevice); + ~QNmeaSatelliteInfoSourceProxy(); + + QGeoSatelliteInfoSource *source() const; + + void feedBytes(const QByteArray &bytes); + +private: + QNmeaSatelliteInfoSource *m_source; + QIODevice *m_outDevice; +}; + +class QNmeaProxyFactory : public QObject +{ + Q_OBJECT +public: + QNmeaProxyFactory(); + + // proxy is created as child of source + QNmeaPositionInfoSourceProxy *createPositionInfoSourceProxy(QNmeaPositionInfoSource *source); + QNmeaSatelliteInfoSourceProxy *createSatelliteInfoSourceProxy(QNmeaSatelliteInfoSource *source); + +private: + QIODevice *createServerConnection(QTcpSocket *client); + + QTcpServer *m_server; +}; + +#endif diff --git a/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt new file mode 100644 index 0000000..941ba9d --- /dev/null +++ b/tests/benchmarks/CMakeLists.txt @@ -0,0 +1,7 @@ +# special case begin + +add_subdirectory(qgeoareamonitorinfo) +add_subdirectory(qgeopositioninfo) +add_subdirectory(qgeosatelliteinfo) + +# special case end diff --git a/tests/benchmarks/README b/tests/benchmarks/README new file mode 100644 index 0000000..8d017cd --- /dev/null +++ b/tests/benchmarks/README @@ -0,0 +1,81 @@ +The most reliable way of running benchmarks is to do it in an otherwise idle +system. On a busy system, the results will vary according to the other tasks +demanding attention in the system. + +We have managed to obtain quite reliable results by doing the following on +Linux (and you need root): + + - switching the scheduler to a Real-Time mode + - setting the processor affinity to one single processor + - disabling the other thread of the same core + +This should work rather well for CPU-intensive tasks. A task that is in Real- +Time mode will simply not be preempted by the OS. But if you make OS syscalls, +especially I/O ones, your task will be de-scheduled. Note that this includes +page faults, so if you can, make sure your benchmark's warmup code paths touch +most of the data. + +To do this you need a tool called schedtool (package schedtool), from +http://freequaos.host.sk/schedtool/ + +From this point on, we are using CPU0 for all tasks: + +If you have a Hyperthreaded multi-core processor (Core-i5 and Core-i7), you +have to disable the other thread of the same core as CPU0. To discover which +one it is: + +$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list + +This will print something like 0,4, meaning that CPUs 0 and 4 are sibling +threads on the same core. So we'll turn CPU 4 off: + +(as root) +# echo 0 > /sys/devices/system/cpu/cpu4/online + +To turn it back on, echo 1 into the same file. + +To run a task on CPU 0 exclusively, using FIFO RT priority 10, you run the +following: + +(as root) +# schedtool -F -p 10 -a 1 -e ./taskname + +For example: +# schedtool -F -p 10 -a 1 -e ./tst_bench_qstring -tickcounter + +Warning: if your task livelocks or takes far too long to complete, your system +may be unusable for a long time, especially if you don't have other cores to +run stuff on. To prevent that, run it before schedtool and time it. + +You can also limit the CPU time that the task is allowed to take. Run in the +same shell as you'll run schedtool: + +$ ulimit -s 300 +To limit to 300 seconds (5 minutes) + +If your task runs away, it will get a SIGXCPU after consuming 5 minutes of CPU +time (5 minutes running at 100%). + +If your app is multithreaded, you may want to give it more CPUs, like CPU0 and +CPU1 with -a 3 (it's a bitmask). + +For best results, you should disable ALL other cores and threads of the same +processor. The new Core-i7 have one processor with 4 cores, +each core can run 2 threads; the older Mac Pros have two processors with 4 +cores each. So on those Mac Pros, you'd disable cores 1, 2 and 3, while on the +Core-i7, you'll need to disable all other CPUs. + +However, disabling just the sibling thread seems to produce very reliable +results for me already, with variance often below 0.5% (even though there are +some measurable spikes). + +Other things to try: + +Running the benchmark with highest priority, i.e. "sudo nice -19" +usually produces stable results on some machines. If the benchmark also +involves displaying something on the screen (on X11), running it with +"-sync" is a must. Though, in that case the "real" cost is not correct, +but it is useful to discover regressions. + +Also; not many people know about ionice (1) + ionice - get/set program io scheduling class and priority diff --git a/tests/benchmarks/qgeoareamonitorinfo/CMakeLists.txt b/tests/benchmarks/qgeoareamonitorinfo/CMakeLists.txt new file mode 100644 index 0000000..f384baa --- /dev/null +++ b/tests/benchmarks/qgeoareamonitorinfo/CMakeLists.txt @@ -0,0 +1,12 @@ +# special case begin + +qt_internal_add_benchmark(tst_bench_qgeoareamonitorinfo + SOURCES + tst_bench_qgeoareamonitorinfo.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning + Qt::Test +) + +# special case end diff --git a/tests/benchmarks/qgeoareamonitorinfo/tst_bench_qgeoareamonitorinfo.cpp b/tests/benchmarks/qgeoareamonitorinfo/tst_bench_qgeoareamonitorinfo.cpp new file mode 100644 index 0000000..e88b1d7 --- /dev/null +++ b/tests/benchmarks/qgeoareamonitorinfo/tst_bench_qgeoareamonitorinfo.cpp @@ -0,0 +1,230 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include + +static const QDateTime expirationTime = QDateTime::currentDateTimeUtc().addSecs(60); +static const QGeoCircle area = QGeoCircle(QGeoCoordinate(1.0, 1.0), 100); + +class tst_QGeoAreaMonitorInfoBenchmark : public QObject +{ + Q_OBJECT +private slots: + void construct(); + void constructCopy(); + void constructMove(); + + void assign(); + void assignMove(); + + void checkEquality(); + + void setName(); + void queryName(); + + void queryIdentifier(); + void isValid(); + + void setArea(); + void queryArea(); + + void setExpiration(); + void queryExpiration(); + + void setPersistent(); + void queryPersistent(); + + void setNotificationParameters(); + void queryNotificationParameters(); +}; + + + +void tst_QGeoAreaMonitorInfoBenchmark::construct() +{ + QBENCHMARK { + QGeoAreaMonitorInfo info("test"); + Q_UNUSED(info) + } +} + +static QGeoAreaMonitorInfo createAreaMonitorInfo() +{ + QGeoAreaMonitorInfo info("test"); + info.setExpiration(expirationTime); + info.setArea(area); + QVariantMap parameters; + parameters["key"] = "value"; + parameters["another_key"] = true; + info.setNotificationParameters(parameters); + return info; +} + +void tst_QGeoAreaMonitorInfoBenchmark::constructCopy() +{ + const auto info = createAreaMonitorInfo(); + QBENCHMARK { + QGeoAreaMonitorInfo newInfo(info); + Q_UNUSED(newInfo) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::constructMove() +{ + QBENCHMARK { + // We need to create a new object at each iteration, so that we don't + // end up moving an already moved-from object. So the real value for + // move can be calculated using the results of construct() + // benchmark. + QGeoAreaMonitorInfo info("test"); + QGeoAreaMonitorInfo newInfo(std::move(info)); + Q_UNUSED(newInfo) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::assign() +{ + const auto info = createAreaMonitorInfo(); + QGeoAreaMonitorInfo newInfo; + QBENCHMARK { + newInfo = info; + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::assignMove() +{ + QGeoAreaMonitorInfo newInfo; + QBENCHMARK { + // We need to create a new object at each iteration, so that we don't + // end up moving an already moved-from object. So the real value for + // move can be calculated using the results of construct() + // benchmark. + QGeoAreaMonitorInfo info("test"); + newInfo = std::move(info); + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::checkEquality() +{ + const auto info1 = createAreaMonitorInfo(); + const auto info2 = createAreaMonitorInfo(); + QBENCHMARK { + const bool equal = info1 == info2; + Q_UNUSED(equal) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::setName() +{ + auto info = createAreaMonitorInfo(); + // Setting the name twice, as there is a check for same name. + // Ideally need to divide the result of the benchmark by 2. + QBENCHMARK { + info.setName("name1"); + info.setName("name2"); + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::queryName() +{ + const auto info = createAreaMonitorInfo(); + QBENCHMARK { + const auto val = info.name(); + Q_UNUSED(val) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::queryIdentifier() +{ + const auto info = createAreaMonitorInfo(); + QBENCHMARK { + const auto val = info.identifier(); + Q_UNUSED(val) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::isValid() +{ + const auto info = createAreaMonitorInfo(); + QBENCHMARK { + const auto val = info.isValid(); + Q_UNUSED(val) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::setArea() +{ + auto info = createAreaMonitorInfo(); + QBENCHMARK { + info.setArea(area); + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::queryArea() +{ + const auto info = createAreaMonitorInfo(); + QBENCHMARK { + const auto val = info.area(); + Q_UNUSED(val) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::setExpiration() +{ + auto info = createAreaMonitorInfo(); + QBENCHMARK { + info.setExpiration(expirationTime); + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::queryExpiration() +{ + const auto info = createAreaMonitorInfo(); + QBENCHMARK { + const auto val = info.expiration(); + Q_UNUSED(val) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::setPersistent() +{ + auto info = createAreaMonitorInfo(); + QBENCHMARK { + info.setPersistent(true); + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::queryPersistent() +{ + const auto info = createAreaMonitorInfo(); + QBENCHMARK { + const auto val = info.isPersistent(); + Q_UNUSED(val) + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::setNotificationParameters() +{ + auto info = createAreaMonitorInfo(); + QVariantMap newParameters; + newParameters["key"] = "value1"; + newParameters["another_key"] = false; + QBENCHMARK { + info.setNotificationParameters(newParameters); + } +} + +void tst_QGeoAreaMonitorInfoBenchmark::queryNotificationParameters() +{ + const auto info = createAreaMonitorInfo(); + QBENCHMARK { + const auto val = info.notificationParameters(); + Q_UNUSED(val) + } +} + +QTEST_MAIN(tst_QGeoAreaMonitorInfoBenchmark) + +#include "tst_bench_qgeoareamonitorinfo.moc" diff --git a/tests/benchmarks/qgeopositioninfo/CMakeLists.txt b/tests/benchmarks/qgeopositioninfo/CMakeLists.txt new file mode 100644 index 0000000..40ba024 --- /dev/null +++ b/tests/benchmarks/qgeopositioninfo/CMakeLists.txt @@ -0,0 +1,12 @@ +# special case begin + +qt_internal_add_benchmark(tst_bench_qgeopositioninfo + SOURCES + tst_bench_qgeopositioninfo.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning + Qt::Test +) + +# special case end diff --git a/tests/benchmarks/qgeopositioninfo/tst_bench_qgeopositioninfo.cpp b/tests/benchmarks/qgeopositioninfo/tst_bench_qgeopositioninfo.cpp new file mode 100644 index 0000000..7a0081e --- /dev/null +++ b/tests/benchmarks/qgeopositioninfo/tst_bench_qgeopositioninfo.cpp @@ -0,0 +1,228 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +static const QGeoCoordinate coordinate(1.0, 2.0); +static const QDateTime dateTime = QDateTime::currentDateTimeUtc(); + +class tst_QGeoPositionInfoBenchmark : public QObject +{ + Q_OBJECT +private slots: + void constructDefault(); + void constructWithParameters(); + void constructCopy(); + void constructMove(); + + void assign(); + void assignMove(); + + void checkEquality(); + + void isValid(); + + void setTimestamp(); + void queryTimestamp(); + + void setCoordinate(); + void queryCoordinate(); + + void setAttribute(); + void queryAttributeExisting(); + void queryAttributeNonExisting(); + void removeAttributeExisting(); + void removeAttributeNonExisting(); + void hasAttributeExisting(); + void hasAttributeNonExisting(); +}; + +void tst_QGeoPositionInfoBenchmark::constructDefault() +{ + QBENCHMARK { + QGeoPositionInfo info; + Q_UNUSED(info) + } +} + +void tst_QGeoPositionInfoBenchmark::constructWithParameters() +{ + QBENCHMARK { + QGeoPositionInfo info(coordinate, dateTime); + Q_UNUSED(info) + } +} + +void tst_QGeoPositionInfoBenchmark::constructCopy() +{ + const QGeoPositionInfo info(coordinate, dateTime); + QBENCHMARK { + QGeoPositionInfo newInfo(info); + Q_UNUSED(newInfo) + } +} + +void tst_QGeoPositionInfoBenchmark::constructMove() +{ + QBENCHMARK { + // We need to create a new object at each iteration, so that we don't + // end up moving an already moved-from object. So the real value for + // move can be calculated using the results of constructDefault() + // benchmark. + QGeoPositionInfo info; + QGeoPositionInfo newInfo(std::move(info)); + Q_UNUSED(newInfo) + } +} + +void tst_QGeoPositionInfoBenchmark::assign() +{ + const QGeoPositionInfo info(coordinate, dateTime); + QGeoPositionInfo newInfo; + QBENCHMARK { + newInfo = info; + } +} + +void tst_QGeoPositionInfoBenchmark::assignMove() +{ + QGeoPositionInfo newInfo; + QBENCHMARK { + // We need to create a new object at each iteration, so that we don't + // end up moving an already moved-from object. So the real value for + // move can be calculated using the results of constructDefault() + // benchmark. + QGeoPositionInfo info; + newInfo = std::move(info); + } +} + +void tst_QGeoPositionInfoBenchmark::checkEquality() +{ + // We will benchmark equal objects, because unequal objects will normally + // take less time to compare (as the comparison will fail at some stage). + const QGeoPositionInfo info1(coordinate, dateTime); + const QGeoPositionInfo info2(coordinate, dateTime); + QBENCHMARK { + const bool equal = info1 == info2; + Q_UNUSED(equal) + } +} + +void tst_QGeoPositionInfoBenchmark::isValid() +{ + const QGeoPositionInfo info(coordinate, dateTime); + QBENCHMARK { + const bool valid = info.isValid(); + Q_UNUSED(valid) + } +} + +void tst_QGeoPositionInfoBenchmark::setTimestamp() +{ + QGeoPositionInfo info; + QBENCHMARK { + info.setTimestamp(dateTime); + } +} + +void tst_QGeoPositionInfoBenchmark::queryTimestamp() +{ + const QGeoPositionInfo info(coordinate, dateTime); + QBENCHMARK { + const auto dt = info.timestamp(); + Q_UNUSED(dt) + } +} + +void tst_QGeoPositionInfoBenchmark::setCoordinate() +{ + QGeoPositionInfo info; + QBENCHMARK { + info.setCoordinate(coordinate); + } +} + +void tst_QGeoPositionInfoBenchmark::queryCoordinate() +{ + const QGeoPositionInfo info(coordinate, dateTime); + QBENCHMARK { + const auto coord = info.coordinate(); + Q_UNUSED(coord) + } +} + +void tst_QGeoPositionInfoBenchmark::setAttribute() +{ + QGeoPositionInfo info; + QBENCHMARK { + info.setAttribute(QGeoPositionInfo::Direction, 1.0); + } +} + +static QGeoPositionInfo generateInfoWithAttributes() +{ + QGeoPositionInfo info; + info.setAttribute(QGeoPositionInfo::Direction, 1.0); + info.setAttribute(QGeoPositionInfo::GroundSpeed, 2.0); + info.setAttribute(QGeoPositionInfo::VerticalSpeed, 3.0); + info.setAttribute(QGeoPositionInfo::MagneticVariation, 4.0); + return info; +} + +void tst_QGeoPositionInfoBenchmark::queryAttributeExisting() +{ + QGeoPositionInfo info = generateInfoWithAttributes(); + QBENCHMARK { + const auto value = info.attribute(QGeoPositionInfo::GroundSpeed); + Q_UNUSED(value) + } +} + +void tst_QGeoPositionInfoBenchmark::queryAttributeNonExisting() +{ + QGeoPositionInfo info = generateInfoWithAttributes(); + QBENCHMARK { + const auto value = info.attribute(QGeoPositionInfo::HorizontalAccuracy); + Q_UNUSED(value) + } +} + +void tst_QGeoPositionInfoBenchmark::removeAttributeExisting() +{ + QGeoPositionInfo info = generateInfoWithAttributes(); + QBENCHMARK { + info.removeAttribute(QGeoPositionInfo::GroundSpeed); + } +} + +void tst_QGeoPositionInfoBenchmark::removeAttributeNonExisting() +{ + QGeoPositionInfo info = generateInfoWithAttributes(); + QBENCHMARK { + info.removeAttribute(QGeoPositionInfo::HorizontalAccuracy); + } +} + +void tst_QGeoPositionInfoBenchmark::hasAttributeExisting() +{ + QGeoPositionInfo info = generateInfoWithAttributes(); + QBENCHMARK { + const auto value = info.hasAttribute(QGeoPositionInfo::GroundSpeed); + Q_UNUSED(value) + } +} + +void tst_QGeoPositionInfoBenchmark::hasAttributeNonExisting() +{ + QGeoPositionInfo info = generateInfoWithAttributes(); + QBENCHMARK { + const auto value = info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy); + Q_UNUSED(value) + } +} + +QTEST_MAIN(tst_QGeoPositionInfoBenchmark) + +#include "tst_bench_qgeopositioninfo.moc" diff --git a/tests/benchmarks/qgeosatelliteinfo/CMakeLists.txt b/tests/benchmarks/qgeosatelliteinfo/CMakeLists.txt new file mode 100644 index 0000000..461bcf6 --- /dev/null +++ b/tests/benchmarks/qgeosatelliteinfo/CMakeLists.txt @@ -0,0 +1,12 @@ +# special case begin + +qt_internal_add_benchmark(tst_bench_qgeosatelliteinfo + SOURCES + tst_bench_qgeosatelliteinfo.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning + Qt::Test +) + +# special case end diff --git a/tests/benchmarks/qgeosatelliteinfo/tst_bench_qgeosatelliteinfo.cpp b/tests/benchmarks/qgeosatelliteinfo/tst_bench_qgeosatelliteinfo.cpp new file mode 100644 index 0000000..e336d0d --- /dev/null +++ b/tests/benchmarks/qgeosatelliteinfo/tst_bench_qgeosatelliteinfo.cpp @@ -0,0 +1,223 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +class tst_QGeoSatelliteInfoBenchmark : public QObject +{ + Q_OBJECT +private slots: + void constructDefault(); + void constructCopy(); + void constructMove(); + + void assign(); + void assignMove(); + + void checkEquality(); + + void setSatelliteSystem(); + void querySatelliteSystem(); + + void setSatelliteIdentifier(); + void querySatelliteIdentifier(); + + void setSignalStrength(); + void querySignalStrength(); + + void setAttribute(); + void queryAttributeExisting(); + void queryAttributeNonExisting(); + void removeAttributeExisting(); + void removeAttributeNonExisting(); + void hasAttributeExisting(); + void hasAttributeNonExisting(); +}; + +void tst_QGeoSatelliteInfoBenchmark::constructDefault() +{ + QBENCHMARK { + QGeoSatelliteInfo info; + Q_UNUSED(info) + } +} + +static QGeoSatelliteInfo createSatelliteInfo() +{ + QGeoSatelliteInfo info; + info.setSatelliteSystem(QGeoSatelliteInfo::GLONASS); + info.setSatelliteIdentifier(1); + info.setSignalStrength(-30); + info.setAttribute(QGeoSatelliteInfo::Elevation, 10.0); + return info; +} + +void tst_QGeoSatelliteInfoBenchmark::constructCopy() +{ + const auto info = createSatelliteInfo(); + QBENCHMARK { + QGeoSatelliteInfo newInfo(info); + Q_UNUSED(newInfo) + } +} + +void tst_QGeoSatelliteInfoBenchmark::constructMove() +{ + QBENCHMARK { + // We need to create a new object at each iteration, so that we don't + // end up moving an already moved-from object. So the real value for + // move can be calculated using the results of constructDefault() + // benchmark. + QGeoSatelliteInfo info; + QGeoSatelliteInfo newInfo(std::move(info)); + Q_UNUSED(newInfo) + } +} + +void tst_QGeoSatelliteInfoBenchmark::assign() +{ + const auto info = createSatelliteInfo(); + QGeoSatelliteInfo newInfo; + QBENCHMARK { + newInfo = info; + } +} + +void tst_QGeoSatelliteInfoBenchmark::assignMove() +{ + QGeoSatelliteInfo newInfo; + QBENCHMARK { + // We need to create a new object at each iteration, so that we don't + // end up moving an already moved-from object. So the real value for + // move can be calculated using the results of constructDefault() + // benchmark. + QGeoSatelliteInfo info; + newInfo = std::move(info); + } +} + +void tst_QGeoSatelliteInfoBenchmark::checkEquality() +{ + const auto info1 = createSatelliteInfo(); + const auto info2 = createSatelliteInfo(); + QBENCHMARK { + const bool equal = info1 == info2; + Q_UNUSED(equal) + } +} + +void tst_QGeoSatelliteInfoBenchmark::setSatelliteSystem() +{ + QGeoSatelliteInfo info; + QBENCHMARK { + info.setSatelliteSystem(QGeoSatelliteInfo::GPS); + } +} + +void tst_QGeoSatelliteInfoBenchmark::querySatelliteSystem() +{ + const auto info = createSatelliteInfo(); + QBENCHMARK { + const auto val = info.satelliteSystem(); + Q_UNUSED(val) + } +} + +void tst_QGeoSatelliteInfoBenchmark::setSatelliteIdentifier() +{ + QGeoSatelliteInfo info; + QBENCHMARK { + info.setSatelliteIdentifier(10); + } +} + +void tst_QGeoSatelliteInfoBenchmark::querySatelliteIdentifier() +{ + const auto info = createSatelliteInfo(); + QBENCHMARK { + const auto val = info.satelliteIdentifier(); + Q_UNUSED(val) + } +} + +void tst_QGeoSatelliteInfoBenchmark::setSignalStrength() +{ + QGeoSatelliteInfo info; + QBENCHMARK { + info.setSignalStrength(-50); + } +} + +void tst_QGeoSatelliteInfoBenchmark::querySignalStrength() +{ + const auto info = createSatelliteInfo(); + QBENCHMARK { + const auto val = info.signalStrength(); + Q_UNUSED(val) + } +} + +void tst_QGeoSatelliteInfoBenchmark::setAttribute() +{ + QGeoSatelliteInfo info; + QBENCHMARK { + info.setAttribute(QGeoSatelliteInfo::Elevation, 10.0); + } +} + +void tst_QGeoSatelliteInfoBenchmark::queryAttributeExisting() +{ + const auto info = createSatelliteInfo(); + QBENCHMARK { + const auto val = info.attribute(QGeoSatelliteInfo::Elevation); + Q_UNUSED(val) + } +} + +void tst_QGeoSatelliteInfoBenchmark::queryAttributeNonExisting() +{ + const auto info = createSatelliteInfo(); + QBENCHMARK { + const auto val = info.attribute(QGeoSatelliteInfo::Azimuth); + Q_UNUSED(val) + } +} + +void tst_QGeoSatelliteInfoBenchmark::removeAttributeExisting() +{ + auto info = createSatelliteInfo(); + QBENCHMARK { + info.removeAttribute(QGeoSatelliteInfo::Elevation); + } +} + +void tst_QGeoSatelliteInfoBenchmark::removeAttributeNonExisting() +{ + auto info = createSatelliteInfo(); + QBENCHMARK { + info.removeAttribute(QGeoSatelliteInfo::Azimuth); + } +} + +void tst_QGeoSatelliteInfoBenchmark::hasAttributeExisting() +{ + auto info = createSatelliteInfo(); + QBENCHMARK { + const auto val = info.hasAttribute(QGeoSatelliteInfo::Elevation); + Q_UNUSED(val) + } +} + +void tst_QGeoSatelliteInfoBenchmark::hasAttributeNonExisting() +{ + auto info = createSatelliteInfo(); + QBENCHMARK { + const auto val = info.hasAttribute(QGeoSatelliteInfo::Azimuth); + Q_UNUSED(val) + } +} + +QTEST_MAIN(tst_QGeoSatelliteInfoBenchmark) + +#include "tst_bench_qgeosatelliteinfo.moc" diff --git a/tests/global/global.cfg b/tests/global/global.cfg new file mode 100644 index 0000000..8cc6269 --- /dev/null +++ b/tests/global/global.cfg @@ -0,0 +1,5 @@ + + + + + -- 2.30.2

    Z6$bLU)QjYD6 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

  • w8HR%LZ0Z{mv6 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 literal 0 HcmV?d00001 diff --git a/examples/positioning/weatherinfo/icons/weather-showers-scattered.png b/examples/positioning/weatherinfo/icons/weather-showers-scattered.png new file mode 100644 index 0000000000000000000000000000000000000000..d3e5b166aab86ae2a0e2e9cf434a4f8cc0a13a13 GIT binary patch literal 76000 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 B_x=C? literal 0 HcmV?d00001 diff --git a/examples/positioning/weatherinfo/icons/weather-showers.png b/examples/positioning/weatherinfo/icons/weather-showers.png new file mode 100644 index 0000000000000000000000000000000000000000..07489aaafbc535d764bead3870e422ba237ac45d GIT binary patch literal 76340 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