diff options
author | Jerome Pasion <jerome.pasion@nokia.com> | 2010-10-18 08:13:11 (GMT) |
---|---|---|
committer | Jerome Pasion <jerome.pasion@nokia.com> | 2010-10-18 08:13:11 (GMT) |
commit | 3b87384bb53f0a4637385b026cb33382fe7843cd (patch) | |
tree | d2a20d90a2de29729fc64a95161093b1c1db2a21 | |
parent | 95e8ba42b11db6036add3c2aa9aabcd1d2f5b4a3 (diff) | |
parent | 6c8748a1f4738c49ba333023c190104a53a647a1 (diff) | |
download | Qt-3b87384bb53f0a4637385b026cb33382fe7843cd.zip Qt-3b87384bb53f0a4637385b026cb33382fe7843cd.tar.gz Qt-3b87384bb53f0a4637385b026cb33382fe7843cd.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-doc-team into 4.7
84 files changed, 2589 insertions, 1561 deletions
diff --git a/.commit-template b/.commit-template index 589ca89..6e0e3a4 100644 --- a/.commit-template +++ b/.commit-template @@ -5,6 +5,6 @@ # ---[ Fields ]-----------------[ uncomment and edit as applicable ]---| #Task-number: -#Reviewed-by: +Reviewed-by: pending # ==================================[ please wrap at 72 characters ]===| diff --git a/bin/createpackage.pl b/bin/createpackage.pl index 41ba2e3..522d1fb 100755 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -140,7 +140,12 @@ unless (GetOptions('i|install' => \$install, } my $epocroot = $ENV{EPOCROOT}; -$epocroot =~ s,[\\/]$,,x; +if ($epocroot ne "") { + $epocroot =~ s,\\,/,g; + if ($epocroot =~ m,[^/]$,) { + $epocroot = $epocroot."/"; + } +} my $certfilepath = abs_path(dirname($certfile)); @@ -328,11 +333,11 @@ if ($preprocessonly) { if($stub) { if(!($epocroot)) { die("ERROR: EPOCROOT must be set to create stub sis files"); } - my $systeminstall = "$epocroot/epoc32/data/z/system/install"; + my $systeminstall = "${epocroot}epoc32/data/z/system/install"; mkpath($systeminstall); my $stub_sis_name = $systeminstall."/".$stub_sis_name; # Create stub SIS. - system ("$epocroot/epoc32/tools/makesis -s $pkgoutput $stub_sis_name"); + system ("${epocroot}epoc32/tools/makesis -s $pkgoutput $stub_sis_name"); } else { if ($certtext eq "Self Signed" && !@certificates @@ -346,7 +351,7 @@ if($stub) { # Create SIS. # The 'and' is because system uses 0 to indicate success. if($epocroot) { - system ("$epocroot/epoc32/tools/makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed"); + system ("${epocroot}epoc32/tools/makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed"); } else { system ("makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed"); } diff --git a/demos/declarative/snake/content/pics/pause.png b/demos/declarative/snake/content/pics/pause.png Binary files differnew file mode 100644 index 0000000..056d97d --- /dev/null +++ b/demos/declarative/snake/content/pics/pause.png diff --git a/demos/declarative/snake/content/snake.js b/demos/declarative/snake/content/snake.js index c2e9d3a..5c089de 100644 --- a/demos/declarative/snake/content/snake.js +++ b/demos/declarative/snake/content/snake.js @@ -32,7 +32,7 @@ function startNewGame() if (state == "starting") return; - if (heartbeat.running) { + if (activeGame) { endGame(); startNewGameTimer.running = true; state = ""; @@ -87,7 +87,7 @@ function startNewGame() function endGame() { - heartbeat.running = false; + activeGame = false; for(var i in snake) snake[i].dying = true; if (cookie) { diff --git a/demos/declarative/snake/snake.qml b/demos/declarative/snake/snake.qml index 5b69217..6eaa976 100644 --- a/demos/declarative/snake/snake.qml +++ b/demos/declarative/snake/snake.qml @@ -47,6 +47,7 @@ Rectangle { id: screen; SystemPalette { id: activePalette } color: activePalette.window + property bool activeGame: false property int gridSize : 34 property int margin: 4 @@ -75,6 +76,7 @@ Rectangle { Timer { id: heartbeat; interval: heartbeatInterval; + running: activeGame && runtime.isActiveWindow repeat: true onTriggered: { Logic.move() } } @@ -94,9 +96,17 @@ Rectangle { Timer { id: startHeartbeatTimer; interval: 1000 ; - onTriggered: { state = "running"; heartbeat.running = true; } + onTriggered: { state = "running"; activeGame = true; } } + Image{ + id: pauseDialog + z: 1 + source: "content/pics/pause.png" + anchors.centerIn: parent; + //opacity is deliberately not animated + opacity: gameActive && !runtime.isActiveWindow + } Image { Image { diff --git a/dist/changes-4.7.1 b/dist/changes-4.7.1 index 51a10a3..b25b95c 100644 --- a/dist/changes-4.7.1 +++ b/dist/changes-4.7.1 @@ -13,7 +13,6 @@ corresponding to tasks in the Qt Bug Tracker, the (now obsolete) Task Tracker, or the Merge Request queue of the public source repository. Qt Bug Tracker: http://bugreports.qt.nokia.com -Task Tracker: http://qt.nokia.com/developer/task-tracker Merge Request: http://qt.gitorious.org **************************************************************************** @@ -31,8 +30,6 @@ Optimizations - On x86 and 86_64, the memory access has been improved for alpha blending and for some composition functions. - * See list of Important Behavior Changes below - **************************************************************************** * Library * @@ -42,69 +39,68 @@ QtCore ------ - Containers - * [QTBUG-13079] Fix assingment of a container included in the container itself + * [QTBUG-13079] Fix assignment of a container included in the container + itself. - - QLibrary - * [QT-3825] System libraries are only loaded from the system directories + - QEventDispatcherUnix + * [QTBUG-13633] Do not process too many timer events if other events need + to be processed first. + - QLibrary + * [QT-3825] System libraries are only loaded from the system directories. - QUuid - * [QTBUG-11213] QUuid::createUuid() should not generate identical sequences on UNIX - - - QEventDispatcherUnix - * [QTBUG-13633] Do not process too many timer events if other events need - to be processed first + * [QTBUG-11213] QUuid::createUuid() should not generate identical sequences + on UNIX. QtGui ----- - - QGraphicsWidget - * [QTBUG-13188] Make sure a font that has propagated from a parent can - be set on a QPainter. - * [QT-3808] Issues when applying effects in combination with ItemHasNoContents flag. + - QGraphicsEffect + * [QT-3633] Wrong bounding rect. - QGraphicsItem * [QTBUG-3633, QT-3828] Wrong children bounding rect when applying effects. - - QGraphicsEffect - * [QT-3633] Wrong bounding rect. - - QGraphicsScene * [QT-3674] Spurious assert triggered from render(). + - QGraphicsWidget + * [QTBUG-13188] Make sure a font that has propagated from a parent can + be set on a QPainter. + * [QT-3808] Issues when applying effects in combination with + ItemHasNoContents flag. + + - QGtkStyle + * [QTBUG-13125] Fixed a regression with custom itemview background color. + + - QLineEdit + * [QTBUG-13520] Fixed the scrolling of text with right alignment. + - QPainter * [QTBUG-13429] Fixed scale point drawing with square cap in the raster engine, plus some potential floating point overflows in the rasterizer. * Optimized pixmap drawing with SmoothPixmapTransform. - - QStaticText - * [QTBUG-12614] Fix crash with zero-width string. - * [QTBUG-12540] Fix rendering of large glyphs with OpenGL2 paint engine. - - - QPinchGesture * The scaleFactor and totalScaleFactor now represent a value that allows an object to track a touchpoint during a Pinch Gesture even when using sequences for zooming. - Therefor the scale factors are initialized to 1.0 and for every new + Therefore the scale factors are initialized to 1.0 and for every new sequence the totalScaleFactor is multiplied with the scaleFactor of the new sequence. - - QLineEdit - * [QTBUG-13520] Fixed the scrolling of text with right alignment - - QPixmap - * [QTBUG-12560] Fixed a regression preventing loading images without extensions + * [QTBUG-12560] Fixed a regression preventing loading images without + extensions. - - QTreeView - * [QTBUG-13567] Do not scroll to top if last item is removed - - - QGtkStyle - * [QTBUG-13125] Fixed a regression with custom itemview background color. + - QStaticText + * [QTBUG-12614] Fix crash with zero-width string. + * [QTBUG-12540] Fix rendering of large glyphs with OpenGL2 paint engine. -QtDBus ------- + - QTreeView + * [QTBUG-13567] Do not scroll to top if last item is removed. QtMultimedia @@ -115,151 +111,170 @@ QtMultimedia * [QTBUG-11883] Fixed segmentation fault when closing a QAudioInput or QAudioOutput. + QtNetwork --------- - - QSslConfiguration - * [QTBUG-13265] fix crash with empty configuration - - QSslCertificate - * [QTBUG-12489] support dates > 2049 - Bearer Management * Improved reliability on Symbian and Maemo. * Added connman/meego backend. - IPv6 - * Disable on Symbian until OpenC properly supports it + * Disable on Symbian until OpenC properly supports it. + - QSslConfiguration + * [QTBUG-13265] Fixed crash with empty configuration. + - QSslCertificate + * [QTBUG-12489] Support dates > 2049. - QNetworkAccessManager - * [QTBUG-12285] Crash fix related to aborted uploads + * [QTBUG-12285] Crash fix related to aborted uploads. QtOpenGL -------- - QGL2PaintEngineEx * Fixed drawing a large number of glyphs with the same font on systems - with small texure size limits. - -QtOpenVG --------- - - -QtWebKit --------- - - -QtSql ------ - + with small texture size limits. -QtSvg ------ QtXml ----- * Fixed a crash when parsing invalid tag names. + QtXmlPatterns ------------- - XML Schema internals: - * [QTBUG-11559] Only parse 3 digits of time fraction + * [QTBUG-11559] Only parse 3 digits of time fraction. + QtDeclarative ------------- - QML language - * [QTBUG-13799] QML core module renamed to QtQuick to decouple it from Qt releases. - Old "import Qt 4.7" will co-exist with "import QtQuick 1.0' at least during Qt 4.7 releases. - * [QTBUG-13047] Support passing QObject derived types to QML methods - * [QTBUG-12837] Support JS "in" operator on QML objects - * [QTBUG-13045] Prevent calling deleteLater() from QML - * [QTBUG-13043] Ignore non-scriptable properties in QML - * [QTBUG-13114] Don't double call classBegin() - * [QTBUG-12946] Ensure the onDestruction handlers are called before the expressions are cleared - * [QTBUG-12599] Re-enabled script program caching on Symbian - * [QTBUG-13374] Don't modify the signal order on the second dynamic meta object pass - * Support for qsTrId and meta-data in comments for QML - - QML debugging: + * [QTBUG-13799] QML core module renamed to QtQuick to decouple it from Qt + releases. Old "import Qt 4.7" will co-exist with "import QtQuick 1.0' at + least during Qt 4.7 releases. + * [QTBUG-13047] Support passing QObject derived types to QML methods. + * [QTBUG-12837] Support JS "in" operator on QML objects. + * [QTBUG-13045] Prevent calling deleteLater() from QML. + * [QTBUG-13043] Ignore non-scriptable properties in QML. + * [QTBUG-13114] Don't double call classBegin(). + * [QTBUG-12946] Ensure the onDestruction handlers are called before the + expressions are cleared. + * [QTBUG-12599] Re-enabled script program caching on Symbian. + * [QTBUG-13374] Don't modify the signal order on the second dynamic meta + object pass. + * Support for qsTrId and meta-data in comments for QML. + - QML debugging * [QTBUG-5162] The debugger is now activated with -qmljsdebugger command - line arg to enable support for platforms without environment variables - * Various improvements to ease debugging in creator + line arg to enable support for platforms without environment variables. + * Various improvements to ease debugging in creator. - AnchorAnimation - * [QTBUG-13398] Fix AnchorAnimation for multiple AnchorChanges with dependancies + * [QTBUG-13398] Fix AnchorAnimation for multiple AnchorChanges with + dependancies. - AnchorChanges - * [QTBUG-11834] Restore any absolute geometry changed by AnchorChanges when returning to the base state + * [QTBUG-11834] Restore any absolute geometry changed by AnchorChanges when + returning to the base state. - Component - * [QTBUG-13170] Complete Component::createObject() creation after setting the parent + * [QTBUG-13170] Complete Component::createObject() creation after setting + the parent. - GridView - * [QTBUG-13166] GridView.view property should not be writable + * [QTBUG-13166] GridView.view property should not be writable. - Flickable - * [QTBUG-13095] Ensure Flickable visibleArea is updated when view height changes - * [QTBUG-13176] Avoid Flickable view jumping when drag threashold is exceeded - * [QTBUG-13078] Fix poor flicking behavior with slower flicks - * Handle QGraphicsWidgets in Flickable + * [QTBUG-13095] Ensure Flickable visibleArea is updated when view height + changes. + * [QTBUG-13176] Avoid Flickable view jumping when drag threashold is + exceeded. + * [QTBUG-13078] Fix poor flicking behavior with slower flicks. + * Handle QGraphicsWidgets in Flickable. - FocusScope - * [QTBUG-12649] Make sure onFocusChanged is correctly emitted for items in a FocusScope. + * [QTBUG-12649] Make sure onFocusChanged is correctly emitted for items + in a FocusScope. - FontLoader - * [QTBUG-13419] Don't add the same font to the font database multiple times + * [QTBUG-13419] Don't add the same font to the font database multiple + times. + - Image + * [QTBUG-13454] Changing the Image 'source' no longer goes through the + 'Loading' state if the image is cached. + * [QTBUG-13383] Do not reset sourceSize when changing image source url. + * [QTBUG-13002] Setting one dimension of the sourceSize should set the other + dimension. + * [QTBUG-12302] Fix remote image url redirects are done in the right thread. + * Ensure all image states are updated before emitting statusChanged signals. - ListModel - * [QTBUG-12363] Modifying an object returned by ListModel.get(0) didn't update the view - * [QTBUG-13666] Calling set() and setProperty() on ListModel from a WorkerScript didn't update the view - * Fix Worker ListModel to emit the right signal when items change - * Fix crash with invalid role indexes - * improved ListModel error messages + * [QTBUG-12363] Modifying an object returned by ListModel.get(0) didn't + update the view. + * [QTBUG-13666] Calling set() and setProperty() on ListModel from a + WorkerScript didn't update the view. + * Fix Worker ListModel to emit the right signal when items change. + * Fix crash with invalid role indexes. + * improved ListModel error messages. - ListView - * [QTBUG-13664] Models with a single role didn't always update correctly - * [QTBUG-13543] Ensure flickable velocity is updated when view is moved by setCurrentIndex - * [QTBUG-12664] Ensure highlight is positioned correctly in positionViewAtIndex() - * [QTBUG-13166] Fix ListView.view attached property with VisualItemModel - * [QTBUG-13039] Fix crash in synchronization of ListModel in WorkerThread - * [QTBUG-11341] Flicking a ListView sometimes made it loose focus - * [QTBUG-13166] ListView.view property should not be writable + * [QTBUG-13664] Models with a single role didn't always update correctly. + * [QTBUG-13543] Ensure flickable velocity is updated when view is moved by + setCurrentIndex. + * [QTBUG-12664] Ensure highlight is positioned correctly in + positionViewAtIndex(). + * [QTBUG-13166] Fix ListView.view attached property with VisualItemModel. + * [QTBUG-13039] Fix crash in synchronization of ListModel in WorkerThread. + * [QTBUG-11341] Flicking a ListView sometimes made it lose focus. + * [QTBUG-13166] ListView.view property should not be writable. + - MouseArea + * [QTBUG-12250] When onDoubleClicked: is handled don't emit a second + onPressed/onClicked. + - NumberAnimation + * [QTBUG-12805] Clear previous animation data for non-triggering animations. + - ParentChange + * [QTBUG-13554] ParentChange fails to apply rotation changes of exactly 180 + degrees. - PathView - * [QTBUG-13689] Moving items in a PathView caused PathView.onPath to be set to false - * [QTBUG-13687] PathView didn't accept mouse events, preventing it from working in a Flickable - * [QTBUG-13416] Fix PathView item position on insertion and removal - * [QTBUG-13017] Fix PathView when setting an empty model that is later filled - * [QTBUG-12747] PathView required some diagonal movement before a drag was initiated + * [QTBUG-13689] Moving items in a PathView caused PathView.onPath to be set + to false. + * [QTBUG-13687] PathView didn't accept mouse events, preventing it from + working in a Flickable. + * [QTBUG-13416] Fix PathView item position on insertion and removal. + * [QTBUG-13017] Fix PathView when setting an empty model that is later + filled. + * [QTBUG-12747] PathView required some diagonal movement before a drag was + initiated. - Positioners - * made positioners work with QGraphicsWidgets + * made positioners work with QGraphicsWidgets. - PropertyChanges - * [QTBUG-12559] Correctly apply PropertyChanges when entering an extended state directly from the base state - - VisualDataModel - * [QTBUG-13754] Fixed a crash when updating a property in ListModel with multiple roles - * [QTBUG-13038] Fix VisualDataModel model update handling when rootIndex is specified - * [QTBUG-13146] Handle layoutChanged() properly in QML views - - XmlListModel - * [QTBUG-13041] XmlListModel thread was left hanging on Symbian application exit - - ParentChange - * [QTBUG-13554] ParentChange fails to apply rotation changes of exactly 180 degrees - - MouseArea - * [QTBUG-12250] When onDoubleClicked: is handled don't emit a second onPressed/onClicked - - Image - * [QTBUG-13454] Changing the Image 'source' no longer goes through the 'Loading' state if the image is cached. - * [QTBUG-13383] Do not reset sourceSize when changing image source url - * [QTBUG-13002] Setting one dimension of the sourceSize should set the other dimensio - * [QTBUG-12302] Fix remote image url redirects are done in the right thread - * Ensure all image states are updated before emitting statusChanged signals - - NumberAnimation - * [QTBUG-12805] Clear previous animation data for non-triggering animations + * [QTBUG-12559] Correctly apply PropertyChanges when entering an extended + state directly from the base state. + - QDeclarativeImageProvider: + * Fixed memory leak. + * Improved concurrency when using in asynchronus mode. - Repeater - * [QTBUG-12905] Emit countChanged where appropriate in Repeater + * [QTBUG-12905] Emit countChanged where appropriate in Repeater. - SmoothedAnimation - * [QTBUG-12336] Update running animations if a SmoothedAnimation is changed + * [QTBUG-12336] Update running animations if a SmoothedAnimation is changed. - SpringAnimation - * [QTBUG-13044] SpringAnimation velocity animation stop logic was fragile + * [QTBUG-13044] SpringAnimation velocity animation stop logic was fragile. - Text - * [QTBUG-13453] Fix jerky scrolling caused by unnecessary repaints of Text element - * [QTBUG-13142] Fix alignment of shadow for rich text when using text styles - * [QTBUG-11002] Improve QML text rendering when LCD smoothing is enabled for OS X + * [QTBUG-13453] Fix jerky scrolling caused by unnecessary repaints of Text + element. + * [QTBUG-13142] Fix alignment of shadow for rich text when using text + styles. + * [QTBUG-11002] Improve QML text rendering when LCD smoothing is enabled + for OS X. - TextInput - * [QTBUG-11127] Fix autoScroll implementation - - XmlHttpRequest - * [QTBUG-13117] Fix responseText to check the charset encoding field and also to not assume that the data is xml + * [QTBUG-11127] Fix autoScroll implementation. + - VisualDataModel + * [QTBUG-13754] Fixed a crash when updating a property in ListModel with + multiple roles. + * [QTBUG-13038] Fix VisualDataModel model update handling when rootIndex is + specified. + * [QTBUG-13146] Handle layoutChanged() properly in QML views. - WebView - * [QTBUG-13342] Ensure WebView gets focus when an editable node is clicked on - - QDeclarativeImageProvider: - * Fixed memory leak - * Improved concurrency when using in assynchronus mode. + * [QTBUG-13342] Ensure WebView gets focus when an editable node is clicked. + - XmlHttpRequest + * [QTBUG-13117] Fix responseText to check the charset encoding field and + also to not assume that the data is xml. + - XmlListModel + * [QTBUG-13041] XmlListModel thread was left hanging on Symbian application + exit. + Qt Plugins ---------- - - Jpeg image IO plugin * [QTBUG-13653] Fixed infinite loop when loading jpeg without EOI marker from memory. @@ -275,15 +290,16 @@ Qt for Unix (X11 and Mac OS X) Qt for Linux/X11 ---------------- - - The configure script now detects all vector extensions of x86 and x86_64 + - The configure script now detects all vector extensions of x86 and x86_64. Qt for Windows -------------- - Event System: - * [QTBUG-12721] Fix Qt applications freezing until mouse/keyboard events occur. + * [QTBUG-12721] Fix Qt applications freezing until mouse/keyboard events + occur. - Drag & Drop: - * [QTBUG-13787] Fixed a possible crash with mingw + * [QTBUG-13787] Fixed a possible crash with mingw. - QPrinter * [QTBUG-12263] Strokes were in some cases not printed with the correct @@ -303,7 +319,6 @@ Qt for Mac OS X Qt for Symbian -------------- - - configure * [QTBUG-4586] Fixed wrong paths in include/ActiveQt/headers.pri. * [QTBUG-11671] Fixed audio-backend detection in configure tests. @@ -319,21 +334,27 @@ Qt for Symbian * [QTBUG-13081] vc[x]proj generators: support /MAP option without file name. * [QTBUG-13902] Added support for unsigned smart installer package creation. - * [QTBUG-13991] No longer need to manually edit smart installer pkg file for publishing. + * [QTBUG-13991] No longer need to manually edit smart installer pkg file for + publishing. * [QT-3949] Load environment.prf from Symbian SDK if it exists there. - * [QTBUG-13499] Provide a way to compile with RVCT 4.0 using generated Makefile. + * [QTBUG-13499] Provide a way to compile with RVCT 4.0 using generated + Makefile. * [QTBUG-13336] Ignore MAKEFILE variable for Symbian abld and sbsv2 builds. - * [QTBUG-13363] Fix Symbian handling of projects with special characters in TARGET. + * [QTBUG-13363] Fix Symbian handling of projects with special characters in + TARGET. * [QTBUG-12762 & QTBUG-13307] Gcce building support for symbian-sbsv2 * [QTBUG-13147] Added support for DEPLOYMENT.pkg_build_version * [QTBUG-12884] Fix "installer_sis" and "deploy" targets when TARGET has path. * [QTBUG-12879] Fix check to remove unnecessary deployments in Symbian. * [QTBUG-12716] Make bld.inf target in Symbian mkspecs to depend on .pro file. - * [QTBUG-12715] Rename Symbian generated mmp/mk files to include target in filename. - * [QTBUG-12617] Fix package header in cases where VERSION doesn't contain all values. + * [QTBUG-12715] Rename Symbian generated mmp/mk files to include target in + filename. + * [QTBUG-12617] Fix package header in cases where VERSION doesn't contain all + values. * Fix run and runonphone targets for projects that have TARGET with path. * Fix QT_LIBINFIX for QT_PLUGINS_BASE_DIR. - * No longer require PRE_TARGETDEPS items to be absolute for symbian-sbsv2 mkspec. + * No longer require PRE_TARGETDEPS items to be absolute for symbian-sbsv2 + mkspec. * Do smart command replacement for commands containing $$QMAKE_* command variables, such as $$QMAKE_COPY, when generating bld.inf extensions for QMAKE_EXTRA_* variables for symbian-sbsv2 mkspec. @@ -364,7 +385,8 @@ Qt for Symbian Check S60_VERSION instead of existence of certain files in bearer plugin. - Demos & Examples - * [QTBUG-13461] Remove some .pro statements left behind after IAP usage cleanup + * [QTBUG-13461] Remove some .pro statements left behind after IAP usage + cleanup. * [QTBUG-12276] Assigned valid UID3 for fortuneserver example. Qt for Windows CE @@ -372,25 +394,21 @@ Qt for Windows CE - Gui * [QTBUG-8408] Show the [X] button on Windows mobile when maximizing. + **************************************************************************** * Tools * **************************************************************************** - - Designer - - uic - * Improve warnings and error reports + * Improve warnings and error reports. - moc - * Show an error if NOTIFY refer to a wrong signal in Q_PROPERTY + * Show an error if NOTIFY refer to a wrong signal in Q_PROPERTY. - QML Viewer - * [QTBUG-13347] Paused orientation sensors in Qml Viewer when the application window is not active to save device battery - * [QTBUG-11019] Add a menu option to open remote files in the QML viewer - * QML Viewer is deployed under QtDemos folder instead of QtExamples folder in Symbian application menu - -**************************************************************************** -* Important Behavior Changes * -**************************************************************************** - + * [QTBUG-13347] Paused orientation sensors in Qml Viewer when the + application window is not active to save device battery. + * [QTBUG-11019] Add a menu option to open remote files in the QML viewer. + * QML Viewer is deployed under QtDemos folder instead of QtExamples + folder in Symbian application menu. diff --git a/doc/src/snippets/declarative/keys/keys-handler.qml b/doc/src/snippets/declarative/keys/keys-handler.qml index 9e3a3b4..be0eedb 100644 --- a/doc/src/snippets/declarative/keys/keys-handler.qml +++ b/doc/src/snippets/declarative/keys/keys-handler.qml @@ -38,7 +38,7 @@ ** ****************************************************************************/ -import Qt 4.7 +import QtQuick 1.0 Item { width: 400; height: 400 diff --git a/doc/src/snippets/declarative/keys/keys-pressed.qml b/doc/src/snippets/declarative/keys/keys-pressed.qml index 523c95b..90a4e37 100644 --- a/doc/src/snippets/declarative/keys/keys-pressed.qml +++ b/doc/src/snippets/declarative/keys/keys-pressed.qml @@ -38,7 +38,7 @@ ** ****************************************************************************/ -import Qt 4.7 +import QtQuick 1.0 Item { width: 400; height: 400 diff --git a/mkspecs/features/link_pkgconfig.prf b/mkspecs/features/link_pkgconfig.prf index 4c528aa..d70e5de 100644 --- a/mkspecs/features/link_pkgconfig.prf +++ b/mkspecs/features/link_pkgconfig.prf @@ -1,6 +1,7 @@ # handle pkg-config files +isEmpty(PKG_CONFIG):PKG_CONFIG = pkg-config for(PKGCONFIG_LIB, $$list($$unique(PKGCONFIG))) { - QMAKE_CXXFLAGS += $$system(pkg-config --cflags $$PKGCONFIG_LIB) - QMAKE_CFLAGS += $$system(pkg-config --cflags $$PKGCONFIG_LIB) - LIBS += $$system(pkg-config --libs $$PKGCONFIG_LIB) + QMAKE_CXXFLAGS += $$system($$PKG_CONFIG --cflags $$PKGCONFIG_LIB) + QMAKE_CFLAGS += $$system($$PKG_CONFIG --cflags $$PKGCONFIG_LIB) + LIBS += $$system($$PKG_CONFIG --libs $$PKGCONFIG_LIB) } diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 776a646..5963773 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -59,7 +59,12 @@ static QString fixPathToEpocOS(const QString &src) { QString ret = Option::fixPathToTargetOS(src); - return ret.replace('/', '\\'); + + bool pathHasDriveLetter = false; + if (ret.size() > 1) + pathHasDriveLetter = (ret.at(1) == QLatin1Char(':')); + + return pathHasDriveLetter ? ret.replace('/', '\\') : QDir::toNativeSeparators(ret); } static bool isPlugin(const QFileInfo& info, const QString& devicePath) diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 9af3fe4..6fea8fd 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -428,9 +428,9 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB t << QString("\"%1epoc32/data/z%2\" - \"!:%3\"") .arg(epocRoot()) .arg(iconFile) - .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; + .arg(QString(iconFile).replace('/', '\\')) << endl << endl; ts << QString("\"\" - \"%1\"") - .arg(romPath(QDir::toNativeSeparators(iconFile))) << endl << endl; + .arg(romPath(QString(iconFile).replace('/', '\\'))) << endl << endl; } else { QDir mifIconDir(project->first("DESTDIR")); QFileInfo mifIcon(mifIconDir.relativeFilePath(project->first("TARGET"))); @@ -439,9 +439,9 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB t << QString("\"%1/%2\" - \"!:%3\"") .arg(mifIcon.path()) .arg(mifIconFileName) - .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; + .arg(QString(iconFile).replace('/', '\\')) << endl << endl; ts << QString("\"\" - \"%1\"") - .arg(romPath(QDir::toNativeSeparators(iconFile))) << endl << endl; + .arg(romPath(QString(iconFile).replace('/', '\\'))) << endl << endl; } } } diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index 7416cbe..127d5c0 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -427,7 +427,8 @@ bool SymbianAbldMakefileGenerator::writeDeploymentTargets(QTextStream &t, bool i t << WINSCW_DEPLOYMENT_TARGET ":" << endl; QString remoteTestPath = epocRoot() - + QLatin1String(isRom ? "epoc32\\data\\z\\private\\" : "epoc32\\winscw\\c\\private\\") + + QDir::toNativeSeparators(QLatin1String(isRom ? "epoc32/data/z/private/" + : "epoc32/winscw/c/private/")) + privateDirUid; DeploymentList depList; @@ -439,11 +440,16 @@ bool SymbianAbldMakefileGenerator::writeDeploymentTargets(QTextStream &t, bool i t << "\t-echo Deploying changed files..." << endl; for (int i = 0; i < depList.size(); ++i) { +#ifdef Q_OS_WIN32 // Xcopy prompts for selecting file or directory if target doesn't exist, // and doesn't provide switch to force file selection. It does provide dir forcing, though, // so strip the last part of the destination. t << "\t-$(XCOPY) \"" << depList.at(i).from << "\" \"" << depList.at(i).to.left(depList.at(i).to.lastIndexOf("\\") + 1) << "\"" << endl; +#else + t << "\t-$(XCOPY) \"" << QDir::toNativeSeparators(depList.at(i).from) << "\" \"" + << QDir::toNativeSeparators(depList.at(i).to) << "\"" << endl; +#endif } t << endl; @@ -455,7 +461,7 @@ bool SymbianAbldMakefileGenerator::writeDeploymentTargets(QTextStream &t, bool i QStringList cleanList; for (int i = 0; i < depList.size(); ++i) { - cleanList.append(depList.at(i).to); + cleanList.append(QDir::toNativeSeparators(depList.at(i).to)); } generateCleanCommands(t, cleanList, "$(DEL_FILE)", "", "", ""); diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 907f8dc..b707607 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -213,7 +213,7 @@ void NmakeMakefileGenerator::init() project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".exp"); } if(project->isActiveConfig("debug")) { - project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"); + project->values("QMAKE_DISTCLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"); project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".ilk"); project->values("QMAKE_CLEAN").append("vc*.pdb"); project->values("QMAKE_CLEAN").append("vc*.idb"); diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 6e37aee..16b14730 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -2636,8 +2636,6 @@ void QAbstractItemModel::endMoveRows() QAbstractItemModelPrivate::Change insertChange = d->changes.pop(); QAbstractItemModelPrivate::Change removeChange = d->changes.pop(); - d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Vertical); - QModelIndex adjustedSource = removeChange.parent; QModelIndex adjustedDestination = insertChange.parent; @@ -2648,6 +2646,8 @@ void QAbstractItemModel::endMoveRows() if (removeChange.needsAdjust) adjustedSource = createIndex(adjustedSource.row() + numMoved, adjustedSource.column(), adjustedSource.internalPointer()); + d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Vertical); + emit rowsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first); emit layoutChanged(); } @@ -2860,8 +2860,6 @@ void QAbstractItemModel::endMoveColumns() QAbstractItemModelPrivate::Change insertChange = d->changes.pop(); QAbstractItemModelPrivate::Change removeChange = d->changes.pop(); - d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Horizontal); - QModelIndex adjustedSource = removeChange.parent; QModelIndex adjustedDestination = insertChange.parent; @@ -2872,6 +2870,8 @@ void QAbstractItemModel::endMoveColumns() if (removeChange.needsAdjust) adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer()); + d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal); + emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first); emit layoutChanged(); } diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 6ee6b0d..f53625f 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -112,7 +112,7 @@ public: , bufferMode(BufferBefore | BufferAfter), snapMode(QDeclarativeGridView::NoSnap) , ownModel(false), wrap(false), autoHighlight(true) , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) - , deferredRelease(false), haveHighlightRange(false) {} + , deferredRelease(false), haveHighlightRange(false), currentIndexSet(false) {} void init(); void clear(); @@ -392,6 +392,7 @@ public: bool layoutScheduled : 1; bool deferredRelease : 1; bool haveHighlightRange : 1; + bool currentIndexSet : 1; }; void QDeclarativeGridViewPrivate::init() @@ -730,6 +731,8 @@ void QDeclarativeGridViewPrivate::createHighlight() QDeclarative_setParent_noEvent(item, q->contentItem()); item->setParentItem(q->contentItem()); highlight = new FxGridItem(item, q); + if (currentItem) + highlight->setPosition(currentItem->colPos(), currentItem->rowPos()); highlightXAnimator = new QSmoothedAnimation(q); highlightXAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("x")); highlightXAnimator->userDuration = highlightMoveDuration; @@ -771,8 +774,11 @@ void QDeclarativeGridViewPrivate::updateCurrent(int modelIndex) currentItem->attached->setIsCurrentItem(false); releaseItem(currentItem); currentItem = 0; - currentIndex = -1; + currentIndex = modelIndex; + emit q->currentIndexChanged(); updateHighlight(); + } else if (currentIndex != modelIndex) { + currentIndex = modelIndex; emit q->currentIndexChanged(); } return; @@ -1236,7 +1242,7 @@ void QDeclarativeGridView::setModel(const QVariant &model) d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore | QDeclarativeGridViewPrivate::BufferAfter; if (isComponentComplete()) { refill(); - if (d->currentIndex >= d->model->count() || d->currentIndex < 0) { + if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexSet) { setCurrentIndex(0); } else { d->moveReason = QDeclarativeGridViewPrivate::SetIndex; @@ -1344,10 +1350,13 @@ void QDeclarativeGridView::setCurrentIndex(int index) Q_D(QDeclarativeGridView); if (d->requestedIndex >= 0) // currently creating item return; - if (isComponentComplete() && d->isValid() && index != d->currentIndex && index < d->model->count() && index >= 0) { + d->currentIndexSet = true; + if (index == d->currentIndex) + return; + if (isComponentComplete() && d->isValid()) { d->moveReason = QDeclarativeGridViewPrivate::SetIndex; d->updateCurrent(index); - } else if (index != d->currentIndex) { + } else { d->currentIndex = index; emit currentIndexChanged(); } @@ -1983,22 +1992,25 @@ void QDeclarativeGridView::keyPressEvent(QKeyEvent *event) Move the currentIndex up one item in the view. The current index will wrap if keyNavigationWraps is true and it - is currently at the end. + is currently at the end. This method has no effect if the \l count is zero. \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeGridView::moveCurrentIndexUp() { Q_D(QDeclarativeGridView); + const int count = d->model ? d->model->count() : 0; + if (!count) + return; if (d->flow == QDeclarativeGridView::LeftToRight) { if (currentIndex() >= d->columns || d->wrap) { int index = currentIndex() - d->columns; - setCurrentIndex(index >= 0 ? index : d->model->count()-1); + setCurrentIndex((index >= 0 && index < count) ? index : count-1); } } else { if (currentIndex() > 0 || d->wrap) { int index = currentIndex() - 1; - setCurrentIndex(index >= 0 ? index : d->model->count()-1); + setCurrentIndex((index >= 0 && index < count) ? index : count-1); } } } @@ -2008,22 +2020,25 @@ void QDeclarativeGridView::moveCurrentIndexUp() Move the currentIndex down one item in the view. The current index will wrap if keyNavigationWraps is true and it - is currently at the end. + is currently at the end. This method has no effect if the \l count is zero. \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeGridView::moveCurrentIndexDown() { Q_D(QDeclarativeGridView); + const int count = d->model ? d->model->count() : 0; + if (!count) + return; if (d->flow == QDeclarativeGridView::LeftToRight) { - if (currentIndex() < d->model->count() - d->columns || d->wrap) { + if (currentIndex() < count - d->columns || d->wrap) { int index = currentIndex()+d->columns; - setCurrentIndex(index < d->model->count() ? index : 0); + setCurrentIndex((index >= 0 && index < count) ? index : 0); } } else { - if (currentIndex() < d->model->count() - 1 || d->wrap) { + if (currentIndex() < count - 1 || d->wrap) { int index = currentIndex() + 1; - setCurrentIndex(index < d->model->count() ? index : 0); + setCurrentIndex((index >= 0 && index < count) ? index : 0); } } } @@ -2033,22 +2048,25 @@ void QDeclarativeGridView::moveCurrentIndexDown() Move the currentIndex left one item in the view. The current index will wrap if keyNavigationWraps is true and it - is currently at the end. + is currently at the end. This method has no effect if the \l count is zero. \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeGridView::moveCurrentIndexLeft() { Q_D(QDeclarativeGridView); + const int count = d->model ? d->model->count() : 0; + if (!count) + return; if (d->flow == QDeclarativeGridView::LeftToRight) { if (currentIndex() > 0 || d->wrap) { int index = currentIndex() - 1; - setCurrentIndex(index >= 0 ? index : d->model->count()-1); + setCurrentIndex((index >= 0 && index < count) ? index : count-1); } } else { if (currentIndex() >= d->columns || d->wrap) { int index = currentIndex() - d->columns; - setCurrentIndex(index >= 0 ? index : d->model->count()-1); + setCurrentIndex((index >= 0 && index < count) ? index : count-1); } } } @@ -2058,22 +2076,25 @@ void QDeclarativeGridView::moveCurrentIndexLeft() Move the currentIndex right one item in the view. The current index will wrap if keyNavigationWraps is true and it - is currently at the end. + is currently at the end. This method has no effect if the \l count is zero. \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeGridView::moveCurrentIndexRight() { Q_D(QDeclarativeGridView); + const int count = d->model ? d->model->count() : 0; + if (!count) + return; if (d->flow == QDeclarativeGridView::LeftToRight) { - if (currentIndex() < d->model->count() - 1 || d->wrap) { + if (currentIndex() < count - 1 || d->wrap) { int index = currentIndex() + 1; - setCurrentIndex(index < d->model->count() ? index : 0); + setCurrentIndex((index >= 0 && index < count) ? index : 0); } } else { - if (currentIndex() < d->model->count() - d->columns || d->wrap) { + if (currentIndex() < count - d->columns || d->wrap) { int index = currentIndex()+d->columns; - setCurrentIndex(index < d->model->count() ? index : 0); + setCurrentIndex((index >= 0 && index < count) ? index : 0); } } } @@ -2201,7 +2222,7 @@ void QDeclarativeGridView::componentComplete() if (d->isValid()) { refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; - if (d->currentIndex < 0) + if (d->currentIndex < 0 && !d->currentIndexSet) d->updateCurrent(0); else d->updateCurrent(d->currentIndex); @@ -2282,7 +2303,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) if (d->currentItem) d->currentItem->index = d->currentIndex; emit currentIndexChanged(); - } else if (d->currentIndex < 0) { + } else if (d->currentIndex < 0 && !d->currentIndexSet) { d->updateCurrent(0); } d->itemCount += count; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 6fd3b71..7dd5c75 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -182,7 +182,8 @@ public: , bufferMode(BufferBefore | BufferAfter) , ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false) , correctFlick(false), inFlickCorrection(false), lazyRelease(false) - , deferredRelease(false), layoutScheduled(false), minExtentDirty(true), maxExtentDirty(true) + , deferredRelease(false), layoutScheduled(false), currentIndexSet(false) + , minExtentDirty(true), maxExtentDirty(true) {} void init(); @@ -544,6 +545,7 @@ public: bool lazyRelease : 1; bool deferredRelease : 1; bool layoutScheduled : 1; + bool currentIndexSet : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; }; @@ -881,6 +883,7 @@ void QDeclarativeListViewPrivate::createHighlight() } else { highlight->item->setWidth(currentItem->item->width()); } + highlight->setPosition(currentItem->itemPosition()); } QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); @@ -1045,8 +1048,11 @@ void QDeclarativeListViewPrivate::updateCurrent(int modelIndex) currentItem->attached->setIsCurrentItem(false); releaseItem(currentItem); currentItem = 0; - currentIndex = -1; + currentIndex = modelIndex; + emit q->currentIndexChanged(); updateHighlight(); + } else if (currentIndex != modelIndex) { + currentIndex = modelIndex; emit q->currentIndexChanged(); } return; @@ -1598,7 +1604,7 @@ void QDeclarativeListView::setModel(const QVariant &model) if (isComponentComplete()) { updateSections(); refill(); - if (d->currentIndex >= d->model->count() || d->currentIndex < 0) { + if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexSet) { setCurrentIndex(0); } else { d->moveReason = QDeclarativeListViewPrivate::SetIndex; @@ -1708,10 +1714,13 @@ void QDeclarativeListView::setCurrentIndex(int index) Q_D(QDeclarativeListView); if (d->requestedIndex >= 0) // currently creating item return; - if (isComponentComplete() && d->isValid() && index != d->currentIndex && index < d->model->count() && index >= 0) { + d->currentIndexSet = true; + if (index == d->currentIndex) + return; + if (isComponentComplete() && d->isValid()) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; d->updateCurrent(index); - } else if (index != d->currentIndex) { + } else { d->currentIndex = index; emit currentIndexChanged(); } @@ -2523,16 +2532,18 @@ void QDeclarativeListView::geometryChanged(const QRectF &newGeometry, Increments the current index. The current index will wrap if keyNavigationWraps is true and it is currently at the end. + This method has no effect if the \l count is zero. \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeListView::incrementCurrentIndex() { Q_D(QDeclarativeListView); - if (currentIndex() < d->model->count() - 1 || d->wrap) { + int count = d->model ? d->model->count() : 0; + if (count && (currentIndex() < count - 1 || d->wrap)) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; int index = currentIndex()+1; - d->updateCurrent(index < d->model->count() ? index : 0); + d->updateCurrent((index >= 0 && index < count) ? index : 0); } } @@ -2541,16 +2552,18 @@ void QDeclarativeListView::incrementCurrentIndex() Decrements the current index. The current index will wrap if keyNavigationWraps is true and it is currently at the beginning. + This method has no effect if the \l count is zero. \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeListView::decrementCurrentIndex() { Q_D(QDeclarativeListView); - if (currentIndex() > 0 || d->wrap) { + int count = d->model ? d->model->count() : 0; + if (count && (currentIndex() > 0 || d->wrap)) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; int index = currentIndex()-1; - d->updateCurrent(index >= 0 ? index : d->model->count()-1); + d->updateCurrent((index >= 0 && index < count) ? index : count-1); } } @@ -2684,7 +2697,7 @@ void QDeclarativeListView::componentComplete() if (d->isValid()) { refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; - if (d->currentIndex < 0) + if (d->currentIndex < 0 && !d->currentIndexSet) d->updateCurrent(0); else d->updateCurrent(d->currentIndex); @@ -2790,7 +2803,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) if (d->currentItem) d->currentItem->index = d->currentIndex; emit currentIndexChanged(); - } else if (d->currentIndex < 0) { + } else if (d->currentIndex < 0 && !d->currentIndexSet) { d->updateCurrent(0); } d->itemCount += count; diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 308aefa..0717b78 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -270,6 +270,7 @@ void QDeclarativeTextPrivate::updateSize() internalWidthUpdate = false; q->setImplicitHeight(size.height()); emit q->paintedSizeChanged(); + q->update(); } /*! @@ -1143,9 +1144,10 @@ QRectF QDeclarativeText::boundingRect() const void QDeclarativeText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QDeclarativeText); - if (!d->internalWidthUpdate && newGeometry.width() != oldGeometry.width() && - (d->wrapMode != QDeclarativeText::NoWrap || d->elideMode != QDeclarativeText::ElideNone)) { - + if ((!d->internalWidthUpdate && newGeometry.width() != oldGeometry.width()) + && (d->wrapMode != QDeclarativeText::NoWrap + || d->elideMode != QDeclarativeText::ElideNone + || d->hAlign != Qt::AlignLeft)) { if (d->singleline && d->elideMode != QDeclarativeText::ElideNone && widthValid()) { // We need to re-elide d->updateLayout(); diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp index 5d73d89..a4ecc77 100644 --- a/src/declarative/qml/qdeclarativecompileddata.cpp +++ b/src/declarative/qml/qdeclarativecompileddata.cpp @@ -205,7 +205,7 @@ const QMetaObject *QDeclarativeCompiledData::TypeReference::metaObject() const return type->metaObject(); } else { Q_ASSERT(component); - return static_cast<QDeclarativeComponentPrivate *>(QObjectPrivate::get(component))->cc->root; + return component->root; } } diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 74bc5bd..b2740b8 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -590,7 +590,7 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, COMPILE_EXCEPTION(parserRef->refObjects.first(), err); } } else if (tref.typeData) { - ref.component = tref.typeData->component(); + ref.component = tref.typeData->compiledData(); ref.ref = tref.typeData; ref.ref->addref(); } @@ -722,7 +722,7 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) obj->metatype = tr.metaObject(); if (tr.component) - obj->url = tr.component->url(); + obj->url = tr.component->url; if (tr.type) obj->typeName = tr.type->qmlTypeName(); obj->className = tr.className; @@ -940,7 +940,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) // ### Surely the creation of this property cache could be more efficient QDeclarativePropertyCache *propertyCache = 0; if (tr.component) - propertyCache = QDeclarativeComponentPrivate::get(tr.component)->cc->rootPropertyCache->copy(); + propertyCache = tr.component->rootPropertyCache->copy(); else propertyCache = enginePrivate->cache(obj->metaObject()->superClass())->copy(); @@ -957,7 +957,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) output->bytecode << meta; } else if (obj == unitRoot) { if (tr.component) - output->rootPropertyCache = QDeclarativeComponentPrivate::get(tr.component)->cc->rootPropertyCache; + output->rootPropertyCache = tr.component->rootPropertyCache; else output->rootPropertyCache = enginePrivate->cache(obj->metaObject()); diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index 89eef09..43a0901 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -93,10 +93,11 @@ public: QByteArray className; QDeclarativeType *type; - QDeclarativeComponent *component; +// QDeclarativeComponent *component; + QDeclarativeCompiledData *component; QDeclarativeRefCount *ref; - QObject *createInstance(QDeclarativeContextData *, const QBitField &) const; + QObject *createInstance(QDeclarativeContextData *, const QBitField &, QList<QDeclarativeError> *) const; const QMetaObject *metaObject() const; }; QList<TypeReference> types; diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index cfef9cf..0a2a6db 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -733,48 +733,45 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons return 0; } - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); + return begin(context, creationContext, cc, start, count, &state, 0, bindings); +} + +QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentContext, + QDeclarativeContextData *componentCreationContext, + QDeclarativeCompiledData *component, int start, int count, + ConstructionState *state, QList<QDeclarativeError> *errors, + const QBitField &bindings) +{ + QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(parentContext->engine); + bool isRoot = !enginePriv->inBeginCreate; + + Q_ASSERT(!isRoot || state); // Either this isn't a root component, or a state data must be provided + Q_ASSERT((state != 0) ^ (errors != 0)); // One of state or errors (but not both) must be provided - bool isRoot = !ep->inBeginCreate; if (isRoot) QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating); - QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, cc->url); QDeclarativeContextData *ctxt = new QDeclarativeContextData; ctxt->isInternal = true; - ctxt->url = cc->url; - ctxt->imports = cc->importCache; + ctxt->url = component->url; + ctxt->imports = component->importCache; // Nested global imports - if (creationContext && start != -1) - ctxt->importedScripts = creationContext->importedScripts; - - cc->importCache->addref(); - ctxt->setParent(context); + if (componentCreationContext && start != -1) + ctxt->importedScripts = componentCreationContext->importedScripts; - QObject *rv = begin(ctxt, ep, cc, start, count, &state, bindings); + component->importCache->addref(); + ctxt->setParent(parentContext); - if (ep->isDebugging && rv) { - if (!context->isInternal) - context->asQDeclarativeContextPrivate()->instances.append(rv); - QDeclarativeEngineDebugServer::instance()->objectCreated(engine, rv); - } - - return rv; -} - -QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, - QDeclarativeCompiledData *component, int start, int count, - ConstructionState *state, const QBitField &bindings) -{ - bool isRoot = !enginePriv->inBeginCreate; enginePriv->inBeginCreate = true; QDeclarativeVME vme; QObject *rv = vme.run(ctxt, component, start, count, bindings); - if (vme.isError()) - state->errors = vme.errors(); + if (vme.isError()) { + if(errors) *errors = vme.errors(); + else state->errors = vme.errors(); + } if (isRoot) { enginePriv->inBeginCreate = false; @@ -794,6 +791,12 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDe enginePriv->inProgressCreations++; } + if (enginePriv->isDebugging && rv) { + if (!parentContext->isInternal) + parentContext->asQDeclarativeContextPrivate()->instances.append(rv); + QDeclarativeEngineDebugServer::instance()->objectCreated(parentContext->engine, rv); + } + return rv; } diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index a551cc8..7b30bad 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -109,9 +109,10 @@ public: }; ConstructionState state; - static QObject *begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, - QDeclarativeCompiledData *component, int start, int count, - ConstructionState *state, const QBitField &bindings = QBitField()); + static QObject *begin(QDeclarativeContextData *parentContext, QDeclarativeContextData *componentCreationContext, + QDeclarativeCompiledData *component, int start, int count, + ConstructionState *state, QList<QDeclarativeError> *errors, + const QBitField &bindings = QBitField()); static void beginDeferred(QDeclarativeEnginePrivate *enginePriv, QObject *object, ConstructionState *state); static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 61a1f55..ea92111 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -838,9 +838,19 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass:: { MethodData *method = static_cast<MethodData *>(o); - if (method->data.flags & QDeclarativePropertyCache::Data::HasArguments) { + if (method->data.relatedIndex == -1) + return callPrecise(method->object, method->data, ctxt); + else + return callOverloaded(method, ctxt); +} - QMetaMethod m = method->object->metaObject()->method(method->data.coreIndex); +QDeclarativeObjectMethodScriptClass::Value +QDeclarativeObjectMethodScriptClass::callPrecise(QObject *object, const QDeclarativePropertyCache::Data &data, + QScriptContext *ctxt) +{ + if (data.flags & QDeclarativePropertyCache::Data::HasArguments) { + + QMetaMethod m = object->metaObject()->method(data.coreIndex); QList<QByteArray> argTypeNames = m.parameterTypes(); QVarLengthArray<int, 9> argTypes(argTypeNames.count()); @@ -848,7 +858,7 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass:: for (int ii = 0; ii < argTypeNames.count(); ++ii) { argTypes[ii] = QMetaType::type(argTypeNames.at(ii)); if (argTypes[ii] == QVariant::Invalid) - argTypes[ii] = enumType(method->object->metaObject(), QString::fromLatin1(argTypeNames.at(ii))); + argTypes[ii] = enumType(object->metaObject(), QString::fromLatin1(argTypeNames.at(ii))); if (argTypes[ii] == QVariant::Invalid) return Value(ctxt, ctxt->throwError(QString::fromLatin1("Unknown method parameter type: %1").arg(QLatin1String(argTypeNames.at(ii))))); } @@ -856,39 +866,301 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass:: if (argTypes.count() > ctxt->argumentCount()) return Value(ctxt, ctxt->throwError(QLatin1String("Insufficient arguments"))); - QVarLengthArray<MetaCallArgument, 9> args(argTypes.count() + 1); - args[0].initAsType(method->data.propType, engine); + return callMethod(object, data.coreIndex, data.propType, argTypes.count(), argTypes.data(), ctxt); + + } else { + + return callMethod(object, data.coreIndex, data.propType, 0, 0, ctxt); + + } +} + +QDeclarativeObjectMethodScriptClass::Value +QDeclarativeObjectMethodScriptClass::callMethod(QObject *object, int index, + int returnType, int argCount, int *argTypes, + QScriptContext *ctxt) +{ + if (argCount > 0) { - for (int ii = 0; ii < argTypes.count(); ++ii) + QVarLengthArray<MetaCallArgument, 9> args(argCount + 1); + args[0].initAsType(returnType, engine); + + for (int ii = 0; ii < argCount; ++ii) args[ii + 1].fromScriptValue(argTypes[ii], engine, ctxt->argument(ii)); QVarLengthArray<void *, 9> argData(args.count()); for (int ii = 0; ii < args.count(); ++ii) argData[ii] = args[ii].dataPtr(); - QMetaObject::metacall(method->object, QMetaObject::InvokeMetaMethod, method->data.coreIndex, argData.data()); + QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data()); return args[0].toValue(engine); - } else if (method->data.propType != 0) { - + } else if (returnType != 0) { + MetaCallArgument arg; - arg.initAsType(method->data.propType, engine); + arg.initAsType(returnType, engine); void *args[] = { arg.dataPtr() }; - QMetaObject::metacall(method->object, QMetaObject::InvokeMetaMethod, method->data.coreIndex, args); + QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args); return arg.toValue(engine); } else { void *args[] = { 0 }; - QMetaObject::metacall(method->object, QMetaObject::InvokeMetaMethod, method->data.coreIndex, args); + QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args); return Value(); } - return Value(); +} + +/*! +Resolve the overloaded method to call. The algorithm works conceptually like this: + 1. Resolve the set of overloads it is *possible* to call. + Impossible overloads include those that have too many parameters or have parameters + of unknown type. + 2. Filter the set of overloads to only contain those with the closest number of + parameters. + For example, if we are called with 3 parameters and there are 2 overloads that + take 2 parameters and one that takes 3, eliminate the 2 parameter overloads. + 3. Find the best remaining overload based on its match score. + If two or more overloads have the same match score, call the last one. The match + score is constructed by adding the matchScore() result for each of the parameters. +*/ +QDeclarativeObjectMethodScriptClass::Value +QDeclarativeObjectMethodScriptClass::callOverloaded(MethodData *method, QScriptContext *ctxt) +{ + int argumentCount = ctxt->argumentCount(); + + QDeclarativePropertyCache::Data *best = 0; + int bestParameterScore = INT_MAX; + int bestMatchScore = INT_MAX; + + QDeclarativePropertyCache::Data dummy; + QDeclarativePropertyCache::Data *attempt = &method->data; + + do { + QList<QByteArray> methodArgTypeNames; + + if (attempt->flags & QDeclarativePropertyCache::Data::HasArguments) + methodArgTypeNames = method->object->metaObject()->method(attempt->coreIndex).parameterTypes(); + + int methodArgumentCount = methodArgTypeNames.count(); + + if (methodArgumentCount > argumentCount) + continue; // We don't have sufficient arguments to call this method + + int methodParameterScore = argumentCount - methodArgumentCount; + if (methodParameterScore > bestParameterScore) + continue; // We already have a better option + + int methodMatchScore = 0; + QVarLengthArray<int, 9> methodArgTypes(methodArgumentCount); + + bool unknownArgument = false; + for (int ii = 0; ii < methodArgumentCount; ++ii) { + methodArgTypes[ii] = QMetaType::type(methodArgTypeNames.at(ii)); + if (methodArgTypes[ii] == QVariant::Invalid) + methodArgTypes[ii] = enumType(method->object->metaObject(), + QString::fromLatin1(methodArgTypeNames.at(ii))); + if (methodArgTypes[ii] == QVariant::Invalid) { + unknownArgument = true; + break; + } + methodMatchScore += matchScore(ctxt->argument(ii), methodArgTypes[ii], methodArgTypeNames.at(ii)); + } + if (unknownArgument) + continue; // We don't understand all the parameters + + if (bestParameterScore > methodParameterScore || bestMatchScore > methodMatchScore) { + best = attempt; + bestParameterScore = methodParameterScore; + bestMatchScore = methodMatchScore; + } + + if (bestParameterScore == 0 && bestMatchScore == 0) + break; // We can't get better than that + + } while((attempt = relatedMethod(method->object, attempt, dummy)) != 0); + + if (best) { + return callPrecise(method->object, *best, ctxt); + } else { + QString error = QLatin1String("Unable to determine callable overload. Candidates are:"); + QDeclarativePropertyCache::Data *candidate = &method->data; + while (candidate) { + error += QLatin1String("\n ") + QString::fromUtf8(method->object->metaObject()->method(candidate->coreIndex).signature()); + candidate = relatedMethod(method->object, candidate, dummy); + } + return Value(ctxt, ctxt->throwError(error)); + } +} + +/*! + Returns the match score for converting \a actual to be of type \a conversionType. A + zero score means "perfect match" whereas a higher score is worse. + + The conversion table is copied out of the QtScript callQtMethod() function. +*/ +int QDeclarativeObjectMethodScriptClass::matchScore(const QScriptValue &actual, int conversionType, + const QByteArray &conversionTypeName) +{ + if (actual.isNumber()) { + switch (conversionType) { + case QMetaType::Double: + return 0; + case QMetaType::Float: + return 1; + case QMetaType::LongLong: + case QMetaType::ULongLong: + return 2; + case QMetaType::Long: + case QMetaType::ULong: + return 3; + case QMetaType::Int: + case QMetaType::UInt: + return 4; + case QMetaType::Short: + case QMetaType::UShort: + return 5; + break; + case QMetaType::Char: + case QMetaType::UChar: + return 6; + default: + return 10; + } + } else if (actual.isString()) { + switch (conversionType) { + case QMetaType::QString: + return 0; + default: + return 10; + } + } else if (actual.isBoolean()) { + switch (conversionType) { + case QMetaType::Bool: + return 0; + default: + return 10; + } + } else if (actual.isDate()) { + switch (conversionType) { + case QMetaType::QDateTime: + return 0; + case QMetaType::QDate: + return 1; + case QMetaType::QTime: + return 2; + default: + return 10; + } + } else if (actual.isRegExp()) { + switch (conversionType) { + case QMetaType::QRegExp: + return 0; + default: + return 10; + } + } else if (actual.isVariant()) { + if (conversionType == qMetaTypeId<QVariant>()) + return 0; + else if (actual.toVariant().userType() == conversionType) + return 0; + else + return 10; + } else if (actual.isArray()) { + switch (conversionType) { + case QMetaType::QStringList: + case QMetaType::QVariantList: + return 5; + default: + return 10; + } + } else if (actual.isQObject()) { + switch (conversionType) { + case QMetaType::QObjectStar: + return 0; + default: + return 10; + } + } else if (actual.isNull()) { + switch (conversionType) { + case QMetaType::VoidStar: + case QMetaType::QObjectStar: + return 0; + default: + if (!conversionTypeName.endsWith('*')) + return 10; + else + return 0; + } + } else { + return 10; + } +} + +static inline int QMetaObject_methods(const QMetaObject *metaObject) +{ + struct Private + { + int revision; + int className; + int classInfoCount, classInfoData; + int methodCount, methodData; + }; + + return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount; +} + +static QByteArray QMetaMethod_name(const QMetaMethod &m) +{ + QByteArray sig = m.signature(); + int paren = sig.indexOf('('); + if (paren == -1) + return sig; + else + return sig.left(paren); +} + +/*! +Returns the next related method, if one, or 0. +*/ +QDeclarativePropertyCache::Data * +QDeclarativeObjectMethodScriptClass::relatedMethod(QObject *object, QDeclarativePropertyCache::Data *current, + QDeclarativePropertyCache::Data &dummy) +{ + QDeclarativePropertyCache *cache = QDeclarativeData::get(object)->propertyCache; + if (current->relatedIndex == -1) + return 0; + + if (cache) { + return cache->method(current->relatedIndex); + } else { + const QMetaObject *mo = object->metaObject(); + int methodOffset = mo->methodCount() - QMetaObject_methods(mo); + + while (methodOffset > current->relatedIndex) { + mo = mo->superClass(); + methodOffset -= QMetaObject_methods(mo); + } + + QMetaMethod method = mo->method(current->relatedIndex); + dummy.load(method); + + // Look for overloaded methods + QByteArray methodName = QMetaMethod_name(method); + for (int ii = current->relatedIndex - 1; ii >= methodOffset; --ii) { + if (methodName == QMetaMethod_name(mo->method(ii))) { + dummy.relatedIndex = ii; + return &dummy; + } + } + + return &dummy; + } } QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h index 75e384c..7956c40 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h @@ -65,6 +65,7 @@ class QDeclarativeEngine; class QScriptContext; class QScriptEngine; class QDeclarativeContextData; +class MethodData; class Q_AUTOTEST_EXPORT QDeclarativeObjectMethodScriptClass : public QScriptDeclarativeClass { @@ -82,6 +83,14 @@ protected: private: int enumType(const QMetaObject *, const QString &); + Value callPrecise(QObject *, const QDeclarativePropertyCache::Data &, QScriptContext *); + Value callOverloaded(MethodData *, QScriptContext *); + Value callMethod(QObject *, int index, int returnType, int argCount, int *argTypes, QScriptContext *ctxt); + + int matchScore(const QScriptValue &, int, const QByteArray &); + QDeclarativePropertyCache::Data *relatedMethod(QObject *, QDeclarativePropertyCache::Data *current, + QDeclarativePropertyCache::Data &dummy); + PersistentIdentifier m_connectId; PersistentIdentifier m_disconnectId; QScriptValue m_connect; diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 9e1ceb8..91aaaa4 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -93,6 +93,7 @@ void QDeclarativePropertyCache::Data::load(const QMetaProperty &p, QDeclarativeE void QDeclarativePropertyCache::Data::load(const QMetaMethod &m) { coreIndex = m.methodIndex(); + relatedIndex = -1; flags |= Data::IsFunction; if (m.methodType() == QMetaMethod::Signal) flags |= Data::IsSignal; @@ -140,15 +141,25 @@ void QDeclarativePropertyCache::clear() if (indexCache.at(ii)) indexCache.at(ii)->release(); } + for (int ii = 0; ii < methodIndexCache.count(); ++ii) { + RData *data = methodIndexCache.at(ii); + if (data) data->release(); + } + for (StringCache::ConstIterator iter = stringCache.begin(); - iter != stringCache.end(); ++iter) - (*iter)->release(); + iter != stringCache.end(); ++iter) { + RData *data = (*iter); + data->release(); + } for (IdentifierCache::ConstIterator iter = identifierCache.begin(); - iter != identifierCache.end(); ++iter) - (*iter)->release(); + iter != identifierCache.end(); ++iter) { + RData *data = (*iter); + data->release(); + } indexCache.clear(); + methodIndexCache.clear(); stringCache.clear(); identifierCache.clear(); } @@ -202,12 +213,16 @@ QDeclarativePropertyCache *QDeclarativePropertyCache::copy() const { QDeclarativePropertyCache *cache = new QDeclarativePropertyCache(engine); cache->indexCache = indexCache; + cache->methodIndexCache = methodIndexCache; cache->stringCache = stringCache; cache->identifierCache = identifierCache; for (int ii = 0; ii < indexCache.count(); ++ii) { if (indexCache.at(ii)) indexCache.at(ii)->addref(); } + for (int ii = 0; ii < methodIndexCache.count(); ++ii) { + if (methodIndexCache.at(ii)) methodIndexCache.at(ii)->addref(); + } for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter) (*iter)->addref(); for (IdentifierCache::ConstIterator iter = identifierCache.begin(); iter != identifierCache.end(); ++iter) @@ -227,19 +242,18 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb indexCache.resize(propCount); for (int ii = propOffset; ii < propCount; ++ii) { QMetaProperty p = metaObject->property(ii); - if (!p.isScriptable()) + if (!p.isScriptable()) continue; QString propName = QString::fromUtf8(p.name()); RData *data = new RData; data->identifier = enginePriv->objectClass->createPersistentIdentifier(propName); + indexCache[ii] = data; data->load(p, engine); data->flags |= propertyFlags; - indexCache[ii] = data; - if (stringCache.contains(propName)) { stringCache[propName]->release(); identifierCache[data->identifier.identifier]->release(); @@ -252,12 +266,13 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb } int methodCount = metaObject->methodCount(); - int methodOffset = qMax(2, metaObject->methodOffset()); // 2 to block the destroyed signal + // 3 to block the destroyed signal and the deleteLater() slot + int methodOffset = qMax(3, metaObject->methodOffset()); methodIndexCache.resize(methodCount); for (int ii = methodOffset; ii < methodCount; ++ii) { QMetaMethod m = metaObject->method(ii); - if (m.access() == QMetaMethod::Private) + if (m.access() == QMetaMethod::Private) continue; QString methodName = QString::fromUtf8(m.signature()); @@ -267,11 +282,7 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb RData *data = new RData; data->identifier = enginePriv->objectClass->createPersistentIdentifier(methodName); - - if (stringCache.contains(methodName)) { - stringCache[methodName]->release(); - identifierCache[data->identifier.identifier]->release(); - } + methodIndexCache[ii] = data; data->load(m); if (m.methodType() == QMetaMethod::Slot || m.methodType() == QMetaMethod::Method) @@ -279,14 +290,32 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb else if (m.methodType() == QMetaMethod::Signal) data->flags |= signalFlags; - methodIndexCache[ii] = data; + if (stringCache.contains(methodName)) { + RData *old = stringCache[methodName]; + // We only overload methods in the same class, exactly like C++ + if (old->flags & Data::IsFunction && old->coreIndex >= methodOffset) + data->relatedIndex = old->coreIndex; + stringCache[methodName]->release(); + identifierCache[data->identifier.identifier]->release(); + } stringCache.insert(methodName, data); identifierCache.insert(data->identifier.identifier, data); data->addref(); + data->addref(); } } +void QDeclarativePropertyCache::updateRecur(QDeclarativeEngine *engine, const QMetaObject *metaObject) +{ + if (!metaObject) + return; + + updateRecur(engine, metaObject->superClass()); + + append(engine, metaObject); +} + void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaObject *metaObject) { Q_ASSERT(engine); @@ -295,57 +324,11 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb clear(); - // ### The properties/methods should probably be spliced on a per-metaobject basis - int propCount = metaObject->propertyCount(); - - indexCache.resize(propCount); - for (int ii = propCount - 1; ii >= 0; --ii) { - QMetaProperty p = metaObject->property(ii); - if (!p.isScriptable()) { - indexCache[ii] = 0; - continue; - } - QString propName = QString::fromUtf8(p.name()); - - RData *data = new RData; - data->identifier = enginePriv->objectClass->createPersistentIdentifier(propName); - - data->load(p, engine); - - indexCache[ii] = data; - - if (stringCache.contains(propName)) - continue; - - stringCache.insert(propName, data); - identifierCache.insert(data->identifier.identifier, data); - data->addref(); - data->addref(); - } - - int methodCount = metaObject->methodCount(); - for (int ii = methodCount - 1; ii >= 3; --ii) { // >=3 to block the destroyed signal and deleteLater() slot - QMetaMethod m = metaObject->method(ii); - if (m.access() == QMetaMethod::Private) - continue; - QString methodName = QString::fromUtf8(m.signature()); - - int parenIdx = methodName.indexOf(QLatin1Char('(')); - Q_ASSERT(parenIdx != -1); - methodName = methodName.left(parenIdx); - - if (stringCache.contains(methodName)) - continue; + // Optimization to prevent unnecessary reallocation of lists + indexCache.reserve(metaObject->propertyCount()); + methodIndexCache.reserve(metaObject->methodCount()); - RData *data = new RData; - data->identifier = enginePriv->objectClass->createPersistentIdentifier(methodName); - - data->load(m); - - stringCache.insert(methodName, data); - identifierCache.insert(data->identifier.identifier, data); - data->addref(); - } + updateRecur(engine,metaObject); } QDeclarativePropertyCache::Data * diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 79b126d..922010d 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -96,7 +96,7 @@ public: IsVMEFunction = 0x00000400, HasArguments = 0x00000800, IsSignal = 0x00001000, - IsVMESignal = 0x00002000, + IsVMESignal = 0x00002000 }; Q_DECLARE_FLAGS(Flags, Flag) @@ -105,7 +105,10 @@ public: Flags flags; int propType; int coreIndex; - int notifyIndex; + union { + int notifyIndex; // When !IsFunction + int relatedIndex; // When IsFunction + }; static Flags flagsForProperty(const QMetaProperty &, QDeclarativeEngine *engine = 0); void load(const QMetaProperty &, QDeclarativeEngine *engine = 0); @@ -152,6 +155,8 @@ private: typedef QHash<QString, RData *> StringCache; typedef QHash<QScriptDeclarativeClass::Identifier, RData *> IdentifierCache; + void updateRecur(QDeclarativeEngine *, const QMetaObject *); + QDeclarativeEngine *engine; IndexCache indexCache; IndexCache methodIndexCache; diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp index c8e1a07..c015519 100644 --- a/src/declarative/qml/qdeclarativetypeloader.cpp +++ b/src/declarative/qml/qdeclarativetypeloader.cpp @@ -719,7 +719,7 @@ void QDeclarativeTypeLoader::clearCache() QDeclarativeTypeData::QDeclarativeTypeData(const QUrl &url, QDeclarativeTypeLoader::Options options, QDeclarativeTypeLoader *manager) : QDeclarativeDataBlob(url, QmlFile), m_options(options), m_typesResolved(false), - m_compiledData(0), m_component(0), m_typeLoader(manager) + m_compiledData(0), m_typeLoader(manager) { } @@ -768,23 +768,6 @@ QDeclarativeCompiledData *QDeclarativeTypeData::compiledData() const return m_compiledData; } -QDeclarativeComponent *QDeclarativeTypeData::component() const -{ - if (!m_component) { - - if (m_compiledData) { - m_component = new QDeclarativeComponent(typeLoader()->engine(), m_compiledData, -1, -1, 0); - } else { - m_component = new QDeclarativeComponent(typeLoader()->engine()); - QDeclarativeComponentPrivate::get(m_component)->url = finalUrl(); - QDeclarativeComponentPrivate::get(m_component)->state.errors = errors(); - } - - } - - return m_component; -} - void QDeclarativeTypeData::registerCallback(TypeDataCallback *callback) { Q_ASSERT(!m_callbacks.contains(callback)); diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h index 7381f28..718537a 100644 --- a/src/declarative/qml/qdeclarativetypeloader_p.h +++ b/src/declarative/qml/qdeclarativetypeloader_p.h @@ -243,7 +243,6 @@ public: const QList<ScriptReference> &resolvedScripts() const; QDeclarativeCompiledData *compiledData() const; - QDeclarativeComponent *component() const; // Used by QDeclarativeComponent to get notifications struct TypeDataCallback { @@ -278,7 +277,6 @@ private: bool m_typesResolved:1; QDeclarativeCompiledData *m_compiledData; - mutable QDeclarativeComponent *m_component; QList<TypeDataCallback *> m_callbacks; diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 360186c..db90aff 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -185,12 +185,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, bindings = bindings.united(bindingSkipList); QObject *o = - types.at(instr.create.type).createInstance(ctxt, bindings); + types.at(instr.create.type).createInstance(ctxt, bindings, &vmeErrors); if (!o) { - if(types.at(instr.create.type).component) - vmeErrors << types.at(instr.create.type).component->errors(); - VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(QString::fromLatin1(types.at(instr.create.type).className))); } @@ -933,8 +930,9 @@ QList<QDeclarativeError> QDeclarativeVME::errors() const } QObject * -QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData *ctxt, - const QBitField &bindings) const +QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData *ctxt, + const QBitField &bindings, + QList<QDeclarativeError> *errors) const { if (type) { QObject *rv = 0; @@ -948,7 +946,7 @@ QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData return rv; } else { Q_ASSERT(component); - return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings); + return QDeclarativeComponentPrivate::begin(ctxt, 0, component, -1, -1, 0, errors, bindings); } } diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index ad4b2b5..e43f7fa 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.cpp +++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp @@ -48,6 +48,7 @@ #include "qgraphicslayoutitem.h" #include "qgraphicslayoutitem_p.h" #include "qwidget.h" +#include "qgraphicswidget.h" #include <QtDebug> @@ -259,6 +260,52 @@ void QGraphicsLayoutItemPrivate::setSizeComponent( q->updateGeometry(); } + +bool QGraphicsLayoutItemPrivate::hasHeightForWidth() const +{ + Q_Q(const QGraphicsLayoutItem); + if (isLayout) { + const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q); + for (int i = l->count() - 1; i >= 0; --i) { + if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasHeightForWidth()) + return true; + } + } else if (QGraphicsItem *item = q->graphicsItem()) { + if (item->isWidget()) { + QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item); + if (w->layout()) { + return QGraphicsLayoutItemPrivate::get(w->layout())->hasHeightForWidth(); + } + } + } + return q->sizePolicy().hasHeightForWidth(); +} + +bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const +{ + // enable this code when we add QSizePolicy::hasWidthForHeight() (For 4.8) +#if 1 + return false; +#else + Q_Q(const QGraphicsLayoutItem); + if (isLayout) { + const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q); + for (int i = l->count() - 1; i >= 0; --i) { + if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasWidthForHeight()) + return true; + } + } else if (QGraphicsItem *item = q->graphicsItem()) { + if (item->isWidget()) { + QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item); + if (w->layout()) { + return QGraphicsLayoutItemPrivate::get(w->layout())->hasWidthForHeight(); + } + } + } + return q->sizePolicy().hasWidthForHeight(); +#endif +} + /*! \class QGraphicsLayoutItem \brief The QGraphicsLayoutItem class can be inherited to allow your custom diff --git a/src/gui/graphicsview/qgraphicslayoutitem_p.h b/src/gui/graphicsview/qgraphicslayoutitem_p.h index 15cc7a5..b752e03 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem_p.h +++ b/src/gui/graphicsview/qgraphicslayoutitem_p.h @@ -65,6 +65,9 @@ class Q_AUTOTEST_EXPORT QGraphicsLayoutItemPrivate public: virtual ~QGraphicsLayoutItemPrivate(); QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout); + static QGraphicsLayoutItemPrivate *get(QGraphicsLayoutItem *q) { return q->d_func();} + static const QGraphicsLayoutItemPrivate *get(const QGraphicsLayoutItem *q) { return q->d_func();} + void init(); QSizeF *effectiveSizeHints(const QSizeF &constraint) const; QGraphicsItem *parentItem() const; @@ -73,6 +76,9 @@ public: enum SizeComponent { Width, Height }; void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value); + bool hasHeightForWidth() const; + bool hasWidthForHeight() const; + QSizePolicy sizePolicy; QGraphicsLayoutItem *parent; diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index ae5bf90..e486b4d 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -545,6 +545,24 @@ QSizePolicy::Policy QGridLayoutItem::sizePolicy(Qt::Orientation orientation) con : sizePolicy.verticalPolicy(); } +/* + returns true if the size policy returns true for either hasHeightForWidth() + or hasWidthForHeight() + */ +bool QGridLayoutItem::hasDynamicConstraint() const +{ + return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth() + || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight(); +} + +Qt::Orientation QGridLayoutItem::dynamicConstraintOrientation() const +{ + if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()) + return Qt::Vertical; + else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight()) + return Qt::Horizontal; +} + QSizePolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /* side */) const { return q_layoutItem->sizePolicy().controlType(); @@ -613,7 +631,17 @@ QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal heig qreal cellWidth = width; qreal cellHeight = height; - QSizeF size = effectiveMaxSize().boundedTo(QSizeF(cellWidth, cellHeight)); + + QSizeF size = effectiveMaxSize(QSizeF(-1,-1)); + if (hasDynamicConstraint()) { + if (dynamicConstraintOrientation() == Qt::Vertical) { + if (size.width() > cellWidth) + size = effectiveMaxSize(QSizeF(cellWidth, -1)); + } else if(size.height() > cellHeight) { + size = effectiveMaxSize(QSizeF(-1, cellHeight)); + } + } + size = size.boundedTo(QSizeF(cellWidth, cellHeight)); width = size.width(); height = size.height(); @@ -675,13 +703,13 @@ void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation ori Note that effectiveSizeHint does not take sizePolicy into consideration, (since it only evaluates the hints, as the name implies) */ -QSizeF QGridLayoutItem::effectiveMaxSize() const +QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const { - QSizeF size; + QSizeF size = constraint; bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; if (!vGrow || !hGrow) { - QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize); + QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint); if (!vGrow) size.setHeight(pref.height()); if (!hGrow) @@ -689,7 +717,7 @@ QSizeF QGridLayoutItem::effectiveMaxSize() const } if (!size.isValid()) { - QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize); + QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, size); if (size.width() == -1) size.setWidth(maxSize.width()); if (size.height() == -1) @@ -1010,6 +1038,7 @@ void QGridLayoutEngine::invalidate() q_cachedEffectiveLastRows[Ver] = -1; q_cachedDataForStyleInfo.invalidate(); q_cachedSize = QSizeF(); + q_cachedConstraintOrientation = UnknownConstraint; } static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect) @@ -1074,19 +1103,78 @@ QRectF QGridLayoutEngine::cellRect(const QLayoutStyleInfo &styleInfo, } QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, - const QSizeF & /* constraint */) const + const QSizeF &constraint) const { - ensureColumnAndRowData(styleInfo); + QGridLayoutBox sizehint_totalBoxes[NOrientations]; + + if(rowCount() < 1 || columnCount() < 1 || !hasDynamicConstraint()) { + //No items with height for width, so it doesn't matter which order we do these in + if(q_cachedDataForStyleInfo != styleInfo) { + ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); + ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); + } else { + sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; + sizehint_totalBoxes[Ver] = q_totalBoxes[Ver]; + } + } else if(constraintOrientation() == Qt::Vertical) { + //We have items whose width depends on their height + if(q_cachedDataForStyleInfo != styleInfo) + ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); + else + sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; + QVector<qreal> sizehint_xx; + QVector<qreal> sizehint_widths; + + sizehint_xx.resize(columnCount()); + sizehint_widths.resize(columnCount()); + qreal width = constraint.width(); + if(width < 0) { + /* It's not obvious what the behaviour should be. */ +/* if(which == Qt::MaximumSize) + width = sizehint_totalBoxes[Hor].q_maximumSize; + else if(which == Qt::MinimumSize) + width = sizehint_totalBoxes[Hor].q_minimumSize; + else*/ + width = sizehint_totalBoxes[Hor].q_preferredSize; + } + //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as + //constraints to find the row heights + q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(), + 0, sizehint_totalBoxes[Hor]); + ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical); + } else { + //We have items whose height depends on their width + ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); + QVector<qreal> sizehint_yy; + QVector<qreal> sizehint_heights; + + sizehint_yy.resize(rowCount()); + sizehint_heights.resize(rowCount()); + qreal height = constraint.height(); + if(height < 0) { +/* if(which == Qt::MaximumSize) + height = sizehint_totalBoxes[Ver].q_maximumSize; + else if(which == Qt::MinimumSize) + height = sizehint_totalBoxes[Ver].q_minimumSize; + else*/ + height = sizehint_totalBoxes[Ver].q_preferredSize; + } + //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as + //constraints to find the column widths + q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(), + 0, sizehint_totalBoxes[Ver]); + ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, sizehint_yy.data(), sizehint_heights.data(), Qt::Vertical); + } switch (which) { case Qt::MinimumSize: - return QSizeF(q_totalBoxes[Hor].q_minimumSize, q_totalBoxes[Ver].q_minimumSize); + return QSizeF(sizehint_totalBoxes[Hor].q_minimumSize, sizehint_totalBoxes[Ver].q_minimumSize); case Qt::PreferredSize: - return QSizeF(q_totalBoxes[Hor].q_preferredSize, q_totalBoxes[Ver].q_preferredSize); + return QSizeF(sizehint_totalBoxes[Hor].q_preferredSize, sizehint_totalBoxes[Ver].q_preferredSize); case Qt::MaximumSize: - return QSizeF(q_totalBoxes[Hor].q_maximumSize, q_totalBoxes[Ver].q_maximumSize); + return QSizeF(sizehint_totalBoxes[Hor].q_maximumSize, sizehint_totalBoxes[Ver].q_maximumSize); case Qt::MinimumDescent: - return QSizeF(-1.0, q_totalBoxes[Hor].q_minimumDescent); // ### doesn't work + return QSizeF(-1.0, sizehint_totalBoxes[Hor].q_minimumDescent); // ### doesn't work default: break; } @@ -1262,6 +1350,7 @@ void QGridLayoutEngine::insertOrRemoveRows(int row, int delta, Qt::Orientation o } void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo, + qreal *colPositions, qreal *colSizes, Qt::Orientation orientation) const { const int ButtonMask = QSizePolicy::ButtonBox | QSizePolicy::PushButton; @@ -1375,7 +1464,21 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt box = &multiCell.q_box; multiCell.q_stretch = itemStretch; } - box->combine(item->box(orientation)); + // Items with constraints need to be passed the constraint + if (colSizes && colPositions && item->hasDynamicConstraint() && orientation == item->dynamicConstraintOrientation()) { + /* Get the width of the item by summing up the widths of the columns that it spans. + * We need to have already calculated the widths of the columns by calling + * q_columns->calculateGeometries() before hand and passing the value in the colSizes + * and colPositions parameters. + * The variable name is still colSizes even when it actually has the row sizes + */ + qreal length = colSizes[item->lastColumn(orientation)]; + if (item->columnSpan(orientation) != 1) + length += colPositions[item->lastColumn(orientation)] - colPositions[item->firstColumn(orientation)]; + box->combine(item->box(orientation, length)); + } else { + box->combine(item->box(orientation)); + } if (effectiveRowSpan == 1) { QSizePolicy::ControlTypes controls = item->controlTypes(top); @@ -1512,44 +1615,99 @@ void QGridLayoutEngine::ensureEffectiveFirstAndLastRows() const } } -void QGridLayoutEngine::ensureColumnAndRowData(const QLayoutStyleInfo &styleInfo) const +void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox, + const QLayoutStyleInfo &styleInfo, + qreal *colPositions, qreal *colSizes, + Qt::Orientation orientation) const { - if (q_cachedDataForStyleInfo == styleInfo) - return; - - q_columnData.reset(columnCount()); - q_rowData.reset(rowCount()); - - fillRowData(&q_columnData, styleInfo, Qt::Horizontal); - fillRowData(&q_rowData, styleInfo, Qt::Vertical); + rowData->reset(rowCount(orientation)); + fillRowData(rowData, styleInfo, colPositions, colSizes, orientation); + rowData->distributeMultiCells(); + *totalBox = rowData->totalBox(0, rowCount(orientation)); + //We have items whose width depends on their height +} - q_columnData.distributeMultiCells(); - q_rowData.distributeMultiCells(); +/** + returns false if the layout has contradicting constraints (i.e. some items with a horizontal + constraint and other items with a vertical constraint) + */ +bool QGridLayoutEngine::ensureDynamicConstraint() const +{ + if (q_cachedConstraintOrientation == UnknownConstraint) { + for (int i = q_items.count() - 1; i >= 0; --i) { + QGridLayoutItem *item = q_items.at(i); + if (item->hasDynamicConstraint()) { + Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation(); + if (q_cachedConstraintOrientation == UnknownConstraint) { + q_cachedConstraintOrientation = itemConstraintOrientation; + } else if (q_cachedConstraintOrientation != itemConstraintOrientation) { + q_cachedConstraintOrientation = UnfeasibleConstraint; + qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and" + " vertical constraint in the same layout"); + return false; + } + } + } + if (q_cachedConstraintOrientation == UnknownConstraint) + q_cachedConstraintOrientation = NoConstraint; + } + return true; +} - q_totalBoxes[Hor] = q_columnData.totalBox(0, columnCount()); - q_totalBoxes[Ver] = q_rowData.totalBox(0, rowCount()); +bool QGridLayoutEngine::hasDynamicConstraint() const +{ + if (!ensureDynamicConstraint()) + return false; + return q_cachedConstraintOrientation != NoConstraint; +} - q_cachedDataForStyleInfo = styleInfo; +/* + * return value is only valid if hasConstraint() returns true + */ +Qt::Orientation QGridLayoutEngine::constraintOrientation() const +{ + (void)ensureDynamicConstraint(); + return (Qt::Orientation)q_cachedConstraintOrientation; } void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, const QSizeF &size) const { - ensureColumnAndRowData(styleInfo); - if (q_cachedSize == size) + if (q_cachedDataForStyleInfo == styleInfo && q_cachedSize == size) return; + q_cachedDataForStyleInfo = styleInfo; + q_cachedSize = size; + q_xx.resize(columnCount()); - q_yy.resize(rowCount()); q_widths.resize(columnCount()); + q_yy.resize(rowCount()); q_heights.resize(rowCount()); q_descents.resize(rowCount()); - q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), - 0, q_totalBoxes[Hor]); - q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), - q_descents.data(), q_totalBoxes[Ver]); - q_cachedSize = size; + if(constraintOrientation() != Qt::Horizontal) { + //We might have items whose width depends on their height + ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); + //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as + //constraints to find the row heights + q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), + 0, q_totalBoxes[Hor]); + ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, q_xx.data(), q_widths.data(), Qt::Vertical); + //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() + q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), + q_descents.data(), q_totalBoxes[Ver]); + } else { + //We have items whose height depends on their width + ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); + //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as + //constraints to find the column widths + q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), + q_descents.data(), q_totalBoxes[Ver]); + ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, q_yy.data(), q_heights.data(), Qt::Horizontal); + //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() + q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), + 0, q_totalBoxes[Hor]); + } } QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h index 9ac9a8e..02c74b0 100644 --- a/src/gui/graphicsview/qgridlayoutengine_p.h +++ b/src/gui/graphicsview/qgridlayoutengine_p.h @@ -91,6 +91,14 @@ enum LayoutSide { Bottom }; +enum { + NoConstraint, + HorizontalConstraint, // Width depends on the height + VerticalConstraint, // Height depends on the width + UnknownConstraint, // need to update cache + UnfeasibleConstraint // not feasible, it be has some items with Vertical and others with Horizontal constraints +}; + template <typename T> class QLayoutParameter { @@ -270,6 +278,10 @@ public: inline void setAlignment(Qt::Alignment alignment) { q_alignment = alignment; } QSizePolicy::Policy sizePolicy(Qt::Orientation orientation) const; + + bool hasDynamicConstraint() const; + Qt::Orientation dynamicConstraintOrientation() const; + QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; QGridLayoutBox box(Qt::Orientation orientation, qreal constraint = -1.0) const; @@ -280,7 +292,7 @@ public: void setGeometry(const QRectF &rect); void transpose(); void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical); - QSizeF effectiveMaxSize() const; + QSizeF effectiveMaxSize(const QSizeF &constraint) const; #ifdef QT_DEBUG void dump(int indent = 0) const; @@ -372,6 +384,14 @@ public: int column, int rowSpan, int columnSpan) const; QSizeF sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, const QSizeF &constraint) const; + + // heightForWidth / widthForHeight support + QSizeF dynamicallyConstrainedSizeHint(Qt::SizeHint which, const QSizeF &constraint) const; + bool ensureDynamicConstraint() const; + bool hasDynamicConstraint() const; + Qt::Orientation constraintOrientation() const; + + QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; void transpose(); void setVisualDirection(Qt::LayoutDirection direction); @@ -390,9 +410,14 @@ private: void setItemAt(int row, int column, QGridLayoutItem *item); void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical); void fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo, - Qt::Orientation orientation = Qt::Vertical) const; + qreal *colPositions, qreal *colSizes, + Qt::Orientation orientation = Qt::Vertical) const; void ensureEffectiveFirstAndLastRows() const; - void ensureColumnAndRowData(const QLayoutStyleInfo &styleInfo) const; + void ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox, + const QLayoutStyleInfo &styleInfo, + qreal *colPositions, qreal *colSizes, + Qt::Orientation orientation) const; + void ensureGeometries(const QLayoutStyleInfo &styleInfo, const QSizeF &size) const; // User input @@ -405,6 +430,7 @@ private: // Lazily computed from the above user input mutable int q_cachedEffectiveFirstRows[NOrientations]; mutable int q_cachedEffectiveLastRows[NOrientations]; + mutable quint8 q_cachedConstraintOrientation : 2; // Layout item input mutable QLayoutStyleInfo q_cachedDataForStyleInfo; diff --git a/src/gui/image/qtiffhandler.cpp b/src/gui/image/qtiffhandler.cpp index de4f680..1627917 100644 --- a/src/gui/image/qtiffhandler.cpp +++ b/src/gui/image/qtiffhandler.cpp @@ -608,6 +608,7 @@ QVariant QTiffHandler::option(ImageOption option) const TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height); imageSize = QSize(width, height); + TIFFClose(tiff); } device()->seek(pos); if (imageSize.isValid()) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index a552ce7..f759fe0 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -939,10 +939,6 @@ static int qCocoaViewCount = 0; } } #endif //QT_NO_WHEELEVENT - - if (!wheelOK) { - return [super scrollWheel:theEvent]; - } } - (void)tabletProximity:(NSEvent *)tabletEvent diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index f7c795e..9b44f15 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -68,6 +68,7 @@ # include "qt_cocoa_helpers_mac_p.h" # include "qmainwindow.h" # include "qtoolbar.h" +# include <private/qmainwindowlayout_p.h> #endif #if defined(Q_WS_QWS) # include "qwsdisplay_qws.h" @@ -3002,6 +3003,15 @@ bool QWidget::isFullScreen() const */ void QWidget::showFullScreen() { +#ifdef Q_WS_MAC + // If the unified toolbar is enabled, we have to disable it before going fullscreen. + QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this); + if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) { + mainWindow->setUnifiedTitleAndToolBarOnMac(false); + QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout()); + mainLayout->activateUnifiedToolbarAfterFullScreen = true; + } +#endif // Q_WS_MAC ensurePolished(); #ifdef QT3_SUPPORT if (parent()) @@ -3034,6 +3044,18 @@ void QWidget::showMaximized() setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowMaximized); +#ifdef Q_WS_MAC + // If the unified toolbar was enabled before going fullscreen, we have to enable it back. + QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this); + if (mainWindow) + { + QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout()); + if (mainLayout->activateUnifiedToolbarAfterFullScreen) { + mainWindow->setUnifiedTitleAndToolBarOnMac(true); + mainLayout->activateUnifiedToolbarAfterFullScreen = false; + } + } +#endif // Q_WS_MAC show(); } @@ -3055,6 +3077,18 @@ void QWidget::showNormal() setWindowState(windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)); +#ifdef Q_WS_MAC + // If the unified toolbar was enabled before going fullscreen, we have to enable it back. + QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this); + if (mainWindow) + { + QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout()); + if (mainLayout->activateUnifiedToolbarAfterFullScreen) { + mainWindow->setUnifiedTitleAndToolBarOnMac(true); + mainLayout->activateUnifiedToolbarAfterFullScreen = false; + } + } +#endif // Q_WS_MAC show(); } diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 1e2aa9f..997419b 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2794,19 +2794,38 @@ void QWidgetPrivate::transferChildren() #ifdef QT_MAC_USE_COCOA void QWidgetPrivate::setSubWindowStacking(bool set) { + // This will set/remove a visual relationship between parent and child on screen. + // The reason for doing this is to ensure that a child always stacks infront of + // its parent. Unfortunatly is turns out that [NSWindow addChildWindow] has + // several unwanted side-effects, one of them being the moving of a child when + // moving the parent, which we choose to accept. A way tougher side-effect is + // that Cocoa will hide the parent if you hide the child. And in the case of + // a tool window, since it will normally hide when you deactivate the + // application, Cocoa will hide the parent upon deactivate as well. The result often + // being no more visible windows on screen. So, to make a long story short, we only + // allow parent-child relationships between windows that both are either a plain window + // or a dialog. + Q_Q(QWidget); - if (!q->isWindow() || !q->testAttribute(Qt::WA_WState_Created)) + if (!q->isWindow()) + return; + NSWindow *qwin = [qt_mac_nativeview_for(q) window]; + if (!qwin) + return; + Qt::WindowType qtype = q->windowType(); + if (set && !(qtype == Qt::Window || qtype == Qt::Dialog)) + return; + if (set && ![qwin isVisible]) return; if (QWidget *parent = q->parentWidget()) { - if (parent->testAttribute(Qt::WA_WState_Created)) { + if (NSWindow *pwin = [qt_mac_nativeview_for(parent) window]) { if (set) { - if (parent->isVisible()) { - NSWindow *childwin = qt_mac_window_for(q); - [qt_mac_window_for(parent) addChildWindow:childwin ordered:NSWindowAbove]; - } + Qt::WindowType ptype = parent->window()->windowType(); + if ([pwin isVisible] && (ptype == Qt::Window || ptype == Qt::Dialog) && ![qwin parentWindow]) + [pwin addChildWindow:qwin ordered:NSWindowAbove]; } else { - [qt_mac_window_for(parent) removeChildWindow:qt_mac_window_for(q)]; + [pwin removeChildWindow:qwin]; } } } @@ -2814,12 +2833,15 @@ void QWidgetPrivate::setSubWindowStacking(bool set) QList<QWidget *> widgets = q->findChildren<QWidget *>(); for (int i=0; i<widgets.size(); ++i) { QWidget *child = widgets.at(i); - if (child->isWindow() && child->testAttribute(Qt::WA_WState_Created) && child->isVisibleTo(q)) { - if (set) { - NSWindow *childwin = qt_mac_window_for(child); - [qt_mac_window_for(q) addChildWindow:childwin ordered:NSWindowAbove]; - } else { - [qt_mac_window_for(q) removeChildWindow:qt_mac_window_for(child)]; + if (child && child->isWindow()) { + if (NSWindow *cwin = [qt_mac_nativeview_for(child) window]) { + if (set) { + Qt::WindowType ctype = child->window()->windowType(); + if ([cwin isVisible] && (ctype == Qt::Window || ctype == Qt::Dialog) && ![cwin parentWindow]) + [qwin addChildWindow:cwin ordered:NSWindowAbove]; + } else { + [qwin removeChildWindow:qt_mac_window_for(child)]; + } } } } @@ -3442,7 +3464,6 @@ void QWidgetPrivate::show_sys() #else // sync the opacity value back (in case of a fade). [window setAlphaValue:q->windowOpacity()]; - setSubWindowStacking(true); QWidget *top = 0; if (QApplicationPrivate::tryModalHelper(q, &top)) { @@ -3461,6 +3482,7 @@ void QWidgetPrivate::show_sys() [modalWin orderFront:window]; } } + setSubWindowStacking(true); #endif if (q->windowType() == Qt::Popup) { if (q->focusWidget()) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 9a451ce..5df5e19 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -544,7 +544,7 @@ void QWidgetPrivate::show_sys() id->MakeVisible(true); - if(q->isWindow()) + if(q->isWindow()&&!q->testAttribute(Qt::WA_ShowWithoutActivating)) id->setFocusSafely(true); } diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 793d380..bd37d9f 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -234,13 +234,14 @@ embedded { symbian { - HEADERS += painting/qwindowsurface_s60_p.h + HEADERS += painting/qwindowsurface_s60_p.h \ + painting/qdrawhelper_arm_simd_p.h SOURCES += painting/qwindowsurface_s60.cpp armccIfdefBlock = \ "$${LITERAL_HASH}if defined(ARMV6)" \ + "MACRO QT_HAVE_ARM_SIMD" \ "SOURCEPATH painting" \ - "SOURCE qblendfunctions_armv6_rvct.s" \ - "SOURCE qdrawhelper_armv6_rvct.s" \ + "SOURCE qdrawhelper_arm_simd.cpp" \ "$${LITERAL_HASH}endif" MMP_RULES += armccIfdefBlock diff --git a/src/gui/painting/qblendfunctions_armv6_rvct.s b/src/gui/painting/qblendfunctions_armv6_rvct.s deleted file mode 100644 index 1e3faa9..0000000 --- a/src/gui/painting/qblendfunctions_armv6_rvct.s +++ /dev/null @@ -1,222 +0,0 @@ -;**************************************************************************** -;** -;** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) -;** -;** This file is part of the QtGui module of the Qt Toolkit. -;** -;** $QT_BEGIN_LICENSE:LGPL$ -;** No Commercial Usage -;** This file contains pre-release code and may not be distributed. -;** You may use this file in accordance with the terms and conditions -;** contained in the Technology Preview License Agreement accompanying -;** this package. -;** -;** GNU Lesser General Public License Usage -;** Alternatively, this file may be used under the terms of the GNU Lesser -;** General Public License version 2.1 as published by the Free Software -;** Foundation and appearing in the file LICENSE.LGPL included in the -;** packaging of this file. Please review the following information to -;** ensure the GNU Lesser General Public License version 2.1 requirements -;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -;** -;** In addition, as a special exception, Nokia gives you certain additional -;** rights. These rights are described in the Nokia Qt LGPL Exception -;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -;** -;** If you have questions regarding the use of this file, please contact -;** Nokia at qt-info@nokia.com. -;** -;** -;** -;** -;** -;** -;** -;** -;** $QT_END_LICENSE$ -;** -;**************************************************************************** - -; -; 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. -; - - - ARM - PRESERVE8 - - INCLUDE qdrawhelper_armv6_rvct.inc - - -;----------------------------------------------------------------------------- -; qt_blend_rgb32_on_rgb32_arm -; -; @brief -; -; @param dest Destination pixels (r0) -; @param dbpl Destination bytes per line (r1) -; @param src Source pixels (r2) -; @param sbpl Source bytes per line (r3) -; @param w Width (s0 -> r4) -; @param h Height (s1 -> r5) -; @param const_alpha Constant alpha (s2 -> r6) -; -;--------------------------------------------------------------------------- -qt_blend_rgb32_on_rgb32_armv6 Function - stmfd sp!, {r4-r12, r14} - - ; read arguments off the stack - add r8, sp, #10 * 4 - ldmia r8, {r9-r11} - - ; Reorganize registers - - mov r4, r10 - mov r5, r1 - mov r6, r3 - - mov r1, r2 - mov r2, r9 - mov r3, r11 - - ; Now we have registers - ; @param dest Destination pixels (r0) - ; @param src Source pixels (r1) - ; @param w Width (r2) - ; @param const_alpha Constant alpha (r3) - ; @param h Height (r4) - ; @param dbpl Destination bytes per line (r5) - ; @param sbpl Source bytes per line (r6) - - cmp r3, #256 ; test if we have fully opaque constant alpha value - bne rgb32_blend_const_alpha ; branch if not - -rgb32_blend_loop - - subs r4, r4, #1 - bmi rgb32_blend_exit ; while(h--) - -rgb321 PixCpySafe r0, r1, r2 - - add r0, r0, r5 ; dest = dest + dbpl - add r1, r1, r6 ; src = src + sbpl - - b rgb32_blend_loop - - -rgb32_blend_const_alpha - - ;ldr r14, =ComponentHalf ; load 0x800080 to r14 - mov r14, #0x800000 - add r14, r14, #0x80 - - sub r3, r3, #1 ; const_alpha -= 1; - -rgb32_blend_loop_const_alpha - - subs r4, r4, #1 - bmi rgb32_blend_exit ; while(h--) - -rgb322 BlendRowSafe PixelSourceOverConstAlpha - - add r0, r0, r5 ; dest = dest + dbpl - add r1, r1, r6 ; src = src + sbpl - - b rgb32_blend_loop_const_alpha - -rgb32_blend_exit - - ldmfd sp!, {r4-r12, pc} ; pop and return - - - -;----------------------------------------------------------------------------- -; qt_blend_argb32_on_argb32_arm -; -; @brief -; -; @param dest Destination pixels (r0) -; @param dbpl Destination bytes per line (r1) -; @param src Source pixels (r2) -; @param sbpl Source bytes per line (r3) -; @param w Width (s0 -> r4) -; @param h Height (s1 -> r5) -; @param const_alpha Constant alpha (s2 -> r6) -; -;--------------------------------------------------------------------------- -qt_blend_argb32_on_argb32_armv6 Function - stmfd sp!, {r4-r12, r14} - - ; read arguments off the stack - add r8, sp, #10 * 4 - ldmia r8, {r9-r11} - - ; Reorganize registers - - mov r4, r10 - mov r5, r1 - mov r6, r3 - - mov r1, r2 - mov r2, r9 - mov r3, r11 - - ; Now we have registers - ; @param dest Destination pixels (r0) - ; @param src Source pixels (r1) - ; @param w Width (r2) - ; @param const_alpha Constant alpha (r3) - ; @param h Height (r4) - ; @param dbpl Destination bytes per line (r5) - ; @param sbpl Source bytes per line (r6) - - ;ldr r14, =ComponentHalf ; load 0x800080 to r14 - mov r14, #0x800000 - add r14, r14, #0x80 - - cmp r3, #256 ; test if we have fully opaque constant alpha value - bne argb32_blend_const_alpha ; branch if not - -argb32_blend_loop - - subs r4, r4, #1 - bmi argb32_blend_exit ; while(h--) - -argb321 BlendRowSafe PixelSourceOver - - add r0, r0, r5 ; dest = dest + dbpl - add r1, r1, r6 ; src = src + sbpl - - b argb32_blend_loop - -argb32_blend_const_alpha - - sub r3, r3, #1 ; const_alpha -= 1; - -argb32_blend_loop_const_alpha - - subs r4, r4, #1 - bmi argb32_blend_exit ; while(h--) - -argb322 BlendRowSafe PixelSourceOverConstAlpha - - add r0, r0, r5 ; dest = dest + dbpl - add r1, r1, r6 ; src = src + sbpl - - b argb32_blend_loop_const_alpha - -argb32_blend_exit - - ldmfd sp!, {r4-r12, pc} ; pop and return - - - END ; File end diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 5f190ba..a4ab278 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -43,7 +43,7 @@ #include <private/qpaintengine_raster_p.h> #include <private/qpainter_p.h> #include <private/qdrawhelper_x86_p.h> -#include <private/qdrawhelper_armv6_p.h> +#include <private/qdrawhelper_arm_simd_p.h> #include <private/qdrawhelper_neon_p.h> #include <private/qmath_p.h> #include <qmath.h> @@ -7678,96 +7678,6 @@ static void qt_memfill16_setup(quint16 *dest, quint16 value, int count); qt_memfill32_func qt_memfill32 = qt_memfill32_setup; qt_memfill16_func qt_memfill16 = qt_memfill16_setup; -#if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6) -// Move these to qdrawhelper_arm.c when all -// functions are implemented using arm assembly. -static CompositionFunctionSolid qt_functionForModeSolid_ARMv6[numCompositionFunctions] = { - comp_func_solid_SourceOver, - comp_func_solid_DestinationOver, - comp_func_solid_Clear, - comp_func_solid_Source, - comp_func_solid_Destination, - comp_func_solid_SourceIn, - comp_func_solid_DestinationIn, - comp_func_solid_SourceOut, - comp_func_solid_DestinationOut, - comp_func_solid_SourceAtop, - comp_func_solid_DestinationAtop, - comp_func_solid_XOR, - comp_func_solid_Plus, - comp_func_solid_Multiply, - comp_func_solid_Screen, - comp_func_solid_Overlay, - comp_func_solid_Darken, - comp_func_solid_Lighten, - comp_func_solid_ColorDodge, - comp_func_solid_ColorBurn, - comp_func_solid_HardLight, - comp_func_solid_SoftLight, - comp_func_solid_Difference, - comp_func_solid_Exclusion, - rasterop_solid_SourceOrDestination, - rasterop_solid_SourceAndDestination, - rasterop_solid_SourceXorDestination, - rasterop_solid_NotSourceAndNotDestination, - rasterop_solid_NotSourceOrNotDestination, - rasterop_solid_NotSourceXorDestination, - rasterop_solid_NotSource, - rasterop_solid_NotSourceAndDestination, - rasterop_solid_SourceAndNotDestination -}; - -static CompositionFunction qt_functionForMode_ARMv6[numCompositionFunctions] = { - comp_func_SourceOver_armv6, - comp_func_DestinationOver, - comp_func_Clear, - comp_func_Source_armv6, - comp_func_Destination, - comp_func_SourceIn, - comp_func_DestinationIn, - comp_func_SourceOut, - comp_func_DestinationOut, - comp_func_SourceAtop, - comp_func_DestinationAtop, - comp_func_XOR, - comp_func_Plus, - comp_func_Multiply, - comp_func_Screen, - comp_func_Overlay, - comp_func_Darken, - comp_func_Lighten, - comp_func_ColorDodge, - comp_func_ColorBurn, - comp_func_HardLight, - comp_func_SoftLight, - comp_func_Difference, - comp_func_Exclusion, - rasterop_SourceOrDestination, - rasterop_SourceAndDestination, - rasterop_SourceXorDestination, - rasterop_NotSourceAndNotDestination, - rasterop_NotSourceOrNotDestination, - rasterop_NotSourceXorDestination, - rasterop_NotSource, - rasterop_NotSourceAndDestination, - rasterop_SourceAndNotDestination -}; - -static void qt_blend_color_argb_armv6(int count, const QSpan *spans, void *userData) -{ - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - - CompositionFunctionSolid func = qt_functionForModeSolid_ARMv6[data->rasterBuffer->compositionMode]; - while (count--) { - uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x; - func(target, spans->len, data->solid.color, spans->coverage); - ++spans; - } -} - -#endif // Q_CC_RVCT && QT_HAVE_ARMV6 - - void qInitDrawhelperAsm() { @@ -7938,46 +7848,39 @@ void qInitDrawhelperAsm() } #endif // IWMMXT -#if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6) - functionForModeAsm = qt_functionForMode_ARMv6; - functionForModeSolidAsm = qt_functionForModeSolid_ARMv6; +#if defined(QT_HAVE_ARM_SIMD) + qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd; + qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd; +#elif defined(QT_HAVE_NEON) + if (features & NEON) { + qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; + qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon; + + qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon; + qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon; - qt_memfill32 = qt_memfill32_armv6; + qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon; + qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon; - qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_armv6; + qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; -#elif defined(QT_HAVE_NEON) - if (features & NEON) { - qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; - qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; - qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; - qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; - qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon; - - qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon; - qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon; - - qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon; - qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon; - - qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; - - functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon; - functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon; - functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon; - destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon; - destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon; - - qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; - qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; - qt_memfill32 = qt_memfill32_neon; - } + functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon; + functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon; + functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon; + destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon; + destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon; + + qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; + qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; + qt_memfill32 = qt_memfill32_neon; + } #endif if (functionForModeSolidAsm) { diff --git a/src/gui/painting/qdrawhelper_arm_simd.cpp b/src/gui/painting/qdrawhelper_arm_simd.cpp new file mode 100644 index 0000000..61dac5e --- /dev/null +++ b/src/gui/painting/qdrawhelper_arm_simd.cpp @@ -0,0 +1,313 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdrawhelper_arm_simd_p.h" + +#include <private/qpaintengine_raster_p.h> +#include <private/qblendfunctions_p.h> + +#ifdef QT_HAVE_ARM_SIMD + +#if defined(Q_OS_SYMBIAN) +#include <u32std.h> +#endif + +#if defined(Q_OS_SYMBIAN) && defined(Q_CC_RVCT) +__asm void qt_blend_argb32_on_argb32_arm_simd(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ +#ifndef __ARMCC__ + __SWITCH_TO_ARM; +#else + CODE32 +#endif // __ARMCC__ + + stmfd sp!, {r4-r12, r14} + + // read arguments off the stack + add r8, sp, #10 * 4 + ldmia r8, {r4-r6} + + // adjust dbpl and sbpl + mov r14, #4 + mul r14, r4, r14 + sub r1, r1, r14 + sub r3, r3, r14 + + // load 0xFF00FF00 to r12 + mov r12, #0xFF000000 + add r12, r12, #0xFF00 + + // load 0x800080 to r14 + mov r14, #0x800000 + add r14, r14, #0x80 + + /* + Registers: + r0 dst + r1 dbpl + r2 src + r3 sbpl + r4 w + r5 h + r6 const_alpha + r12 0xFF0000 + r14 0x800080 + */ + + cmp r6, #256 //test if we have fully opaque constant alpha value + bne argb32constalpha // branch if not + +argb32_next_row + + mov r7, r4 + +argb32_next_pixel + + ldr r8, [r2], #4 // load src pixel + + // Negate r8 and extract src alpha + mvn r11, r8 // bitwise not + uxtb r11, r11, ror #24 + + cmp r11, #0 // test for full src opacity (negated) + beq argb32_no_blend + + cmp r11, #255 // test for full src transparency (negated) + addeq r0, #4 + beq argb32_nop + + ldr r9, [r0] // load dst pixel + + // blend + uxtb16 r10, r9 + uxtb16 r6, r9, ror #8 + mla r10, r11, r10, r14 + mla r9, r6, r11, r14 + uxtab16 r10, r10, r10, ror #8 + uxtab16 r9, r9, r9, ror #8 + and r9, r9, r12 + uxtab16 r10, r9, r10, ror #8 + + uqadd8 r8, r10, r8 + +argb32_no_blend + + str r8, [r0], #4 + +argb32_nop + + subs r7, r7, #1 + bgt argb32_next_pixel + + add r0, r0, r1 // dest = dest + dbpl + add r2, r2, r3 // src = src + sbpl + + subs r5, r5, #1 + bgt argb32_next_row + + b argb32_blend_exit + +argb32constalpha + + cmp r6, #0 + beq argb32_blend_exit + + ; const_alpha = (const_alpha * 255) >> 8; + mov r11, #255 + mul r6, r6, r11 + mov r11, r6, lsr #8 + +argb32constalpha_next_row + + mov r7, r4 + +argb32constalpha_next_pixel + + ldr r9, [r2], #4 // load src pixel + + // blend + uxtb16 r10, r9 + uxtb16 r6, r9, ror #8 + mla r10, r11, r10, r14 + mla r9, r6, r11, r14 + uxtab16 r10, r10, r10, ror #8 + uxtab16 r9, r9, r9, ror #8 + and r9, r9, r12 + uxtab16 r8, r9, r10, ror #8 + + ldr r9, [r0] // load dst pixel + + // blend + uxtb16 r10, r9 + uxtb16 r6, r9, ror #8 + + // Negate r11 and extract src alpha + mvn r9, r11 // bitwise not + uxtb r9, r9, ror #24 + + mla r10, r9, r10, r14 + mla r9, r6, r9, r14 + uxtab16 r10, r10, r10, ror #8 + uxtab16 r9, r9, r9, ror #8 + and r9, r9, r12 + uxtab16 r10, r9, r10, ror #8 + + uqadd8 r8, r10, r8 + + str r8, [r0], #4 + + subs r7, r7, #1 + bgt argb32constalpha_next_pixel + + add r0, r0, r1 // dest = dest + dbpl + add r2, r2, r3 // src = src + sbpl + + subs r5, r5, #1 + bgt argb32constalpha_next_row + +argb32_blend_exit + + // Restore registers + ldmfd sp!, {r4-r12, lr} + bx lr + + __END_ARM +} + +void qt_blend_rgb32_on_rgb32_arm_simd(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ + if (const_alpha != 256) { + qt_blend_argb32_on_argb32_arm_simd(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + return; + } + + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + if (w <= 64) { + for (int y=0; y<h; ++y) { + qt_memconvert(dst, src, w); + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } else { + int len = w * 4; + for (int y=0; y<h; ++y) { + memcpy(dst, src, len); + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } +} + +#else // defined(Q_OS_SYMBIAN) && defined(Q_CC_RVCT) + +// TODO: add GNU assembler instructions and support for other platforms. +// Default to C code for now + +void qt_blend_argb32_on_argb32_arm_simd(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + if (const_alpha == 256) { + for (int y=0; y<h; ++y) { + for (int x=0; x<w; ++x) { + uint s = src[x]; + if (s >= 0xff000000) + dst[x] = s; + else if (s != 0) + dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } else if (const_alpha != 0) { + const_alpha = (const_alpha * 255) >> 8; + for (int y=0; y<h; ++y) { + for (int x=0; x<w; ++x) { + uint s = BYTE_MUL(src[x], const_alpha); + dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } +} + +void qt_blend_rgb32_on_rgb32_arm_simd(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ + if (const_alpha != 256) { + qt_blend_argb32_on_argb32_arm_simd(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + return; + } + + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + if (w <= 64) { + for (int y=0; y<h; ++y) { + qt_memconvert(dst, src, w); + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } else { + int len = w * 4; + for (int y=0; y<h; ++y) { + memcpy(dst, src, len); + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } +} + +#endif + +#endif // QT_HAVE_ARMV_SIMD diff --git a/src/gui/painting/qdrawhelper_armv6_p.h b/src/gui/painting/qdrawhelper_arm_simd_p.h index e58f8bb..6c96a84 100644 --- a/src/gui/painting/qdrawhelper_armv6_p.h +++ b/src/gui/painting/qdrawhelper_arm_simd_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QDRAWHELPER_ARMV6_P_H -#define QDRAWHELPER_ARMV6_P_H +#ifndef QDRAWHELPER_ARM_SIMD_P_H +#define QDRAWHELPER_ARM_SIMD_P_H // // W A R N I N G @@ -57,25 +57,20 @@ QT_BEGIN_NAMESPACE -#if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6) +#if defined(QT_HAVE_ARM_SIMD) -extern "C" void qt_blend_rgb32_on_rgb32_armv6(uchar *destPixels, int dbpl, +void qt_blend_argb32_on_argb32_arm_simd(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, int const_alpha); -extern "C" void qt_blend_argb32_on_argb32_armv6(uchar *destPixels, int dbpl, +void qt_blend_rgb32_on_rgb32_arm_simd(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, int const_alpha); -extern "C" void qt_memfill32_armv6(quint32 *dest, quint32 value, int count); - -extern "C" void comp_func_Source_armv6(uint *dest, const uint *src, int length, uint const_alpha); -extern "C" void comp_func_SourceOver_armv6(uint *dest, const uint *src, int length, uint const_alpha); - -#endif // QT_HAVE_ARMV6 +#endif // QT_HAVE_ARM_SIMD QT_END_NAMESPACE -#endif // QDRAWHELPER_ARMV6_P_H +#endif // QDRAWHELPER_ARM_SIMD_P_H diff --git a/src/gui/painting/qdrawhelper_armv6_rvct.inc b/src/gui/painting/qdrawhelper_armv6_rvct.inc deleted file mode 100644 index 8c6d803..0000000 --- a/src/gui/painting/qdrawhelper_armv6_rvct.inc +++ /dev/null @@ -1,496 +0,0 @@ -;**************************************************************************** -;** -;** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) -;** -;** This file is part of the QtGui module of the Qt Toolkit. -;** -;** $QT_BEGIN_LICENSE:LGPL$ -;** No Commercial Usage -;** This file contains pre-release code and may not be distributed. -;** You may use this file in accordance with the terms and conditions -;** contained in the Technology Preview License Agreement accompanying -;** this package. -;** -;** GNU Lesser General Public License Usage -;** Alternatively, this file may be used under the terms of the GNU Lesser -;** General Public License version 2.1 as published by the Free Software -;** Foundation and appearing in the file LICENSE.LGPL included in the -;** packaging of this file. Please review the following information to -;** ensure the GNU Lesser General Public License version 2.1 requirements -;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -;** -;** In addition, as a special exception, Nokia gives you certain additional -;** rights. These rights are described in the Nokia Qt LGPL Exception -;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -;** -;** If you have questions regarding the use of this file, please contact -;** Nokia at qt-info@nokia.com. -;** -;** -;** -;** -;** -;** -;** -;** -;** $QT_END_LICENSE$ -;** -;**************************************************************************** - -; -; 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. -; - -;----------------------------------------------------------------------------- -; Globals. -; Earch marcro expects that caller has loaded 0x800080 to r14. -;----------------------------------------------------------------------------- - -ComponentHalf EQU 0x800080 - -;----------------------------------------------------------------------------- -; ARM assembly implementations of accelerated graphics operations. -; -; Conventions: -; -; - r0 = Target buffer pointer -; - r1 = Source buffer pointer -; - r2 = Length of the buffer to blend -; - r3 = Constant alpha for source buffer -; -;----------------------------------------------------------------------------- - -; A macro for transparently defining ARM functions - MACRO -$func Function - AREA Function_$func, CODE - GLOBAL $func - ALIGN 4 - CODE32 -$func - MEND - - -;----------------------------------------------------------------------------- -; Armv6 boosted implementation of BYTE_MUL(...) function found in qdrawhelper_p.h. -; -; @param dst Destination register where to store the result -; @param x Value to multiply -; @param a Multiplicator byte -; @param r14 Component half 0x800080 -; -; @note Trashes x, r8 -;----------------------------------------------------------------------------- - MACRO - ByteMul $dst, $x, $a - - ; static inline uint BYTE_MUL(uint x, uint a) - - ; uint r8 = (x & 0xff00ff) * a + 0x800080 - uxtb16 r8, $x ; r8 = r8 & 0x00FF00FF - mla r8, r8, $a, r14 - - ; x = ((r >> 8) & 0xff00ff) * a + 0x800080 - uxtb16 $x, $x, ror #8 - mla $x, $x, $a, r14 - - - ; r8 = (r8 + ((r8 >> 8) & 0xff00ff) ) >> 8 - ; r8 &= 0xff00ff - uxtab16 r8, r8, r8, ror #8 - uxtb16 r8, r8, ror #8 - - ; x = x + ((x >>8) & 0xff00ff) - uxtab16 $x, $x, $x, ror #8 - - ; x &= 0xff00ff00 - ; x |= r8 - uxtb16 $x, $x, ror #8 - orr $dst, r8, $x, lsl #8 - - MEND - -;----------------------------------------------------------------------------- -; Armv6 boosted implementation of INTERPOLATE_PIXEL_255(...) function found in -; qdrawhelper_p.h. -; -; @param dst Destination register where to store the result -; @param x First value to multiply -; @param a Multiplicator byte for first value -; @param y Second value to multiply -; @param b Multiplicator byte for second value -; @param r14 Component half 0x800080 -; -; -; @note Trashes x, r8, r14 -;----------------------------------------------------------------------------- - MACRO - InterpolatePixel255 $dst, $x, $a, $y, $b - - ; static inline uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) - - ; First calculate the parts where we need 0x800080 - - ; uint r8 = (((x & 0xff00ff) * a) + 0x800080) - uxtb16 r8, $x ; r8 = r8 & 0x00FF00FF - mla r8, r8, $a, r14 - - ; x = ((((x >> 8) & 0xff00ff) * a) + 0x800080) - uxtb16 $x, $x, ror #8 - mla $x, $x, $a, r14 - - ; Now we are trashing r14 to free it for other purposes - - ; uint r14 = (y & 0xff00ff) * b - uxtb16 r14, $y ; r14 = y & 0x00FF00FF - mul r14, r14, $b - - ; r8 = r8 + r14 - add r8, r8, r14 - - ; r8 = (r8 + ((r8 >> 8) & 0xff00ff) ) >> 8 - ; r8 &= 0xff00ff - uxtab16 r8, r8, r8, ror #8 - uxtb16 r8, r8, ror #8 - - ; r14 = ((y >> 8) & 0xff00ff) * b - uxtb16 r14, $y, ror #8 ; r14 = ((y >> 8) & 0xFF00FF) - mul r14, r14, $b - - ; x = x + r14 - add $x, $x, r14 - - ; x = x + ((x >>8) & 0xff00ff) - uxtab16 $x, $x, $x, ror #8 - - ; x &= 0xff00ff00 - ; x |= r8 - uxtb16 $x, $x, ror #8 - orr $dst, r8, $x, lsl #8 - - MEND - -;----------------------------------------------------------------------------- -; -;----------------------------------------------------------------------------- - MACRO -$label Blend4Pixels $BlendPixel - - ; Blend first 4 pixels - - ldmia r1!, {r4-r7} - ldm r0, {r9-r12} - -b4p1_$label $BlendPixel r9, r4, r3 -b4p2_$label $BlendPixel r10, r5, r3 -b4p3_$label $BlendPixel r11, r6, r3 -b4p4_$label $BlendPixel r12, r7, r3 - - stmia r0!, {r9-r12} - - MEND - -;----------------------------------------------------------------------------- -; -;----------------------------------------------------------------------------- - MACRO -$label Blend8Pixels $BlendPixel - -b8p1_$label Blend4Pixels $BlendPixel -b8p2_$label Blend4Pixels $BlendPixel - - MEND - -;----------------------------------------------------------------------------- -; -;----------------------------------------------------------------------------- - MACRO -$label Blend16Pixels $BlendPixel - -b16p1_$label Blend8Pixels $BlendPixel -b16p2_$label Blend8Pixels $BlendPixel - - MEND - -;----------------------------------------------------------------------------- -; -;----------------------------------------------------------------------------- - MACRO -$label Blend32Pixels $BlendPixel - -b32p1_$label Blend16Pixels $BlendPixel -b32p2_$label Blend16Pixels $BlendPixel - - MEND - -;----------------------------------------------------------------------------- -; A macro for source over compositing one row of pixels and saving the results -; to destination buffer. -; -; @param dest Destination buffer (r0) -; @param src Source buffer (r1) -; @param length Length (r2) -; @param const_alpha Constant alpha (r3) -; @param r14 Component Half (0x800080) (r14) -; -; @note Advances r0, r1 -; @note Trashes r2, r4-r12 -;----------------------------------------------------------------------------- - MACRO -$label BlendRow $BlendPixel - - pld [r1] - -bloop_$label - ; Blend 32 pixels per loop iteration - subs r2, r2, #32 - bmi b_remaining_$label - -brp1_$label Blend32Pixels $BlendPixel - - b bloop_$label - -b_remaining_$label - - ; Remaining 31 pixels - - addmi r2, r2, #32 - - ; Blend 16 pixels - tst r2, #16 - beq b_remaining8_$label - -brp2_$label Blend16Pixels $BlendPixel - -b_remaining8_$label - - ; Blend 8 pixels - tst r2, #8 - beq b_remaining4_$label - -brp3_$label Blend8Pixels $BlendPixel - -b_remaining4_$label - - ; Blend 4 pixels - tst r2, #4 - beq b_remaining3_$label - -brp4_$label Blend4Pixels $BlendPixel - -b_remaining3_$label - - ; Remaining 3 pixels - - tst r2, #2 - beq b_last_$label - - ldmia r1!, {r4-r5} - ldm r0, {r9-r10} - -brp5_$label $BlendPixel r9, r4, r3 -brp6_$label $BlendPixel r10, r5, r3 - - stmia r0!, {r9-r10} - -b_last_$label - - tst r2, #1 - beq bexit_$label - - ldr r4, [r1] - ldr r9, [r0] - -bpl_$label $BlendPixel r9, r4, r3 - - str r9, [r0] - -bexit_$label - - MEND - -;----------------------------------------------------------------------------- -; A macro for source over compositing one row of pixels and saving the results -; to destination buffer. Restores all registers. -; -; @param dest Destination buffer (r0) -; @param src Source buffer (r1) -; @param length Length (r2) -; @param const_alpha Constant alpha (r3) -; @param r14 Component Half (0x800080) (r14) -; -; @note Advances r0, r1 -; @note Trashes r2, r4-r12 -;----------------------------------------------------------------------------- - MACRO -$label BlendRowSafe $BlendPixel - - stmfd sp!, {r0-r6} ; Preserves registers only up to r6 - -brs_$label BlendRow $BlendPixel - - ldmfd sp!, {r0-r6} - - MEND - - -;----------------------------------------------------------------------------- -; Pix Copy. -; NOTE! Cache line size of ARM1136JF-S and ARM1136J-S is 32 bytes (8 pixels). -; -; @param dst Destination pixels (r0) -; @param src Source pixels (r1) -; @param len Length (r2) -; -; @note Trashes r3-r10 -;----------------------------------------------------------------------------- - MACRO -$label PixCpy $dst, $src, $len - - pld [$src] - -pcpy_loop_$label - ; Copy 8 pixels per loop iteration - pld [$src, #96] - subs $len, $len, #8 - ldmgeia $src!, {r3-r10} - stmgeia $dst!, {r3-r10} - bgt pcpy_loop_$label - -pcpy_remaining_$label - - ; Copy up to 7 remaining pixels - - ; Copy 4 pixels - tst $len, #4 - ldmneia $src!, {r3-r6} - stmneia $dst!, {r3-r6} - - tst $len, #2 - ldmneia $src!, {r3-r4} - stmneia $dst!, {r3-r4} - - tst $len, #1 - ldrne r3, [$src] - strne r3, [$dst] - - MEND - -;----------------------------------------------------------------------------- -; General Pix Copy. Maximum 8 pixels at time. Restores all registers. -; -; @param dst Destination pixels (r0) -; @param src Source pixels (r1) -; @param len Length (r2) -; -; @note Trashes r3-r10 -;----------------------------------------------------------------------------- - MACRO -$label PixCpySafe $dst, $src, $len - - stmfd sp!, {r0-r6} ; Preserves registers only up to r6 - -pcs_$label PixCpy $dst, $src, $len - - ldmfd sp!, {r0-r6} ; pop - - MEND - - -;----------------------------------------------------------------------------- -; A macro for source over compositing one pixel and saving the result to -; dst register. -; -; @param dst Destination register, must contain destination pixel upon entry -; @param src Source register, must contain source pixel upon entry -; @param const_alpha Constant source alpha -; @param r14 Component half 0x800080 -; -; @note Trashes const_alpha, r8 -;----------------------------------------------------------------------------- - MACRO -$label PixelSourceOver $dst, $src, $const_alpha - - ; Negate src and extract alpha - mvn $const_alpha, $src ; bitwise not - uxtb $const_alpha, $const_alpha, ror #24 ; r3 = ((r3 & 0xFF000000) >> 24); - - ;cmp $const_alpha, #255 ; test for full transparency ( negated ) - ;beq exit_$label - cmp $const_alpha, #0 ; test for full opacity ( negated ) - moveq $dst, $src - beq exit_$label - - ByteMul $dst, $dst, $const_alpha - add $dst, $src, $dst - -exit_$label - MEND - -;----------------------------------------------------------------------------- -; A macro for source over compositing one pixel and saving the result to -; dst register. -; -; @param dst Destination register, must contain destination pixel upon entry -; @param src Source register, must contain source pixel upon entry -; @param const_alpha Constant source alpha -; @param r14 Component half 0x800080 -; -; @note Trashes src, const_alpha, r8 -;----------------------------------------------------------------------------- - MACRO -$label PixelSourceOverConstAlpha $dst, $src, $const_alpha - - ; store alpha because we are going to trash it - stmfd sp!, {$const_alpha} - - ByteMul $src, $src, $const_alpha - - ; Negate src and extract alpha - mvn $const_alpha, $src ; bitwise not - uxtb $const_alpha, $const_alpha, ror #24 ; r3 = ((r3 & 0xFF000000) >> 24); - - ByteMul $dst, $dst, $const_alpha - - add $dst, $src, $dst - - ; recover alpha - ldmfd sp!, {$const_alpha} - - MEND - -;----------------------------------------------------------------------------- -; A macro for source over compositing one pixel and saving the result to -; a register. -; -; @param dst Destination register, must contain destination pixel upon entry -; @param src Source register, must contain source pixel upon entry -; @param const_alpha Constant source alpha -; @param r14 Component half 0x800080 -; -; @note Trashes src, r8 -;----------------------------------------------------------------------------- - MACRO -$label PixelSourceConstAlpha $dst, $src, $const_alpha - - ; store r2 and r14 because we are going to trash them - stmfd sp!, {r2, r14} - - rsb r2, $const_alpha, #255 - InterpolatePixel255 $dst, $src, $const_alpha, $dst, r2 - - ; recover r2 and r14 - ldmfd sp!, {r2, r14} - - MEND - - END ; File end diff --git a/src/gui/painting/qdrawhelper_armv6_rvct.s b/src/gui/painting/qdrawhelper_armv6_rvct.s deleted file mode 100644 index 180980a..0000000 --- a/src/gui/painting/qdrawhelper_armv6_rvct.s +++ /dev/null @@ -1,177 +0,0 @@ -;**************************************************************************** -;** -;** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) -;** -;** This file is part of the QtGui module of the Qt Toolkit. -;** -;** $QT_BEGIN_LICENSE:LGPL$ -;** No Commercial Usage -;** This file contains pre-release code and may not be distributed. -;** You may use this file in accordance with the terms and conditions -;** contained in the Technology Preview License Agreement accompanying -;** this package. -;** -;** GNU Lesser General Public License Usage -;** Alternatively, this file may be used under the terms of the GNU Lesser -;** General Public License version 2.1 as published by the Free Software -;** Foundation and appearing in the file LICENSE.LGPL included in the -;** packaging of this file. Please review the following information to -;** ensure the GNU Lesser General Public License version 2.1 requirements -;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -;** -;** In addition, as a special exception, Nokia gives you certain additional -;** rights. These rights are described in the Nokia Qt LGPL Exception -;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -;** -;** If you have questions regarding the use of this file, please contact -;** Nokia at qt-info@nokia.com. -;** -;** -;** -;** -;** -;** -;** -;** -;** $QT_END_LICENSE$ -;** -;**************************************************************************** - -; -; 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. -; - - ARM - PRESERVE8 - - INCLUDE qdrawhelper_armv6_rvct.inc - -;----------------------------------------------------------------------------- -; qt_memfill32_armv6 -; -; @brief Not yet in use! -; -; @param dest Destination buffer (r0) -; @param value Value (r1) -; @param count Count (r2) -; -;--------------------------------------------------------------------------- -qt_memfill32_armv6 Function - stmfd sp!, {r4-r12, r14} - - mov r3, r1 - mov r4, r1 - mov r5, r1 - mov r6, r1 - mov r7, r1 - mov r8, r1 - mov r9, r1 - -mfill_loop - ; Fill 32 pixels per loop iteration - subs r2, r2, #32 - stmgeia r0!, {r1, r3, r4, r5, r6, r7, r8, r9} - stmgeia r0!, {r1, r3, r4, r5, r6, r7, r8, r9} - stmgeia r0!, {r1, r3, r4, r5, r6, r7, r8, r9} - stmgeia r0!, {r1, r3, r4, r5, r6, r7, r8, r9} - bgt mfill_loop - -mfill_remaining - - ; Fill up to 31 remaining pixels - - ; Fill 16 pixels - tst r2, #16 - stmneia r0!, {r1, r3, r4, r5, r6, r7, r8, r9} - stmneia r0!, {r1, r3, r4, r5, r6, r7, r8, r9} - - ; Fill 8 pixels - tst r2, #8 - stmneia r0!, {r1, r3, r4, r5, r6, r7, r8, r9} - - ; Fill 4 pixels - tst r2, #4 - stmneia r0!, {r1, r3, r4, r5} - - ; Fill 2 pixels - tst r2, #2 - stmneia r0!, {r1, r3} - - ; Fill last one - tst r2, #1 - strne r1, [r0] - - ldmfd sp!, {r4-r12, pc} ; pop and return - -;----------------------------------------------------------------------------- -; comp_func_Source_arm -; -; @brief -; -; @param dest Destination buffer (r0) -; @param src Source buffer (r1) -; @param length Length (r2) -; @param const_alpha Constant alpha (r3) -; -;--------------------------------------------------------------------------- -comp_func_Source_armv6 Function - stmfd sp!, {r4-r12, r14} - - cmp r3, #255 ; if(r3 == 255) - bne src2 ; branch if not - -src1 PixCpy r0, r1, r2 - - ldmfd sp!, {r4-r12, pc} ; pop and return - -src2 - ;ldr r14, =ComponentHalf ; load 0x800080 to r14 - mov r14, #0x800000 - add r14, r14, #0x80 - -src22 BlendRow PixelSourceConstAlpha - - ldmfd sp!, {r4-r12, pc} ; pop and return - -;----------------------------------------------------------------------------- -; comp_func_SourceOver_arm -; -; @brief -; -; @param dest Destination buffer (r0) -; @param src Source buffer (r1) -; @param length Length (r2) -; @param const_alpha Constant alpha (r3) -; -;--------------------------------------------------------------------------- -comp_func_SourceOver_armv6 Function - stmfd sp!, {r4-r12, r14} - - ;ldr r14, =ComponentHalf ; load 0x800080 to r14 - mov r14, #0x800000 - add r14, r14, #0x80 - - cmp r3, #255 ; if(r3 == 255) - bne srcovr2 ; branch if not - -srcovr1 BlendRow PixelSourceOver - - ldmfd sp!, {r4-r12, pc} ; pop and return - -srcovr2 - -srcovr22 BlendRow PixelSourceOverConstAlpha - - ldmfd sp!, {r4-r12, pc} ; pop and return - - - END ; File end diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index e718212..bcd601b 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -782,7 +782,8 @@ QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& /////////////////////////////////////////////////////////////////////////////// QCompleterPrivate::QCompleterPrivate() : widget(0), proxy(0), popup(0), cs(Qt::CaseSensitive), role(Qt::EditRole), column(0), - maxVisibleItems(7), sorting(QCompleter::UnsortedModel), wrap(true), eatFocusOut(true) + maxVisibleItems(7), sorting(QCompleter::UnsortedModel), wrap(true), eatFocusOut(true), + hiddenBecauseNoMatch(false) { } @@ -921,12 +922,14 @@ void QCompleterPrivate::showPopup(const QRect& rect) void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path) { Q_Q(QCompleter); -#ifndef QT_NO_LINEEDIT - QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget); - //the path given by QFileSystemModel does not end with / - if (lineEdit && !lineEdit->text().isEmpty() && !q->completionPrefix().isEmpty() && q->completionPrefix() != path + QLatin1Char('/')) + // Slot called when QFileSystemModel has finished loading. + // If we hide the popup because there was no match because the model was not loaded yet, + // we re-start the completion when we get the results + if (hiddenBecauseNoMatch + && prefix.startsWith(path) && prefix != (path + '/') + && widget) { q->complete(); -#endif + } } /*! @@ -1200,6 +1203,7 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) Q_D(QCompleter); if (d->eatFocusOut && o == d->widget && e->type() == QEvent::FocusOut) { + d->hiddenBecauseNoMatch = false; if (d->popup && d->popup->isVisible()) return true; } @@ -1378,6 +1382,7 @@ void QCompleter::complete(const QRect& rect) { Q_D(QCompleter); QModelIndex idx = d->proxy->currentIndex(false); + d->hiddenBecauseNoMatch = false; if (d->mode == QCompleter::InlineCompletion) { if (idx.isValid()) d->_q_complete(idx, true); @@ -1389,6 +1394,7 @@ void QCompleter::complete(const QRect& rect) || (d->mode == QCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) { if (d->popup) d->popup->hide(); // no suggestion, hide + d->hiddenBecauseNoMatch = true; return; } diff --git a/src/gui/util/qcompleter_p.h b/src/gui/util/qcompleter_p.h index 8f00793..19b76e5 100644 --- a/src/gui/util/qcompleter_p.h +++ b/src/gui/util/qcompleter_p.h @@ -93,6 +93,7 @@ public: bool eatFocusOut; QRect popupRect; + bool hiddenBecauseNoMatch; void showPopup(const QRect&); void _q_complete(QModelIndex, bool = false); diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 1183be6..d971f61 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -78,6 +78,7 @@ public: : layout(0), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly) #ifdef Q_WS_MAC , useHIToolBar(false) + , activateUnifiedToolbarAfterFullScreen(false) #endif #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR) , hasOldCursor(false) , cursorAdjusted(false) @@ -89,6 +90,7 @@ public: Qt::ToolButtonStyle toolButtonStyle; #ifdef Q_WS_MAC bool useHIToolBar; + bool activateUnifiedToolbarAfterFullScreen; #endif void init(); QList<int> hoverSeparator; @@ -1501,8 +1503,6 @@ bool QMainWindow::event(QEvent *event) \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling the toolbars out and back into the regular toolbar and vice versa when you swap out. - However, a good practice would be that turning off the unified toolbar before you call - showFullScreen() and restoring it after you call showNormal(). \endlist Setting this back to false will remove these restrictions. diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index e1b981c..3e1a95d 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -335,6 +335,7 @@ public: void cleanUpMacToolbarItems(); void fixSizeInUnifiedToolbar(QToolBar *tb) const; bool useHIToolBar; + bool activateUnifiedToolbarAfterFullScreen; void syncUnifiedToolbarVisibility(); bool blockVisiblityCheck; #endif diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 6437f6f..d10f951 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -105,12 +105,22 @@ void QHttpNetworkConnectionChannel::init() QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(_q_readyRead()), Qt::DirectConnection); + + // The disconnected() and error() signals may already come + // while calling connectToHost(). + // In case of a cached hostname or an IP this + // will then emit a signal to the user of QNetworkReply + // but cannot be caught because the user did not have a chance yet + // to connect to QNetworkReply's signals. + qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(_q_disconnected()), - Qt::DirectConnection); + Qt::QueuedConnection); QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(_q_error(QAbstractSocket::SocketError)), - Qt::DirectConnection); + Qt::QueuedConnection); + + #ifndef QT_NO_NETWORKPROXY QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(_q_proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index a637474..12fe094 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -944,6 +944,22 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera { Q_D(QNetworkAccessManager); + // 4.7 only hotfix fast path for data:// URLs + // In 4.8 this is solved with QNetworkReplyDataImpl and will work there + // This hotfix is done for not needing a QNetworkSession for data:// + if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) + && (req.url().scheme() == QLatin1String("data"))) { + QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); + QNetworkReplyImplPrivate *priv = reply->d_func(); + priv->manager = this; + priv->backend = new QNetworkAccessDataBackend(); + priv->backend->manager = this->d_func(); + priv->backend->setParent(reply); + priv->backend->reply = priv; + priv->setup(op, req, outgoingData); + return reply; + } + // fast path for GET on file:// URLs // Also if the scheme is empty we consider it a file. // The QNetworkAccessFileBackend will right now only be used for PUT diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index f759a95..ef273c1 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -1365,16 +1365,12 @@ void AccessPointsAvailabilityScanner::StartScanning() // don't need time-consuming scans (WLAN). // Note: EBearerIdWCDMA covers also GPRS bearer iConnectionMonitor.GetPckgAttribute(EBearerIdWCDMA, 0, KIapAvailability, iIapBuf, iStatus); - User::WaitForRequest(iStatus); - if (iStatus.Int() == KErrNone) { - iOwner.accessPointScanningReady(true,iIapBuf()); - } } else { iConnectionMonitor.GetPckgAttribute(EBearerIdAll, 0, KIapAvailability, iIapBuf, iStatus); - if (!IsActive()) { - SetActive(); - } } + + if (!IsActive()) + SetActive(); } void AccessPointsAvailabilityScanner::RunL() diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp index f8b228c..27e728a 100644 --- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp @@ -275,7 +275,7 @@ bool QMeeGoGraphicsSystem::unlockLiveTexture(Qt::HANDLE h) } } -void QMeeGoGraphicsSystem::queryLiveTexture(Qt::HANDLE h, void **data, int *pitch) +void QMeeGoGraphicsSystem::queryLiveTexture(Qt::HANDLE h, void **data, int *pitch, QImage::Format *f) { // FIXME Only allow this on locked surfaces if (! liveTexturePixmaps.contains(h)) { @@ -289,6 +289,14 @@ void QMeeGoGraphicsSystem::queryLiveTexture(Qt::HANDLE h, void **data, int *pitc EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h)); eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) data); eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) pitch); + + // Ok, here we know we just support those two formats. Real solution would be: + // in liveTexturePixmaps store a small structure containing the pixmap and the + // original Qt format. + if (liveTexturePixmaps.value(h)->depth() > 16) + *f = QImage::Format_ARGB32_Premultiplied; + else + *f = QImage::Format_RGB16; } Qt::HANDLE QMeeGoGraphicsSystem::liveTextureToEGLImage(Qt::HANDLE h) @@ -363,7 +371,9 @@ EGLSurface QMeeGoGraphicsSystem::getSurfaceForLiveTexturePixmap(QPixmap *pixmap) pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config); if (hasAlpha) - pixmapData->flags = pixmapData->flags | QX11PixmapData::GlSurfaceCreatedWithAlpha; + pixmapData->flags |= QX11PixmapData::GlSurfaceCreatedWithAlpha; + else + pixmapData->flags &= ~QX11PixmapData::GlSurfaceCreatedWithAlpha; if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) return NULL; @@ -439,9 +449,9 @@ bool qt_meego_live_texture_unlock(Qt::HANDLE h) return QMeeGoGraphicsSystem::unlockLiveTexture(h); } -void qt_meego_live_texture_query(Qt::HANDLE h, void **data, int *pitch) +void qt_meego_live_texture_query(Qt::HANDLE h, void **data, int *pitch, QImage::Format *f) { - return QMeeGoGraphicsSystem::queryLiveTexture(h, data, pitch); + return QMeeGoGraphicsSystem::queryLiveTexture(h, data, pitch, f); } Qt::HANDLE qt_meego_live_texture_to_egl_image(Qt::HANDLE h) diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h index 934d32d..fad0db6 100644 --- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h @@ -71,7 +71,7 @@ public: static void destroyLiveTexture(Qt::HANDLE h); static bool lockLiveTexture(Qt::HANDLE h); static bool unlockLiveTexture(Qt::HANDLE h); - static void queryLiveTexture(Qt::HANDLE h, void **data, int *pitch); + static void queryLiveTexture(Qt::HANDLE h, void **data, int *pitch, QImage::Format *format); static Qt::HANDLE liveTextureToEGLImage(Qt::HANDLE h); private: @@ -99,7 +99,7 @@ extern "C" { Q_DECL_EXPORT void m_live_texture_destroy(Qt::HANDLE h); Q_DECL_EXPORT bool m_live_texture_lock(Qt::HANDLE h); Q_DECL_EXPORT bool m_live_texture_unlock(Qt::HANDLE h); - Q_DECL_EXPORT void m_live_texture_query(Qt::HANDLE h, void **data, int *pitch); + Q_DECL_EXPORT void m_live_texture_query(Qt::HANDLE h, void **data, int *pitch, QImage::Format *f); Q_DECL_EXPORT Qt::HANDLE m_live_texture_to_egl_image(Qt::HANDLE h); } diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp index 84fc593..5473d09 100644 --- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp +++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp @@ -51,6 +51,24 @@ static EGLint preserved_image_attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, E QHash <void*, QMeeGoImageInfo*> QMeeGoPixmapData::sharedImagesMap; +// This helper method converts (in place) a QImage::Format_ARGB4444_Premultiplied to +// GL-friendly Format_RGBA4444_Premultiplied. Just swaps the bits around really. +static void qARGBA4ToRGBA4(QImage *image) +{ + unsigned char *raw = static_cast <unsigned char *> (image->data_ptr()->data); + // FIXME image.bytesPerLine() is broken. Returns 512 for 128x128 image while it should + // return 256 + int bytesPerLine = image->width() * 2; + + for (int y = 0; y < image->height(); y++) { + for (int x = 0; x < image->width(); x++) { + unsigned short *target = (unsigned short *) (raw + (y * bytesPerLine + (x * 2))); + // FIXME Oh yeah, that's broken with endianness. + *target = (*target << 4) | (* target >> 12); + } + } +} + /* Public */ QMeeGoPixmapData::QMeeGoPixmapData() : QGLPixmapData(QPixmapData::PixmapType) @@ -108,8 +126,6 @@ void QMeeGoPixmapData::fromEGLImage(Qt::HANDLE handle) QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), (EGLImageKHR) handle, EGL_HEIGHT, &newHeight); if (textureIsBound) { - // FIXME Remove this ugly hasAlphaChannel check when Qt lands the NoOpaqueCheck flag fix - // for QGLPixmapData. fromTexture(newTextureId, newWidth, newHeight, true); } else { qWarning("Failed to create a texture from an egl image!"); @@ -152,10 +168,9 @@ void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si) } if (textureIsBound) { - // FIXME Remove this ugly hasAlphaChannel check when Qt lands the NoOpaqueCheck flag fix - // for QGLPixmapData. fromTexture(newTextureId, newWidth, newHeight, (si.hasAlphaChannel() && const_cast<QImage &>(si).data_ptr()->checkForAlphaPixels())); + texture()->options &= ~QGLContext::InvertedYBindOption; softImage = si; QMeeGoPixmapData::registerSharedImage(handle, softImage); } else { @@ -171,15 +186,31 @@ Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image) QMeeGoExtensions::ensureInitialized(); glFinish(); - QGLPixmapData pixmapData(QPixmapData::PixmapType); - pixmapData.fromImage(image, 0); - GLuint textureId = pixmapData.bind(); + + GLuint textureId; + + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + if (image.hasAlphaChannel() && (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())) { + QImage convertedImage = image.convertToFormat(QImage::Format_ARGB4444_Premultiplied, Qt::DiffuseAlphaDither | Qt::DiffuseDither | Qt::PreferDither); + qARGBA4ToRGBA4(&convertedImage); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, convertedImage.bits()); + } else { + QImage convertedImage = image.convertToFormat(QImage::Format_RGB16, Qt::DiffuseAlphaDither | Qt::DiffuseDither | Qt::PreferDither); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, convertedImage.bits()); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glFinish(); + + glBindTexture(GL_TEXTURE_2D, textureId); EGLImageKHR eglimage = QEgl::eglCreateImageKHR(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->context(), EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer) textureId, preserved_image_attribs); + glDeleteTextures(1, &textureId); glFinish(); if (eglimage) { @@ -195,6 +226,7 @@ Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image) void QMeeGoPixmapData::updateFromSoftImage() { + // FIXME That's broken with recent 16bit textures changes. m_dirty = true; m_source = softImage; ensureCreated(); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertySplicing.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertySplicing.qml new file mode 100644 index 0000000..7deb84a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertySplicing.qml @@ -0,0 +1,10 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyDerivedObject { + property bool test: false + + Component.onCompleted: { + test = intProperty() + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp index 810a0f7..94135f9 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp @@ -109,6 +109,7 @@ void registerTypes() qmlRegisterExtendedType<MyBaseExtendedObject, BaseExtensionObject>("Qt.test", 1,0, "MyBaseExtendedObject"); qmlRegisterExtendedType<MyExtendedObject, ExtensionObject>("Qt.test", 1,0, "MyExtendedObject"); qmlRegisterType<MyTypeObject>("Qt.test", 1,0, "MyTypeObject"); + qmlRegisterType<MyDerivedObject>("Qt.test", 1,0, "MyDerivedObject"); qmlRegisterType<NumberAssignment>("Qt.test", 1,0, "NumberAssignment"); qmlRegisterExtendedType<DefaultPropertyExtendedObject, DefaultPropertyExtensionObject>("Qt.test", 1,0, "DefaultPropertyExtendedObject"); qmlRegisterType<OverrideDefaultPropertyObject>("Qt.test", 1,0, "OverrideDefaultPropertyObject"); diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index 220318d..40451c3 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -562,8 +562,27 @@ signals: }; Q_DECLARE_OPERATORS_FOR_FLAGS(MyTypeObject::MyFlags) +class MyDerivedObject : public MyTypeObject +{ + Q_OBJECT +public: + Q_INVOKABLE bool intProperty() const { + return true; + } +}; + Q_DECLARE_METATYPE(QScriptValue); -class MyInvokableObject : public QObject +class MyInvokableBaseObject : public QObject +{ + Q_OBJECT +public: + inline ~MyInvokableBaseObject() = 0; + + Q_INVOKABLE inline void method_inherited(int a); + Q_INVOKABLE inline void method_overload(); +}; + +class MyInvokableObject : public MyInvokableBaseObject { Q_OBJECT Q_ENUMS(TestEnum) @@ -599,16 +618,34 @@ public: Q_INVOKABLE void method_overload(int a) { invoke(16); m_actuals << a; } Q_INVOKABLE void method_overload(int a, int b) { invoke(17); m_actuals << a << b; } + Q_INVOKABLE void method_overload(QString a) { invoke(18); m_actuals << a; } - Q_INVOKABLE void method_with_enum(TestEnum e) { invoke(18); m_actuals << (int)e; } + Q_INVOKABLE void method_with_enum(TestEnum e) { invoke(19); m_actuals << (int)e; } + + Q_INVOKABLE int method_default(int a, int b = 19) { invoke(20); m_actuals << a << b; return b; } private: + friend class MyInvokableBaseObject; void invoke(int idx) { if (m_invoked != -1) m_invokedError = true; m_invoked = idx;} int m_invoked; bool m_invokedError; QVariantList m_actuals; }; +MyInvokableBaseObject::~MyInvokableBaseObject() {} + +void MyInvokableBaseObject::method_inherited(int a) +{ + static_cast<MyInvokableObject *>(this)->invoke(-3); + static_cast<MyInvokableObject *>(this)->m_actuals << a; +} + +// This is a hidden overload of the MyInvokableObject::method_overload() method +void MyInvokableBaseObject::method_overload() +{ + static_cast<MyInvokableObject *>(this)->invoke(-2); +} + class NumberAssignment : public QObject { Q_OBJECT diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 02832f3..e4e5a54 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -139,6 +139,7 @@ private slots: void strictlyEquals(); void compiled(); void numberAssignment(); + void propertySplicing(); void bug1(); void bug2(); @@ -1709,7 +1710,6 @@ void tst_qdeclarativeecmascript::callQtInvokables() QCOMPARE(o.actuals().at(0), QVariant(44)); QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(1)).isArray()); - // Test overloads - QML will always invoke the *last* method o.reset(); QCOMPARE(engine->evaluate("object.method_overload()").isError(), true); QCOMPARE(o.error(), false); @@ -1717,10 +1717,11 @@ void tst_qdeclarativeecmascript::callQtInvokables() QCOMPARE(o.actuals().count(), 0); o.reset(); - QCOMPARE(engine->evaluate("object.method_overload(10)").isError(), true); + QCOMPARE(engine->evaluate("object.method_overload(10)").isUndefined(), true); QCOMPARE(o.error(), false); - QCOMPARE(o.invoked(), -1); - QCOMPARE(o.actuals().count(), 0); + QCOMPARE(o.invoked(), 16); + QCOMPARE(o.actuals().count(), 1); + QCOMPARE(o.actuals().at(0), QVariant(10)); o.reset(); QCOMPARE(engine->evaluate("object.method_overload(10, 11)").isUndefined(), true); @@ -1731,10 +1732,40 @@ void tst_qdeclarativeecmascript::callQtInvokables() QCOMPARE(o.actuals().at(1), QVariant(11)); o.reset(); - QCOMPARE(engine->evaluate("object.method_with_enum(9)").isUndefined(), true); + QCOMPARE(engine->evaluate("object.method_overload(\"Hello\")").isUndefined(), true); QCOMPARE(o.error(), false); QCOMPARE(o.invoked(), 18); QCOMPARE(o.actuals().count(), 1); + QCOMPARE(o.actuals().at(0), QVariant(QString("Hello"))); + + o.reset(); + QCOMPARE(engine->evaluate("object.method_with_enum(9)").isUndefined(), true); + QCOMPARE(o.error(), false); + QCOMPARE(o.invoked(), 19); + QCOMPARE(o.actuals().count(), 1); + QCOMPARE(o.actuals().at(0), QVariant(9)); + + o.reset(); + QVERIFY(engine->evaluate("object.method_default(10)").strictlyEquals(QScriptValue(19))); + QCOMPARE(o.error(), false); + QCOMPARE(o.invoked(), 20); + QCOMPARE(o.actuals().count(), 2); + QCOMPARE(o.actuals().at(0), QVariant(10)); + QCOMPARE(o.actuals().at(1), QVariant(19)); + + o.reset(); + QVERIFY(engine->evaluate("object.method_default(10, 13)").strictlyEquals(QScriptValue(13))); + QCOMPARE(o.error(), false); + QCOMPARE(o.invoked(), 20); + QCOMPARE(o.actuals().count(), 2); + QCOMPARE(o.actuals().at(0), QVariant(10)); + QCOMPARE(o.actuals().at(1), QVariant(13)); + + o.reset(); + QCOMPARE(engine->evaluate("object.method_inherited(9)").isUndefined(), true); + QCOMPARE(o.error(), false); + QCOMPARE(o.invoked(), -3); + QCOMPARE(o.actuals().count(), 1); QCOMPARE(o.actuals().at(0), QVariant(9)); } @@ -2175,6 +2206,18 @@ void tst_qdeclarativeecmascript::numberAssignment() delete object; } +void tst_qdeclarativeecmascript::propertySplicing() +{ + QDeclarativeComponent component(&engine, TEST_FILE("propertySplicing.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test").toBool(), true); + + delete object; +} + // Test that assigning a null object works // Regressed with: df1788b4dbbb2826ae63f26bdf166342595343f4 void tst_qdeclarativeecmascript::nullObjectBinding() diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview-noCurrent.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview-noCurrent.qml new file mode 100644 index 0000000..1189649 --- /dev/null +++ b/tests/auto/declarative/qdeclarativegridview/data/gridview-noCurrent.qml @@ -0,0 +1,52 @@ +import QtQuick 1.0 + +Rectangle { + property int current: grid.currentIndex + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + Text { + text: index + } + Text { + x: 40 + text: wrapper.x + ", " + wrapper.y + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + Text { + y: 40 + id: textNumber + objectName: "textNumber" + text: number + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ] + GridView { + id: grid + objectName: "grid" + focus: true + width: 240 + height: 320 + currentIndex: -1 + cellWidth: 80 + cellHeight: 60 + delegate: myDelegate + model: testModel + } +} diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index f7acd87..327bba2 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -71,6 +71,7 @@ private slots: void moved(); void changeFlow(); void currentIndex(); + void noCurrentIndex(); void defaultValues(); void properties(); void propertyChanges(); @@ -696,9 +697,51 @@ void tst_QDeclarativeGridView::currentIndex() model.insertItem(0, "Foo", "1111"); QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); + // check removing highlight by setting currentIndex to -1; + gridview->setCurrentIndex(-1); + + QCOMPARE(gridview->currentIndex(), -1); + QVERIFY(!gridview->highlightItem()); + QVERIFY(!gridview->currentItem()); + delete canvas; } +void tst_QDeclarativeGridView::noCurrentIndex() +{ + TestModel model; + for (int i = 0; i < 60; i++) + model.addItem("Item" + QString::number(i), QString::number(i)); + + QDeclarativeView *canvas = new QDeclarativeView(0); + canvas->setFixedSize(240,320); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + QString filename(SRCDIR "/data/gridview-noCurrent.qml"); + canvas->setSource(QUrl::fromLocalFile(filename)); + + qApp->processEvents(); + + QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); + QVERIFY(gridview != 0); + + QDeclarativeItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + + // current index should be -1 + QCOMPARE(gridview->currentIndex(), -1); + QVERIFY(!gridview->currentItem()); + QVERIFY(!gridview->highlightItem()); + QCOMPARE(gridview->contentY(), 0.0); + + gridview->setCurrentIndex(5); + QCOMPARE(gridview->currentIndex(), 5); + QVERIFY(gridview->currentItem()); + QVERIFY(gridview->highlightItem()); +} + void tst_QDeclarativeGridView::changeFlow() { QDeclarativeView *canvas = createView(); diff --git a/tests/auto/declarative/qdeclarativelistview/data/listview-noCurrent.qml b/tests/auto/declarative/qdeclarativelistview/data/listview-noCurrent.qml new file mode 100644 index 0000000..1997010 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistview/data/listview-noCurrent.qml @@ -0,0 +1,50 @@ +import QtQuick 1.0 + +Rectangle { + property int current: list.currentIndex + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ] + ListView { + id: list + objectName: "list" + focus: true + currentIndex: -1 + width: 240 + height: 320 + delegate: myDelegate + highlightMoveSpeed: 1000 + model: testModel + } +} diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 2649c0d..080631c 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -85,6 +85,7 @@ private slots: void itemList(); void currentIndex(); + void noCurrentIndex(); void enforceRange(); void spacing(); void sections(); @@ -1087,9 +1088,52 @@ void tst_QDeclarativeListView::currentIndex() model.insertItem(0, "Foo", "1111"); QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); + // check removing highlight by setting currentIndex to -1; + listview->setCurrentIndex(-1); + + QCOMPARE(listview->currentIndex(), -1); + QVERIFY(!listview->highlightItem()); + QVERIFY(!listview->currentItem()); + delete canvas; } +void tst_QDeclarativeListView::noCurrentIndex() +{ + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), QString::number(i)); + + QDeclarativeView *canvas = new QDeclarativeView(0); + canvas->setFixedSize(240,320); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + QString filename(SRCDIR "/data/listview-noCurrent.qml"); + canvas->setSource(QUrl::fromLocalFile(filename)); + + qApp->processEvents(); + + QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // current index should be -1 at startup + // and we should not have a currentItem or highlightItem + QCOMPARE(listview->currentIndex(), -1); + QCOMPARE(listview->contentY(), 0.0); + QVERIFY(!listview->highlightItem()); + QVERIFY(!listview->currentItem()); + + listview->setCurrentIndex(2); + QCOMPARE(listview->currentIndex(), 2); + QVERIFY(listview->highlightItem()); + QVERIFY(listview->currentItem()); +} + void tst_QDeclarativeListView::itemList() { QDeclarativeView *canvas = createView(); diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/data/modelproperties.qml b/tests/auto/declarative/qdeclarativevisualdatamodel/data/modelproperties.qml new file mode 100644 index 0000000..8cd5763 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/data/modelproperties.qml @@ -0,0 +1,17 @@ +import QtQuick 1.0 + +ListView { + model: myModel + delegate: Item { + objectName: "delegate" + property variant test1: name + property variant test2: model.name + property variant test3: modelData + property variant test4: model.modelData + property variant test5: modelData.name + property variant test6: model + property variant test7: index + property variant test8: model.index + property variant test9: model.modelData.name + } +} diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/data/modelproperties2.qml b/tests/auto/declarative/qdeclarativevisualdatamodel/data/modelproperties2.qml new file mode 100644 index 0000000..67721c9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/data/modelproperties2.qml @@ -0,0 +1,17 @@ +import QtQuick 1.0 + +ListView { + model: myModel + delegate: Item { + objectName: "delegate" + property variant test1: display + property variant test2: model.display + property variant test3: modelData + property variant test4: model.modelData + property variant test5: modelData.display + property variant test6: model + property variant test7: index + property variant test8: model.index + property variant test9: model.modelData.display + } +} diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp index d73a872..0aad099 100644 --- a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp @@ -120,6 +120,7 @@ private slots: void childChanged(); void objectListModel(); void singleRole(); + void modelProperties(); private: QDeclarativeEngine engine; @@ -364,6 +365,113 @@ void tst_qdeclarativevisualdatamodel::singleRole() } } +void tst_qdeclarativevisualdatamodel::modelProperties() +{ + { + QDeclarativeView view; + + SingleRoleModel model; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(SRCDIR "/data/modelproperties.qml")); + + QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject()); + QVERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QDeclarativeItem *delegate = findItem<QDeclarativeItem>(contentItem, "delegate", 1); + QCOMPARE(delegate->property("test1").toString(),QString("two")); + QCOMPARE(delegate->property("test2").toString(),QString("two")); + QCOMPARE(delegate->property("test3").toString(),QString("two")); + QCOMPARE(delegate->property("test4").toString(),QString("two")); + QVERIFY(!delegate->property("test9").isValid()); + QCOMPARE(delegate->property("test5").toString(),QString("")); + QVERIFY(delegate->property("test6").value<QObject*>() != 0); + QCOMPARE(delegate->property("test7").toInt(),1); + QCOMPARE(delegate->property("test8").toInt(),1); + } + + { + QDeclarativeView view; + + QList<QObject*> dataList; + dataList.append(new DataObject("Item 1", "red")); + dataList.append(new DataObject("Item 2", "green")); + dataList.append(new DataObject("Item 3", "blue")); + dataList.append(new DataObject("Item 4", "yellow")); + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", QVariant::fromValue(dataList)); + + view.setSource(QUrl::fromLocalFile(SRCDIR "/data/modelproperties.qml")); + + QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject()); + QVERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QDeclarativeItem *delegate = findItem<QDeclarativeItem>(contentItem, "delegate", 1); + QCOMPARE(delegate->property("test1").toString(),QString("Item 2")); + QEXPECT_FAIL("", "QTBUG-13576", Continue); + QCOMPARE(delegate->property("test2").toString(),QString("Item 2")); + QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0); + QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0); + QCOMPARE(delegate->property("test5").toString(),QString("Item 2")); + QCOMPARE(delegate->property("test9").toString(),QString("Item 2")); + QVERIFY(delegate->property("test6").value<QObject*>() != 0); + QCOMPARE(delegate->property("test7").toInt(),1); + QCOMPARE(delegate->property("test8").toInt(),1); + } + + { + QDeclarativeView view; + + QStandardItemModel model; + initStandardTreeModel(&model); + + view.rootContext()->setContextProperty("myModel", &model); + + QUrl source(QUrl::fromLocalFile(SRCDIR "/data/modelproperties2.qml")); + + //3 items, 3 warnings each + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":9: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":9: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":9: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":15: TypeError: Result of expression 'model.modelData' [undefined] is not an object."); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":15: TypeError: Result of expression 'model.modelData' [undefined] is not an object."); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":15: TypeError: Result of expression 'model.modelData' [undefined] is not an object."); + + view.setSource(source); + + QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject()); + QVERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QDeclarativeItem *delegate = findItem<QDeclarativeItem>(contentItem, "delegate", 1); + QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item")); + QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item")); + QVERIFY(!delegate->property("test3").isValid()); + QVERIFY(!delegate->property("test4").isValid()); + QVERIFY(!delegate->property("test5").isValid()); + QVERIFY(!delegate->property("test9").isValid()); + QVERIFY(delegate->property("test6").value<QObject*>() != 0); + QCOMPARE(delegate->property("test7").toInt(),1); + QCOMPARE(delegate->property("test8").toInt(),1); + } + + //### should also test QStringList and QVariantList +} + template<typename T> T *tst_qdeclarativevisualdatamodel::findItem(QGraphicsObject *parent, const QString &objectName, int index) { diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/elide2.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/elide2.qml index edf0cb5..b772982 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/elide2.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/elide2.qml @@ -5,7 +5,7 @@ Rectangle { height: 100 Text { - width: NumberAnimation { from: 500; to: 0; loops: Animation.Infinite; duration: 5000 } + NumberAnimation on width { from: 500; to: 0; loops: Animation.Infinite; duration: 5000 } elide: Text.ElideRight text: 'Here is some very long text that we should truncate when sizing window' } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/multilength.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/multilength.qml index 6698421..3ef64ef 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/multilength.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/multilength.qml @@ -11,7 +11,7 @@ Rectangle { anchors.centerIn: parent Text { id: myText - width: NumberAnimation { from: 500; to: 0; loops: Animation.Infinite; duration: 1000 } + NumberAnimation on width { from: 500; to: 0; loops: Animation.Infinite; duration: 5000 } elide: "ElideRight" text: "Brevity is the soul of wit, and tediousness the limbs and outward flourishes.\x9CBrevity is a great charm of eloquence.\x9CBe concise!\x9CSHHHHHHHHHHHHHHHHHHHHHHHHHHHH" } diff --git a/tests/auto/modeltest/dynamictreemodel.cpp b/tests/auto/modeltest/dynamictreemodel.cpp index b572eb1..fa634b6 100644 --- a/tests/auto/modeltest/dynamictreemodel.cpp +++ b/tests/auto/modeltest/dynamictreemodel.cpp @@ -63,6 +63,13 @@ QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &pare QList<QList<qint64> > childIdColumns = m_childItems.value(parent.internalId()); + const qint64 grandParent = findParentId(parent.internalId()); + if (grandParent >= 0) { + QList<QList<qint64> > parentTable = m_childItems.value(grandParent); + Q_ASSERT(parent.column() < parentTable.size()); + QList<qint64> parentSiblings = parentTable.at(parent.column()); + Q_ASSERT(parent.row() < parentSiblings.size()); + } if (childIdColumns.size() == 0) return QModelIndex(); diff --git a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp index dbcccc9..b723253 100644 --- a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -1167,6 +1167,7 @@ void tst_QAbstractItemModel::testMoveToGrandParent_data() // Moving everything from one parent to another QTest::newRow("move12") << 0 << 9 << 10; + QTest::newRow("move13") << 0 << 9 << 0; } void tst_QAbstractItemModel::testMoveToGrandParent() @@ -1314,6 +1315,11 @@ void tst_QAbstractItemModel::testMoveToSibling_data() QTest::newRow("move09") << 8 << 8 << 4; QTest::newRow("move10") << 8 << 8 << 5; QTest::newRow("move11") << 8 << 8 << 6; + + // Move such that the destination parent no longer valid after the move. + // The destination parent is always QMI(5, 0), but after this move the + // row count is 5, so (5, 0) (used internally in QAIM) no longer refers to a valid index. + QTest::newRow("move12") << 0 << 4 << 0; } void tst_QAbstractItemModel::testMoveToSibling() diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index 1590528..650c328 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -119,6 +119,8 @@ private slots: void directoryModel_data(); void directoryModel(); + void fileSystemModel_data(); + void fileSystemModel(); void changingModel_data(); void changingModel(); @@ -149,15 +151,17 @@ private slots: void task253125_lineEditCompletion_data(); void task253125_lineEditCompletion(); void task247560_keyboardNavigation(); + void QTBUG_14292_filesystem(); private: - void filter(); + void filter(bool assync = false); void testRowCount(); enum ModelType { CASE_SENSITIVELY_SORTED_MODEL, CASE_INSENSITIVELY_SORTED_MODEL, DIRECTORY_MODEL, - HISTORY_MODEL + HISTORY_MODEL, + FILESYSTEM_MODEL }; void setSourceModel(ModelType); @@ -233,12 +237,21 @@ void tst_QCompleter::setSourceModel(ModelType type) completer->setModel(new QDirModel(completer)); completer->setCompletionColumn(0); break; + case FILESYSTEM_MODEL: + completer->setCsvCompletion(false); + { + QFileSystemModel *m = new QFileSystemModel(completer); + m->setRootPath("/"); + completer->setModel(m); + } + completer->setCompletionColumn(0); + break; default: qDebug() << "Invalid type"; } } -void tst_QCompleter::filter() +void tst_QCompleter::filter(bool assync) { QFETCH(QString, filterText); QFETCH(QString, step); @@ -250,6 +263,9 @@ void tst_QCompleter::filter() return; } + int times = 0; +retry: + completer->setCompletionPrefix(filterText); for (int i = 0; i < step.length(); i++) { @@ -265,9 +281,13 @@ void tst_QCompleter::filter() completer->setCurrentRow(row); } - //QModelIndex si = completer->currentIndex(); - //QCOMPARE(completer->model()->data(si).toString(), completion); - QVERIFY(0 == QString::compare(completer->currentCompletion(), completionText, completer->caseSensitivity())); + int r = QString::compare(completer->currentCompletion(), completionText, completer->caseSensitivity()); + if (assync && r && times < 10) { + times++; + QTest::qWait(50*times); + goto retry; + } + QVERIFY(!r); } // Testing get/set functions @@ -552,6 +572,7 @@ void tst_QCompleter::csMatchingOnCiSortedModel() void tst_QCompleter::directoryModel_data() { delete completer; + completer = new CsvCompleter; completer->setModelSorting(QCompleter::CaseSensitivelySortedModel); setSourceModel(DIRECTORY_MODEL); @@ -598,6 +619,57 @@ void tst_QCompleter::directoryModel() filter(); } +void tst_QCompleter::fileSystemModel_data() +{ + delete completer; + completer = new CsvCompleter; + completer->setModelSorting(QCompleter::CaseSensitivelySortedModel); + setSourceModel(FILESYSTEM_MODEL); + completer->setCaseSensitivity(Qt::CaseInsensitive); + + QTest::addColumn<QString>("filterText"); + QTest::addColumn<QString>("step"); + QTest::addColumn<QString>("completion"); + QTest::addColumn<QString>("completionText"); + + // NOTE: Add tests carefully, ensurely the paths exist on all systems + // Output is the sourceText; currentCompletionText() + + for (int i = 0; i < 2; i++) { + if (i == 1) + QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << ""; + +#if defined(Q_OS_WINCE) + QTest::newRow("()") << "" << "" << "/" << "/"; + QTest::newRow("()") << "\\Program" << "" << "Program Files" << "\\Program Files"; +#elif defined(Q_OS_WIN) + QTest::newRow("()") << "C" << "" << "C:" << "C:"; + QTest::newRow("()") << "C:\\Program" << "" << "Program Files" << "C:\\Program Files"; +#elif defined(Q_OS_SYMBIAN) + QTest::newRow("()") << "C" << "" << "C:" << "C:"; + QTest::newRow("()") << "C:\\re" << "" << "resource" << "C:\\resource"; +#elif defined (Q_OS_MAC) + QTest::newRow("()") << "" << "" << "/" << "/"; + QTest::newRow("(/a)") << "/a" << "" << "Applications" << "/Applications"; +// QTest::newRow("(/d)") << "/d" << "" << "Developer" << "/Developer"; +#else + QTest::newRow("()") << "" << "" << "/" << "/"; +#if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_OS_HPUX) + QTest::newRow("(/h)") << "/h" << "" << "home" << "/home"; +#endif + QTest::newRow("(/et)") << "/et" << "" << "etc" << "/etc"; + QTest::newRow("(/etc/passw)") << "/etc/passw" << "" << "passwd" << "/etc/passwd"; +#endif + } +} + +void tst_QCompleter::fileSystemModel() +{ + //QFileSystemModel is assync. + filter(true); +} + + void tst_QCompleter::changingModel_data() { } @@ -1381,5 +1453,80 @@ void tst_QCompleter::task247560_keyboardNavigation() QCOMPARE(edit.text(), QString("row 3 column 1")); } +void tst_QCompleter::QTBUG_14292_filesystem() +{ + QDir tmpDir = QDir::temp(); + qsrand(QTime::currentTime().msec()); + QString d = "tst_QCompleter_" + QString::number(qrand()); + QVERIFY(tmpDir.mkdir(d)); + +#if 0 + struct Cleanup { + QString dir; + ~Cleanup() { + qDebug() << dir << + QFile::remove(dir); } + } cleanup; + cleanup.dir = tmpDir.absolutePath()+"/" +d; +#endif + + QVERIFY(tmpDir.cd(d)); + QVERIFY(tmpDir.mkdir("hello")); + QVERIFY(tmpDir.mkdir("holla")); + + QLineEdit edit; + QCompleter comp; + QFileSystemModel model; + model.setRootPath(tmpDir.path()); + comp.setModel(&model); + edit.setCompleter(&comp); + + edit.show(); + QApplication::setActiveWindow(&edit); + QTest::qWaitForWindowShown(&edit); + QTRY_VERIFY(QApplication::activeWindow() == &edit); + edit.setFocus(); + QTRY_VERIFY(edit.hasFocus()); + + QVERIFY(!comp.popup()->isVisible()); + edit.setText(tmpDir.path()); + QTest::keyClick(&edit, '/'); + QTRY_VERIFY(comp.popup()->isVisible()); + QCOMPARE(comp.popup()->model()->rowCount(), 2); + QApplication::processEvents(); + QTest::keyClick(&edit, 'h'); + QCOMPARE(comp.popup()->model()->rowCount(), 2); + QTest::keyClick(&edit, 'e'); + QCOMPARE(comp.popup()->model()->rowCount(), 1); + QTest::keyClick(&edit, 'r'); + QTRY_VERIFY(!comp.popup()->isVisible()); + QVERIFY(tmpDir.mkdir("hero")); + QTRY_VERIFY(comp.popup()->isVisible()); + QCOMPARE(comp.popup()->model()->rowCount(), 1); + QTest::keyClick(comp.popup(), Qt::Key_Escape); + QTRY_VERIFY(!comp.popup()->isVisible()); + QVERIFY(tmpDir.mkdir("nothingThere")); + //there is no reason creating a file should open a popup, it did in Qt 4.7.0 + QTest::qWait(60); + QVERIFY(!comp.popup()->isVisible()); + + QTest::keyClick(&edit, Qt::Key_Backspace); + QTRY_VERIFY(comp.popup()->isVisible()); + QCOMPARE(comp.popup()->model()->rowCount(), 2); + QTest::keyClick(&edit, 'm'); + QTRY_VERIFY(!comp.popup()->isVisible()); + + QWidget w; + w.show(); + QApplication::setActiveWindow(&w); + QTest::qWaitForWindowShown(&w); + QTRY_VERIFY(!edit.hasFocus() && !comp.popup()->hasFocus()); + + QVERIFY(tmpDir.mkdir("hemo")); + //there is no reason creating a file should open a popup, it did in Qt 4.7.0 + QTest::qWait(60); + QVERIFY(!comp.popup()->isVisible()); +} + QTEST_MAIN(tst_QCompleter) #include "tst_qcompleter.moc" diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 5b03767..174e4aa 100644 --- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -61,13 +61,19 @@ private slots: void qgraphicsgridlayout(); void addItem_data(); void addItem(); + void alignment_data(); void alignment(); void alignment2(); void alignment2_data(); + void columnAlignment_data(); void columnAlignment(); + void columnCount_data(); void columnCount(); + void columnMaximumWidth_data(); void columnMaximumWidth(); + void columnMinimumWidth_data(); void columnMinimumWidth(); + void columnPreferredWidth_data(); void columnPreferredWidth(); void setColumnFixedWidth(); void columnSpacing(); @@ -78,12 +84,18 @@ private slots: void horizontalSpacing(); void itemAt(); void removeAt(); + void rowAlignment_data(); void rowAlignment(); + void rowCount_data(); void rowCount(); + void rowMaximumHeight_data(); void rowMaximumHeight(); + void rowMinimumHeight_data(); void rowMinimumHeight(); + void rowPreferredHeight_data(); void rowPreferredHeight(); void rowSpacing(); + void rowStretchFactor_data(); void rowStretchFactor(); void setColumnSpacing_data(); void setColumnSpacing(); @@ -98,6 +110,7 @@ private slots: void sizeHint(); void verticalSpacing_data(); void verticalSpacing(); + void layoutDirection_data(); void layoutDirection(); void removeLayout(); void defaultStretchFactors_data(); @@ -107,12 +120,14 @@ private slots: void avoidRecursionInInsertItem(); void styleInfoLeak(); void task236367_maxSizeHint(); + void heightForWidth(); + void heightForWidthWithSpanning(); }; class RectWidget : public QGraphicsWidget { public: - RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent){} + RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent), m_fnConstraint(0) {} void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { @@ -125,9 +140,12 @@ public: QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const { - if (m_sizeHints[which].isValid()) { + if (constraint.width() < 0 && constraint.height() < 0 && m_sizeHints[which].isValid()) { return m_sizeHints[which]; } + if (m_fnConstraint) { + return m_fnConstraint(which, constraint); + } return QGraphicsWidget::sizeHint(which, constraint); } @@ -136,7 +154,13 @@ public: updateGeometry(); } + void setConstraintFunction(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &)) { + m_fnConstraint = fnConstraint; + } + QSizeF m_sizeHints[Qt::NSizeHints]; + QSizeF (*m_fnConstraint)(Qt::SizeHint, const QSizeF &); + }; struct ItemDesc @@ -146,7 +170,8 @@ struct ItemDesc m_rowSpan(1), m_colSpan(1), m_sizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)), - m_align(0) + m_align(0), + m_fnConstraint(0) { } @@ -213,8 +238,20 @@ struct ItemDesc return (*this); } + ItemDesc &heightForWidth(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &)) { + m_fnConstraint = fnConstraint; + m_constraintOrientation = Qt::Vertical; + return (*this); + } + void apply(QGraphicsGridLayout *layout, QGraphicsWidget *item) { - item->setSizePolicy(m_sizePolicy); + QSizePolicy sp = m_sizePolicy; + if (m_fnConstraint) { + sp.setHeightForWidth(m_constraintOrientation == Qt::Vertical); + //sp.setWidthForHeight(m_constraintOrientation == Qt::Horizontal); + } + + item->setSizePolicy(sp); for (int i = 0; i < Qt::NSizeHints; ++i) { if (!m_sizes[i].isValid()) continue; @@ -233,6 +270,7 @@ struct ItemDesc break; } } + layout->addItem(item, m_pos.first, m_pos.second, m_rowSpan, m_colSpan); layout->setAlignment(item, m_align); } @@ -240,6 +278,7 @@ struct ItemDesc void apply(QGraphicsGridLayout *layout, RectWidget *item) { for (int i = 0; i < Qt::NSizeHints; ++i) item->setSizeHint((Qt::SizeHint)i, m_sizeHints[i]); + item->setConstraintFunction(m_fnConstraint); apply(layout, static_cast<QGraphicsWidget*>(item)); } @@ -251,6 +290,9 @@ struct ItemDesc QSizeF m_sizeHints[Qt::NSizeHints]; QSizeF m_sizes[Qt::NSizeHints]; Qt::Alignment m_align; + + Qt::Orientation m_constraintOrientation; + QSizeF (*m_fnConstraint)(Qt::SizeHint, const QSizeF &); }; typedef QList<ItemDesc> ItemList; @@ -342,7 +384,7 @@ void tst_QGraphicsGridLayout::qgraphicsgridlayout() layout.verticalSpacing(); } -static void populateLayout(QGraphicsGridLayout *gridLayout, int width, int height) +static void populateLayout(QGraphicsGridLayout *gridLayout, int width, int height, bool hasHeightForWidth = false) { for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { @@ -351,6 +393,9 @@ static void populateLayout(QGraphicsGridLayout *gridLayout, int width, int heigh item->setPreferredSize(25, 25); item->setMaximumSize(50, 50); gridLayout->addItem(item, y, x); + QSizePolicy policy = item->sizePolicy(); + policy.setHeightForWidth(hasHeightForWidth); + item->setSizePolicy(policy); } } } @@ -367,18 +412,22 @@ static void populateLayout(QGraphicsGridLayout *gridLayout, int width, int heigh * |xxxx|+---|---+| * +----+----+----+ */ -static void populateLayoutWithSpansAndHoles(QGraphicsGridLayout *gridLayout) +static void populateLayoutWithSpansAndHoles(QGraphicsGridLayout *gridLayout, bool hasHeightForWidth = false) { QGraphicsWidget *item = new RectWidget(); item->setMinimumSize(10, 10); item->setPreferredSize(25, 25); item->setMaximumSize(50, 50); + QSizePolicy sizepolicy = item->sizePolicy(); + sizepolicy.setHeightForWidth(hasHeightForWidth); + item->setSizePolicy(sizepolicy); gridLayout->addItem(item, 0, 0, 1, 2); item = new RectWidget(); item->setMinimumSize(10, 10); item->setPreferredSize(25, 25); item->setMaximumSize(50, 50); + item->setSizePolicy(sizepolicy); gridLayout->addItem(item, 1, 1, 1, 2); } @@ -431,19 +480,28 @@ void tst_QGraphicsGridLayout::addItem() delete layout; } +void tst_QGraphicsGridLayout::alignment_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} + // public Qt::Alignment alignment(QGraphicsLayoutItem* item) const void tst_QGraphicsGridLayout::alignment() { #ifdef Q_WS_MAC QSKIP("Resizing a QGraphicsWidget to effectiveSizeHint(Qt::MaximumSize) is currently not supported on mac", SkipAll); #endif + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -495,6 +553,14 @@ void tst_QGraphicsGridLayout::alignment() delete widget; } +void tst_QGraphicsGridLayout::columnAlignment_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} + // public void setColumnAlignment(int column, Qt::Alignment alignment) // public Qt::Alignment columnAlignment(int column) const void tst_QGraphicsGridLayout::columnAlignment() @@ -502,13 +568,14 @@ void tst_QGraphicsGridLayout::columnAlignment() #ifdef Q_WS_MAC QSKIP("Resizing a QGraphicsWidget to effectiveSizeHint(Qt::MaximumSize) is currently not supported on mac", SkipAll); #endif + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(1); widget->setContentsMargins(0, 0, 0, 0); @@ -554,9 +621,17 @@ void tst_QGraphicsGridLayout::columnAlignment() delete widget; } +void tst_QGraphicsGridLayout::columnCount_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} // public int columnCount() const void tst_QGraphicsGridLayout::columnCount() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); @@ -588,7 +663,7 @@ void tst_QGraphicsGridLayout::columnCount() // ### Talk with Jasmin. Not sure if removeAt() should adjust columnCount(). widget->setLayout(0); layout = new QGraphicsGridLayout(); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); QCOMPARE(layout->columnCount(), 3); layout->removeAt(5); layout->removeAt(3); @@ -603,16 +678,24 @@ void tst_QGraphicsGridLayout::columnCount() delete widget; } +void tst_QGraphicsGridLayout::columnMaximumWidth_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} // public qreal columnMaximumWidth(int column) const void tst_QGraphicsGridLayout::columnMaximumWidth() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -638,16 +721,24 @@ void tst_QGraphicsGridLayout::columnMaximumWidth() delete widget; } +void tst_QGraphicsGridLayout::columnMinimumWidth_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} // public qreal columnMinimumWidth(int column) const void tst_QGraphicsGridLayout::columnMinimumWidth() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -673,16 +764,24 @@ void tst_QGraphicsGridLayout::columnMinimumWidth() delete widget; } +void tst_QGraphicsGridLayout::columnPreferredWidth_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} // public qreal columnPreferredWidth(int column) const void tst_QGraphicsGridLayout::columnPreferredWidth() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -992,16 +1091,25 @@ void tst_QGraphicsGridLayout::removeAt() delete widget; } +void tst_QGraphicsGridLayout::rowAlignment_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} + // public Qt::Alignment rowAlignment(int row) const void tst_QGraphicsGridLayout::rowAlignment() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 2, 3); + populateLayout(layout, 2, 3, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(1); widget->setContentsMargins(0, 0, 0, 0); @@ -1051,17 +1159,26 @@ void tst_QGraphicsGridLayout::rowAlignment() delete widget; } +void tst_QGraphicsGridLayout::rowCount_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} + // public int rowCount() const // public int columnCount() const void tst_QGraphicsGridLayout::rowCount() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 2, 3); + populateLayout(layout, 2, 3, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); widget->setContentsMargins(0, 0, 0, 0); @@ -1071,23 +1188,32 @@ void tst_QGraphicsGridLayout::rowCount() // with spans and holes... widget->setLayout(0); layout = new QGraphicsGridLayout(); - populateLayoutWithSpansAndHoles(layout); + populateLayoutWithSpansAndHoles(layout, hasHeightForWidth); QCOMPARE(layout->rowCount(), 2); QCOMPARE(layout->columnCount(), 3); delete widget; } +void tst_QGraphicsGridLayout::rowMaximumHeight_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} + // public qreal rowMaximumHeight(int row) const void tst_QGraphicsGridLayout::rowMaximumHeight() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout; scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 2, 3); + populateLayout(layout, 2, 3, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -1113,16 +1239,24 @@ void tst_QGraphicsGridLayout::rowMaximumHeight() delete widget; } +void tst_QGraphicsGridLayout::rowMinimumHeight_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} // public qreal rowMinimumHeight(int row) const void tst_QGraphicsGridLayout::rowMinimumHeight() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 2, 3); + populateLayout(layout, 2, 3, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -1148,16 +1282,24 @@ void tst_QGraphicsGridLayout::rowMinimumHeight() delete widget; } +void tst_QGraphicsGridLayout::rowPreferredHeight_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} // public qreal rowPreferredHeight(int row) const void tst_QGraphicsGridLayout::rowPreferredHeight() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 2, 3); + populateLayout(layout, 2, 3, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -1246,16 +1388,25 @@ void tst_QGraphicsGridLayout::rowSpacing() } +void tst_QGraphicsGridLayout::rowStretchFactor_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} + // public int rowStretchFactor(int row) const void tst_QGraphicsGridLayout::rowStretchFactor() { + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 2, 3); + populateLayout(layout, 2, 3, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -1279,9 +1430,12 @@ void tst_QGraphicsGridLayout::setColumnSpacing_data() { QTest::addColumn<int>("column"); QTest::addColumn<qreal>("spacing"); - QTest::newRow("null") << 0 << qreal(0.0); - QTest::newRow("10") << 0 << qreal(10.0); + QTest::addColumn<bool>("hasHeightForWidth"); + QTest::newRow("null") << 0 << qreal(0.0) << false; + QTest::newRow("10") << 0 << qreal(10.0) << false; + QTest::newRow("null, hasHeightForWidth") << 0 << qreal(0.0) << true; + QTest::newRow("10, hasHeightForWidth") << 0 << qreal(10.0) << true; } // public void setColumnSpacing(int column, qreal spacing) @@ -1289,6 +1443,7 @@ void tst_QGraphicsGridLayout::setColumnSpacing() { QFETCH(int, column); QFETCH(qreal, spacing); + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); @@ -1296,7 +1451,7 @@ void tst_QGraphicsGridLayout::setColumnSpacing() QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); qreal oldSpacing = layout->columnSpacing(column); @@ -1333,9 +1488,12 @@ void tst_QGraphicsGridLayout::setRowSpacing_data() { QTest::addColumn<int>("row"); QTest::addColumn<qreal>("spacing"); - QTest::newRow("null") << 0 << qreal(0.0); - QTest::newRow("10") << 0 << qreal(10.0); + QTest::addColumn<bool>("hasHeightForWidth"); + QTest::newRow("null") << 0 << qreal(0.0) << false; + QTest::newRow("10") << 0 << qreal(10.0) << false; + QTest::newRow("null, hasHeightForWidth") << 0 << qreal(0.0) << true; + QTest::newRow("10, hasHeightForWidth") << 0 << qreal(10.0) << true; } // public void setRowSpacing(int row, qreal spacing) @@ -1343,6 +1501,7 @@ void tst_QGraphicsGridLayout::setRowSpacing() { QFETCH(int, row); QFETCH(qreal, spacing); + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); @@ -1350,7 +1509,7 @@ void tst_QGraphicsGridLayout::setRowSpacing() QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); qreal oldSpacing = layout->rowSpacing(row); @@ -1364,21 +1523,25 @@ void tst_QGraphicsGridLayout::setRowSpacing() void tst_QGraphicsGridLayout::setSpacing_data() { QTest::addColumn<qreal>("spacing"); - QTest::newRow("zero") << qreal(0.0); - QTest::newRow("17") << qreal(17.0); + QTest::addColumn<bool>("hasHeightForWidth"); + QTest::newRow("zero") << qreal(0.0) << false; + QTest::newRow("17") << qreal(17.0) << false; + QTest::newRow("zero, hasHeightForWidth") << qreal(0.0) << true; + QTest::newRow("17, hasHeightForWidth") << qreal(17.0) << true; } // public void setSpacing(qreal spacing) void tst_QGraphicsGridLayout::setSpacing() { QFETCH(qreal, spacing); + QFETCH(bool, hasHeightForWidth); QGraphicsScene scene; QGraphicsView view(&scene); QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); QGraphicsGridLayout *layout = new QGraphicsGridLayout(); scene.addItem(widget); widget->setLayout(layout); - populateLayout(layout, 3, 2); + populateLayout(layout, 3, 2, hasHeightForWidth); layout->setContentsMargins(0, 0, 0, 0); QSizeF sh = layout->sizeHint(Qt::PreferredSize, QSizeF()); qreal oldVSpacing = layout->verticalSpacing(); @@ -1509,8 +1672,18 @@ void tst_QGraphicsGridLayout::verticalSpacing() delete widget; } +void tst_QGraphicsGridLayout::layoutDirection_data() +{ + QTest::addColumn<bool>("hasHeightForWidth"); + + QTest::newRow("") << false; + QTest::newRow("hasHeightForWidth") << true; +} + void tst_QGraphicsGridLayout::layoutDirection() { + QFETCH(bool, hasHeightForWidth); + QGraphicsScene scene; QGraphicsView view(&scene); @@ -1533,6 +1706,12 @@ void tst_QGraphicsGridLayout::layoutDirection() w4->setMinimumSize(30, 20); layout->addItem(w4, 1, 1); + QSizePolicy policy = w1->sizePolicy(); + policy.setHeightForWidth(hasHeightForWidth); + w1->setSizePolicy(policy); + w2->setSizePolicy(policy); + w4->setSizePolicy(policy); + layout->setAlignment(w2, Qt::AlignRight); layout->setAlignment(w3, Qt::AlignLeft); @@ -2116,6 +2295,17 @@ void tst_QGraphicsGridLayout::alignment2() delete widget; } +static QSizeF hfw1(Qt::SizeHint, const QSizeF &constraint) +{ + QSizeF result(constraint); + if (constraint.width() < 0 && constraint.height() < 0) { + return QSizeF(50, 400); + } else if (constraint.width() >= 0) { + result.setHeight(20000./constraint.width()); + } + return result; +} + void tst_QGraphicsGridLayout::geometries_data() { @@ -2145,6 +2335,57 @@ void tst_QGraphicsGridLayout::geometries_data() << QRectF(0, 0, 60,10) << QRectF(0, 10, 60,10) ); + // change layout height and verify + QTest::newRow("hfw-h401") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .minSize(QSizeF(40,-1)) + .preferredSize(QSizeF(50,-1)) + .maxSize(QSizeF(500, -1)) + .heightForWidth(hfw1) + ) + << QSizeF(100, 401) + << (RectList() + << QRectF(0, 0, 50, 1) << QRectF(50, 0, 50, 1) + << QRectF(0, 1, 50,100) << QRectF(50, 1, 50,400) + ); + + QTest::newRow("hfw-h410") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .minSize(QSizeF(40,40)) + .preferredSize(QSizeF(50,400)) + .maxSize(QSizeF(500, 500)) + .heightForWidth(hfw1) + ) + << QSizeF(100, 410) + << (RectList() + << QRectF(0, 0, 50,10) << QRectF(50, 0, 50,10) + << QRectF(0, 10, 50,100) << QRectF(50, 10, 50,400) + ); + } void tst_QGraphicsGridLayout::geometries() @@ -2215,6 +2456,177 @@ void tst_QGraphicsGridLayout::task236367_maxSizeHint() QCOMPARE(widget->size(), QSizeF(w, h)); } +/* +static qreal hfw(qreal w) +{ + if (w == 0) + return 20000; + return 20000/w; +} +*/ +static QSizeF hfw(Qt::SizeHint /*which*/, const QSizeF &constraint) +{ + QSizeF result(constraint); + const qreal cw = constraint.width(); + const qreal ch = constraint.height(); + if (cw < 0 && ch < 0) { + return QSizeF(200, 100); + } else if (cw >= 0) { + result.setHeight(20000./cw); + } else if (cw == 0) { + result.setHeight(20000); + } else if (ch >= 0) { + result.setWidth(20000./ch); + } else if (ch == 0) { + result.setWidth(20000); + } + + return result; +} + +static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired) +{ + Q_ASSERT(sumDesired != 0.0); + return desired * qPow(sumAvailable / sumDesired, desired / sumDesired); +} + +static void expectedWidth(qreal minSize1, qreal prefSize1, + qreal minSize2, qreal prefSize2, + qreal targetSize, qreal *width1, qreal *width2) +{ + qreal sumAvail,factor1,factor2; + // stretch behaviour is different below and above preferred size... + if (targetSize < prefSize1 + prefSize2) { + sumAvail = targetSize - minSize1 - minSize2; + const qreal desired1 = prefSize1 - minSize1; + const qreal desired2 = prefSize2 - minSize2; + const qreal sumDesired = desired1 + desired2; + factor1 = growthFactorBelowPreferredSize(desired1, sumAvail, sumDesired); + factor2 = growthFactorBelowPreferredSize(desired2, sumAvail, sumDesired); + const qreal sumFactors = factor1 + factor2; + *width1 = sumAvail*factor1/sumFactors + minSize1; + *width2 = sumAvail*factor2/sumFactors + minSize2; + } else { + sumAvail = targetSize - prefSize1 - prefSize2; + factor1 = prefSize1; + factor2 = prefSize2; + const qreal sumFactors = factor1 + factor2; + *width1 = sumAvail*factor1/sumFactors + prefSize1; + *width2 = sumAvail*factor2/sumFactors + prefSize2; + } +} + + +bool qFuzzyCompare(const QSizeF &a, const QSizeF &b) +{ + return qFuzzyCompare(a.width(), b.width()) && qFuzzyCompare(a.height(), b.height()); +} + +void tst_QGraphicsGridLayout::heightForWidth() +{ + QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsGridLayout *layout = new QGraphicsGridLayout; + widget->setLayout(layout); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + RectWidget *w00 = new RectWidget; + w00->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); + w00->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); + w00->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); + layout->addItem(w00, 0, 0); + + RectWidget *w01 = new RectWidget; + w01->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); + w01->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); + w01->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); + layout->addItem(w01, 0, 1); + + RectWidget *w10 = new RectWidget; + w10->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); + w10->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); + w10->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); + layout->addItem(w10, 1, 0); + + RectWidget *w11 = new RectWidget; + w11->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); + w11->setSizeHint(Qt::MaximumSize, QSizeF(30000,30000)); + w11->setConstraintFunction(hfw); + QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); + sp.setHeightForWidth(true); + w11->setSizePolicy(sp); + layout->addItem(w11, 1, 1); + + QSizeF prefSize = layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); + QCOMPARE(prefSize, QSizeF(10+200, 10+100)); + + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(2, -1)), QSizeF(2, 20001)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(2, -1)), QSizeF(2, 20010)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(2, -1)), QSizeF(2, 20100)); + qreal width1; + qreal width2; + expectedWidth(1, 10, 1, 200, 20, &width1, &width2); + QSizeF expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(20, -1)), expectedSize); + expectedSize.rheight()+=9; + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(20, -1)), expectedSize); + expectedSize.rheight()+=90; + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(20, -1)), expectedSize); + + expectedWidth(1, 10, 1, 200, 300, &width1, &width2); + expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(300, -1)), expectedSize); + expectedSize.rheight()+=9; + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(300, -1)), expectedSize); + // the height of the hfw widget is shorter than the one to the left, which is 100, so + // the total height of the last row is 100 (which leaves the layout height to be 200) + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(300, -1)), QSizeF(300, 200)); + + // the hfw item is shorter than the item to the left + expectedWidth(1, 10, 1, 200, 500, &width1, &width2); + expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(500, -1)), expectedSize); + expectedSize.rheight()+=9; + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(500, -1)), expectedSize); + // the height of the hfw widget is shorter than the one to the left, which is 100, so + // the total height of the last row is 100 (which leaves the layout height to be 200) + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(500, -1)), QSizeF(500, 200)); + +} + +void tst_QGraphicsGridLayout::heightForWidthWithSpanning() +{ + QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsGridLayout *layout = new QGraphicsGridLayout; + widget->setLayout(layout); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + RectWidget *w = new RectWidget; + w->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); + w->setSizeHint(Qt::MaximumSize, QSizeF(30000,30000)); + w->setConstraintFunction(hfw); + QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); + sp.setHeightForWidth(true); + w->setSizePolicy(sp); + layout->addItem(w, 0,0,2,2); + + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1)), QSizeF(1, 100)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)), QSizeF(200, 100)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, -1)), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(200, -1)), QSizeF(200, 100)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(200, -1)), QSizeF(200, 100)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, QWIDGETSIZE_MAX)); + + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(2, -1)), QSizeF(2, 10000)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(2, -1)), QSizeF(2, 10000)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(2, -1)), QSizeF(2, QWIDGETSIZE_MAX)); + + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(200, -1)), QSizeF(200, 100)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(200, -1)), QSizeF(200, 100)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, QWIDGETSIZE_MAX)); +} + QTEST_MAIN(tst_QGraphicsGridLayout) #include "tst_qgraphicsgridlayout.moc" diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 306b5f8..88714e6 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -291,6 +291,8 @@ private Q_SLOTS: void qtbug12908compressedHttpReply(); + void getFromUnreachableIp(); + // NOTE: This test must be last! void parentingRepliesToTheApp(); }; @@ -4301,6 +4303,19 @@ void tst_QNetworkReply::qtbug12908compressedHttpReply() QCOMPARE(reply->error(), QNetworkReply::NoError); } +void tst_QNetworkReply::getFromUnreachableIp() +{ + QNetworkAccessManager manager; + + QNetworkRequest request(QUrl("http://255.255.255.255/42/23/narf/narf/narf")); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(reply->error() != QNetworkReply::NoError); +} // NOTE: This test must be last testcase in tst_qnetworkreply! void tst_QNetworkReply::parentingRepliesToTheApp() diff --git a/tools/assistant/lib/qhelpgenerator.cpp b/tools/assistant/lib/qhelpgenerator.cpp index 85bdd75..f94031b 100644 --- a/tools/assistant/lib/qhelpgenerator.cpp +++ b/tools/assistant/lib/qhelpgenerator.cpp @@ -712,14 +712,15 @@ bool QHelpGenerator::insertKeywords(const QList<QHelpDataIndexItem> &keywords, d->query->exec(QLatin1String("BEGIN")); QSet<QString> indices; foreach (const QHelpDataIndexItem &itm, keywords) { - - /* - * Identical ids make no sense and just confuse the Assistant user, - * so we ignore all repetitions. - */ + // Identical ids make no sense and just confuse the Assistant user, + // so we ignore all repetitions. if (indices.contains(itm.identifier)) continue; - indices.insert(itm.identifier); + + // Still empty ids should be ignored, as otherwise we will include only + // the first keyword with an empty id. + if (!itm.identifier.isEmpty()) + indices.insert(itm.identifier); pos = itm.reference.indexOf(QLatin1Char('#')); fileName = itm.reference.left(pos); diff --git a/tools/designer/src/lib/shared/qtresourcemodel.cpp b/tools/designer/src/lib/shared/qtresourcemodel.cpp index 709f389..e3fc805 100644 --- a/tools/designer/src/lib/shared/qtresourcemodel.cpp +++ b/tools/designer/src/lib/shared/qtresourcemodel.cpp @@ -428,10 +428,10 @@ void QtResourceModelPrivate::removeOldPaths(QtResourceSet *resourceSet, const QS void QtResourceModelPrivate::setWatcherEnabled(const QString &path, bool enable) { - m_fileWatcher->removePath(path); - - if (!enable) + if (!enable) { + m_fileWatcher->removePath(path); return; + } QFileInfo fi(path); if (fi.exists()) diff --git a/tools/qmeegographicssystemhelper/qmeegolivepixmap.cpp b/tools/qmeegographicssystemhelper/qmeegolivepixmap.cpp index b9dbb2b..5e36631 100644 --- a/tools/qmeegographicssystemhelper/qmeegolivepixmap.cpp +++ b/tools/qmeegographicssystemhelper/qmeegolivepixmap.cpp @@ -118,20 +118,20 @@ QImage* QMeeGoLivePixmap::lock() void *data = NULL; int pitch = 0; + QImage::Format format; if (! QMeeGoRuntime::lockLiveTexture(d->handle)) { qWarning("Failed to lock a live texture!"); return new QImage(); } - QMeeGoRuntime::queryLiveTexture(d->handle, &data, &pitch); + QMeeGoRuntime::queryLiveTexture(d->handle, &data, &pitch, &format); if (data == NULL || pitch == 0) { qWarning("Failed to query the live texture!"); return new QImage(); } - // FIXME Bug here! FIX FIX FIX FIX FIX FIX - return new QImage((uchar *) data, width(), height(), QImage::Format_RGB16); + return new QImage((uchar *) data, width(), height(), format); } void QMeeGoLivePixmap::release(QImage *img) diff --git a/tools/qmeegographicssystemhelper/qmeegoruntime.cpp b/tools/qmeegographicssystemhelper/qmeegoruntime.cpp index 44f9f58..215dffc 100644 --- a/tools/qmeegographicssystemhelper/qmeegoruntime.cpp +++ b/tools/qmeegographicssystemhelper/qmeegoruntime.cpp @@ -62,7 +62,7 @@ typedef Qt::HANDLE (*QMeeGoLiveTextureCreateFunc) (int w, int h, QImage::Format typedef bool (*QMeeGoLiveTextureLockFunc) (Qt::HANDLE h); typedef bool (*QMeeGoLiveTextureUnlockFunc) (Qt::HANDLE h); typedef void (*QMeeGoLiveTextureDestroyFunc) (Qt::HANDLE h); -typedef void (*QMeeGoLiveTextureQueryFunc) (Qt::HANDLE h, void **data, int *pitch); +typedef void (*QMeeGoLiveTextureQueryFunc) (Qt::HANDLE h, void **data, int *pitch, QImage::Format *format); typedef Qt::HANDLE (*QMeeGoLiveTextureToEglImageFunc) (Qt::HANDLE h); static QMeeGoImageToEglSharedImageFunc qt_meego_image_to_egl_shared_image = NULL; @@ -216,11 +216,11 @@ void QMeeGoRuntime::destroyLiveTexture(Qt::HANDLE h) qt_meego_live_texture_destroy(h); } -void QMeeGoRuntime::queryLiveTexture(Qt::HANDLE h, void **data, int *pitch) +void QMeeGoRuntime::queryLiveTexture(Qt::HANDLE h, void **data, int *pitch, QImage::Format *format) { ENSURE_INITIALIZED; Q_ASSERT(qt_meego_live_texture_query); - qt_meego_live_texture_query(h, data, pitch); + qt_meego_live_texture_query(h, data, pitch, format); } Qt::HANDLE QMeeGoRuntime::liveTextureToEGLImage(Qt::HANDLE handle) diff --git a/tools/qmeegographicssystemhelper/qmeegoruntime.h b/tools/qmeegographicssystemhelper/qmeegoruntime.h index 048b9be..9f2d505 100644 --- a/tools/qmeegographicssystemhelper/qmeegoruntime.h +++ b/tools/qmeegographicssystemhelper/qmeegoruntime.h @@ -60,7 +60,7 @@ public: static bool lockLiveTexture(Qt::HANDLE h); static bool unlockLiveTexture(Qt::HANDLE h); static void destroyLiveTexture(Qt::HANDLE h); - static void queryLiveTexture(Qt::HANDLE h, void **data, int *pitch); + static void queryLiveTexture(Qt::HANDLE h, void **data, int *pitch, QImage::Format *format); static Qt::HANDLE liveTextureToEGLImage(Qt::HANDLE); private: diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 5e169d8..9f9eba0 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -1518,6 +1518,7 @@ void QDeclarativeViewer::updateSizeHints(bool initial) //qWarning() << "USH: R2V: setting free size "; layout()->setSizeConstraint(QLayout::SetNoConstraint); layout()->activate(); + setMinimumSize(QSize(1,1)); setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); canvas->setMinimumSize(QSize(0,0)); canvas->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); diff --git a/tools/qtconfig/mainwindow.cpp b/tools/qtconfig/mainwindow.cpp index 9675f99..4fe2868 100644 --- a/tools/qtconfig/mainwindow.cpp +++ b/tools/qtconfig/mainwindow.cpp @@ -81,7 +81,7 @@ QT_BEGIN_NAMESPACE // external use ignore them // extern bool Q_CORE_EXPORT qt_resolve_symlinks; -static const char *appearance_text = +static const char *appearance_text = QT_TRANSLATE_NOOP("MainWindow", "<p><b><font size+=2>Appearance</font></b></p>" "<hr>" "<p>Use this tab to customize the appearance of your Qt applications.</p>" @@ -95,9 +95,9 @@ static const char *appearance_text = "To customize colors further, press the Tune Palette button to open " "the advanced palette editor." "<p>The Preview Window shows what the selected Style and colors look " -"like."; +"like."); -static const char *font_text = +static const char *font_text = QT_TRANSLATE_NOOP("MainWindow", "<p><b><font size+=2>Fonts</font></b></p>" "<hr>" "<p>Use this tab to select the default font for your Qt applications. " @@ -114,9 +114,9 @@ static const char *font_text = "Korean characters that are not found in the Lucida font will be taken " "from the Mincho font. Because the font substitutions are " "lists, you can also select multiple families, such as Song Ti (for " -"use with Chinese text)."; +"use with Chinese text)."); -static const char *interface_text = +static const char *interface_text = QT_TRANSLATE_NOOP("MainWindow", "<p><b><font size+=2>Interface</font></b></p>" "<hr>" "<p>Use this tab to customize the feel of your Qt applications.</p>" @@ -131,10 +131,10 @@ static const char *interface_text = "at 0 will disable the Global Strut feature</p>" "<p>XIM (Extended Input Methods) are used for entering characters in " "languages that have large character sets, for example, Chinese and " -"Japanese."; +"Japanese."); // ### What does the 'Enhanced support for languages written R2L do? -static const char *printer_text = +static const char *printer_text = QT_TRANSLATE_NOOP("MainWindow", "<p><b><font size+=2>Printer</font></b></p>" "<hr>" "<p>Use this tab to configure the way Qt generates output for the printer." @@ -145,14 +145,14 @@ static const char *printer_text = "size will be bigger." "<p>When using font embedding you can select additional directories where " "Qt should search for embeddable font files. By default, the X " -"server font path is used."; +"server font path is used."); -static const char *phonon_text = +static const char *phonon_text = QT_TRANSLATE_NOOP("MainWindow", "<p><b><font size+=2>Phonon</font></b></p>" "<hr>" "<p>Use this tab to configure the Phonon GStreamer multimedia backend. " "<p>It is reccommended to leave all settings on \"Auto\" to let " -"Phonon determine your settings automatically."; +"Phonon determine your settings automatically."); static QColorGroup::ColorRole centralFromItem( int item ) { diff --git a/translations/assistant_ja.ts b/translations/assistant_ja.ts index c449e00..c449e00 100755..100644 --- a/translations/assistant_ja.ts +++ b/translations/assistant_ja.ts diff --git a/translations/linguist_ja.ts b/translations/linguist_ja.ts index 2f948e8..2f948e8 100755..100644 --- a/translations/linguist_ja.ts +++ b/translations/linguist_ja.ts diff --git a/translations/qt_ja.ts b/translations/qt_ja.ts index 095631e..095631e 100755..100644 --- a/translations/qt_ja.ts +++ b/translations/qt_ja.ts diff --git a/util/s60pixelmetrics/pm_mapperapp.cpp b/util/s60pixelmetrics/pm_mapperapp.cpp index a88499d..d68a0b0 100644 --- a/util/s60pixelmetrics/pm_mapperapp.cpp +++ b/util/s60pixelmetrics/pm_mapperapp.cpp @@ -166,6 +166,7 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) else bufferPtr.Append(_L("screen.")); ShowL( *buffer, last ); + CleanupStack::PopAndDestroy( buffer ); } break; case ECmdStatus: @@ -257,7 +258,7 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) bufferPtr.Append(_L("Orientation cannot be changed.")); ShowL( *buffer, last ); bufferPtr.Zero(); - delete buffer; + CleanupStack::PopAndDestroy( buffer ); break; } #endif //__SERIES60_31__ @@ -278,7 +279,7 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) bufferPtr.Append(_L("Orientation changed.")); ShowL( *buffer, last ); bufferPtr.Zero(); - delete buffer; + CleanupStack::PopAndDestroy( buffer ); break; } case ECmdStartCalculations: @@ -787,11 +788,14 @@ void CPixelMetricsMapperAppUi::CreateHeaderFileL() const CleanupStack::PopAndDestroy(); //sourceFile } - bufferLayoutHdr = bufferLayoutHdr.Left(bufferLayoutHdr.Length()-2); - bufferPMData = bufferPMData.Left(bufferPMData.Length()-2); - textFile.Write(bufferLayoutHdr); - textFile.Write(KCRLF); - textFile.Write(bufferPMData); + if (fileCount > 0) + { + bufferLayoutHdr = bufferLayoutHdr.Left(bufferLayoutHdr.Length()-2); + bufferPMData = bufferPMData.Left(bufferPMData.Length()-2); + textFile.Write(bufferLayoutHdr); + textFile.Write(KCRLF); + textFile.Write(bufferPMData); + } delete dirList; CleanupStack::PopAndDestroy(); //file |