diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-08-12 00:06:53 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-08-12 00:06:53 (GMT) |
commit | add9c43407a63c28f1107b9a77e74f6f62593246 (patch) | |
tree | 63df6f0d12bf8ffb4e94727fba290cd95a6dc788 | |
parent | 263bdc38f494e5d0be69b61c92ca6456fc4db330 (diff) | |
parent | af7d477b4c02cb4576ffae2e510cd53afaa2fba4 (diff) | |
download | Qt-add9c43407a63c28f1107b9a77e74f6f62593246.zip Qt-add9c43407a63c28f1107b9a77e74f6f62593246.tar.gz Qt-add9c43407a63c28f1107b9a77e74f6f62593246.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: (31 commits)
Fix typos in docs
Layout items had the wrong size if the layout was resized to maximum.
Disable minRightBearing optimization in QTextLayout on Mac
Added one test for QRegExp
QMetaObject::normalizeSignature avoid reading past the string in case of invalid signature given.
Fix (implement!) hfw/wfh in QGridLayoutEngine
Fixed a bug in implementation of sizeHint() when there was a constraint
Add text decoration support to QStaticText
Fix QString::arg: When specifying %L1, the group separator would be added even if the local specify QLocale::OmitGroupSeparator
QtDeclarative: get rid of warnings in public header
doc: Clarify documentation of QStaticText
Fix scrollbar randomly popping up in QPlainTextEdit
Remove the definition of QT_HAVE_NEON from qt.prf
Use the fast Neon conversion for converting colors of jpeg images.
Do the conversion from RGB888 to RGB32 using Neon
Move the build of Neon file from painting.pri to gui.pro
QSharedPointer documentation: specify that it is not safe to operate on the same object in different threads
compilation with QT_NO_DEPRECATED
Test we do not have compiler warnings in our headers with more options
QStyleSheet documentation: QMenu's tear-off is styled with ::tearoff
...
67 files changed, 1688 insertions, 279 deletions
diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index b25d000..ce35f26 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -27,7 +27,7 @@ /*! \title Qt Quick -\page declarativeui.html +\page qtquick.html \brief Qt Quick provides a declarative framework for building highly dynamic, custom user interfaces. diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc index 413eb59..b4f4c83 100644 --- a/doc/src/declarative/qtdeclarative.qdoc +++ b/doc/src/declarative/qtdeclarative.qdoc @@ -48,7 +48,7 @@ \endcode For more information on the Qt Declarative module, see the - \l{declarativeui.html}{Qt Quick} documentation. + \l{Qt Quick} documentation. */ diff --git a/doc/src/deployment/deployment.qdoc b/doc/src/deployment/deployment.qdoc index 020ca16..00771ed 100644 --- a/doc/src/deployment/deployment.qdoc +++ b/doc/src/deployment/deployment.qdoc @@ -1458,8 +1458,10 @@ /*! \page deployment-symbian.html \contentspage Deploying Qt Applications + \ingroup qtsymbian + \title Deploying an Application on the Symbian Platform - \title Deploying an Application on the Symbian platform + \section1 Overview Applications are deployed to Symbian devices in signed \c .sis package files. The \c .sis file content is controlled with \c .pkg files. The \c .pkg file contains a set @@ -1469,10 +1471,17 @@ to end-users some changes are needed. This document describes what changes are typically needed and how to implement them. + \section1 Requirements + + Download the latest release of the Smart Installer from + \l{http://get.qt.nokia.com/nokiasmartinstaller/}, and install it on top + of the Qt package. + \section1 Static Linking - Qt for the Symbian platform does currently not support static linking of - Qt libraries. + Qt for the Symbian platform does not currently support static linking of + Qt libraries with application binaries. You will need to build shared + libraries as described below and link your application with them. \section1 Shared Libraries @@ -1518,7 +1527,7 @@ S60 3rd edition FP1, S60 3rd edition FP2 and S60 5th edition devices. Now we are ready to compile the application and create the application - deployment file. Run \c qmake to create Symbian specific makefiles, resources (\.rss) + deployment file. Run \c qmake to create Symbian specific makefiles, resources (\c .rss) and deployment packaging files (\c .pkg). And do build to create the application binaries and resources. @@ -1548,4 +1557,14 @@ For more information about creating a \c .sis file and installing it to device see also \l {The Symbian platform - Introduction to Qt#Installing your own applications}{here}. + \section1 Further Reading + + This document aims to cover the common case for developers who want to + deploy Qt applications on devices using the Smart Installer. It does not + aim to cover every possible way of installing applications, Qt and other + dependencies on a device. + + A wider selection of deployment methods is described in the + \l{Deploying a Qt Application article} on the Symbian Foundation + Developer Wiki. */ diff --git a/doc/src/examples/simpletreemodel.qdoc b/doc/src/examples/simpletreemodel.qdoc index 16cf8b7..88aa27a 100644 --- a/doc/src/examples/simpletreemodel.qdoc +++ b/doc/src/examples/simpletreemodel.qdoc @@ -32,7 +32,7 @@ The Simple Tree Model example shows how to create a basic, read-only hierarchical model to use with Qt's standard view classes. For a description of simple non-hierarchical list and table models, see the - \l{model-view-programming.html}{Model/View Programming} overview. + \l{Model/View Programming} overview. \image simpletreemodel-example.png @@ -41,7 +41,7 @@ of the data to simplify and standardize the way it is accessed. Simple models represent data as a table of items, and allow views to access this data via an - \l{model-view-programming.html#model-indexes} {index-based} + \l{Model/View Programming#model-indexes} {index-based} system. More generally, models can be used to represent data in the form of a tree structure by allowing each item to act as a parent to a table of child items. diff --git a/doc/src/examples/spinboxdelegate.qdoc b/doc/src/examples/spinboxdelegate.qdoc index da65831..44308ca 100644 --- a/doc/src/examples/spinboxdelegate.qdoc +++ b/doc/src/examples/spinboxdelegate.qdoc @@ -42,9 +42,8 @@ \image spinboxdelegate-example.png This concepts behind this example are covered in the - \l{model-view-programming.html#delegate-classes}{Delegate Classes} - chapter of the \l{model-view-programming.html}{Model/View - Programming} overview. + \l{Model/View Programming#Delegate Classes}{Delegate Classes} chapter + of the \l{Model/View Programming} overview. \section1 SpinBoxDelegate Class Definition diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc index 61c9da2..e901124c 100644 --- a/doc/src/external-resources.qdoc +++ b/doc/src/external-resources.qdoc @@ -416,5 +416,15 @@ /*! \externalpage http://opensource.org/licenses/bsd-license.php - \title BSD License + \title New and Modified BSD Licenses +*/ + +/*! + \externalpage http://developer.symbian.org/wiki/index.php/Platform_Security_%28Fundamentals_of_Symbian_C%2B%2B%29#Self-Signed_Applications + \title Symbian Platform Security +*/ + +/*! + \externalpage http://developer.symbian.org/wiki/index.php/Deploying_a_Qt_Application + \title Deploying a Qt Application article */ diff --git a/doc/src/frameworks-technologies/gestures.qdoc b/doc/src/frameworks-technologies/gestures.qdoc index 927df22..f7c8312 100644 --- a/doc/src/frameworks-technologies/gestures.qdoc +++ b/doc/src/frameworks-technologies/gestures.qdoc @@ -60,7 +60,8 @@ \section1 Using Standard Gestures with Widgets Gestures can be enabled for instances of QWidget and QGraphicsObject subclasses. - An object that accepts gesture input is referred to as a \e{target object}. + An object that accepts gesture input is referred to throughout the documentation + as a \e{target object}. To enable a gesture for a target object, call its QWidget::grabGesture() or QGraphicsObject::grabGesture() function with an argument describing the @@ -69,13 +70,57 @@ \snippet examples/gestures/imagegestures/imagewidget.cpp enable gestures - In the above code, the gesture is set up in the constructor of the target object + In the above code, the gestures are set up in the constructor of the target object itself. + \section1 Handling Events + When the user performs a gesture, QGestureEvent events will be delivered to the target object, and these can be handled by reimplementing the QWidget::event() handler function for widgets or QGraphicsItem::sceneEvent() for graphics objects. + As one target object can subscribe to more than one gesture type, the QGestureEvent + can contain more than one QGesture, indicating several possible gestures are active + at the same time. It is then up to the widget to determine how to handle those + multiple gestures and choose if some should be canceled in favor of others. + + Each QGesture contained within a QGestureEvent object can be accepted() or ignored() + individually, or all together. Additionally, you can query the individual QGesture + data objects (the state) using several getters. + + \section2 Standard Procedure for Event Handling + + A QGesture is by default accepted when it arrives at your widget. However, it is good + practice to always explicitly accept or reject a gesture. The general rule is that, if + you accept a gesture, you are using it. If you are ignoring it you are not interested + in it. Ignoring a gesture may mean it gets offered to another target object, or it will + get canceled. + + Each QGesture has several states it goes through; there is a well defined way to change + the state, typically the user input is the cause of state changes (by starting and + stopping interaction, for instance) but the widget can also cause state changes. + + The first time a particular QGesture is delivered to a widget or graphics item, it will + be in the Qt::GestureStarted state. The way you handle the gesture at this point + influences whether you can interact with it later. + + \list + \o Accepting the gesture means the widget acts on the gesture and there will follow + gestures with the Qt::GestureUpdatedstate. + \o Ignoring the gesture will mean the gesture will never be offered to you again. + It will be offered to a parent widget or item as well. + \o Calling setGestureCancelPolicy() on the gesture when it is in its starting state, + and is also accepted can cause other gestures to be canceled. + \endlist + + Using QGesture::CancelAllInContext to cancel a gesture will cause all gestures, in any + state, to be canceled unless they are explicitly accepted. This means that active + gestures on children will get canceled. It also means that gestures delivered in the + same QGestureEvent will get canceled if the widget ignores them. This can be a useful + way to filter out all gestures except the one you are interested in. + + \section2 Example Event Handling + For convenience, the \l{Image Gestures Example} reimplements the general \l{QWidget::}{event()} handler function and delegates gesture events to a specialized gestureEvent() function: diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index 0609eb8..38586ef 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -65,18 +65,19 @@ </div> <div class="sectionlist tricol"> <ul> - <li><a href="qt-basic-concepts.html">Basic Concepts</a></li> + <li><a href="qt-basic-concepts.html">Basic Qt Architecture</a></li> <li><a href="qt-gui-concepts.html">UI Components</a></li> - <li><a href="developing-with-qt.html">Cross-platform & Platform-specific</a></li> - <li><a href="technology-apis.html">Qt API's for standard technologies </a></li> + <li><a href="developing-with-qt.html">Cross-platform & Platform-specific Development</a></li> + <li><a href="technology-apis.html">Qt & standard technologies </a></li> <li><a href="best-practices.html">Qt How-to's & best practices</a></li> </ul> </div> <div class="sectionlist"> <ul> - <li><a href="declarativeui.html">Qt Quick</a></li> + <li><a href="qtquick.html">Qt Quick</a></li> <li><a href="qdeclarativeintroduction.html">Introduction to QML</a></li> <li><a href="qdeclarativeelements.html">QML Elements</a></li> + <li><a href="qt-gui-concepts.html">UI components</a></li> <li><a href="model-view-programming.html">Model/View Programming</a></li> <li><a href="qt-network.html">Network Programming</a></li> <li><a href="qt-graphics.html">Graphics and Printing</a></li> @@ -101,8 +102,7 @@ <li><a href="assistant-manual.html">Qt Assistant</a></li> <li><a href="qmake-manual.html">Qt qmake</a></li> <li><a href="http://doc.qt.nokia.com/qtsimulator-1.0/simulator-description.html">Qt Simulator</a></li> - <li><a href="http://qt.nokia.com/developer/eclipse-integration">Eclipse Integration</a></li> - <li><a href="http://qt.nokia.com/products/appdev">Add-On Products and Services</a></li> + <li><a href="http://qt.nokia.com/developer/eclipse-integration">Integration</a> and <a href="http://qt.nokia.com/products/appdev">add-ins</a></li> <li><a href="qvfb.html">Virtual Framebuffer</a></li> </ul> </div> diff --git a/doc/src/modules.qdoc b/doc/src/modules.qdoc index 941459b..8912490 100644 --- a/doc/src/modules.qdoc +++ b/doc/src/modules.qdoc @@ -110,7 +110,6 @@ /*! \module QtMultimedia - \page qtmultimedia-module.html \title QtMultimedia Module \ingroup modules diff --git a/doc/src/overviews.qdoc b/doc/src/overviews.qdoc index caf9404..1c35a63 100644 --- a/doc/src/overviews.qdoc +++ b/doc/src/overviews.qdoc @@ -55,8 +55,7 @@ These pages are about Qt's traditional set of GUI components for building both native look ^ feel and custom UI's for the desktop - environment. Use \l {declarativeui.html} {Qt Quick} for building - UI's for mobile devices. + environment. Use \l{Qt Quick} for building UI's for mobile devices. \generatelist {related} */ diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc index afb17c4..701707e 100644 --- a/doc/src/platforms/symbian-introduction.qdoc +++ b/doc/src/platforms/symbian-introduction.qdoc @@ -86,12 +86,12 @@ \tableofcontents - \section1 Required tools + \section1 Required Tools See \l{Qt for the Symbian platform Requirements} to see what tools are required to use Qt for the Symbian platform. - \section1 Installing Qt and running demos + \section1 Installing Qt and Running Demos Follow the instructions found in \l{Installing Qt on the Symbian platform from a Binary Package} to learn how to install Qt using a binary package and how to build and run Qt demos. @@ -99,7 +99,7 @@ Follow the instructions found in \l{Installing Qt on the Symbian platform} to learn how to install Qt using using source package and how to build and run the Qt demos. - \section1 Building your own applications + \section1 Building Your Own Applications If you are new to Qt development, have a look at \l{How to Learn Qt}. In general, the difference between developing a @@ -112,12 +112,19 @@ \snippet doc/src/snippets/code/doc_src_symbian-introduction.qdoc 0 For more information on how to use qmake have a look at the \l - {qmake Tutorial}. + {qmake Tutorial}. In particular, see the + \l{qmake Platform Notes#Symbian platform}{qmake Platform Notes} for + details of Symbian-specific build settings. Now you can build the Qt for the Symbian platform application with - standard build tools. By default, running \c make will produce binaries for - the emulator. However, the Symbian platform comes with several alternative - build targets, as shown in the table below: + standard build tools. + + \section2 Alternative Build Targets + + By default, running \c make will produce binaries for the emulator. + However, the Symbian platform comes with several alternative + build targets that can be used to create binaries for target hardware + and deploy them on devices, as shown in the table below: \table \row \o \c debug-winscw \o Build debug binaries for the emulator (default). @@ -149,19 +156,30 @@ To work on your project in Carbide, simply import the \c .pro file by right clicking on the project explorer and executing "Import...". - \section2 Smart Installer + \section1 Running Applications from the Command Line - The Smart Installer makes sure that deployed applications have all the Qt dependencies - they need to run on a device. + The application can be launched on the emulator using \c{make run} command. - Download the latest release of the Smart Installer from \l{http://get.qt.nokia.com/nokiasmartinstaller/}, - and install it on top of the Qt package. + The application can be launched on a device using \c{make runonphone} command. + When this command is invoked, a \c .sis file is first created as if \c{make sis} + command was invoked (see above for details). + \bold{Note:} Running the application on a device using this command requires + \c TRK application to be running on the device. - \section1 Installing your own applications + Additional environment variables that can be utilized with these commands are: + \table + \row \o \c QT_RUN_OPTIONS \o Any command line parameters you wish to pass + to your application. + \row \o \c QT_RUN_ON_PHONE_OPTIONS \o Options for runonphone application. + Execute \c runonphone from command line for + more information about available options. + \c{make runonphone} only. + \endtable + + \section1 Installing Your Own Applications To install your own applications on hardware, you need a signed \c .sis file. - (Refer to the \l{http://developer.symbian.org/wiki/index.php/Platform_Security_%28Fundamentals_of_Symbian_C%2B%2B%29#Self-Signed_Applications} - {Platform Security Article} for more informations about self-signing.) + (Refer to the \l{Symbian Platform Security} article for more informations about self-signing.) The signed \c .sis file can be created with \c make \c sis target. \c sis target is only supported for executables or projects with \c DEPLOYMENT statements. By default the \c sis target will create signed \c .sis file for last build @@ -220,23 +238,19 @@ \snippet doc/src/snippets/code/doc_src_symbian-introduction.qdoc 5 - \section1 Running applications from command line + \section1 Deployment and the Smart Installer - The application can be launched on the emulator using \c{make run} command. + Although some Symbian devices may already have a version of Qt installed + on them, there needs to be a way to ensure that an appropriate version + of Qt is available for your application to use. Rather than deploy the + required Qt libraries with your application, the preferred way to + package Qt applications for deployment is to download and use the Smart + Installer. - The application can be launched on a device using \c{make runonphone} command. - When this command is invoked, a \c .sis file is first created as if \c{make sis} - command was invoked (see above for details). - \bold{Note:} Running the application on a device using this command requires - \c TRK application to be running on the device. + The Smart Installer makes sure that deployed applications have all the + Qt dependencies they need to run on a device, performing the necessary + updates when the user installs the application. - Additional environment variables that can be utilized with these commands are: - \table - \row \o \c QT_RUN_OPTIONS \o Any command line parameters you wish to pass - to your application. - \row \o \c QT_RUN_ON_PHONE_OPTIONS \o Options for runonphone application. - Execute \c runonphone from command line for - more information about available options. - \c{make runonphone} only. - \endtable + More information about deployment can be found in the + \l{Deploying an Application on the Symbian Platform} document. */ diff --git a/doc/src/qt-webpages.qdoc b/doc/src/qt-webpages.qdoc index 0c61285..5d9b41b 100644 --- a/doc/src/qt-webpages.qdoc +++ b/doc/src/qt-webpages.qdoc @@ -234,3 +234,8 @@ \externalpage http://qt.gitorious.org \title Public Qt Repository */ + +/*! + \externalpage http://get.qt.nokia.com/nokiasmartinstaller/ + \title Smart Installer +*/ diff --git a/doc/src/widgets-and-layouts/stylesheet.qdoc b/doc/src/widgets-and-layouts/stylesheet.qdoc index 475de3d..5c72570 100644 --- a/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -925,7 +925,7 @@ The scroller is styled using the \l{#scroller-sub}{::scroller}. - The tear-off is styled using the \l{#tear-off-sub}{::tear-off}. + The tear-off is styled using the \l{#tearoff-sub}{::tearoff}. See \l{Qt Style Sheets Examples#Customizing QMenu}{Customizing QMenu} for an example. @@ -3337,7 +3337,7 @@ \o The tear indicator of a QTabBar. \row - \o \c ::tear-off \target tear-off-sub + \o \c ::tearoff \target tearoff-sub \o The tear-off indicator of a QMenu. \row diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 07c89dd..4fd804d 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -208,7 +208,6 @@ mac { } #SIMD defines: -neon: DEFINES += QT_HAVE_NEON mmx:DEFINES += QT_HAVE_MMX 3dnow:DEFINES += QT_HAVE_3DNOW sse:DEFINES += QT_HAVE_SSE QT_HAVE_MMXEXT diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index bc8ef9f..728bdf9 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -53,6 +53,9 @@ symbian: { DEPLOYMENT = partial_upgrade $$DEPLOYMENT } -neon: QMAKE_CXXFLAGS *= -mfpu=neon +neon { + DEFINES += QT_HAVE_NEON + QMAKE_CXXFLAGS *= -mfpu=neon +} diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 79a38cd..9854e68 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1009,8 +1009,11 @@ QByteArray QMetaObject::normalizedSignature(const char *method) int argdepth = 0; int templdepth = 0; while (*d) { - if (argdepth == 1) + if (argdepth == 1) { d = qNormalizeType(d, templdepth, result); + if (!*d) //most likely an invalid signature. + break; + } if (*d == '(') ++argdepth; if (*d == ')') diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index f102598..5fac960 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -67,8 +67,8 @@ QSharedPointer and QWeakPointer are thread-safe and operate atomically on the pointer value. Different threads can also access - the same QSharedPointer or QWeakPointer object at the same time - without need for locking mechanisms. + the QSharedPointer or QWeakPointer pointing to the same object at + the same time without need for locking mechanisms. It should be noted that, while the pointer value can be accessed in this manner, QSharedPointer and QWeakPointer provide no diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 5ff0f97..a3148fb 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -150,7 +150,9 @@ enum CPUFeatures { Q_CORE_EXPORT uint qDetectCPUFeatures(); -Q_CORE_EXPORT uint qDetectCPUFeatures(); + +#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \ + for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i) QT_END_NAMESPACE diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index d6ab5da..2fd9a0b 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -6645,8 +6645,9 @@ QString QString::arg(qlonglong a, int fieldWidth, int base, const QChar &fillCha QString locale_arg; if (d.locale_occurrences > 0) { QLocale locale; - locale_arg = locale.d()->longLongToString(a, -1, base, fieldWidth, - flags | QLocalePrivate::ThousandsGroup); + if (!locale.numberOptions() & QLocale::OmitGroupSeparator) + flags |= QLocalePrivate::ThousandsGroup; + locale_arg = locale.d()->longLongToString(a, -1, base, fieldWidth, flags); } return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar); @@ -6688,8 +6689,9 @@ QString QString::arg(qulonglong a, int fieldWidth, int base, const QChar &fillCh QString locale_arg; if (d.locale_occurrences > 0) { QLocale locale; - locale_arg = locale.d()->unsLongLongToString(a, -1, base, fieldWidth, - flags | QLocalePrivate::ThousandsGroup); + if (!locale.numberOptions() & QLocale::OmitGroupSeparator) + flags |= QLocalePrivate::ThousandsGroup; + locale_arg = locale.d()->unsLongLongToString(a, -1, base, fieldWidth, flags); } return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar); @@ -6822,7 +6824,8 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, const QChar & if (d.locale_occurrences > 0) { QLocale locale; - flags |= QLocalePrivate::ThousandsGroup; + if (!locale.numberOptions() & QLocale::OmitGroupSeparator) + flags |= QLocalePrivate::ThousandsGroup; locale_arg = locale.d()->doubleToString(a, prec, form, fieldWidth, flags); } diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index e1fcb36..bf771a8 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -231,6 +231,7 @@ void QDBusConnectionManager::setConnection(const QString &name, QDBusConnectionP \value ExportAllInvokables export all of this object's invokables \value ExportAllContents export all of this object's contents \value ExportChildObjects export this object's child objects + \sa registerObject(), QDBusAbstractAdaptor, {usingadaptors.html}{Using adaptors} */ diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 5771f84..380c6ad 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -426,7 +426,7 @@ QDeclarativePathView::~QDeclarativePathView() The model provides a set of data that is used to create the items for the view. For large or dynamic datasets the model is usually provided by a C++ model object. - Models can also be created directly in XML, using the ListModel element. + Models can also be created directly in QML, using the ListModel element. \sa {qmlmodels}{Data Models} */ @@ -650,8 +650,8 @@ void QDeclarativePathViewPrivate::setOffset(qreal o) so as to stay with the current item. The below example demonstrates how to make a simple highlight. Note the use - of the PathView.onPath property to ensure that the highlight is hidden - when flicked off of the path. + of the \l{PathView::onPath}{PathView.onPath} attached property to ensure that + the highlight is hidden when flicked away from the path. \code Component { diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index 2b268fb..68e7e9a 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -133,13 +133,13 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate() create items as they are required. Also, note that Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects. - For example, it cannot be used to repeat QtObjects: + For example, it cannot be used to repeat QObjects: \badcode Item { - //XXX does not work! Can't repeat QtObject as it doesn't derive from Item. + //XXX does not work! Can't repeat QObject as it doesn't derive from Item. Repeater { model: 10 - QtObject {} + QObject {} } } \endcode diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp index 340bfa7..ea68327 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.cpp +++ b/src/declarative/qml/qdeclarativeimageprovider.cpp @@ -59,13 +59,13 @@ public: \list \o Loaded using QPixmaps rather than actual image files - \o Loaded asynchronously in a separate thread, if imageType() is \l Image + \o Loaded asynchronously in a separate thread, if imageType() is \l{QDeclarativeImageProvider::ImageType}{ImageType::Image} \endlist To specify that an image should be loaded by an image provider, use the \bold {"image:"} scheme for the URL source of the image, followed by the identifiers of the image provider and the requested image. For example: - + \qml Image { source: "image://myimageprovider/image.png" } \endqml @@ -83,7 +83,7 @@ public: and "red", respectively: \snippet examples/declarative/cppextensions/imageprovider/imageprovider-example.qml 0 - + When these images are loaded by QML, it looks for a matching image provider and calls its requestImage() or requestPixmap() method (depending on its imageType()) to load the image. The method is called with the \c id @@ -136,7 +136,7 @@ public: main thread. In this case, if \l {Image::}{asynchronous} is set to \c true, the value is ignored and the image is loaded synchronously. - + \sa QDeclarativeEngine::addImageProvider() */ diff --git a/src/declarative/qml/qdeclarativelist.h b/src/declarative/qml/qdeclarativelist.h index 399b2a1..c10bc11 100644 --- a/src/declarative/qml/qdeclarativelist.h +++ b/src/declarative/qml/qdeclarativelist.h @@ -98,16 +98,16 @@ public: private: static void qlist_append(QDeclarativeListProperty *p, T *v) { - ((QList<T *> *)p->data)->append(v); + reinterpret_cast<QList<T *> *>(p->data)->append(v); } static int qlist_count(QDeclarativeListProperty *p) { - return ((QList<T *> *)p->data)->count(); + return reinterpret_cast<QList<T *> *>(p->data)->count(); } static T *qlist_at(QDeclarativeListProperty *p, int idx) { - return ((QList<T *> *)p->data)->at(idx); + return reinterpret_cast<QList<T *> *>(p->data)->at(idx); } static void qlist_clear(QDeclarativeListProperty *p) { - return ((QList<T *> *)p->data)->clear(); + return reinterpret_cast<QList<T *> *>(p->data)->clear(); } }; #endif diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h index cb916bf..d45ddbc 100644 --- a/src/declarative/qml/qdeclarativeprivate.h +++ b/src/declarative/qml/qdeclarativeprivate.h @@ -105,7 +105,7 @@ namespace QDeclarativePrivate template<class From, class To> struct StaticCastSelectorClass<From, To, sizeof(int)> { - static inline int cast() { return (int)((intptr_t)static_cast<To *>((From *)0x10000000)) - 0x10000000; } + static inline int cast() { return int(reinterpret_cast<intptr_t>(static_cast<To *>(reinterpret_cast<From *>(0x10000000)))) - 0x10000000; } }; template<class From, class To> @@ -119,7 +119,7 @@ namespace QDeclarativePrivate static inline int cast() { - return StaticCastSelectorClass<From, To, sizeof(check((From *)0))>::cast(); + return StaticCastSelectorClass<From, To, sizeof(check(reinterpret_cast<From *>(0)))>::cast(); } }; diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index b901bb3..a747706 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1329,7 +1329,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) \snippet doc/src/snippets/declarative/rotationanimation.qml 0 - Notice the RotationAnimation did not need to set a \l {PropertyAnimation::}{target} + Notice the RotationAnimation did not need to set a \l target value. As a convenience, when used in a transition, RotationAnimation will rotate all properties named "rotation" or "angle". You can override this by providing your own properties via \l {PropertyAnimation::properties}{properties} or diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp index 7042d0c..aa1426c 100644 --- a/src/declarative/util/qdeclarativetransition.cpp +++ b/src/declarative/util/qdeclarativetransition.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE to (50, 50). The added Transition specifies that when the rectangle changes between the default and the "moved" state, any changes to the \c x and \c y properties should be animated, using an \c Easing.InOutQuad. - + \snippet doc/src/snippets/declarative/transition.qml 0 Notice the example does not require \l{PropertyAnimation::}{to} and diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp index 062b5ac..3fc7f10 100644 --- a/src/gui/graphicsview/qgraphicsgridlayout.cpp +++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp @@ -641,7 +641,8 @@ QSizeF QGraphicsGridLayout::sizeHint(Qt::SizeHint which, const QSizeF &constrain Q_D(const QGraphicsGridLayout); qreal left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); - return d->engine.sizeHint(d->styleInfo(), which , constraint) + QSizeF(left + right, top + bottom); + const QSizeF extraMargins(left + right, top + bottom); + return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins; } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index e1e27d2..0b3b164 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -7985,6 +7985,24 @@ void QGraphicsItemPrivate::resetHeight() */ /*! + \property QGraphicsObject::children + \since 4.7 + \internal +*/ + +/*! + \property QGraphicsObject::width + \since 4.7 + \internal +*/ + +/*! + \property QGraphicsObject::height + \since 4.7 + \internal +*/ + +/*! \class QAbstractGraphicsShapeItem \brief The QAbstractGraphicsShapeItem class provides a common base for all path items. diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index 5a7f1af..3707591 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> @@ -139,9 +140,11 @@ QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint) if (!sizeHintCacheDirty && cachedConstraint == constraint) return cachedSizeHints; + const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0; + for (int i = 0; i < Qt::NSizeHints; ++i) { cachedSizeHints[i] = constraint; - if (userSizeHints) + if (userSizeHints && !hasConstraint) combineSize(cachedSizeHints[i], userSizeHints[i]); } @@ -259,6 +262,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/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 37408ef..1588364 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -528,7 +528,8 @@ QSizeF QGraphicsLinearLayout::sizeHint(Qt::SizeHint which, const QSizeF &constra Q_D(const QGraphicsLinearLayout); qreal left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); - return d->engine.sizeHint(d->styleInfo(), which , constraint) + QSizeF(left + right, top + bottom); + const QSizeF extraMargins(left + right, top + bottom); + return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins; } /*! diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp index 7b69317..bd3f2ef 100644 --- a/src/gui/graphicsview/qgraphicstransform.cpp +++ b/src/gui/graphicsview/qgraphicstransform.cpp @@ -583,6 +583,27 @@ void QGraphicsRotation::applyTo(QMatrix4x4 *matrix) const \sa QGraphicsRotation::axis */ +/*! + \fn QGraphicsScale::xScaleChanged() + \since 4.7 + + This signal is emitted whenever the \l xScale property changes. +*/ + +/*! + \fn QGraphicsScale::yScaleChanged() + \since 4.7 + + This signal is emitted whenever the \l yScale property changes. +*/ + +/*! + \fn QGraphicsScale::zScaleChanged() + \since 4.7 + + This signal is emitted whenever the \l zScale property changes. +*/ + #include "moc_qgraphicstransform.cpp" QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index a084647..f3b2026 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -250,6 +250,7 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz sumAvailable = targetSize - totalBox.q_preferredSize; if (sumAvailable > 0.0) { + qreal sumCurrentAvailable = sumAvailable; bool somethingHasAMaximumSize = false; qreal sumPreferredSizes = 0.0; @@ -308,12 +309,12 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz qreal ultimateFactor = (stretch * ultimateSumPreferredSizes / sumStretches) - (box.q_preferredSize); - qreal transitionalFactor = sumAvailable + qreal transitionalFactor = sumCurrentAvailable * (ultimatePreferredSize - box.q_preferredSize) / (ultimateSumPreferredSizes - sumPreferredSizes); - qreal alpha = qMin(sumAvailable, + qreal alpha = qMin(sumCurrentAvailable, ultimateSumPreferredSizes - sumPreferredSizes); qreal beta = ultimateSumPreferredSizes - sumPreferredSizes; @@ -321,7 +322,7 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz + ((beta - alpha) * transitionalFactor)) / beta; } sumFactors += factors[i]; - if (desired < sumAvailable) + if (desired < sumCurrentAvailable) somethingHasAMaximumSize = true; newSizes[i] = -1.0; @@ -337,12 +338,12 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz continue; const QGridLayoutBox &box = boxes.at(start + i); - qreal avail = sumAvailable * factors[i] / sumFactors; + qreal avail = sumCurrentAvailable * factors[i] / sumFactors; if (sizes[i] + avail >= box.q_maximumSize) { newSizes[i] = box.q_maximumSize; - sumAvailable -= box.q_maximumSize - sizes[i]; + sumCurrentAvailable -= box.q_maximumSize - sizes[i]; sumFactors -= factors[i]; - keepGoing = (sumAvailable > 0.0); + keepGoing = (sumCurrentAvailable > 0.0); if (!keepGoing) break; } @@ -352,7 +353,7 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz for (int i = 0; i < n; ++i) { if (newSizes[i] < 0.0) { qreal delta = (sumFactors == 0.0) ? 0.0 - : sumAvailable * factors[i] / sumFactors; + : sumCurrentAvailable * factors[i] / sumFactors; newSizes[i] = sizes[i] + delta; } } @@ -545,6 +546,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 +632,14 @@ QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal heig qreal cellWidth = width; qreal cellHeight = height; - QSizeF size = effectiveMaxSize().boundedTo(QSizeF(cellWidth, cellHeight)); + QSize constraint; + if (hasDynamicConstraint()) { + if (dynamicConstraintOrientation() == Qt::Vertical) + constraint.setWidth(cellWidth); + else + constraint.setHeight(cellHeight); + } + QSizeF size = effectiveMaxSize(constraint).boundedTo(QSizeF(cellWidth, cellHeight)); width = size.width(); height = size.height(); @@ -675,13 +701,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 +715,7 @@ QSizeF QGridLayoutItem::effectiveMaxSize() const } if (!size.isValid()) { - QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize); + QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, constraint); if (size.width() == -1) size.setWidth(maxSize.width()); if (size.height() == -1) @@ -1010,6 +1036,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,10 +1101,13 @@ 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); + if (hasDynamicConstraint()) + return dynamicallyConstrainedSizeHint(which, constraint); + switch (which) { case Qt::MinimumSize: return QSizeF(q_totalBoxes[Hor].q_minimumSize, q_totalBoxes[Ver].q_minimumSize); @@ -1375,7 +1405,11 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt box = &multiCell.q_box; multiCell.q_stretch = itemStretch; } - box->combine(item->box(orientation)); + // Items with constraints are not included in the orientation that + // they are constrained (since it depends on the hfw/constraint function). + // They must be combined at a later stage. + if (!item->hasDynamicConstraint() || orientation != item->dynamicConstraintOrientation()) + box->combine(item->box(orientation)); if (effectiveRowSpan == 1) { QSizePolicy::ControlTypes controls = item->controlTypes(top); @@ -1532,6 +1566,138 @@ void QGridLayoutEngine::ensureColumnAndRowData(const QLayoutStyleInfo &styleInfo q_cachedDataForStyleInfo = styleInfo; } +QSizeF QGridLayoutEngine::dynamicallyConstrainedSizeHint(Qt::SizeHint which, + const QSizeF &constraint) const +{ + Q_ASSERT(hasDynamicConstraint()); + if (constraint.width() < 0 && constraint.height() < 0) { + // Process the hfw / wfh items that we did not process in fillRowData() + const Qt::Orientation constraintOrient = constraintOrientation(); + + QGridLayoutRowData rowData = constraintOrient == Qt::Vertical ? q_rowData : q_columnData; + for (int i = q_items.count() - 1; i >= 0; --i) { + QGridLayoutItem *item = q_items.at(i); + if (item->hasDynamicConstraint()) { + QGridLayoutBox box = item->box(constraintOrient); + QGridLayoutBox &rowBox = rowData.boxes[item->firstRow(constraintOrient)]; + rowBox.combine(box); + } + } + + QGridLayoutBox totalBoxes[2]; + if (constraintOrient == Qt::Vertical) { + totalBoxes[Hor] = q_columnData.totalBox(0, columnCount()); + totalBoxes[Ver] = rowData.totalBox(0, rowCount()); + } else { + totalBoxes[Hor] = rowData.totalBox(0, columnCount()); + totalBoxes[Ver] = q_rowData.totalBox(0, rowCount()); + } + return QSizeF(totalBoxes[Hor].q_sizes(which), totalBoxes[Ver].q_sizes(which)); + } + + + Q_ASSERT(constraint.width() >= 0 || constraint.height() >= 0); + q_xx.resize(columnCount()); + q_yy.resize(rowCount()); + q_widths.resize(columnCount()); + q_heights.resize(rowCount()); + q_descents.resize(rowCount()); + + + const Qt::Orientation orientation = constraintOrientation(); + QGridLayoutRowData *colData; + QGridLayoutRowData constrainedRowData; + QGridLayoutBox *totalBox; + qreal *sizes; + qreal *pos; + qreal *descents; + qreal targetSize; + qreal cCount; + qreal rCount; + + if (orientation == Qt::Vertical) { + // height for width + colData = &q_columnData; + totalBox = &q_totalBoxes[Hor]; + sizes = q_widths.data(); + pos = q_xx.data(); + descents = 0; + targetSize = constraint.width(); + cCount = columnCount(); + rCount = rowCount(); + constrainedRowData = q_rowData; + } else { + // width for height + colData = &q_rowData; + totalBox = &q_totalBoxes[Ver]; + sizes = q_heights.data(); + pos = q_yy.data(); + descents = q_descents.data(); + targetSize = constraint.height(); + cCount = rowCount(); + rCount = columnCount(); + constrainedRowData = q_columnData; + } + colData->calculateGeometries(0, cCount, targetSize, pos, sizes, descents, *totalBox); + for (int i = q_items.count() - 1; i >= 0; --i) { + QGridLayoutItem *item = q_items.at(i); + + if (item->hasDynamicConstraint()) { + const qreal size = sizes[item->firstColumn(orientation)]; + QGridLayoutBox box = item->box(orientation, size); + QGridLayoutBox &rowBox = constrainedRowData.boxes[item->firstRow(orientation)]; + rowBox.combine(box); + } + } + const qreal newSize = constrainedRowData.totalBox(0, rCount).q_sizes(which); + + return (orientation == Qt::Vertical) ? QSizeF(targetSize, newSize) : QSizeF(newSize, targetSize); +} + + +/** + 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; +} + +bool QGridLayoutEngine::hasDynamicConstraint() const +{ + if (!ensureDynamicConstraint()) + return false; + return q_cachedConstraintOrientation != NoConstraint; +} + +/* + * 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 { @@ -1544,10 +1710,74 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, q_widths.resize(columnCount()); 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]); + + + Qt::Orientation orientation = Qt::Vertical; + if (hasDynamicConstraint()) + orientation = constraintOrientation(); + + /* + In order to do hfw we need to first distribute the columns, then the rows. + In order to do wfh we need to first distribute the rows, then the columns. + + If there is no constraint, the order of distributing the rows or columns first is irrelevant. + We choose horizontal just to keep the same behaviour as before (however, there shouldn't + be any behaviour difference). + */ + + QGridLayoutRowData *colData; + QGridLayoutRowData rowData; + qreal *widths; + qreal *heights; + qreal *xx; + qreal *yy; + qreal *xdescents = 0; + qreal *ydescents = 0; + qreal cCount; + qreal rCount; + QSizeF oSize = size; + if (orientation == Qt::Vertical) { + // height for width + colData = &q_columnData; + rowData = q_rowData; + widths = q_widths.data(); + heights = q_heights.data(); + xx = q_xx.data(); + yy = q_yy.data(); + cCount = columnCount(); + rCount = rowCount(); + ydescents = q_descents.data(); + } else { + // width for height + colData = &q_rowData; + rowData = q_columnData; + widths = q_heights.data(); + heights = q_widths.data(); + xx = q_yy.data(); + yy = q_xx.data(); + cCount = rowCount(); + rCount = columnCount(); + xdescents = q_descents.data(); + oSize.transpose(); + } + + colData->calculateGeometries(0, cCount, oSize.width(), xx, widths, + xdescents, q_totalBoxes[orientation == Qt::Horizontal]); + for (int i = q_items.count() - 1; i >= 0; --i) { + QGridLayoutItem *item = q_items.at(i); + const int col = item->firstColumn(orientation); + const int row = item->firstRow(orientation); + if (item->hasDynamicConstraint()) { + const qreal sz = widths[col]; + QGridLayoutBox box = item->box(orientation, sz); + rowData.boxes[row].combine(box); + } + } + + QGridLayoutBox &totalBox = q_totalBoxes[orientation == Qt::Vertical]; + totalBox = rowData.totalBox(0, rCount); + rowData.calculateGeometries(0, rCount, oSize.height(), yy, heights, + ydescents, totalBox); q_cachedSize = size; } diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h index 9ac9a8e..580af7e 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, + VerticalConstraint, + 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); @@ -405,6 +425,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/gui.pro b/src/gui/gui.pro index 28440cc..3943e26 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -77,6 +77,25 @@ symbian { DEPLOYMENT = partial_upgrade $$DEPLOYMENT } +neon:*-g++* { + DEFINES += QT_HAVE_NEON + QMAKE_CXXFLAGS *= -mfpu=neon + HEADERS += $$NEON_HEADERS + SOURCES += $$NEON_SOURCES + + DRAWHELPER_NEON_ASM_FILES = $$NEON_ASM + + neon_compiler.commands = $$QMAKE_CXX -c + neon_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} + neon_compiler.dependency_type = TYPE_C + neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} + neon_compiler.input = DRAWHELPER_NEON_ASM_FILES + neon_compiler.variable_out = OBJECTS + neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN} + silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands + QMAKE_EXTRA_COMPILERS += neon_compiler +} + contains(QMAKE_MAC_XARCH, no) { DEFINES += QT_NO_MAC_XARCH } else { diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index b20a04f..f89706c 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -94,5 +94,6 @@ contains(QT_CONFIG, tiff):include($$PWD/qtiffhandler.pri) contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri) # SIMD +NEON_SOURCES += image/qimage_neon.cpp SSE2_SOURCES += image/qimage_sse2.cpp SSSE3_SOURCES += image/qimage_ssse3.cpp diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index cb834c0..ac148ee 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3769,6 +3769,14 @@ void qInitImageConversions() converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3; } #endif +#ifdef QT_HAVE_NEON + if (features & NEON) { + extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); + converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon; + converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon; + converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon; + } +#endif } /*! diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp new file mode 100644 index 0000000..15bf472 --- /dev/null +++ b/src/gui/image/qimage_neon.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the 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 <qimage.h> +#include <private/qimage_p.h> +#include <private/qsimd_p.h> + +#ifdef QT_HAVE_NEON + +QT_BEGIN_NAMESPACE + +Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len) +{ + if (!len) + return; + + const quint32 *const end = dst + len; + + // align dst on 64 bits + const int offsetToAlignOn8Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x1; + for (int i = 0; i < offsetToAlignOn8Bytes; ++i) { + *dst++ = qRgb(src[0], src[1], src[2]); + src += 3; + } + + if ((len - offsetToAlignOn8Bytes) >= 8) { + const quint32 *const simdEnd = end - 7; + register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff); + do { +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + asm volatile ( + "vld3.8 { d4, d5, d6 }, [%[SRC]] !\n\t" + "vst4.8 { d3, d4, d5, d6 }, [%[DST],:64] !\n\t" + : [DST]"+r" (dst), [SRC]"+r" (src) + : "w"(fullVector) + : "memory", "d4", "d5", "d6" + ); +#else + asm volatile ( + "vld3.8 { d0, d1, d2 }, [%[SRC]] !\n\t" + "vswp d0, d2\n\t" + "vst4.8 { d0, d1, d2, d3 }, [%[DST],:64] !\n\t" + : [DST]"+r" (dst), [SRC]"+r" (src) + : "w"(fullVector) + : "memory", "d0", "d1", "d2" + ); +#endif + } while (dst < simdEnd); + } + + while (dst != end) { + *dst++ = qRgb(src[0], src[1], src[2]); + src += 3; + } +} + +void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGB888); + Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const uchar *src_data = (uchar *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + qt_convert_rgb888_to_rgb32_neon(dest_data, src_data, src->width); + src_data += src->bytes_per_line; + dest_data = (quint32 *)((uchar*)dest_data + dest->bytes_per_line); + } +} + +QT_END_NAMESPACE + +#endif // QT_HAVE_NEON diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index d358a5e..eda5efb 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -803,9 +803,16 @@ bool QJpegHandlerPrivate::read(QImage *image) QJpegHandler::QJpegHandler() : d(new QJpegHandlerPrivate(this)) { -#if defined(QT_HAVE_SSSE3) const uint features = qDetectCPUFeatures(); - + Q_UNUSED(features); +#if defined(QT_HAVE_NEON) + // from qimage_neon.cpp + Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len); + + if (features & NEON) + rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon; +#endif // QT_HAVE_NEON +#if defined(QT_HAVE_SSSE3) // from qimage_ssse3.cpp Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index bbc9e0b..eade02e 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4281,6 +4281,11 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T QGestureEvent::accept() for each of them, or an event filter consumes the event. + \section1 Further Reading + + For an overview of gesture handling in Qt and information on using gestures + in your applications, see the \l{Gestures Programming} document. + \sa QGesture, QGestureRecognizer, QWidget::grabGesture(), QGraphicsObject::grabGesture() */ diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 4a4452a..13274c4 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE the QGestureRecognizer object that is registered with the application; see QGestureRecognizer::registerRecognizer(). + For an overview of gesture handling in Qt and information on using gestures + in your applications, see the \l{Gestures Programming} document. + \section1 Gesture Properties The class has a list of properties that can be queried by the user to get @@ -219,7 +222,10 @@ QGesture::GestureCancelPolicy QGesture::gestureCancelPolicy() const \image pangesture.png - \sa {Gestures Programming}, QPinchGesture, QSwipeGesture + For an overview of gesture handling in Qt and information on using gestures + in your applications, see the \l{Gestures Programming} document. + + \sa QPinchGesture, QSwipeGesture */ /*! @@ -314,6 +320,9 @@ void QPanGesture::setAcceleration(qreal value) them closer together or further apart to change the scale factor, zoom, or level of detail of the user interface. + For an overview of gesture handling in Qt and information on using gestures + in your applications, see the \l{Gestures Programming} document. + \image pinchgesture.png Instead of repeatedly applying the same pinching gesture, the user may @@ -322,7 +331,7 @@ void QPanGesture::setAcceleration(qreal value) will continue to be delivered to the target object, containing an instance of QPinchGesture in the Qt::GestureUpdated state. - \sa {Gestures Programming}, QPanGesture, QSwipeGesture + \sa QPanGesture, QSwipeGesture */ /*! @@ -572,7 +581,10 @@ void QPinchGesture::setRotationAngle(qreal value) \image swipegesture.png - \sa {Gestures Programming}, QPanGesture, QPinchGesture + For an overview of gesture handling in Qt and information on using gestures + in your applications, see the \l{Gestures Programming} document. + + \sa QPanGesture, QPinchGesture */ /*! @@ -667,7 +679,10 @@ void QSwipeGesture::setSwipeAngle(qreal value) \brief The QTapGesture class describes a tap gesture made by the user. \ingroup gestures - \sa {Gestures Programming}, QPanGesture, QPinchGesture + For an overview of gesture handling in Qt and information on using gestures + in your applications, see the \l{Gestures Programming} document. + + \sa QPanGesture, QPinchGesture */ /*! @@ -700,7 +715,10 @@ void QTapGesture::setPosition(const QPointF &value) gesture made by the user. \ingroup gestures - \sa {Gestures Programming}, QPanGesture, QPinchGesture + For an overview of gesture handling in Qt and information on using gestures + in your applications, see the \l{Gestures Programming} document. + + \sa QPanGesture, QPinchGesture */ /*! diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index 3e23bbf..e0e7784 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -62,6 +62,9 @@ QT_BEGIN_NAMESPACE need to use this class directly. Instances will be created behind the scenes by the framework. + For an overview of gesture handling in Qt and information on using gestures + in your applications, see the \l{Gestures Programming} document. + \section1 Recognizing Gestures The process of recognizing gestures involves filtering input events sent to specific diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 4023f65..dfa4a48 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -246,23 +246,8 @@ symbian { QMAKE_CXXFLAGS.ARMCC *= -O3 } -neon:*-g++* { - DEFINES += QT_HAVE_NEON - HEADERS += painting/qdrawhelper_neon_p.h - SOURCES += painting/qdrawhelper_neon.cpp - QMAKE_CXXFLAGS *= -mfpu=neon - - DRAWHELPER_NEON_ASM_FILES = ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S - - neon_compiler.commands = $$QMAKE_CXX -c - neon_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} - neon_compiler.dependency_type = TYPE_C - neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} - neon_compiler.input = DRAWHELPER_NEON_ASM_FILES - neon_compiler.variable_out = OBJECTS - neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN} - silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands - QMAKE_EXTRA_COMPILERS += neon_compiler -} +NEON_SOURCES += painting/qdrawhelper_neon.cpp +NEON_HEADERS += painting/qdrawhelper_neon_p.h +NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S include($$PWD/../../3rdparty/zlib_dependency.pri) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 7ab9eda..22c0384 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -112,9 +112,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, int x = 0; // First, align dest to 16 bytes: - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3; - const int prologLength = qMin(w, offsetToAlignOn16Bytes); - for (; x < prologLength; ++x) { + ALIGNMENT_PROLOGUE_16BYTES(dst, x, w) { quint32 s = src[x]; s = BYTE_MUL(s, const_alpha); dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); @@ -182,12 +180,10 @@ inline int comp_func_Plus_one_pixel(uint d, const uint s) void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha) { int x = 0; - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3; - const int prologLength = qMin(length, offsetToAlignOn16Bytes); if (const_alpha == 255) { // 1) Prologue: align destination on 16 bytes - for (; x < prologLength; ++x) + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]); // 2) composition with SSE2 @@ -208,7 +204,7 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin const __m128i oneMinusConstAlpha = _mm_set1_epi16(one_minus_const_alpha); // 1) Prologue: align destination on 16 bytes - for (; x < prologLength; ++x) + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha); const __m128i half = _mm_set1_epi16(0x80); @@ -239,9 +235,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u int x = 0; // 1) prologue, align on 16 bytes - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3; - const int prologLength = qMin(length, offsetToAlignOn16Bytes); - for (; x < prologLength; ++x) + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); // 2) interpolate pixels with SSE2 diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index 18355c2..d8f6bf5 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -143,9 +143,7 @@ QT_BEGIN_NAMESPACE int x = 0; \ \ /* First, get dst aligned. */ \ - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;\ - const int prologLength = qMin(length, offsetToAlignOn16Bytes);\ - for (; x < prologLength; ++x) { \ + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \ uint s = src[x]; \ if (s >= 0xff000000) \ dst[x] = s; \ @@ -202,9 +200,7 @@ QT_BEGIN_NAMESPACE { \ int x = 0; \ \ - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;\ - const int prologLength = qMin(length, offsetToAlignOn16Bytes);\ - for (; x < prologLength; ++x) { \ + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \ quint32 s = src[x]; \ if (s != 0) { \ s = BYTE_MUL(s, const_alpha); \ diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 9dadbd5..b694d9c 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -90,6 +90,15 @@ void qt_format_text(const QFont &font, const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect, int tabstops, int* tabarray, int tabarraylen, QPainter *painter); +static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, + QTextCharFormat::UnderlineStyle underlineStyle, + const QTextItem::RenderFlags flags, qreal width, + const QTextCharFormat &charFormat); +// Helper function to calculate left most position, width and flags for decoration drawing +static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat); static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush) { @@ -5923,6 +5932,10 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText currentColor = item->color; } d->extended->drawStaticTextItem(item); + + drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions, + item->numGlyphs, item->fontEngine, staticText_d->font, + QTextCharFormat()); } if (currentColor != oldPen.color()) setPen(oldPen); @@ -6290,15 +6303,15 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) return pixmap; } -static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti) +static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, + QTextCharFormat::UnderlineStyle underlineStyle, + const QTextItem::RenderFlags flags, qreal width, + const QTextCharFormat &charFormat) { - QTextCharFormat::UnderlineStyle underlineStyle = ti.underlineStyle; if (underlineStyle == QTextCharFormat::NoUnderline - && !(ti.flags & (QTextItem::StrikeOut | QTextItem::Overline))) + && !(flags & (QTextItem::StrikeOut | QTextItem::Overline))) return; - QFontEngine *fe = ti.fontEngine; - const QPen oldPen = painter->pen(); const QBrush oldBrush = painter->brush(); painter->setBrush(Qt::NoBrush); @@ -6307,7 +6320,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setWidthF(fe->lineThickness().toReal()); pen.setCapStyle(Qt::FlatCap); - QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y()); + QLineF line(pos.x(), pos.y(), pos.x() + width, pos.y()); const qreal underlineOffset = fe->underlinePosition().toReal(); // deliberately ceil the offset to avoid the underline coming too close to @@ -6322,21 +6335,21 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->save(); painter->translate(0, pos.y() + 1); - QColor uc = ti.charFormat.underlineColor(); + QColor uc = charFormat.underlineColor(); if (uc.isValid()) pen.setColor(uc); // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen); - const int descent = (int) ti.descent.toReal(); + const int descent = (int) fe->descent().toReal(); painter->setBrushOrigin(painter->brushOrigin().x(), 0); - painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave); + painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave); painter->restore(); } else if (underlineStyle != QTextCharFormat::NoUnderline) { QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos); - QColor uc = ti.charFormat.underlineColor(); + QColor uc = charFormat.underlineColor(); if (uc.isValid()) pen.setColor(uc); @@ -6348,14 +6361,14 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setStyle(Qt::SolidLine); pen.setColor(oldPen.color()); - if (ti.flags & QTextItem::StrikeOut) { + if (flags & QTextItem::StrikeOut) { QLineF strikeOutLine = line; strikeOutLine.translate(0., - fe->ascent().toReal() / 3.); painter->setPen(pen); painter->drawLine(strikeOutLine); } - if (ti.flags & QTextItem::Overline) { + if (flags & QTextItem::Overline) { QLineF overLine = line; overLine.translate(0., - fe->ascent().toReal()); painter->setPen(pen); @@ -6366,6 +6379,50 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setBrush(oldBrush); } +static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat) +{ + if (!(font.underline() || font.strikeOut() || font.overline())) + return; + + QFixed leftMost; + QFixed rightMost; + QFixed baseLine; + for (int i=0; i<glyphCount; ++i) { + glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]); + if (i == 0 || leftMost > positions[i].x) + leftMost = positions[i].x; + + // We don't support glyphs that do not share a common baseline. If this turns out to + // be a relevant use case, then we need to find clusters of glyphs that share a baseline + // and do a drawTextItemDecorations call per cluster. + if (i == 0 || baseLine < positions[i].y) + baseLine = positions[i].y; + + // We use the advance rather than the actual bounds to match the algorithm in drawText() + if (i == 0 || rightMost < positions[i].x + gm.xoff) + rightMost = positions[i].x + gm.xoff; + } + + QFixed width = rightMost - leftMost; + QTextItem::RenderFlags flags = 0; + + if (font.underline()) + flags |= QTextItem::Underline; + if (font.overline()) + flags |= QTextItem::Overline; + if (font.strikeOut()) + flags |= QTextItem::StrikeOut; + + drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()), + fontEngine, + font.underline() ? QTextCharFormat::SingleUnderline + : QTextCharFormat::NoUnderline, flags, + width.toReal(), charFormat); +} + void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) { #ifdef QT_DEBUG_DRAW @@ -6496,7 +6553,8 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) else d->engine->drawTextItem(p, ti); } - drawTextItemDecoration(this, p, ti); + drawTextItemDecoration(this, p, ti.fontEngine, ti.underlineStyle, ti.flags, ti.width.toReal(), + ti.charFormat); if (d->state->renderHints != oldRenderHints) { d->state->renderHints = oldRenderHints; diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 7396bcd..21c2e02 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -109,10 +109,18 @@ QT_BEGIN_NAMESPACE QPainter::drawStaticText() and can change from call to call with a minimal impact on performance. - QStaticText will attempt to guess the format of the input text using Qt::mightBeRichText(). - To force QStaticText to display its contents as either plain text or rich text, use the - function QStaticText::setTextFormat() and pass in, respectively, Qt::PlainText and - Qt::RichText. + For extra convenience, it is possible to apply formatting to the text using the HTML subset + supported by QTextDocument. QStaticText will attempt to guess the format of the input text using + Qt::mightBeRichText(), and interpret it as rich text if this function returns true. To force + QStaticText to display its contents as either plain text or rich text, use the function + QStaticText::setTextFormat() and pass in, respectively, Qt::PlainText and Qt::RichText. + + QStaticText can only represent text, so only HTML tags which alter the layout or appearance of + the text will be respected. Adding an image to the input HTML, for instance, will cause the + image to be included as part of the layout, affecting the positions of the text glyphs, but it + will not be displayed. The result will be an empty area the size of the image in the output. + Similarly, using tables will cause the text to be laid out in table format, but the borders + will not be drawn. If it's the first time the static text is drawn, or if the static text, or the painter's font has been altered since the last time it was drawn, the text's layout has to be diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 439f2a4..5670e29 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -923,6 +923,13 @@ void QTextEngine::shapeText(int item) const si.width += glyphs.advances_x[i]; } +static inline bool hasCaseChange(const QScriptItem &si) +{ + return si.analysis.flags == QScriptAnalysis::SmallCaps || + si.analysis.flags == QScriptAnalysis::Uppercase || + si.analysis.flags == QScriptAnalysis::Lowercase; +} + #if defined(Q_WS_WINCE) //TODO // set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs // and no reordering. @@ -1050,14 +1057,15 @@ void QTextEngine::shapeTextWithCE(int item) const if (option.useDesignMetrics()) flags |= DesignMetrics; - attributes(); // pre-initialize char attributes + // pre-initialize char attributes + if (! attributes()) + return; const int len = length(item); int num_glyphs = length(item); const QChar *str = layoutData->string.unicode() + si.position; ushort upperCased[256]; - if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase - || si.analysis.flags == QScriptAnalysis::Lowercase) { + if (hasCaseChange(si)) { ushort *uc = upperCased; if (len > 256) uc = new ushort[len]; @@ -1071,7 +1079,14 @@ void QTextEngine::shapeTextWithCE(int item) const } while (true) { - ensureSpace(num_glyphs); + if (! ensureSpace(num_glyphs)) { + // If str is converted to uppercase/lowercase form with a new buffer, + // we need to delete that buffer before return for error + const ushort *uc = reinterpret_cast<const ushort *>(str); + if (hasCaseChange(si) && uc != upperCased) + delete [] uc; + return; + } num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used; QGlyphLayout g = availableGlyphs(&si); @@ -1092,9 +1107,7 @@ void QTextEngine::shapeTextWithCE(int item) const layoutData->used += si.num_glyphs; const ushort *uc = reinterpret_cast<const ushort *>(str); - if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase - || si.analysis.flags == QScriptAnalysis::Lowercase) - && uc != upperCased) + if (hasCaseChange(si) && uc != upperCased) delete [] uc; } #endif @@ -1133,8 +1146,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const entire_shaper_item.item.bidiLevel = si.analysis.bidiLevel; HB_UChar16 upperCased[256]; // XXX what about making this 4096, so we don't have to extend it ever. - if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase - || si.analysis.flags == QScriptAnalysis::Lowercase) { + if (hasCaseChange(si)) { HB_UChar16 *uc = upperCased; if (entire_shaper_item.item.length > 256) uc = new HB_UChar16[entire_shaper_item.item.length]; @@ -1156,17 +1168,24 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const entire_shaper_item.shaperFlags |= HB_ShaperFlag_UseDesignMetrics; entire_shaper_item.num_glyphs = qMax(layoutData->glyphLayout.numGlyphs - layoutData->used, int(entire_shaper_item.item.length)); - ensureSpace(entire_shaper_item.num_glyphs); + if (! ensureSpace(entire_shaper_item.num_glyphs)) { + if (hasCaseChange(si)) + delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string); + return; + } QGlyphLayout initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs); if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) { - ensureSpace(entire_shaper_item.num_glyphs); + if (! ensureSpace(entire_shaper_item.num_glyphs)) { + if (hasCaseChange(si)) + delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string); + return; + } initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs); if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) { // ############ if this happens there's a bug in the fontengine - if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase - || si.analysis.flags == QScriptAnalysis::Lowercase) && entire_shaper_item.string != upperCased) + if (hasCaseChange(si) && entire_shaper_item.string != upperCased) delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string); return; } @@ -1231,7 +1250,11 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const remaining_glyphs -= shaper_item.initialGlyphCount; do { - ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs); + if (! ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs)) { + if (hasCaseChange(si)) + delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string); + return; + } const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos); moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); @@ -1271,8 +1294,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const layoutData->used += si.num_glyphs; - if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase) - && entire_shaper_item.string != upperCased) + if (hasCaseChange(si) && entire_shaper_item.string != upperCased) delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string); } @@ -1317,7 +1339,8 @@ const HB_CharAttributes *QTextEngine::attributes() const return (HB_CharAttributes *) layoutData->memory; itemize(); - ensureSpace(layoutData->string.length()); + if (! ensureSpace(layoutData->string.length())) + return NULL; QVarLengthArray<HB_ScriptItem> hbScriptItems(layoutData->items.size()); @@ -1864,7 +1887,10 @@ void QTextEngine::justify(const QScriptLine &line) // don't include trailing white spaces when doing justification int line_length = line.length; - const HB_CharAttributes *a = attributes()+line.from; + const HB_CharAttributes *a = attributes(); + if (! a) + return; + a += line.from; while (line_length && a[line_length-1].whiteSpace) --line_length; // subtract one char more, as we can't justfy after the last character @@ -2045,7 +2071,7 @@ QTextEngine::LayoutData::LayoutData() memory_on_stack = false; used = 0; hasBidi = false; - inLayout = false; + layoutState = LayoutEmpty; haveCharAttributes = false; logClustersPtr = 0; available_glyphs = 0; @@ -2079,7 +2105,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int } used = 0; hasBidi = false; - inLayout = false; + layoutState = LayoutEmpty; haveCharAttributes = false; } @@ -2090,12 +2116,12 @@ QTextEngine::LayoutData::~LayoutData() memory = 0; } -void QTextEngine::LayoutData::reallocate(int totalGlyphs) +bool QTextEngine::LayoutData::reallocate(int totalGlyphs) { Q_ASSERT(totalGlyphs >= glyphLayout.numGlyphs); if (memory_on_stack && available_glyphs >= totalGlyphs) { glyphLayout.grow(glyphLayout.data(), totalGlyphs); - return; + return true; } int space_charAttributes = sizeof(HB_CharAttributes)*string.length()/sizeof(void*) + 1; @@ -2103,7 +2129,14 @@ void QTextEngine::LayoutData::reallocate(int totalGlyphs) int space_glyphs = QGlyphLayout::spaceNeededForGlyphLayout(totalGlyphs)/sizeof(void*) + 2; int newAllocated = space_charAttributes + space_glyphs + space_logClusters; - Q_ASSERT(newAllocated >= allocated); + // These values can be negative if the length of string/glyphs causes overflow, + // we can't layout such a long string all at once, so return false here to + // indicate there is a failure + if (space_charAttributes < 0 || space_logClusters < 0 || space_glyphs < 0 || newAllocated < allocated) { + layoutState = LayoutFailed; + return false; + } + void **newMem = memory; newMem = (void **)::realloc(memory_on_stack ? 0 : memory, newAllocated*sizeof(void *)); Q_CHECK_PTR(newMem); @@ -2124,6 +2157,7 @@ void QTextEngine::LayoutData::reallocate(int totalGlyphs) glyphLayout.grow(reinterpret_cast<char *>(m), totalGlyphs); allocated = newAllocated; + return true; } // grow to the new size, copying the existing data to the new layout @@ -2155,7 +2189,7 @@ void QTextEngine::freeMemory() } else { layoutData->used = 0; layoutData->hasBidi = false; - layoutData->inLayout = false; + layoutData->layoutState = LayoutEmpty; layoutData->haveCharAttributes = false; } for (int i = 0; i < lines.size(); ++i) { @@ -2314,6 +2348,9 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int shape(i); HB_CharAttributes *attributes = const_cast<HB_CharAttributes *>(this->attributes()); + if (!attributes) + return QString(); + unsigned short *logClusters = this->logClusters(&si); QGlyphLayout glyphs = shapedGlyphs(&si); @@ -2385,6 +2422,8 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int return QString(); const HB_CharAttributes *attributes = this->attributes(); + if (!attributes) + return QString(); if (mode == Qt::ElideRight) { QFixed currentWidth; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index e623fa5..4cbe81f 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -416,6 +416,11 @@ class QTextFormatCollection; class Q_GUI_EXPORT QTextEngine { public: + enum LayoutState { + LayoutEmpty, + InLayout, + LayoutFailed, + }; struct LayoutData { LayoutData(const QString &str, void **stack_memory, int mem_size); LayoutData(); @@ -428,11 +433,11 @@ public: QGlyphLayout glyphLayout; mutable int used; uint hasBidi : 1; - uint inLayout : 1; + uint layoutState : 2; uint memory_on_stack : 1; bool haveCharAttributes; QString string; - void reallocate(int totalGlyphs); + bool reallocate(int totalGlyphs); }; QTextEngine(LayoutData *data); @@ -520,9 +525,10 @@ public: return layoutData->glyphLayout.mid(si->glyph_data_offset, si->num_glyphs); } - inline void ensureSpace(int nGlyphs) const { + inline bool ensureSpace(int nGlyphs) const { if (layoutData->glyphLayout.numGlyphs - layoutData->used < nGlyphs) - layoutData->reallocate((((layoutData->used + nGlyphs)*3/2 + 15) >> 4) << 4); + return layoutData->reallocate((((layoutData->used + nGlyphs)*3/2 + 15) >> 4) << 4); + return true; } void freeMemory(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 674064e..7d5fa43 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -74,6 +74,8 @@ static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line int pos = line.length; const HB_CharAttributes *attributes = eng->attributes(); + if (!attributes) + return QFixed(); while (pos > 0 && attributes[line.from + pos - 1].whiteSpace) --pos; return eng->width(line.from + pos, line.length - pos); @@ -601,7 +603,7 @@ bool QTextLayout::cacheEnabled() const void QTextLayout::beginLayout() { #ifndef QT_NO_DEBUG - if (d->layoutData && d->layoutData->inLayout) { + if (d->layoutData && d->layoutData->layoutState == QTextEngine::InLayout) { qWarning("QTextLayout::beginLayout: Called while already doing layout"); return; } @@ -609,7 +611,7 @@ void QTextLayout::beginLayout() d->invalidate(); d->clearLineData(); d->itemize(); - d->layoutData->inLayout = true; + d->layoutData->layoutState = QTextEngine::InLayout; } /*! @@ -618,7 +620,7 @@ void QTextLayout::beginLayout() void QTextLayout::endLayout() { #ifndef QT_NO_DEBUG - if (!d->layoutData || !d->layoutData->inLayout) { + if (!d->layoutData || d->layoutData->layoutState == QTextEngine::LayoutEmpty) { qWarning("QTextLayout::endLayout: Called without beginLayout()"); return; } @@ -627,7 +629,7 @@ void QTextLayout::endLayout() if (l && d->lines.at(l-1).length < 0) { QTextLine(l-1, d).setNumColumns(INT_MAX); } - d->layoutData->inLayout = false; + d->layoutData->layoutState = QTextEngine::LayoutEmpty; if (!d->cacheGlyphs) d->freeMemory(); } @@ -757,11 +759,14 @@ bool QTextLayout::isValidCursorPosition(int pos) const QTextLine QTextLayout::createLine() { #ifndef QT_NO_DEBUG - if (!d->layoutData || !d->layoutData->inLayout) { + if (!d->layoutData || d->layoutData->layoutState == QTextEngine::LayoutEmpty) { qWarning("QTextLayout::createLine: Called without layouting"); return QTextLine(); } #endif + if (d->layoutData->layoutState == QTextEngine::LayoutFailed) + return QTextLine(); + int l = d->lines.size(); if (l && d->lines.at(l-1).length < 0) { QTextLine(l-1, d).setNumColumns(INT_MAX); @@ -1704,14 +1709,18 @@ namespace { return glyphs.glyphs[logClusters[currentPosition - 1]]; } + inline void adjustRightBearing(glyph_t glyph) + { + qreal rb; + fontEngine->getGlyphBearings(glyph, 0, &rb); + rightBearing = qMin(QFixed(), QFixed::fromReal(rb)); + } + inline void adjustRightBearing() { if (currentPosition <= 0) return; - - qreal rb; - fontEngine->getGlyphBearings(currentGlyph(), 0, &rb); - rightBearing = qMin(QFixed(), QFixed::fromReal(rb)); + adjustRightBearing(currentGlyph()); } inline void resetRightBearing() @@ -1801,6 +1810,8 @@ void QTextLine::layout_helper(int maxGlyphs) Qt::Alignment alignment = eng->option.alignment(); const HB_CharAttributes *attributes = eng->attributes(); + if (!attributes) + return; lbh.currentPosition = line.from; int end = 0; lbh.logClusters = eng->layoutData->logClustersPtr; @@ -1814,6 +1825,8 @@ void QTextLine::layout_helper(int maxGlyphs) if (!current.num_glyphs) { eng->shape(item); attributes = eng->attributes(); + if (!attributes) + return; lbh.logClusters = eng->layoutData->logClustersPtr; } lbh.currentPosition = qMax(line.from, current.position); @@ -1892,6 +1905,9 @@ void QTextLine::layout_helper(int maxGlyphs) } else { lbh.whiteSpaceOrObject = false; bool sb_or_ws = false; + glyph_t previousGlyph = 0; + if (lbh.currentPosition > 0 && lbh.logClusters[lbh.currentPosition - 1] <lbh.glyphs.numGlyphs) + previousGlyph = lbh.currentGlyph(); // needed to calculate right bearing later do { addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount, current, lbh.logClusters, lbh.glyphs); @@ -1935,9 +1951,17 @@ void QTextLine::layout_helper(int maxGlyphs) // We ignore the right bearing if the minimum negative bearing is too little to // expand the text beyond the edge. if (sb_or_ws|breakany) { + QFixed rightBearing = lbh.rightBearing; // store previous right bearing +#if !defined(Q_WS_MAC) if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width) +#endif lbh.adjustRightBearing(); if (lbh.checkFullOtherwiseExtend(line)) { + // we are too wide, fix right bearing + if (rightBearing <= 0) + lbh.rightBearing = rightBearing; // take from cache + else if (previousGlyph > 0) + lbh.adjustRightBearing(previousGlyph); if (!breakany) { line.textWidth += lbh.softHyphenWidth; } diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 38cae8b..d3084cf 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -175,12 +175,12 @@ QT_BEGIN_NAMESPACE When using this flag with sequential upload data, the ContentLengthHeader header must be set. - \value HttpPipeliningAllowedAttribute + \value HttpPipeliningAllowedAttribute Requests only, type: QVariant::Bool (default: false) Indicates whether the QNetworkAccessManager code is allowed to use HTTP pipelining with this request. - \value HttpPipeliningWasUsedAttribute + \value HttpPipeliningWasUsedAttribute Replies only, type: QVariant::Bool Indicates whether the HTTP pipelining was used for receiving this reply. @@ -192,25 +192,31 @@ QT_BEGIN_NAMESPACE when calling QNetworkAccessManager::sendCustomRequest(). \value CookieLoadControlAttribute - Requests only, type: QVariant::Int (default: - QNetworkRequest::Automatic) Indicates whether to send 'Cookie' - headers in the request. This attribute is set to false by - QtWebKit when creating a cross-origin XMLHttpRequest where - withCredentials has not been set explicitly to true by the - Javascript that created the request. See - \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} - {here} for more information. - - \value CookieSaveControlAttribute + Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) + Indicates whether to send 'Cookie' headers in the request. + + This attribute is set to false by QtWebKit when creating a cross-origin + XMLHttpRequest where withCredentials has not been set explicitly to true by the + Javascript that created the request. + + See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag}{here} for more information. + + (This value was introduced in 4.7.) + + + \value CookieSaveControlAttribute Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) Indicates whether to save 'Cookie' headers received from the server in reply to the request. This attribute is set to false by QtWebKit when creating a cross-origin XMLHttpRequest where withCredentials has not been set explicitly to true by the Javascript that created the request. + See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information. - \value AuthenticationReuseAttribute + (This value was introduced in 4.7.) + + \value AuthenticationReuseAttribute Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic) Indicates whether to use cached authorization credentials in the request, if available. If this is set to QNetworkRequest::Manual and the authentication @@ -219,11 +225,16 @@ QT_BEGIN_NAMESPACE This attribute is set to QNetworkRequest::Manual by QtWebKit when creating a cross-origin XMLHttpRequest where withCredentials has not been set explicitly to true by the Javascript that created the request. + See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information. + (This value was introduced in 4.7.) + \omitvalue MaximumDownloadBufferSizeAttribute + (This value was introduced in 4.7.) \omitvalue DownloadBufferAttribute + (This value was introduced in 4.7.) \value User Special type. Additional information can be passed in diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h index e4f762a..18b92a9 100644 --- a/src/network/bearer/qnetworkconfiguration.h +++ b/src/network/bearer/qnetworkconfiguration.h @@ -120,7 +120,9 @@ public: Purpose purpose() const; // Required to maintain source compatibility with Qt Mobility. +#ifdef QT_DEPRECATED QT_DEPRECATED QString bearerName() const; +#endif BearerType bearerType() const; QString bearerTypeName() const; diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 1267e7e..662c796 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -7418,8 +7418,10 @@ bool QDomHandler::startElement(const QString& nsURI, const QString&, const QStri n = doc->createElement(qName); } - if (n) - n->setLocation(locator->lineNumber(), locator->columnNumber()); + if (!n) + return false; + + n->setLocation(locator->lineNumber(), locator->columnNumber()); node->appendChild(n); node = n; diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp index 7f2ad9f..0f9760d 100644 --- a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp +++ b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp @@ -1355,7 +1355,7 @@ bool QXmlItem::isNull() const QAbstractXmlNodeModel for its existence, the only way you can create an instance of QXmlNodeModelIndex is by asking the node model to create one for you with QAbstractXmlNodeModel::createIndex(). Since - that function is protected, it is usually a good ide to write a + that function is protected, it is usually a good idea to write a public function that creates a QXmlNodeModelIndex from arguments that are appropriate for your particular node model. diff --git a/tests/auto/compilerwarnings/test_cpp.txt b/tests/auto/compilerwarnings/test_cpp.txt index 62b35eb..1d317b8 100644 --- a/tests/auto/compilerwarnings/test_cpp.txt +++ b/tests/auto/compilerwarnings/test_cpp.txt @@ -58,6 +58,9 @@ #include <QtDBus/QtDBus> #endif +#include <QtDeclarative/QtDeclarative> + + #ifndef Q_OS_MAC int main(int, char **) { diff --git a/tests/auto/compilerwarnings/tst_compilerwarnings.cpp b/tests/auto/compilerwarnings/tst_compilerwarnings.cpp index 82c327a..8d344d8 100644 --- a/tests/auto/compilerwarnings/tst_compilerwarnings.cpp +++ b/tests/auto/compilerwarnings/tst_compilerwarnings.cpp @@ -114,6 +114,9 @@ void tst_CompilerWarnings::warnings_data() QTest::addColumn<QStringList>("cflags"); QTest::newRow("standard") << QStringList(); + QTest::newRow("warn deprecated, fast plus, no debug") << (QStringList() << "-DQT_DEPRECATED_WARNINGS" + << "-DQT_USE_FAST_OPERATOR_PLUS" << "-DQT_NU_DEBUG" << "-DQT_NO_DEBUG_STREAM" << "-DQT_NO_WARNING_OUTPUT"); + QTest::newRow("no deprecated, no keywords") << (QStringList() << "-DQT_NO_DEPRECATED" << "-DQT_NO_KEYWORDS"); #if 0 #ifdef Q_WS_QWS @@ -136,14 +139,14 @@ void tst_CompilerWarnings::warnings() QSKIP("gcc 3.x outputs too many bogus warnings", SkipAll); #endif - static QString tmpFile; + /*static*/ QString tmpFile; if (tmpFile.isEmpty()) { QTemporaryFile tmpQFile; tmpQFile.open(); tmpFile = tmpQFile.fileName(); tmpQFile.close(); } - static QString tmpSourceFile; + /*static*/ QString tmpSourceFile; bool openResult = true; const QString tmpBaseName("XXXXXX-test.cpp"); QString templatePath = QDir::temp().absoluteFilePath(tmpBaseName); diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp index 0f6cdaa..8bf7620 100644 --- a/tests/auto/qdom/tst_qdom.cpp +++ b/tests/auto/qdom/tst_qdom.cpp @@ -1776,6 +1776,7 @@ void tst_QDom::crashInSetContent() const QDomImplementation::setInvalidDataPolicy(QDomImplementation::ReturnNullNode); QDomDocument docImport; + QCOMPARE(docImport.setContent(QLatin1String("<a:>text</a:>"), true), false); QVERIFY(docImport.setContent(QLatin1String("<?xml version=\"1.0\"?><e/>"))); } diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index d1d6860..03c1d5b 100644 --- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -107,12 +107,13 @@ private slots: void avoidRecursionInInsertItem(); void styleInfoLeak(); void task236367_maxSizeHint(); + void heightForWidth(); }; 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 +126,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 +140,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 +156,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 +224,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 +256,7 @@ struct ItemDesc break; } } + layout->addItem(item, m_pos.first, m_pos.second, m_rowSpan, m_colSpan); layout->setAlignment(item, m_align); } @@ -240,6 +264,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 +276,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; @@ -485,12 +513,12 @@ void tst_QGraphicsGridLayout::alignment() widget->resize(widget->effectiveSizeHint(Qt::MaximumSize)); QApplication::processEvents(); - QCOMPARE(layout->itemAt(0,0)->geometry(), QRectF(0, 0, 50, 25)); - QCOMPARE(layout->itemAt(1,0)->geometry(), QRectF(0, 25, 50, 25)); - QCOMPARE(layout->itemAt(0,1)->geometry(), QRectF(125, 0, 50, 25)); - QCOMPARE(layout->itemAt(1,1)->geometry(), QRectF(125, 25, 50, 25)); - QCOMPARE(layout->itemAt(0,2)->geometry(), QRectF(250, 0, 50, 25)); - QCOMPARE(layout->itemAt(1,2)->geometry(), QRectF(250, 25, 50, 25)); + QCOMPARE(layout->itemAt(0,0)->geometry(), QRectF(0, 0, 50, 50)); + QCOMPARE(layout->itemAt(1,0)->geometry(), QRectF(0, 50, 50, 50)); + QCOMPARE(layout->itemAt(0,1)->geometry(), QRectF(125, 0, 50, 50)); + QCOMPARE(layout->itemAt(1,1)->geometry(), QRectF(125, 50, 50, 50)); + QCOMPARE(layout->itemAt(0,2)->geometry(), QRectF(250, 0, 50, 50)); + QCOMPARE(layout->itemAt(1,2)->geometry(), QRectF(250, 50, 50, 50)); delete widget; } @@ -544,12 +572,12 @@ void tst_QGraphicsGridLayout::columnAlignment() | HCenter | Right | Left | +---------------------------------+ */ - QCOMPARE(layout->itemAt(0,0)->geometry(), QRectF(0, 0, 50, 25)); - QCOMPARE(layout->itemAt(1,0)->geometry(), QRectF(25, 26, 50, 25)); // item is king - QCOMPARE(layout->itemAt(0,1)->geometry(), QRectF(126, 0, 50, 25)); - QCOMPARE(layout->itemAt(1,1)->geometry(), QRectF(151, 26, 50, 25)); // item is king - QCOMPARE(layout->itemAt(0,2)->geometry(), QRectF(252, 0, 50, 25)); - QCOMPARE(layout->itemAt(1,2)->geometry(), QRectF(202, 26, 50, 25)); // item is king + QCOMPARE(layout->itemAt(0,0)->geometry(), QRectF(0, 0, 50, 50)); + QCOMPARE(layout->itemAt(1,0)->geometry(), QRectF(25, 51, 50, 50)); // item is king + QCOMPARE(layout->itemAt(0,1)->geometry(), QRectF(126, 0, 50, 50)); + QCOMPARE(layout->itemAt(1,1)->geometry(), QRectF(151, 51, 50, 50)); // item is king + QCOMPARE(layout->itemAt(0,2)->geometry(), QRectF(252, 0, 50, 50)); + QCOMPARE(layout->itemAt(1,2)->geometry(), QRectF(202, 51, 50, 50)); // item is king delete widget; } @@ -2116,6 +2144,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 +2184,186 @@ 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,40)) + .preferredSize(QSizeF(50,400)) + .maxSize(QSizeF(500, 500)) + .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-h408") << (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, 408) + << (RectList() + << QRectF(0, 0, 50, 8) << QRectF(50, 0, 50, 8) + << QRectF(0, 8, 50,100) << QRectF(50, 8, 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) + ); + + QTest::newRow("hfw-h470") << (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, 470) + << (RectList() + << QRectF(0, 0, 50,70) << QRectF(50, 0, 50,70) + << QRectF(0, 70, 50,100) << QRectF(50, 70, 50,400) + ); + + + // change layout width and verify + QTest::newRow("hfw-w100") << (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(5000, 5000)) + .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-w160") << (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(5000, 5000)) + .heightForWidth(hfw1) + ) + << QSizeF(160, 401) + << (RectList() + << QRectF( 0, 0, 80, 100) << QRectF( 80, 0, 80, 100) + << QRectF( 0, 100, 80, 100) << QRectF( 80, 100, 80, 250) + ); + + + QTest::newRow("hfw-w500") << (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(5000, 5000)) + .heightForWidth(hfw1) + ) + << QSizeF(500, 401) + << (RectList() + << QRectF( 0, 0, 100, 100) << QRectF(100, 0, 100, 100) + << QRectF( 0, 100, 100, 100) << QRectF(100, 100, 400, 50) + ); + } void tst_QGraphicsGridLayout::geometries() @@ -2215,6 +2434,143 @@ 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)); + +} + QTEST_MAIN(tst_QGraphicsGridLayout) #include "tst_qgraphicsgridlayout.moc" diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index 62416b1..bb96da1 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -714,6 +714,8 @@ void tst_QMetaObject::normalizedSignature_data() QTest::newRow("const12") << "void foo(Foo<Bar>const*const *const)" << "void foo(Foo<Bar>*const*const)"; QTest::newRow("const13") << "void foo(const Foo<Bar>&)" << "void foo(Foo<Bar>)"; QTest::newRow("const14") << "void foo(Foo<Bar>const&)" << "void foo(Foo<Bar>)"; + + QTest::newRow("invalid1") << "a( b" << "a(b"; } void tst_QMetaObject::normalizedSignature() @@ -721,7 +723,7 @@ void tst_QMetaObject::normalizedSignature() QFETCH(QString, signature); QFETCH(QString, result); - QCOMPARE(QString::fromLatin1(QMetaObject::normalizedSignature(signature.toLatin1())), result); + QCOMPARE(QMetaObject::normalizedSignature(signature.toLatin1()), result.toLatin1()); } void tst_QMetaObject::normalizedType_data() @@ -759,7 +761,7 @@ void tst_QMetaObject::normalizedType() QFETCH(QString, type); QFETCH(QString, result); - QCOMPARE(QString::fromLatin1(QMetaObject::normalizedType(type.toLatin1())), result); + QCOMPARE(QMetaObject::normalizedType(type.toLatin1()), result.toLatin1()); } void tst_QMetaObject::customPropertyType() diff --git a/tests/auto/qregexp/tst_qregexp.cpp b/tests/auto/qregexp/tst_qregexp.cpp index ea07323..d0d26ee 100644 --- a/tests/auto/qregexp/tst_qregexp.cpp +++ b/tests/auto/qregexp/tst_qregexp.cpp @@ -105,6 +105,7 @@ private slots: void QTBUG_7049_data(); void QTBUG_7049(); + void interval(); }; // Testing get/set functions @@ -1426,5 +1427,22 @@ void tst_QRegExp::QTBUG_7049() QCOMPARE( re.cap(2), cap2 ); } +void tst_QRegExp::interval() +{ + { + QRegExp exp("a{0,1}"); + QVERIFY(exp.isValid()); + } + { + QRegExp exp("a{1,1}"); + QVERIFY(exp.isValid()); + } + { + QRegExp exp("a{1,0}"); + QVERIFY(!exp.isValid()); + } +} + + QTEST_APPLESS_MAIN(tst_QRegExp) #include "tst_qregexp.moc" diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index 1d166f4..0ae5320 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -85,6 +85,10 @@ private slots: void setPenPlainText(); void setPenRichText(); void richTextOverridesPen(); + + void drawStruckOutText(); + void drawOverlinedText(); + void drawUnderlinedText(); }; void tst_QStaticText::init() @@ -620,5 +624,107 @@ void tst_QStaticText::richTextOverridesPen() } } +void tst_QStaticText::drawStruckOutText() +{ + QPixmap imageDrawText(1000, 1000); + QPixmap imageDrawStaticText(1000, 1000); + + imageDrawText.fill(Qt::white); + imageDrawStaticText.fill(Qt::white); + + QString s = QString::fromLatin1("Foobar"); + + QFont font; + font.setStrikeOut(true); + + { + QPainter p(&imageDrawText); + p.setFont(font); + p.drawText(QPointF(50, 50), s); + } + + { + QPainter p(&imageDrawStaticText); + QStaticText text = QStaticText(s); + p.setFont(font); + p.drawStaticText(QPointF(50, 50 - QFontMetricsF(p.font()).ascent()), text); + } + +#if defined(DEBUG_SAVE_IMAGE) + imageDrawText.save("drawStruckOutText_imageDrawText.png"); + imageDrawStaticText.save("drawStruckOutText_imageDrawStaticText.png"); +#endif + + QCOMPARE(imageDrawText, imageDrawStaticText); +} + +void tst_QStaticText::drawOverlinedText() +{ + QPixmap imageDrawText(1000, 1000); + QPixmap imageDrawStaticText(1000, 1000); + + imageDrawText.fill(Qt::white); + imageDrawStaticText.fill(Qt::white); + + QString s = QString::fromLatin1("Foobar"); + + QFont font; + font.setOverline(true); + + { + QPainter p(&imageDrawText); + p.setFont(font); + p.drawText(QPointF(50, 50), s); + } + + { + QPainter p(&imageDrawStaticText); + QStaticText text = QStaticText(s); + p.setFont(font); + p.drawStaticText(QPointF(50, 50 - QFontMetricsF(p.font()).ascent()), text); + } + +#if defined(DEBUG_SAVE_IMAGE) + imageDrawText.save("drawOverlinedText_imageDrawText.png"); + imageDrawStaticText.save("drawOverlinedText_imageDrawStaticText.png"); +#endif + + QCOMPARE(imageDrawText, imageDrawStaticText); +} + +void tst_QStaticText::drawUnderlinedText() +{ + QPixmap imageDrawText(1000, 1000); + QPixmap imageDrawStaticText(1000, 1000); + + imageDrawText.fill(Qt::white); + imageDrawStaticText.fill(Qt::white); + + QString s = QString::fromLatin1("Foobar"); + + QFont font; + font.setUnderline(true); + + { + QPainter p(&imageDrawText); + p.setFont(font); + p.drawText(QPointF(50, 50), s); + } + + { + QPainter p(&imageDrawStaticText); + QStaticText text = QStaticText(s); + p.setFont(font); + p.drawStaticText(QPointF(50, 50 - QFontMetricsF(p.font()).ascent()), text); + } + +#if defined(DEBUG_SAVE_IMAGE) + imageDrawText.save("drawUnderlinedText_imageDrawText.png"); + imageDrawStaticText.save("drawUnderlinedText_imageDrawStaticText.png"); +#endif + + QCOMPARE(imageDrawText, imageDrawStaticText); +} + QTEST_MAIN(tst_QStaticText) #include "tst_qstatictext.moc" diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index c887936..ef82769 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -208,6 +208,7 @@ private slots: void repeated_data() const; void task262677remove(); void QTBUG10404_compareRef(); + void QTBUG9281_arg_locale(); }; typedef QList<int> IntList; @@ -4860,6 +4861,17 @@ void tst_QString::QTBUG10404_compareRef() QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0); } +void tst_QString::QTBUG9281_arg_locale() +{ + QLocale l(QLocale::English, QLocale::UnitedKingdom); + l.setNumberOptions(QLocale::OmitGroupSeparator); + QLocale::setDefault(l); + QString str("*%L1*%L2*"); + str = str.arg(123456).arg(1234.56); + QCOMPARE(str, QString::fromLatin1("*123456*1234.56*")); + QLocale::setDefault(QLocale::C); +} + QTEST_APPLESS_MAIN(tst_QString) diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp index f798faf..659ba1a 100644 --- a/tests/auto/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp @@ -122,6 +122,7 @@ private slots: void smallTextLengthWrapAtWordBoundaryOrAnywhere(); void testLineBreakingAllSpaces(); void lineWidthFromBOM(); + void textWidthVsWIdth(); private: @@ -1359,5 +1360,34 @@ void tst_QTextLayout::glyphLessItems() } } +void tst_QTextLayout::textWidthVsWIdth() +{ + QTextLayout layout; + QTextOption opt; + opt.setWrapMode(QTextOption::WrapAnywhere); + layout.setTextOption(opt); + layout.setText(QString::fromLatin1( + "g++ -c -m64 -pipe -g -fvisibility=hidden -fvisibility-inlines-hidden -Wall -W -D_REENTRANT -fPIC -DCORE_LIBRARY -DIDE_LIBRARY_BASENAME=\"lib\" -DWITH_TESTS " + "-DQT_NO_CAST_TO_ASCII -DQT_USE_FAST_OPERATOR_PLUS -DQT_USE_FAST_CONCATENATION -DQT_PLUGIN -DQT_TESTLIB_LIB -DQT_SCRIPT_LIB -DQT_SVG_LIB -DQT_SQL_LIB -DQT_XM" + "L_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I../../../../qt-qml/mkspecs/linux-g++-64 -I. -I../../../../qt-qml/include/QtCore -I../../../." + "./qt-qml/include/QtNetwork -I../../../../qt-qml/include/QtGui -I../../../../qt-qml/include/QtXml -I../../../../qt-qml/include/QtSql -I../../../../qt-qml/inc" + "lude/QtSvg -I../../../../qt-qml/include/QtScript -I../../../../qt-qml/include/QtTest -I../../../../qt-qml/include -I../../../../qt-qml/include/QtHelp -I../." + "./libs -I/home/ettrich/dev/creator/tools -I../../plugins -I../../shared/scriptwrapper -I../../libs/3rdparty/botan/build -Idialogs -Iactionmanager -Ieditorma" + "nager -Iprogressmanager -Iscriptmanager -I.moc/debug-shared -I.uic -o .obj/debug-shared/sidebar.o sidebar.cpp")); + + // textWidth includes right bearing, but it should never be LARGER than width if there is space for at least one character + for (int width = 100; width < 1000; ++width) { + layout.beginLayout(); + QTextLine line = layout.createLine(); + line.setLineWidth(width); + layout.endLayout(); + + qreal textWidthIsLargerBy = qMax(qreal(0), line.naturalTextWidth() - line.width()); + qreal thisMustBeZero = 0; + QCOMPARE(textWidthIsLargerBy, thisMustBeZero); + } +} + + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" diff --git a/tools/qdoc3/test/qt-html-templates.qdocconf b/tools/qdoc3/test/qt-html-templates.qdocconf index 94c8f47..70f3a40 100644 --- a/tools/qdoc3/test/qt-html-templates.qdocconf +++ b/tools/qdoc3/test/qt-html-templates.qdocconf @@ -4,9 +4,6 @@ HTML.stylesheets = style/style.css \ style/style_ie8.css \ style/style_ie6.css -HTML.creatorpostheader = "**\n" -HTML.creatorpostpostheader = "***\n" - HTML.postheader = " <div class=\"header\" id=\"qtdocheader\">\n" \ " <div class=\"content\"> \n" \ " <div id=\"nav-logo\">\n" \ @@ -48,7 +45,7 @@ HTML.postheader = " <div class=\"header\" id=\"qtdocheader\">\n" \ " <li><a href=\"#\">Qt Topics</a> \n" \ " <ul id=\"topmenuTopic\"> \n" \ " <li><a href=\"qt-basic-concepts.html\">Basic Qt architecture</a></li> \n" \ - " <li><a href=\"declarativeui.html\">Device UI's & Qt Quick</a></li> \n" \ + " <li><a href=\"qtquick.html\">Device UI's & Qt Quick</a></li> \n" \ " <li><a href=\"qt-gui-concepts.html\">Desktop UI components</a></li> \n" \ " <li><a href=\"platform-specific.html\">Platform-specific info</a></li> \n" \ " <li><a href=\"best-practices.html\">How-To's and Best Practices</a></li> \n" \ @@ -100,7 +97,7 @@ HTML.postheader = " <div class=\"header\" id=\"qtdocheader\">\n" \ " <div id=\"list002\" class=\"list\">\n" \ " <ul id=\"ul002\" >\n" \ " <li class=\"defaultLink\"><a href=\"qt-basic-concepts.html\">Basic Qt architecture</a></li>\n" \ - " <li class=\"defaultLink\"><a href=\"declarativeui.html\">Device UI's & Qt Quick</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"qtquick.html\">Device UI's & Qt Quick</a></li>\n" \ " <li class=\"defaultLink\"><a href=\"qt-gui-concepts.html\">Desktop UI components</a></li>\n" \ " <li class=\"defaultLink\"><a href=\"platform-specific.html\">Platform-specific info</a></li>\n" \ " </ul> \n" \ diff --git a/tools/qdoc3/test/qt-html-templates_ja_JP.qdocconf b/tools/qdoc3/test/qt-html-templates_ja_JP.qdocconf index 027548e..e2abd2a 100644 --- a/tools/qdoc3/test/qt-html-templates_ja_JP.qdocconf +++ b/tools/qdoc3/test/qt-html-templates_ja_JP.qdocconf @@ -160,19 +160,9 @@ HTML.footer = " <!-- /div -->\n" \ " <div id=\"feedbackBox\">\n" \ " <div id=\"feedcloseX\" class=\"feedclose t_button\">X</div>\n" \ " <form id=\"feedform\" action=\"http://doc.qt.nokia.com/docFeedbck/feedback.php\" method=\"get\">\n" \ - " <p><textarea id=\"feedbox\" name=\"feedText\" rows=\"5\" cols=\"40\">Please submit you feedback...</textarea></p>\n" \ + " <p><textarea id=\"feedbox\" name=\"feedText\" rows=\"5\" cols=\"40\">Please submit your feedback...</textarea></p>\n" \ " <p><input id=\"feedsubmit\" class=\"feedclose\" type=\"submit\" name=\"feedback\" /></p>\n" \ " </form>\n" \ " </div>\n" \ " <div id=\"blurpage\">\n" \ - " </div>\n" \ - "<script type=\"text/javascript\">\n" \ - " var _gaq = _gaq || [];\n" \ - " _gaq.push([\'_setAccount\', \'UA-4457116-5\']);\n" \ - " _gaq.push([\'_trackPageview\']);\n" \ - " (function() {\n" \ - " var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;\n" \ - " ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';\n" \ - " var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);\n" \ - " })();\n" \ - "</script>\n" + " </div>\n" diff --git a/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf b/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf index 5fb68cf..e00bef9 100644 --- a/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf +++ b/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf @@ -1,25 +1,168 @@ -HTML.stylesheets = classic.css -HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \ - "<tr>\n" \ - "<td align=\"left\" valign=\"top\" width=\"32\">" \ - "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" border=\"0\" /></a>" \ - "</td>\n" \ - "<td width=\"1\"> </td>" \ - "<td class=\"postheader\" valign=\"center\">" \ - "<a href=\"http://qt.nokia.com/doc/4.7/index.html\">" \ - "<font color=\"#004faf\">主页</font></a> ·" \ - " <a href=\"http://qt.nokia.com/doc/4.7/classes.html\">" \ - "<font color=\"#004faf\">所有类</font></a> ·" \ - " <a href=\"http://qt.nokia.com/doc/4.7/functions.html\">" \ - "<font color=\"#004faf\">所有函数</font></a> ·" \ - " <a href=\"http://qt.nokia.com/doc/4.7/overviews.html\">" \ - "<font color=\"#004faf\">简介</font></a>" \ - "</td>" \ - "</tr></table>" +HTML.stylesheets = style/style.css \ + style/OfflineStyle.css \ + style/style_ie7.css \ + style/style_ie8.css \ + style/style_ie6.css -HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ - "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \ - "<td width=\"40%\" align=\"left\">版权所有 © 2010 诺基亚公司和/或其子公司</td>\n" \ - "<td width=\"20%\" align=\"center\"><a href=\"trademarks.html\">商标</a></td>\n" \ - "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \ - "</tr></table></div></address>" +HTML.postheader = " <div class=\"header\" id=\"qtdocheader\">\n" \ + " <div class=\"content\"> \n" \ + " <div id=\"nav-logo\">\n" \ + " <a href=\"index.html\">Home</a></div>\n" \ + " <a href=\"index.html\" class=\"qtref\"><span>Qt Reference Documentation</span></a>\n" \ + " <div id=\"narrowsearch\"><form onsubmit=\"return false;\" action=\"\" id=\"qtdocsearch\">\n" \ + " <fieldset>\n" \ + " <input type=\"text\" value=\"\" id=\"pageType\" name=\"searchstring\">\n" \ + " </fieldset>\n" \ + " </form></div>\n" \ + " <div id=\"nav-topright\">\n" \ + " <ul>\n" \ + " <li class=\"nav-topright-home\"><a href=\"http://qt.nokia.com/\">Qt HOME</a></li>\n" \ + " <li class=\"nav-topright-dev\"><a href=\"http://qt.nokia.com/developer\">DEV</a></li>\n" \ + " <li class=\"nav-topright-labs\"><a href=\"http://labs.qt.nokia.com/blogs/\">LABS</a></li>\n" \ + " <li class=\"nav-topright-doc nav-topright-doc-active\"><a href=\"http://doc.qt.nokia.com/\">\n" \ + " DOC</a></li>\n" \ + " <li class=\"nav-topright-blog\"><a href=\"http://blog.qt.nokia.com/\">BLOG</a></li>\n" \ + " <li class=\"nav-topright-shop\"><a title=\"SHOP\" href=\"http://shop.qt.nokia.com\">SHOP</a></li>\n" \ + " </ul>\n" \ + " </div>\n" \ + " <div id=\"shortCut\">\n" \ + " <ul>\n" \ + " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \ + " <li class=\"shortCut-topleft-active\"><a href=\"http://qt.nokia.com/doc/\">ALL VERSIONS" \ + " </a></li>\n" \ + " </ul>\n" \ + " </div>\n" \ + " <ul class=\"sf-menu sf-js-enabled sf-shadow\" id=\"narrowmenu\"> \n" \ + " <li><a href=\"#\">API Lookup</a> \n" \ + " <ul id=\"topmenuLook\"> \n" \ + " <li><a href=\"classes.html\">所有类</a></li> \n" \ + " <li><a href=\"functions.html\">所有函数</a></li> \n" \ + " <li><a href=\"modules.html\">Modules</a></li> \n" \ + " <li><a href=\"namespaces.html\">Namespaces</a></li> \n" \ + " <li><a href=\"qtglobal.html\">Global stuff</a></li> \n" \ + " <li><a href=\"qdeclarativeelements.html\">QML elements</a></li> \n" \ + " </ul> \n" \ + " </li> \n" \ + " <li><a href=\"#\">Qt Topics</a> \n" \ + " <ul id=\"topmenuTopic\"> \n" \ + " <li><a href=\"qt-basic-concepts.html\">Basic Qt architecture</a></li> \n" \ + " <li><a href=\"declarativeui.html\">Device UI's & Qt Quick</a></li> \n" \ + " <li><a href=\"qt-gui-concepts.html\">Desktop UI components</a></li> \n" \ + " <li><a href=\"platform-specific.html\">Platform-specific info</a></li> \n" \ + " </ul> \n" \ + " </li> \n" \ + " <li><a href=\"#\">Examples</a> \n" \ + " <ul id=\"topmenuexample\"> \n" \ + " <li><a href=\"all-examples.html\">Examples</a></li> \n" \ + " <li><a href=\"tutorials.html\">Tutorials</a></li> \n" \ + " <li><a href=\"demos.html\">Demos</a></li> \n" \ + " <li><a href=\"qdeclarativeexamples.html\">QML Examples</a></li> \n" \ + " <li><a href=\"qdeclarativeexamples.html#Demos\">QML Demos</a></li> \n" \ + " </ul> \n" \ + " </li> \n" \ + " </ul> \n" \ + " </div>\n" \ + " </div>\n" \ + " <div class=\"wrapper\">\n" \ + " <div class=\"hd\">\n" \ + " <span></span>\n" \ + " </div>\n" \ + " <div class=\"bd group\">\n" \ + " <div class=\"sidebar\">\n" \ + " <div class=\"searchlabel\">\n" \ + " Search index:</div>\n" \ + " <div class=\"search\">\n" \ + " <form id=\"qtdocsearch\" action=\"\" onsubmit=\"return false;\">\n" \ + " <fieldset>\n" \ + " <input type=\"text\" name=\"searchstring\" id=\"pageType\" value=\"\" />\n" \ + " </fieldset>\n" \ + " </form>\n" \ + " </div>\n" \ + " <div class=\"box first bottombar\" id=\"lookup\">\n" \ + " <h2 title=\"API Lookup\"><span></span>\n" \ + " API Lookup</h2>\n" \ + " <div id=\"list001\" class=\"list\">\n" \ + " <ul id=\"ul001\" >\n" \ + " <li class=\"defaultLink\"><a href=\"classes.html\">所有类</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"functions.html\">所有函数</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"modules.html\">Modules</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"namespaces.html\">Namespaces</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"qtglobal.html\">Global stuff</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"qdeclarativeelements.html\">QML elements</a></li>\n" \ + " </ul> \n" \ + " </div>\n" \ + " </div>\n" \ + " <div class=\"box bottombar\" id=\"topics\">\n" \ + " <h2 title=\"Qt Topics\"><span></span>\n" \ + " Qt Topics</h2>\n" \ + " <div id=\"list002\" class=\"list\">\n" \ + " <ul id=\"ul002\" >\n" \ + " <li class=\"defaultLink\"><a href=\"qt-basic-concepts.html\">Basic Qt architecture</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"declarativeui.html\">Device UI's & Qt Quick</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"qt-gui-concepts.html\">Desktop UI components</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"platform-specific.html\">Platform-specific info</a></li>\n" \ + " </ul> \n" \ + " </div>\n" \ + " </div>\n" \ + " <div class=\"box\" id=\"examples\">\n" \ + " <h2 title=\"Examples\"><span></span>\n" \ + " Examples</h2>\n" \ + " <div id=\"list003\" class=\"list\">\n" \ + " <ul id=\"ul003\">\n" \ + " <li class=\"defaultLink\"><a href=\"all-examples.html\">Examples</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"tutorials.html\">Tutorials</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"demos.html\">Demos</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"qdeclarativeexamples.html\">QML Examples</a></li>\n" \ + " <li class=\"defaultLink\"><a href=\"qdeclarativeexamples.html#Demos\">QML Demos</a></li>\n" \ + " </ul> \n" \ + " </div>\n" \ + " </div>\n" \ + " </div>\n" \ + " <div class=\"wrap\">\n" \ + " <div class=\"toolbar\">\n" \ + " <div class=\"breadcrumb toolblock\">\n" \ + " <ul>\n" \ + " <li class=\"first\"><a href=\"index.html\">Home</a></li>\n" \ + " <!-- Bread crumbs goes here -->\n" + +HTML.postpostheader = " </ul>\n" \ + " </div>\n" \ + " <div class=\"toolbuttons toolblock\">\n" \ + " <ul>\n" \ + " <li id=\"smallA\" class=\"t_button\">A</li>\n" \ + " <li id=\"medA\" class=\"t_button active\">A</li>\n" \ + " <li id=\"bigA\" class=\"t_button\">A</li>\n" \ + " <li id=\"print\" class=\"t_button\"><a href=\"javascript:this.print();\">\n" \ + " <span>Print</span></a></li>\n" \ + " </ul>\n" \ + " </div>\n" \ + " </div>\n" \ + " <div class=\"content\">\n" + +HTML.footer = " <!-- /div -->\n" \ + " <div class=\"feedback t_button\">\n" \ + " [+] Documentation Feedback</div>\n" \ + " </div>\n" \ + " </div>\n" \ + " <div class=\"ft\">\n" \ + " <span></span>\n" \ + " </div>\n" \ + " </div> \n" \ + " <div class=\"footer\">\n" \ + " <p>\n" \ + " <acronym title=\"Copyright\">©</acronym> 2008-2010 Nokia Corporation and/or its\n" \ + " subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \ + " in Finland and/or other countries worldwide.</p>\n" \ + " <p>\n" \ + " All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \ + " href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \ + " </div>\n" \ + " <div id=\"feedbackBox\">\n" \ + " <div id=\"feedcloseX\" class=\"feedclose t_button\">X</div>\n" \ + " <form id=\"feedform\" action=\"http://doc.qt.nokia.com/docFeedbck/feedback.php\" method=\"get\">\n" \ + " <p><textarea id=\"feedbox\" name=\"feedText\" rows=\"5\" cols=\"40\">Please submit your feedback...</textarea></p>\n" \ + " <p><input id=\"feedsubmit\" class=\"feedclose\" type=\"submit\" name=\"feedback\" /></p>\n" \ + " </form>\n" \ + " </div>\n" \ + " <div id=\"blurpage\">\n" \ + " </div>\n" |