From 322db8410bf7609f072837d554e7256dc385265b Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Tue, 8 Dec 2009 08:04:20 +1000 Subject: Qt fails to build on RHEL 4 and other older Linux versions because of old ALSA Added alsa version checking in config test, must have >= 1.0.10 to enable. Task-number:QTBUG-6493 Reviewed-by:Justin McPherson --- config.tests/unix/alsa/alsatest.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config.tests/unix/alsa/alsatest.cpp b/config.tests/unix/alsa/alsatest.cpp index 1307c4e..f1092f8 100644 --- a/config.tests/unix/alsa/alsatest.cpp +++ b/config.tests/unix/alsa/alsatest.cpp @@ -40,8 +40,11 @@ ****************************************************************************/ #include +#if(!(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 10)) +#error "Alsa version found too old, require >= 1.0.10" +#endif + int main(int argc,char **argv) { - return 0; } -- cgit v0.12 From b70f9d3969fdf7789ba1c5f4d942b2625b1bf689 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Tue, 8 Dec 2009 08:07:13 +1000 Subject: audioinput and audiooutput examples not using isFormatSupported function. The examples failed to easy, added check to test and get if required a format to use from the backend. Increases the chance of examples working on various platforms like n900. Reviewed-by:Justin McPherson --- examples/multimedia/audioinput/audioinput.cpp | 12 +++++++++++- examples/multimedia/audiooutput/audiooutput.cpp | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp index 62afd73..75bddd6 100644 --- a/examples/multimedia/audioinput/audioinput.cpp +++ b/examples/multimedia/audioinput/audioinput.cpp @@ -195,7 +195,6 @@ InputTest::InputTest() pullMode = true; - // AudioInfo class only supports mono S16LE samples! format.setFrequency(8000); format.setChannels(1); format.setSampleSize(16); @@ -203,6 +202,17 @@ InputTest::InputTest() format.setByteOrder(QAudioFormat::LittleEndian); format.setCodec("audio/pcm"); + QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice()); + if (!info.isFormatSupported(format)) { + qWarning()<<"default format not supported try to use nearest"; + format = info.nearestFormat(format); + } + + if(format.sampleSize() != 16) { + qWarning()<<"audio device doesn't support 16 bit samples, example cannot run"; + return; + } + audioInput = new QAudioInput(format,this); connect(audioInput,SIGNAL(notify()),SLOT(status())); connect(audioInput,SIGNAL(stateChanged(QAudio::State)),SLOT(state(QAudio::State))); diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp index 244840d..b6047db 100644 --- a/examples/multimedia/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audiooutput/audiooutput.cpp @@ -170,6 +170,18 @@ AudioTest::AudioTest() settings.setCodec("audio/pcm"); settings.setByteOrder(QAudioFormat::LittleEndian); settings.setSampleType(QAudioFormat::SignedInt); + + QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); + if (!info.isFormatSupported(settings)) { + qWarning()<<"default format not supported try to use nearest"; + settings = info.nearestFormat(settings); + } + + if(settings.sampleSize() != 16) { + qWarning()<<"audio device doesn't support 16 bit samples, example cannot run"; + return; + } + audioOutput = new QAudioOutput(settings,this); connect(audioOutput,SIGNAL(notify()),SLOT(status())); connect(audioOutput,SIGNAL(stateChanged(QAudio::State)),SLOT(state(QAudio::State))); -- cgit v0.12 From f814791b18df3ba0828fefa9f40b2fc955185daf Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Wed, 9 Dec 2009 10:31:53 +1000 Subject: Add -audio-backend and -no-audio-backend configure option. Allow better control over audio backend used. Reviewed-by:Justin McPherson --- configure | 19 +++++++++++++++++-- configure.exe | Bin 1173504 -> 1176576 bytes src/multimedia/audio/audio.pri | 5 +++++ src/multimedia/audio/qaudiodevicefactory.cpp | 14 ++++++++++++++ tools/configure/configureapp.cpp | 11 +++++++++-- 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/configure b/configure index b6ce9e6..41f4991 100755 --- a/configure +++ b/configure @@ -672,6 +672,7 @@ CFG_RELEASE_QMAKE=no CFG_PHONON=auto CFG_PHONON_BACKEND=yes CFG_MULTIMEDIA=yes +CFG_AUDIO_BACKEND=yes CFG_SVG=yes CFG_DECLARATIVE=auto CFG_WEBKIT=auto # (yes|no|auto) @@ -914,7 +915,7 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-svg|-declarative|-webkit|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config) + -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-webkit|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; @@ -2078,6 +2079,13 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + audio-backend) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_AUDIO_BACKEND="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; *) UNKNOWN_OPT=yes ;; @@ -3255,7 +3263,7 @@ Usage: $relconf [-h] [-prefix ] [-prefix-install] [-bindir ] [-libdir [-qtnamespace ] [-qtlibinfix ] [-separate-debug-info] [-armfpa] [-no-optimized-qmake] [-optimized-qmake] [-no-xmlpatterns] [-xmlpatterns] [-no-multimedia] [-multimedia] [-no-phonon] [-phonon] [-no-phonon-backend] [-phonon-backend] - [-no-openssl] [-openssl] [-openssl-linked] + [-no-audio-backend] [-audio-backend] [-no-openssl] [-openssl] [-openssl-linked] [-no-gtkstyle] [-gtkstyle] [-no-svg] [-svg] [-no-webkit] [-webkit] [-no-javascript-jit] [-javascript-jit] [-no-script] [-script] [-no-scripttools] [-scripttools] [-no-declarative] [-declarative] @@ -3393,6 +3401,9 @@ fi -no-multimedia ..... Do not build the QtMultimedia module. + -multimedia ........ Build the QtMultimedia module. + -no-audio-backend .. Do not build the platform audio backend into QtMultimedia. + + -audio-backend ..... Build the platform audio backend into QtMultimedia if available. + -no-phonon ......... Do not build the Phonon module. + -phonon ............ Build the Phonon module. Phonon is built if a decent C++ compiler is used. @@ -6440,6 +6451,10 @@ else QT_CONFIG="$QT_CONFIG multimedia" fi +if [ "$CFG_AUDIO_BACKEND" = "yes" ]; then + QT_CONFIG="$QT_CONFIG audio-backend" +fi + if [ "$CFG_SVG" = "yes" ]; then QT_CONFIG="$QT_CONFIG svg" else diff --git a/configure.exe b/configure.exe index 7fe4a93..a410efc 100755 Binary files a/configure.exe and b/configure.exe differ diff --git a/src/multimedia/audio/audio.pri b/src/multimedia/audio/audio.pri index c445941..625b871c 100644 --- a/src/multimedia/audio/audio.pri +++ b/src/multimedia/audio/audio.pri @@ -17,6 +17,8 @@ SOURCES += $$PWD/qaudio.cpp \ $$PWD/qaudioengine.cpp \ $$PWD/qaudiodevicefactory.cpp +contains(QT_CONFIG, audio-backend) { + mac { HEADERS += $$PWD/qaudioinput_mac_p.h \ $$PWD/qaudiooutput_mac_p.h \ @@ -51,3 +53,6 @@ mac { } } } +} else { + DEFINES += QT_NO_AUDIO_BACKEND +} diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp index 89e4394..bc1656d 100644 --- a/src/multimedia/audio/qaudiodevicefactory.cpp +++ b/src/multimedia/audio/qaudiodevicefactory.cpp @@ -45,6 +45,7 @@ #include #include "qaudiodevicefactory_p.h" +#ifndef QT_NO_AUDIO_BACKEND #if defined(Q_OS_WIN) #include "qaudiodeviceinfo_win32_p.h" #include "qaudiooutput_win32_p.h" @@ -58,6 +59,7 @@ #include "qaudiooutput_alsa_p.h" #include "qaudioinput_alsa_p.h" #endif +#endif QT_BEGIN_NAMESPACE @@ -125,10 +127,12 @@ public: QList QAudioDeviceFactory::availableDevices(QAudio::Mode mode) { QList devices; +#ifndef QT_NO_AUDIO_BACKEND #if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) foreach (const QByteArray &handle, QAudioDeviceInfoInternal::availableDevices(mode)) devices << QAudioDeviceInfo(QLatin1String("builtin"), handle, mode); #endif +#endif QFactoryLoader* l = loader(); foreach (QString const& key, l->keys()) { @@ -153,9 +157,11 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice() if (list.size() > 0) return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioInput); } +#ifndef QT_NO_AUDIO_BACKEND #if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultInputDevice(), QAudio::AudioInput); #endif +#endif return QAudioDeviceInfo(); } @@ -168,9 +174,11 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice() if (list.size() > 0) return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioOutput); } +#ifndef QT_NO_AUDIO_BACKEND #if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultOutputDevice(), QAudio::AudioOutput); #endif +#endif return QAudioDeviceInfo(); } @@ -178,10 +186,12 @@ QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &re { QAbstractAudioDeviceInfo *rc = 0; +#ifndef QT_NO_AUDIO_BACKEND #if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) if (realm == QLatin1String("builtin")) return new QAudioDeviceInfoInternal(handle, mode); #endif +#endif QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(realm)); @@ -205,10 +215,12 @@ QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo con { if (deviceInfo.isNull()) return new QNullInputDevice(); +#ifndef QT_NO_AUDIO_BACKEND #if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) if (deviceInfo.realm() == QLatin1String("builtin")) return new QAudioInputPrivate(deviceInfo.handle(), format); #endif +#endif QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(deviceInfo.realm())); @@ -222,10 +234,12 @@ QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceInfo c { if (deviceInfo.isNull()) return new QNullOutputDevice(); +#ifndef QT_NO_AUDIO_BACKEND #if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA)) if (deviceInfo.realm() == QLatin1String("builtin")) return new QAudioOutputPrivate(deviceInfo.handle(), format); #endif +#endif QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(deviceInfo.realm())); diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 735e030..9143ca7 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -247,6 +247,7 @@ Configure::Configure( int& argc, char** argv ) dictionary[ "PHONON" ] = "auto"; dictionary[ "PHONON_BACKEND" ] = "yes"; dictionary[ "MULTIMEDIA" ] = "yes"; + dictionary[ "AUDIO_BACKEND" ] = "yes"; dictionary[ "DIRECTSHOW" ] = "no"; dictionary[ "WEBKIT" ] = "auto"; dictionary[ "DECLARATIVE" ] = "auto"; @@ -897,6 +898,10 @@ void Configure::parseCmdLine() dictionary[ "MULTIMEDIA" ] = "no"; } else if( configCmdLine.at(i) == "-multimedia" ) { dictionary[ "MULTIMEDIA" ] = "yes"; + } else if( configCmdLine.at(i) == "-audio-backend" ) { + dictionary[ "AUDIO_BACKEND" ] = "yes"; + } else if( configCmdLine.at(i) == "-no-audio-backend" ) { + dictionary[ "AUDIO_BACKEND" ] = "no"; } else if( configCmdLine.at(i) == "-no-phonon" ) { dictionary[ "PHONON" ] = "no"; } else if( configCmdLine.at(i) == "-phonon" ) { @@ -1567,9 +1572,9 @@ bool Configure::displayHelp() "[-no-openssl] [-no-dbus] [-dbus] [-dbus-linked] [-platform ]\n" "[-qtnamespace ] [-qtlibinfix ] [-no-phonon]\n" "[-phonon] [-no-phonon-backend] [-phonon-backend]\n" - "[-no-multimedia] [-multimedia] [-no-webkit] [-webkit]\n" + "[-no-multimedia] [-multimedia] [-no-audio-backend] [-audio-backend]\n" "[-no-script] [-script] [-no-scripttools] [-scripttools]\n" - "[-graphicssystem raster|opengl|openvg]\n\n", 0, 7); + "[-no-webkit] [-webkit] [-graphicssystem raster|opengl|openvg]\n\n", 0, 7); desc("Installation options:\n\n"); @@ -1749,6 +1754,8 @@ bool Configure::displayHelp() desc("PHONON_BACKEND","yes","-phonon-backend", "Compile in the platform-specific Phonon backend-plugin"); desc("MULTIMEDIA", "no", "-no-multimedia", "Do not compile the multimedia module"); desc("MULTIMEDIA", "yes","-multimedia", "Compile in multimedia module"); + desc("AUDIO_BACKEND", "no","-no-audio-backend", "Do not compile in the platform audio backend into QtMultimedia"); + desc("AUDIO_BACKEND", "yes","-audio-backend", "Compile in the platform audio backend into QtMultimedia"); desc("WEBKIT", "no", "-no-webkit", "Do not compile in the WebKit module"); desc("WEBKIT", "yes", "-webkit", "Compile in the WebKit module (WebKit is built if a decent C++ compiler is used.)"); desc("SCRIPT", "no", "-no-script", "Do not build the QtScript module."); -- cgit v0.12 From ad2509f8d7c634364ae7082dcc83b6906d235750 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Wed, 9 Dec 2009 10:34:19 +1000 Subject: Fix up documentation examples for low-level audio. QTBUG-6548 QAudioOutput::start() crashes when the QIODevice is destructed Made documentation clearer. Task-number:QTBUG-6548 Reviewed-by:Justin McPherson --- src/multimedia/audio/qaudioinput.cpp | 15 +++++++++++++-- src/multimedia/audio/qaudiooutput.cpp | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 8b368d5..d81df7a 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -77,8 +77,12 @@ QT_BEGIN_NAMESPACE file, you can: \code + QFile outputFile; // class member. + QAudioInput* audio; // class member. + \endcode + + \code { - QFile outputFile; outputFile.setFileName("/tmp/test.raw"); outputFile.open( QIODevice::WriteOnly | QIODevice::Truncate ); @@ -91,7 +95,13 @@ QT_BEGIN_NAMESPACE format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::UnSignedInt); - QAudioInput *audio = new QAudioInput(format, this); + if (QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice()); + if (!info.isFormatSupported(format)) { + qWarning()<<"default format not supported try to use nearest"; + format = info.nearestFormat(format); + } + + audio = new QAudioInput(format, this); QTimer::singleShot(3000, this, SLOT(stopRecording())); audio->start(outputFile); // Records audio for 3000ms @@ -109,6 +119,7 @@ QT_BEGIN_NAMESPACE { audio->stop(); outputFile->close(); + delete audio; } \endcode diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index f8f2fa1..1c7b617 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -73,7 +73,11 @@ QT_BEGIN_NAMESPACE simple as: \code - QFile inputFile; + QFile inputFile; // class member. + QAudioOutput* audio; // class member. + \endcode + + \code inputFile.setFileName("/tmp/test.raw"); inputFile.open(QIODevice::ReadOnly); @@ -86,7 +90,13 @@ QT_BEGIN_NAMESPACE format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::UnSignedInt); - QAudioOutput *audio = new QAudioOutput(format, this); + QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); + if (!info.isFormatSupported(format)) { + qWarning()<<"raw audio format not supported by backend, cannot play audio."; + return; + } + + audio = new QAudioOutput(format, this); connect(audio,SIGNAL(stateChanged(QAudio::State)),SLOT(finishedPlaying(QAudio::State))); audio->start(inputFile); @@ -104,6 +114,7 @@ QT_BEGIN_NAMESPACE if(state == QAudio::IdleState) { audio->stop(); inputFile.close(); + delete audio; } } \endcode -- cgit v0.12 From d5d39f04c2c473401e9147d57d5a7c62f6111656 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 8 Dec 2009 12:15:19 +0100 Subject: Fix regression in qVariantFromValue when converting from complex type to simple type QVariant v = QColor(Qt::red); v.setValue(1000); Would produce a variant with garbage. the destructor of QColor would not be called, and the 1000 would be in the QVariant::PrivateShared, while most of the QVariant code assume that numbers are dirrectly in the QVariant::Data union Task-number: QTBUG-6602 Reviewed-by: Thierry --- src/corelib/kernel/qvariant.h | 2 +- tests/auto/qvariant/tst_qvariant.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 3c10788..74ff17f 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -458,7 +458,7 @@ inline void qVariantSetValue(QVariant &v, const T &t) //if possible we reuse the current QVariant private const uint type = qMetaTypeId(reinterpret_cast(0)); QVariant::Private &d = v.data_ptr(); - if (v.isDetached() && (type <= uint(QVariant::Char) || type == d.type)) { + if (v.isDetached() && (type == d.type || (type <= uint(QVariant::Char) && d.type <= uint(QVariant::Char)))) { d.type = type; d.is_null = false; T *old = reinterpret_cast(d.is_shared ? d.data.shared->ptr : &d.data.ptr); diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index 3d68a73..ae0131c 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -272,6 +272,8 @@ private slots: void numericalConvert(); void moreCustomTypes(); void variantInVariant(); + + void colorInteger(); }; Q_DECLARE_METATYPE(QDate) @@ -3388,5 +3390,20 @@ void tst_QVariant::variantInVariant() QCOMPARE(qvariant_cast(var9), var1); } +void tst_QVariant::colorInteger() +{ + QVariant v = QColor(Qt::red); + QCOMPARE(v.type(), QVariant::Color); + QCOMPARE(v.value(), QColor(Qt::red)); + + v.setValue(1000); + QCOMPARE(v.type(), QVariant::Int); + QCOMPARE(v.toInt(), 1000); + + v.setValue(QColor(Qt::yellow)); + QCOMPARE(v.type(), QVariant::Color); + QCOMPARE(v.value(), QColor(Qt::yellow)); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" -- cgit v0.12 From 934d4b9852060b2870f6774cd854331422147d3e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 8 Dec 2009 10:50:01 +0100 Subject: Use 64bit for the connectedSignals as QML objects may have lots of signals Do not use quint64 as it would produce lots of useless padding on MSVC 32bit Reviewed-by: Brad --- src/corelib/kernel/qobject.cpp | 6 +++--- src/corelib/kernel/qobject_p.h | 11 ++++++----- tests/auto/qobject/tst_qobject.cpp | 8 ++++---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 30cd011..85915c2 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -145,7 +145,7 @@ QObjectPrivate::QObjectPrivate(int version) receiveChildEvents = true; postedEvents = 0; extraData = 0; - connectedSignals = 0; + connectedSignals[0] = connectedSignals[1] = 0; inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; @@ -2924,9 +2924,9 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index, QObjectPrivate *const sender_d = QObjectPrivate::get(s); if (signal_index < 0) { - sender_d->connectedSignals = ~ulong(0); + sender_d->connectedSignals[0] = sender_d->connectedSignals[1] = ~0; } else if (signal_index < (int)sizeof(sender_d->connectedSignals) * 8) { - sender_d->connectedSignals |= ulong(1) << signal_index; + sender_d->connectedSignals[signal_index >> 5] |= (1 << (signal_index & 0x1f)); } return true; diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index f899c78..d1841be 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -172,7 +172,7 @@ public: } int signalIndex(const char *signalName) const; - inline bool isSignalConnected(int signalIdx) const; + inline bool isSignalConnected(uint signalIdx) const; public: QString objectName; @@ -183,7 +183,7 @@ public: Connection *senders; // linked list of connections connected to this object Sender *currentSender; // object currently activating the object - mutable ulong connectedSignals; + mutable quint32 connectedSignals[2]; #ifdef QT3_SUPPORT QList pendingChildInsertedEvents; @@ -205,6 +205,7 @@ public: int *deleteWatch; }; + /*! \internal Returns true if the signal with index \a signal_index from object \a sender is connected. @@ -213,12 +214,12 @@ public: \a signal_index must be the index returned by QObjectPrivate::signalIndex; */ -inline bool QObjectPrivate::isSignalConnected(int signal_index) const +inline bool QObjectPrivate::isSignalConnected(uint signal_index) const { - return signal_index >= (int)sizeof(connectedSignals) * 8 + return signal_index >= sizeof(connectedSignals) * 8 || qt_signal_spy_callback_set.signal_begin_callback || qt_signal_spy_callback_set.signal_end_callback - || (connectedSignals & (ulong(1) << signal_index)); + || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f))); } diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 67a9c46..a2524aa 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -3058,10 +3058,8 @@ void tst_QObject::isSignalConnected() QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig05()"))); QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig15()"))); QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig29()"))); - if (sizeof(void *) >= 8) { //on 32bit isSignalConnected only works with the first 32 signals - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig60()"))); - QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig61()"))); - } + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig60()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig61()"))); #endif QObject::connect(&o, SIGNAL(sig00()), &o, SIGNAL(sig69())); @@ -3115,6 +3113,8 @@ void tst_QObject::isSignalConnected() QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig04()"))); QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig21()"))); QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig25()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig55()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig61()"))); #endif emit o.sig00(); -- cgit v0.12 From 6744e241ee41a50b02a76e3e755ec448676589a4 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 9 Dec 2009 13:21:23 +0100 Subject: Compile with QT_NO_DEPRECATED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit uses of QT_DEPRECATED must be protected by #ifdef Task-number: QTBUG-6649 Reviewed-by: João Abecasis --- src/corelib/tools/qregexp.h | 2 ++ src/gui/embedded/qscreen_qws.h | 2 ++ src/gui/image/qimage.h | 6 ++++++ src/gui/image/qpixmap.h | 2 ++ src/gui/painting/qmatrix.h | 2 ++ src/gui/painting/qpaintdevice.h | 2 ++ src/gui/painting/qregion.h | 2 ++ src/gui/widgets/qlcdnumber.h | 3 ++- src/gui/widgets/qprintpreviewwidget.h | 2 ++ tools/assistant/lib/qhelpsearchengine.h | 2 ++ 10 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h index 2bad40e..8a46b98 100644 --- a/src/corelib/tools/qregexp.h +++ b/src/corelib/tools/qregexp.h @@ -119,7 +119,9 @@ public: #endif int matchedLength() const; #ifndef QT_NO_REGEXP_CAPTURE +#ifdef QT_DEPRECATED QT_DEPRECATED int numCaptures() const; +#endif int captureCount() const; QStringList capturedTexts() const; QStringList capturedTexts(); diff --git a/src/gui/embedded/qscreen_qws.h b/src/gui/embedded/qscreen_qws.h index b3246f9..7ab49fb 100644 --- a/src/gui/embedded/qscreen_qws.h +++ b/src/gui/embedded/qscreen_qws.h @@ -243,7 +243,9 @@ public: int totalSize() const { return mapsize; } QRgb * clut() { return screenclut; } +#ifdef QT_DEPRECATED QT_DEPRECATED int numCols() { return screencols; } +#endif int colorCount() { return screencols; } virtual QSize mapToDevice(const QSize &) const; diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index d8809ef..ce7f450 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -165,12 +165,16 @@ public: QRect rect() const; int depth() const; +#ifdef QT_DEPRECATED QT_DEPRECATED int numColors() const; +#endif int colorCount() const; QRgb color(int i) const; void setColor(int i, QRgb c); +#ifdef QT_DEPRECATED QT_DEPRECATED void setNumColors(int); +#endif void setColorCount(int); bool allGray() const; @@ -178,7 +182,9 @@ public: uchar *bits(); const uchar *bits() const; +#ifdef QT_DEPRECATED QT_DEPRECATED int numBytes() const; +#endif int byteCount() const; uchar *scanLine(int); diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index d95b4ee..e02b0d6 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -185,7 +185,9 @@ public: const uchar *qwsBits() const; int qwsBytesPerLine() const; QRgb *clut() const; +#ifdef QT_DEPRECATED QT_DEPRECATED int numCols() const; +#endif int colorCount() const; #elif defined(Q_WS_MAC) Qt::HANDLE macQDHandle() const; diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index 152b3c9..af48bcb 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -102,7 +102,9 @@ public: bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); } qreal determinant() const { return _m11*_m22 - _m12*_m21; } +#ifdef QT_DEPRECATED QT_DEPRECATED qreal det() const { return _m11*_m22 - _m12*_m21; } +#endif QMatrix inverted(bool *invertible = 0) const; diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h index 9148e4b..0f8191e 100644 --- a/src/gui/painting/qpaintdevice.h +++ b/src/gui/painting/qpaintdevice.h @@ -96,7 +96,9 @@ public: int logicalDpiY() const { return metric(PdmDpiY); } int physicalDpiX() const { return metric(PdmPhysicalDpiX); } int physicalDpiY() const { return metric(PdmPhysicalDpiY); } +#ifdef QT_DEPRECATED QT_DEPRECATED int numColors() const { return metric(PdmNumColors); } +#endif int colorCount() const { return metric(PdmNumColors); } int depth() const { return metric(PdmDepth); } diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h index 2a1be86..f99fbf6 100644 --- a/src/gui/painting/qregion.h +++ b/src/gui/painting/qregion.h @@ -116,7 +116,9 @@ public: QRect boundingRect() const; QVector rects() const; void setRects(const QRect *rect, int num); +#ifdef QT_DEPRECATED QT_DEPRECATED int numRects() const; +#endif int rectCount() const; const QRegion operator|(const QRegion &r) const; diff --git a/src/gui/widgets/qlcdnumber.h b/src/gui/widgets/qlcdnumber.h index e65637d..b7162cd 100644 --- a/src/gui/widgets/qlcdnumber.h +++ b/src/gui/widgets/qlcdnumber.h @@ -82,9 +82,10 @@ public: }; bool smallDecimalPoint() const; - +#ifdef QT_DEPRECATED QT_DEPRECATED int numDigits() const; QT_DEPRECATED void setNumDigits(int nDigits); +#endif int digitCount() const; void setDigitCount(int nDigits); diff --git a/src/gui/widgets/qprintpreviewwidget.h b/src/gui/widgets/qprintpreviewwidget.h index 08e596d..d8504de 100644 --- a/src/gui/widgets/qprintpreviewwidget.h +++ b/src/gui/widgets/qprintpreviewwidget.h @@ -82,7 +82,9 @@ public: ViewMode viewMode() const; ZoomMode zoomMode() const; int currentPage() const; +#ifdef QT_DEPRECATED QT_DEPRECATED int numPages() const; +#endif int pageCount() const; void setVisible(bool visible); diff --git a/tools/assistant/lib/qhelpsearchengine.h b/tools/assistant/lib/qhelpsearchengine.h index 21f04c5..632ac0b 100644 --- a/tools/assistant/lib/qhelpsearchengine.h +++ b/tools/assistant/lib/qhelpsearchengine.h @@ -86,7 +86,9 @@ public: QHelpSearchQueryWidget* queryWidget(); QHelpSearchResultWidget* resultWidget(); +#ifdef QT_DEPRECATED QT_DEPRECATED int hitsCount() const; +#endif int hitCount() const; typedef QPair SearchHit; -- cgit v0.12 From c4d66e27ea69b84bf280209fc72239132924930d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 9 Dec 2009 12:14:58 +0100 Subject: GLES 2 should *not* use a multisampled format by default. This is a platform regression and should never have been there in the first place. Having this as the default format on embedded devices may drop the framerates with as much as 30% on selected HW. Reviewed-by: Tom Cooksey --- src/opengl/qgl.cpp | 3 +-- src/opengl/qgl_p.h | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 25285b5..dcf8c00 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -397,8 +397,7 @@ static inline GLint qgluProject(GLdouble objx, GLdouble objy, GLdouble objz, \i \link setDirectRendering() Direct rendering:\endlink Enabled. \i \link setOverlay() Overlay:\endlink Disabled. \i \link setPlane() Plane:\endlink 0 (i.e., normal plane). - \i \link setSampleBuffers() Multisample buffers:\endlink Enabled on - OpenGL/ES 2.0, disabled on other platforms. + \i \link setSampleBuffers() Multisample buffers:\endlink Disabled. \endlist */ diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 615fb60..8a0b31f 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -133,9 +133,6 @@ public: : ref(1) { opts = QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::DirectRendering | QGL::StencilBuffer; -#if defined(QT_OPENGL_ES_2) - opts |= QGL::SampleBuffers; -#endif pln = 0; depthSize = accumSize = stencilSize = redSize = greenSize = blueSize = alphaSize = -1; numSamples = -1; -- cgit v0.12 From 7fecd890ce50d86120566acc7e71fcac915a671f Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 9 Dec 2009 14:19:33 +0100 Subject: Fixed a regression in dock widget resizing It could happen that they grow much more than the movement of the mouse Task-number: QTBUG-6499 Reviewed-by: gabi --- src/gui/widgets/qdockarealayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 0a26a77..cf82da0 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1303,9 +1303,9 @@ QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList &path) index = -index - 1; if (index >= item_list.count()) return this; - if (path.count() == 1 || item_list.at(index).subinfo == 0) + if (path.count() == 1 || item_list[index].subinfo == 0) return this; - return item_list.at(index).subinfo->info(path.mid(1)); + return item_list[index].subinfo->info(path.mid(1)); } QRect QDockAreaLayoutInfo::itemRect(int index) const -- cgit v0.12 From bdb485519d957bb551d5eeae8a866df45a59c647 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 9 Dec 2009 14:35:32 +0100 Subject: Use realpath() only on systems we know it works on. We use realpath(X,0) extension that is defined by the latest POSIX standard and not many systems support it at the moment. For now we limit it to Linux and Symbian. Mac supports it starting with 10.6, and we'll implement it properly for Mac in 4.7. We know that neither *BSD systems nor Solaris do not support it. Reviewed-by: Markus Goetz --- src/corelib/io/qfsfileengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 37b0ea1..e4c4e3f 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -144,7 +144,7 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path) return path; #endif // Mac OS X 10.5.x doesn't support the realpath(X,0) extenstion we use here. -#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) || defined(Q_OS_SYMBIAN) +#if defined(Q_OS_LINIX) || defined(Q_OS_SYMBIAN) char *ret = realpath(path.toLocal8Bit().constData(), (char*)0); if (ret) { QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret)); -- cgit v0.12 From 9f3cde38bffb79da82d6248a873a687d37177954 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 9 Dec 2009 14:49:15 +0100 Subject: Don't assert on valid math in qbezier --- src/gui/painting/qbezier_p.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h index 7dbd0c2..c284871 100644 --- a/src/gui/painting/qbezier_p.h +++ b/src/gui/painting/qbezier_p.h @@ -166,8 +166,6 @@ inline void QBezier::coefficients(qreal t, qreal &a, qreal &b, qreal &c, qreal & inline QPointF QBezier::pointAt(qreal t) const { - Q_ASSERT(t >= 0); - Q_ASSERT(t <= 1); #if 1 qreal a, b, c, d; coefficients(t, a, b, c, d); -- cgit v0.12 From 0c30418556d978f730c33aa3bb066961981ccc9b Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 9 Dec 2009 15:15:35 +0100 Subject: Fix crash when rotating cleartype text under gl engine. Reviewed-by: Eskil --- src/gui/painting/qtextureglyphcache_p.h | 5 +---- src/gui/text/qfontengine.cpp | 10 ++++++---- src/gui/text/qfontengine_p.h | 4 ++-- src/gui/text/qfontengineglyphcache_p.h | 7 +++++-- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 4 ++-- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index 57473d1..bb0c630 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -76,7 +76,7 @@ class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache { public: QTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix) - : QFontEngineGlyphCache(matrix), m_w(0), m_h(0), m_cx(0), m_cy(0), m_type(type) { } + : QFontEngineGlyphCache(matrix, type), m_w(0), m_h(0), m_cx(0), m_cy(0) { } virtual ~QTextureGlyphCache() { } @@ -98,8 +98,6 @@ public: virtual void resizeTextureData(int width, int height) = 0; virtual int glyphMargin() const { return 0; } - QFontEngineGlyphCache::Type cacheType() const { return m_type; } - virtual void fillTexture(const Coord &coord, glyph_t glyph) = 0; inline void createCache(int width, int height) { @@ -121,7 +119,6 @@ protected: int m_h; // image height int m_cx; // current x int m_cy; // current y - QFontEngineGlyphCache::Type m_type; }; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 27fc3c1..0eadf04 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -742,14 +742,15 @@ void QFontEngine::expireGlyphCache() } } -void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data) +void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data, QFontEngineGlyphCache::Type type) { Q_ASSERT(data); QList items = m_glyphPointerHash.value(key); for (QList::iterator it = items.begin(), end = items.end(); it != end; ++it) { QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) { + if (qtransform_equals_no_translate(c->m_transform, data->m_transform) + && c->cacheType() == type) { if (c == data) return; items.removeAll(c); @@ -786,13 +787,14 @@ void QFontEngine::setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyp expireGlyphCache(); } -QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, const QTransform &transform) const +QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, const QTransform &transform, QFontEngineGlyphCache::Type type) const { QList items = m_glyphPointerHash.value(key); for (QList::iterator it = items.begin(), end = items.end(); it != end; ++it) { QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, transform)) { + if (qtransform_equals_no_translate(c->m_transform, transform) + && type == c->cacheType()) { m_glyphCacheQueue.removeAll(c); // last used, move it up m_glyphCacheQueue.append(c); return c; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 728c344..62bff85 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -218,9 +218,9 @@ public: virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints); - void setGlyphCache(void *key, QFontEngineGlyphCache *data); + void setGlyphCache(void *key, QFontEngineGlyphCache *data, QFontEngineGlyphCache::Type type); void setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data); - QFontEngineGlyphCache *glyphCache(void *key, const QTransform &transform) const; + QFontEngineGlyphCache *glyphCache(void *key, const QTransform &transform, QFontEngineGlyphCache::Type type) const; QFontEngineGlyphCache *glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const; static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize); diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h index e04f4ac..c6112ba 100644 --- a/src/gui/text/qfontengineglyphcache_p.h +++ b/src/gui/text/qfontengineglyphcache_p.h @@ -75,17 +75,20 @@ QT_BEGIN_NAMESPACE class QFontEngineGlyphCache { public: - QFontEngineGlyphCache(const QTransform &matrix) : m_transform(matrix) { } - enum Type { Raster_RGBMask, Raster_A8, Raster_Mono }; + QFontEngineGlyphCache(const QTransform &matrix, Type type) : m_transform(matrix), m_type(type) { } + virtual ~QFontEngineGlyphCache() { } + Type cacheType() const { return m_type; } + QTransform m_transform; + QFontEngineGlyphCache::Type m_type; }; typedef QHash > GlyphPointerHash; typedef QHash > GlyphIntHash; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 17af9cb..9f42217 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1562,11 +1562,11 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); QGLTextureGlyphCache *cache = - (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, QTransform()); + (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, QTransform(), glyphType); if (!cache || cache->cacheType() != glyphType) { cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform()); - ti.fontEngine->setGlyphCache(ctx, cache); + ti.fontEngine->setGlyphCache(ctx, cache, glyphType); } cache->setPaintEnginePrivate(this); -- cgit v0.12 From 293db01f907ad8644e8242055521e6b8e7c4dfec Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 9 Dec 2009 16:07:13 +0100 Subject: Fix a crash on the focus chain when removing items from the scene. The crash was because of the dangling pointer set on the tabFocusFirst attribute in QGraphicsScene. A child which was the tabFocusFirst was removed from the scene and fixFocusChainBeforeReparenting was setting the new tabFocusFirst pointer to the parent (since in that example it was the focusNext) but later on the parent was removed also from the scene (due to the recursion of removeItem if you call it with the parent : first children, then the parent itself) and fixFocusChainBeforeReparenting was not called again so if you delete the parent then the scene has the dangling pointer set. Task-number:QTBUG-6544 Reviewed-by:janarve --- src/gui/graphicsview/qgraphicsscene.cpp | 11 ++++---- src/gui/graphicsview/qgraphicswidget.cpp | 2 +- src/gui/graphicsview/qgraphicswidget_p.cpp | 4 +-- src/gui/graphicsview/qgraphicswidget_p.h | 2 +- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 32 ++++++++++++++++++++++ 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 27ebb79..2af90b8 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -569,14 +569,10 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) item->d_ptr->clearSubFocus(); - if (!item->d_ptr->inDestructor && item == tabFocusFirst) { - QGraphicsWidget *widget = static_cast(item); - widget->d_func()->fixFocusChainBeforeReparenting(0, 0); - } - if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges) unregisterScenePosItem(item); + QGraphicsScene *oldScene = item->d_func()->scene; item->d_func()->scene = 0; //We need to remove all children first because they might use their parent @@ -587,6 +583,11 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) q->removeItem(item->d_ptr->children.at(i)); } + if (!item->d_ptr->inDestructor && item == tabFocusFirst) { + QGraphicsWidget *widget = static_cast(item); + widget->d_func()->fixFocusChainBeforeReparenting(0, oldScene, 0); + } + // Unregister focus proxy. item->d_ptr->resetFocusProxy(); diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index fe569f4..8de81c2 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1054,7 +1054,7 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant & break; case ItemParentChange: { QGraphicsItem *parent = qVariantValue(value); - d->fixFocusChainBeforeReparenting((parent && parent->isWidget()) ? static_cast(parent) : 0); + d->fixFocusChainBeforeReparenting((parent && parent->isWidget()) ? static_cast(parent) : 0, scene()); // Deliver ParentAboutToChange. QEvent event(QEvent::ParentAboutToChange); diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index b747a30..5b6490f 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -743,7 +743,7 @@ bool QGraphicsWidgetPrivate::hasDecoration() const /** * is called after a reparent has taken place to fix up the focus chain(s) */ -void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *newScene) +void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene) { Q_Q(QGraphicsWidget); @@ -789,7 +789,7 @@ void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *new // update tabFocusFirst for oldScene if the item is going to be removed from oldScene if (newParent) newScene = newParent->scene(); - QGraphicsScene *oldScene = q->scene(); + if (oldScene && newScene != oldScene) oldScene->d_func()->tabFocusFirst = firstOld; diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index eb53649..65e6962 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -98,7 +98,7 @@ public: mutable qreal *margins; void ensureMargins() const; - void fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *newScene = 0); + void fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene = 0); void setLayout_helper(QGraphicsLayout *l); // Layouts diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 3303df5..a835259 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -168,6 +168,7 @@ private slots: void task236127_bspTreeIndexFails(); void task243004_setStyleCrash(); void task250119_shortcutContext(); + void QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems(); }; @@ -2855,6 +2856,37 @@ void tst_QGraphicsWidget::polishEvent2() QVERIFY(widget->events.contains(QEvent::Polish)); } +void tst_QGraphicsWidget::QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems() +{ + QGraphicsScene scene; + QGraphicsWidget* parent1 = new QGraphicsWidget; + QGraphicsWidget* child1_0 = new QGraphicsWidget; + QGraphicsWidget* child1_1 = new QGraphicsWidget; + + QGraphicsWidget* parent2 = new QGraphicsWidget; + + // Add the parent and child to the scene. + scene.addItem(parent1); + child1_0->setParentItem(parent1); + child1_1->setParentItem(parent1); + + // Hide and show the child. + child1_0->setParentItem(NULL); + scene.removeItem(child1_0); + + // Remove parent from the scene. + scene.removeItem(parent1); + + delete child1_0; + delete child1_1; + delete parent1; + + // Add an item into the scene. + scene.addItem(parent2); + + //This should not crash +} + QTEST_MAIN(tst_QGraphicsWidget) #include "tst_qgraphicswidget.moc" -- cgit v0.12 From 16de24d638deafb6e985b531fdf0c15691c0b7b4 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 10 Dec 2009 09:28:04 +1000 Subject: Recreate VGImage properly in out of memory case If vgCreateImage() runs out of memory, then the drawPixmap() will fail. But previously, it would also prevent future attempts to call vgImageSubData() to populate the data when memory was present. Task-number: QTBUG-6639 Reviewed-by: Sarah Smith --- src/openvg/qpixmapdata_vg.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 5d5fcbf..af6f0f0 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -250,6 +250,10 @@ VGImage QVGPixmapData::toVGImage() if (vgImage == VG_INVALID_HANDLE) { vgImage = vgCreateImage (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER); + + // Bail out if we run out of GPU memory - try again next time. + if (vgImage == VG_INVALID_HANDLE) + return VG_INVALID_HANDLE; } if (!source.isNull() && recreate) { @@ -280,6 +284,10 @@ VGImage QVGPixmapData::toVGImage(qreal opacity) if (vgImageOpacity == VG_INVALID_HANDLE) { vgImageOpacity = vgCreateImage (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER); + + // Bail out if we run out of GPU memory - try again next time. + if (vgImageOpacity == VG_INVALID_HANDLE) + return VG_INVALID_HANDLE; } VGfloat matrix[20] = { 1.0f, 0.0f, 0.0f, 0.0f, -- cgit v0.12 From c73d4f8b55dbb79b7a2df38d167a7c5ffd4520ce Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 10 Dec 2009 10:04:36 +0100 Subject: Fix compilation: private headers must be #included with "" The reason is that the private headers don't exist in any of the -I lines, so they need to be found by the preprocessor relative to the source file, which means "". Task-number: QTBUG-6665 Reviewed-by: Trust Me --- src/dbus/qdbusargument_p.h | 2 +- src/dbus/qdbusconnection_p.h | 2 +- src/dbus/qdbusconnectioninterface.cpp | 2 +- src/dbus/qdbuserror.cpp | 2 +- src/dbus/qdbusintegrator_p.h | 2 +- src/dbus/qdbusinterface.cpp | 2 +- src/dbus/qdbusinterface_p.h | 4 ++-- src/dbus/qdbusinternalfilters.cpp | 2 +- src/dbus/qdbusmessage.cpp | 2 +- src/dbus/qdbusmetatype.cpp | 2 +- src/dbus/qdbusutil.cpp | 2 +- src/dbus/qdbusxmlparser_p.h | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h index 47c5e62..17302b4 100644 --- a/src/dbus/qdbusargument_p.h +++ b/src/dbus/qdbusargument_p.h @@ -54,7 +54,7 @@ // #include -#include +#include "qdbus_symbols_p.h" QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index b65e101..d6f7598 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -67,7 +67,7 @@ #include #include -#include +#include "qdbus_symbols_p.h" #include diff --git a/src/dbus/qdbusconnectioninterface.cpp b/src/dbus/qdbusconnectioninterface.cpp index 0f9a67f..ec61859 100644 --- a/src/dbus/qdbusconnectioninterface.cpp +++ b/src/dbus/qdbusconnectioninterface.cpp @@ -49,7 +49,7 @@ #include #include -#include // for the DBUS_* constants +#include "qdbus_symbols_p.h" // for the DBUS_* constants QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp index 5c2fa2b..a48b878 100644 --- a/src/dbus/qdbuserror.cpp +++ b/src/dbus/qdbuserror.cpp @@ -44,7 +44,7 @@ #include #include -#include +#include "qdbus_symbols_p.h" #include "qdbusmessage.h" #include "qdbusmessage_p.h" diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h index 5b18aca..85c6cb2 100644 --- a/src/dbus/qdbusintegrator_p.h +++ b/src/dbus/qdbusintegrator_p.h @@ -54,7 +54,7 @@ #ifndef QDBUSINTEGRATOR_P_H #define QDBUSINTEGRATOR_P_H -#include +#include "qdbus_symbols_p.h" #include "qcoreevent.h" #include "qeventloop.h" diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp index d0a693f..c05e6a9 100644 --- a/src/dbus/qdbusinterface.cpp +++ b/src/dbus/qdbusinterface.cpp @@ -41,7 +41,7 @@ #include "qdbusinterface.h" -#include +#include "qdbus_symbols_p.h" #include #include diff --git a/src/dbus/qdbusinterface_p.h b/src/dbus/qdbusinterface_p.h index 3d11af1..a601608 100644 --- a/src/dbus/qdbusinterface_p.h +++ b/src/dbus/qdbusinterface_p.h @@ -54,8 +54,8 @@ #ifndef QDBUSINTERFACEPRIVATE_H #define QDBUSINTERFACEPRIVATE_H -#include -#include +#include "qdbusabstractinterface_p.h" +#include "qdbusmetaobject_p.h" #include QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index acd04d3..37110c5 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -41,7 +41,7 @@ #include "qdbusconnection_p.h" -#include +#include "qdbus_symbols_p.h" #include #include #include diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index 4f1950b..a37ba1f 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -44,7 +44,7 @@ #include #include -#include +#include "qdbus_symbols_p.h" #include "qdbusargument_p.h" #include "qdbuserror.h" diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp index 237aea3..afa3bbf 100644 --- a/src/dbus/qdbusmetatype.cpp +++ b/src/dbus/qdbusmetatype.cpp @@ -42,7 +42,7 @@ #include "qdbusmetatype.h" #include -#include +#include "qdbus_symbols_p.h" #include #include diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp index bf5a739..01b1dbd 100644 --- a/src/dbus/qdbusutil.cpp +++ b/src/dbus/qdbusutil.cpp @@ -41,7 +41,7 @@ #include "qdbusutil_p.h" -#include +#include "qdbus_symbols_p.h" #include diff --git a/src/dbus/qdbusxmlparser_p.h b/src/dbus/qdbusxmlparser_p.h index 3dbae1b..1a0523b 100644 --- a/src/dbus/qdbusxmlparser_p.h +++ b/src/dbus/qdbusxmlparser_p.h @@ -56,7 +56,7 @@ #include #include #include -#include +#include "qdbusintrospection_p.h" QT_BEGIN_NAMESPACE -- cgit v0.12 From 2705480b5cd740eee3ed684a26508b0497b00477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Thu, 10 Dec 2009 09:51:03 +0100 Subject: Doc: Try to explain better when and how the easing curve is applied Maybe not perfect, but it should be *better* at least. Task-number: QTBUG-6623 Reviewed-by: Thierry --- src/corelib/animation/qvariantanimation.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index d529f67..bc0d35e 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -373,6 +373,13 @@ QVariantAnimation::~QVariantAnimation() Another example is QEasingCurve::InOutElastic, which provides an elastic effect on the values of the interpolated variant. + QVariantAnimation will use the QEasingCurve::valueForProgress() to + transform the "normalized progress" (currentTime / totalDuration) + of the animation into the effective progress actually + used by the animation. It is this effective progress that will be + the progress when interpolated() is called. Also, the steps in the + keyValues are referring to this effective progress. + The easing curve is used with the interpolator, the interpolated() virtual function, the animation's duration, and iterationCount, to control how the current value changes as the animation progresses. -- cgit v0.12 From f85306467b84cbc300d13aa52e0f5db4b1a2b1e6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 10 Dec 2009 10:10:43 +0100 Subject: Fix compilation if QT_NO_DATESTRING is defined. If we have no string parsing in QDateTime, then we use sscanf, so we must include Task-number: QTBUG-6668 Reviewed-by: Markus Goetz --- src/network/access/qnetworkrequest.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index c91c608..923f2e3 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -49,6 +49,9 @@ #include "QtCore/qdatetime.h" #include +#ifndef QT_NO_DATESTRING +# include +#endif QT_BEGIN_NAMESPACE -- cgit v0.12 From ba9ea2b97bdd2329cb479bb7a6aef1bc7cee82d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Thu, 10 Dec 2009 10:26:06 +0100 Subject: Doc: The ctor of of QGraphicsLayout might install the layout. Task-number: QTBUG-6447 --- src/gui/graphicsview/qgraphicslayout.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index 2e9a30c..1e426c8 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -148,6 +148,10 @@ QT_BEGIN_NAMESPACE \a parent is passed to QGraphicsLayoutItem's constructor and the QGraphicsLayoutItem's isLayout argument is set to \e true. + + If \a parent is a QGraphicsWidget the layout will be installed + on that widget. (Note that installing a layout will delete the old one + installed.) */ QGraphicsLayout::QGraphicsLayout(QGraphicsLayoutItem *parent) : QGraphicsLayoutItem(*new QGraphicsLayoutPrivate) -- cgit v0.12 From ab5d00edea76d3b1d38d6e7e59159042ec69f2f2 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 10 Dec 2009 10:41:53 +0100 Subject: Clean up the QFontEngine glyphcaching code to not crash and be more tidy Reviewed-by: Eskil --- src/gui/painting/qpaintengine_raster.cpp | 4 +- src/gui/text/qfontengine.cpp | 124 ++++----------------- src/gui/text/qfontengine_p.h | 18 +-- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 5 +- 4 files changed, 32 insertions(+), 119 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 4a72434..aa3b89e 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3018,10 +3018,10 @@ void QRasterPaintEngine::drawCachedGlyphs(const QPointF &p, const QTextItemInt & QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat) : d->glyphCacheType; QImageTextureGlyphCache *cache = - (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(glyphType, s->matrix); + (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(0, glyphType, s->matrix); if (!cache) { cache = new QImageTextureGlyphCache(glyphType, s->matrix); - ti.fontEngine->setGlyphCache(glyphType, cache); + ti.fontEngine->setGlyphCache(0, cache); } cache->populate(ti, glyphs, positions); diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 0eadf04..d364025 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -185,22 +185,11 @@ QFontEngine::QFontEngine() QFontEngine::~QFontEngine() { - for (GlyphPointerHash::const_iterator it = m_glyphPointerHash.constBegin(), - end = m_glyphPointerHash.constEnd(); it != end; ++it) { - for (QList::const_iterator it2 = it.value().constBegin(), - end2 = it.value().constEnd(); it2 != end2; ++it2) { - delete *it2; - } - } - m_glyphPointerHash.clear(); - for (GlyphIntHash::const_iterator it = m_glyphIntHash.constBegin(), - end = m_glyphIntHash.constEnd(); it != end; ++it) { - for (QList::const_iterator it2 = it.value().constBegin(), - end2 = it.value().constEnd(); it2 != end2; ++it2) { - delete *it2; - } + for (QLinkedList::const_iterator it = m_glyphCaches.constBegin(), + end = m_glyphCaches.constEnd(); it != end; ++it) { + delete it->cache; } - m_glyphIntHash.clear(); + m_glyphCaches.clear(); qHBFreeFace(hbFace); } @@ -713,105 +702,30 @@ QByteArray QFontEngine::getSfntTable(uint tag) const return table; } -void QFontEngine::expireGlyphCache() -{ - if (m_glyphCacheQueue.count() > 10) { // hold only 10 caches in memory. - QFontEngineGlyphCache *old = m_glyphCacheQueue.takeFirst(); - // remove the value from either of our hashes - for (GlyphPointerHash::iterator i = m_glyphPointerHash.begin(); i != m_glyphPointerHash.end(); ++i) { - QList list = i.value(); - if (list.removeAll(old)) { - if (list.isEmpty()) - m_glyphPointerHash.remove(i.key()); - else - m_glyphPointerHash.insert(i.key(), list); - break; - } - } - for (GlyphIntHash::iterator i = m_glyphIntHash.begin(); i != m_glyphIntHash.end(); ++i) { - QList list = i.value(); - if (list.removeAll(old)) { - if (list.isEmpty()) - m_glyphIntHash.remove(i.key()); - else - m_glyphIntHash.insert(i.key(), list); - break; - } - } - delete old; - } -} - -void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data, QFontEngineGlyphCache::Type type) +void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data) { Q_ASSERT(data); - QList items = m_glyphPointerHash.value(key); - - for (QList::iterator it = items.begin(), end = items.end(); it != end; ++it) { - QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, data->m_transform) - && c->cacheType() == type) { - if (c == data) - return; - items.removeAll(c); - delete c; - break; - } - } - items.append(data); - m_glyphPointerHash.insert(key, items); - m_glyphCacheQueue.append(data); - expireGlyphCache(); -} + GlyphCacheEntry entry = { key, data }; + if (m_glyphCaches.contains(entry)) + return; -void QFontEngine::setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data) -{ - Q_ASSERT(data); - QList items = m_glyphIntHash.value(key); - - for (QList::iterator it = items.begin(), end = items.end(); it != end; ++it) { - QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) { - if (c == data) - return; - items.removeAll(c); - delete c; - break; - } - } - items.append(data); - m_glyphIntHash.insert(key, items); + // Limit the glyph caches to 4. This covers all 90 degree rotations and limits + // memory use when there is continous or random rotation + if (m_glyphCaches.size() == 4) + delete m_glyphCaches.takeLast().cache; - m_glyphCacheQueue.append(data); - expireGlyphCache(); -} + m_glyphCaches.push_front(entry); -QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, const QTransform &transform, QFontEngineGlyphCache::Type type) const -{ - QList items = m_glyphPointerHash.value(key); - - for (QList::iterator it = items.begin(), end = items.end(); it != end; ++it) { - QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, transform) - && type == c->cacheType()) { - m_glyphCacheQueue.removeAll(c); // last used, move it up - m_glyphCacheQueue.append(c); - return c; - } - } - return 0; } -QFontEngineGlyphCache *QFontEngine::glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const +QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const { - QList items = m_glyphIntHash.value(key); - - for (QList::iterator it = items.begin(), end = items.end(); it != end; ++it) { - QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, transform)) { - m_glyphCacheQueue.removeAll(c); // last used, move it up - m_glyphCacheQueue.append(c); + for (QLinkedList::const_iterator it = m_glyphCaches.constBegin(), end = m_glyphCaches.constEnd(); it != end; ++it) { + QFontEngineGlyphCache *c = it->cache; + if (key == it->context + && type == c->cacheType() + && qtransform_equals_no_translate(c->m_transform, transform)) { return c; } } diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 62bff85..a9883b4 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -56,6 +56,7 @@ #include "QtCore/qglobal.h" #include "QtCore/qatomic.h" #include +#include #include "private/qtextengine_p.h" #include "private/qfont_p.h" @@ -218,10 +219,8 @@ public: virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints); - void setGlyphCache(void *key, QFontEngineGlyphCache *data, QFontEngineGlyphCache::Type type); - void setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data); - QFontEngineGlyphCache *glyphCache(void *key, const QTransform &transform, QFontEngineGlyphCache::Type type) const; - QFontEngineGlyphCache *glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const; + void setGlyphCache(void *key, QFontEngineGlyphCache *data); + QFontEngineGlyphCache *glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const; static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize); static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode); @@ -254,12 +253,13 @@ protected: static const QVector &grayPalette(); private: - /// remove old entries from the glyph cache. Helper method for the setGlyphCache ones. - void expireGlyphCache(); + struct GlyphCacheEntry { + void *context; + QFontEngineGlyphCache *cache; + bool operator==(const GlyphCacheEntry &other) { return context == other.context && cache == other.cache; } + }; - GlyphPointerHash m_glyphPointerHash; - GlyphIntHash m_glyphIntHash; - mutable QList m_glyphCacheQueue; + mutable QLinkedList m_glyphCaches; }; inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 9f42217..fb9bcb4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1554,7 +1554,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly const QTextItemInt &ti) { Q_Q(QGL2PaintEngineEx); - QOpenGL2PaintEngineState *s = q->state(); QVarLengthArray positions; QVarLengthArray glyphs; @@ -1562,11 +1561,11 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); QGLTextureGlyphCache *cache = - (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, QTransform(), glyphType); + (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, glyphType, QTransform()); if (!cache || cache->cacheType() != glyphType) { cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform()); - ti.fontEngine->setGlyphCache(ctx, cache, glyphType); + ti.fontEngine->setGlyphCache(ctx, cache); } cache->setPaintEnginePrivate(this); -- cgit v0.12 From 16e4047a627d85182d9d9622a839fa51a9650aca Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 10 Dec 2009 11:15:28 +0100 Subject: Fixes a qfileinfo autotest. Canonical file paths can begin with slash only on unix platforms. Reviewed-by: Prasanth --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index cd58fd6..1445f5b 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -513,9 +513,11 @@ void tst_QFileInfo::canonicalFilePath() QFileInfo info("/tmp/../../../../../../../../../../../../../../../../../"); info.canonicalFilePath(); +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) // This used to crash on Mac QFileInfo dontCrash(QLatin1String("/")); QCOMPARE(dontCrash.canonicalFilePath(), QLatin1String("/")); +#endif #ifndef Q_OS_WIN // test symlinks -- cgit v0.12 From bb0ab1d8cf57dd4a7b69c8478c2a40c1cd1782e9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 10 Dec 2009 11:27:51 +0100 Subject: Fix spinbox input when seecting the prefix If you were selcting the prefix and entering a digit the cursor position would not be updated correctly Task-number: QTBUG-6670 Reviewed-by: ogoffart --- src/gui/widgets/qabstractspinbox.cpp | 4 +++- tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index a18af4f..c015589 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1856,8 +1856,10 @@ QValidator::State QSpinBoxValidator::validate(QString &input, int &pos) const if (dptr->specialValueText.size() > 0 && input == dptr->specialValueText) return QValidator::Acceptable; - if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix)) + if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix)) { input.prepend(dptr->prefix); + pos += dptr->prefix.length(); + } if (!dptr->suffix.isEmpty() && !input.endsWith(dptr->suffix)) input.append(dptr->suffix); diff --git a/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp index 7f03153..a3f0915 100644 --- a/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp @@ -148,6 +148,7 @@ private slots: void task255471_decimalsValidation(); void taskQTBUG_5008_textFromValueAndValidate(); + void taskQTBUG_6670_selectAllWithPrefix(); public slots: void valueChangedHelper(const QString &); @@ -1084,5 +1085,16 @@ void tst_QDoubleSpinBox::taskQTBUG_5008_textFromValueAndValidate() QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value())); } +void tst_QDoubleSpinBox::taskQTBUG_6670_selectAllWithPrefix() +{ + DoubleSpinBox spin; + spin.setPrefix("$ "); + spin.lineEdit()->selectAll(); + QTest::keyClick(spin.lineEdit(), Qt::Key_1); + QCOMPARE(spin.value(), 1.); + QTest::keyClick(spin.lineEdit(), Qt::Key_2); + QCOMPARE(spin.value(), 12.); +} + QTEST_MAIN(tst_QDoubleSpinBox) #include "tst_qdoublespinbox.moc" -- cgit v0.12 From a2ccf692cdc4113cc90ef12c27ba8c4aa552d81f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 10 Dec 2009 11:35:53 +0100 Subject: Fixes internal drag and drop in QListWidget while dropping to the end Task-number: QTBUG-6565 Reviewed-by: Gabriel --- src/gui/itemviews/qlistwidget.cpp | 2 +- tests/auto/qlistwidget/tst_qlistwidget.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp index 929d688..0ce0e5e 100644 --- a/src/gui/itemviews/qlistwidget.cpp +++ b/src/gui/itemviews/qlistwidget.cpp @@ -173,7 +173,7 @@ void QListModel::move(int srcRow, int dstRow) { if (srcRow == dstRow || srcRow < 0 || srcRow >= items.count() - || dstRow < 0 || dstRow >= items.count()) + || dstRow < 0 || dstRow > items.count()) return; if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow)) diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp index 863c308..e165190 100644 --- a/tests/auto/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp @@ -862,12 +862,18 @@ void tst_QListWidget::moveItemsPriv_data() QTest::newRow("Empty") << 0 << 0 << 0 << false; QTest::newRow("Overflow src") << 5 << 5 << 2 << false; QTest::newRow("Underflow src") << 5 << -1 << 2 << false; - QTest::newRow("Overflow dst") << 5 << 2 << 5 << false; + QTest::newRow("Overflow dst") << 5 << 2 << 6 << false; QTest::newRow("Underflow dst") << 5 << 2 << -1 << false; QTest::newRow("Same place") << 5 << 2 << 2 << false; QTest::newRow("Up") << 5 << 4 << 2 << true; QTest::newRow("Down") << 5 << 2 << 4 << true; QTest::newRow("QTBUG-6532 assert") << 5 << 0 << 1 << false; + QTest::newRow("QTBUG-6565 to the end") << 5 << 3 << 5 << true; + QTest::newRow("Same place 2") << 2 << 0 << 1 << false; + QTest::newRow("swap") << 2 << 0 << 2 << true; + QTest::newRow("swap2") << 4 << 1 << 3 << true; + QTest::newRow("swap3") << 4 << 3 << 2 << true; + QTest::newRow("swap4") << 2 << 1 << 0 << true; } void tst_QListWidget::moveItemsPriv() -- cgit v0.12 From 4d3839eb99d720393e1386d63fa04c83367bb076 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 10 Dec 2009 11:29:22 +0100 Subject: Ensure that QProcessEnvironment::operator== doesn't crash Also add an extensive autotest suite for QProcessEnvironment Task-number: QTBUG-6701 Reviewed-by: Markus Goetz --- src/corelib/io/qprocess.cpp | 3 +- tests/auto/auto.pro | 1 + .../qprocessenvironment/qprocessenvironment.pro | 5 + .../tst_qprocessenvironment.cpp | 265 +++++++++++++++++++++ 4 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qprocessenvironment/qprocessenvironment.pro create mode 100644 tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 37161bc..c78af3c 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -275,7 +275,7 @@ QProcessEnvironment &QProcessEnvironment::operator=(const QProcessEnvironment &o */ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const { - return d->hash == other.d->hash; + return d == other.d || (d && other.d && d->hash == other.d->hash); } /*! @@ -334,6 +334,7 @@ bool QProcessEnvironment::contains(const QString &name) const */ void QProcessEnvironment::insert(const QString &name, const QString &value) { + // d detaches from null d->hash.insert(prepareName(name), prepareValue(value)); } diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 92d29ae..5041812 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -256,6 +256,7 @@ SUBDIRS += \ qprinter \ qprinterinfo \ qprocess \ + qprocessenvironment \ qprogressbar \ qprogressdialog \ qpropertyanimation \ diff --git a/tests/auto/qprocessenvironment/qprocessenvironment.pro b/tests/auto/qprocessenvironment/qprocessenvironment.pro new file mode 100644 index 0000000..398facc --- /dev/null +++ b/tests/auto/qprocessenvironment/qprocessenvironment.pro @@ -0,0 +1,5 @@ +load(qttest_p4) + +QT = core + +SOURCES += tst_qprocessenvironment.cpp diff --git a/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp new file mode 100644 index 0000000..1cde33c --- /dev/null +++ b/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp @@ -0,0 +1,265 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +// Note: +// in cross-platform tests, ALWAYS use UPPERCASE variable names +// That's because on Windows, the variables are uppercased + +class tst_QProcessEnvironment: public QObject +{ + Q_OBJECT +private slots: + void operator_eq(); + void clearAndIsEmpty(); + void insert(); + void emptyNull(); + void toStringList(); + + void caseSensitivity(); + void systemEnvironment(); + void putenv(); +}; + +void tst_QProcessEnvironment::operator_eq() +{ + QProcessEnvironment e1; + QVERIFY(e1 == e1); + e1.clear(); + QVERIFY(e1 == e1); + + e1 = QProcessEnvironment(); + QProcessEnvironment e2; + QVERIFY(e1 == e2); + + e1.clear(); + QVERIFY(e1 != e2); + + e2.clear(); + + QVERIFY(e1 == e2); +} + +void tst_QProcessEnvironment::clearAndIsEmpty() +{ + QProcessEnvironment e; + e.insert("FOO", "bar"); + QVERIFY(!e.isEmpty()); + e.clear(); + QVERIFY(e.isEmpty()); +} + +void tst_QProcessEnvironment::insert() +{ + QProcessEnvironment e; + e.insert("FOO", "bar"); + QVERIFY(!e.isEmpty()); + QVERIFY(e.contains("FOO")); + QCOMPARE(e.value("FOO"), QString("bar")); + + e.remove("FOO"); + QVERIFY(!e.contains("FOO")); + QVERIFY(e.value("FOO").isNull()); + + e.clear(); + QVERIFY(!e.contains("FOO")); +} + +void tst_QProcessEnvironment::emptyNull() +{ + QProcessEnvironment e; + + e.insert("FOO", ""); + QVERIFY(e.contains("FOO")); + QVERIFY(e.value("FOO").isEmpty()); + QVERIFY(!e.value("FOO").isNull()); + + e.insert("FOO", QString()); + QVERIFY(e.contains("FOO")); + QVERIFY(e.value("FOO").isEmpty()); + // don't test if it's NULL, since we shall not make a guarantee + + e.remove("FOO"); + QVERIFY(!e.contains("FOO")); +} + +void tst_QProcessEnvironment::toStringList() +{ + QProcessEnvironment e; + QVERIFY(e.isEmpty()); + QVERIFY(e.toStringList().isEmpty()); + + e.insert("FOO", "bar"); + QStringList result = e.toStringList(); + QVERIFY(!result.isEmpty()); + QCOMPARE(result.length(), 1); + QCOMPARE(result.at(0), QString("FOO=bar")); + + e.clear(); + e.insert("BAZ", ""); + result = e.toStringList(); + QCOMPARE(result.at(0), QString("BAZ=")); + + e.insert("FOO", "bar"); + e.insert("A", "bc"); + e.insert("HELLO", "World"); + result = e.toStringList(); + QCOMPARE(result.length(), 4); + + // order is not specified, so use contains() + QVERIFY(result.contains("FOO=bar")); + QVERIFY(result.contains("BAZ=")); + QVERIFY(result.contains("A=bc")); + QVERIFY(result.contains("HELLO=World")); +} + +void tst_QProcessEnvironment::caseSensitivity() +{ + QProcessEnvironment e; + e.insert("foo", "bar"); + +#ifdef Q_OS_WIN + // on Windows, it's uppercased + QVERIFY(e.contains("foo")); + QVERIFY(e.contains("FOO")); + QVERIFY(e.contains("FoO")); + + QCOMPARE(e.value("foo"), QString("bar")); + QCOMPARE(e.value("FOO"), QString("bar")); + QCOMPARE(e.value("FoO"), QString("bar")); + + QStringList list = e.toStringList(); + QCOMPARE(list.at(0), QString("FOO=bar")); +#else + // otherwise, it's case sensitive + QVERIFY(e.contains("foo")); + QVERIFY(!e.contains("FOO")); + + e.insert("FOO", "baz"); + QVERIFY(e.contains("FOO")); + QCOMPARE(e.value("FOO"), QString("baz")); + QCOMPARE(e.value("foo"), QString("bar")); + + QStringList list = e.toStringList(); + QVERIFY(list.contains("foo=bar")); + QVERIFY(list.contains("FOO=baz")); +#endif +} + +void tst_QProcessEnvironment::systemEnvironment() +{ + static const char envname[] = "THIS_ENVIRONMENT_VARIABLE_HOPEFULLY_DOESNT_EXIST"; + QByteArray path = qgetenv("PATH"); + QByteArray nonexistant = qgetenv(envname); + QProcessEnvironment system = QProcessEnvironment::systemEnvironment(); + + QVERIFY(nonexistant.isNull()); + +#ifdef Q_WS_WINCE + // Windows CE has no environment + QVERIFY(path.isEmpty()); + QVERIFY(!system.contains("PATH")); + QVERIFY(system.isEmpty()); +#else + // all other system have environments + if (path.isEmpty()) + QFAIL("Could not find the PATH environment variable -- please correct the test environment"); + + QVERIFY(system.contains("PATH")); + QCOMPARE(system.value("PATH"), QString::fromLocal8Bit(path)); + + QVERIFY(!system.contains(envname)); + +# ifdef Q_OS_WIN + // check case-insensitive too + QVERIFY(system.contains("path")); + QCOMPARE(system.value("path"), QString::fromLocal8Bit(path)); + + QVERIFY(!system.contains(QString(envname).toLower())); +# endif +#endif +} + +void tst_QProcessEnvironment::putenv() +{ +#ifdef Q_WS_WINCE + QSKIP("Windows CE has no environment", SkipAll); +#else + static const char envname[] = "WE_RE_SETTING_THIS_ENVIRONMENT_VARIABLE"; + static bool testRan = false; + + if (testRan) + QFAIL("You cannot run this test more than once, since we modify the environment"); + testRan = true; + + QByteArray valBefore = qgetenv(envname); + if (!valBefore.isNull()) + QFAIL("The environment variable we set in the environment is already set! -- please correct the test environment"); + QProcessEnvironment eBefore = QProcessEnvironment::systemEnvironment(); + + qputenv(envname, "Hello, World"); + QByteArray valAfter = qgetenv(envname); + if (valAfter != "Hello, World") + QSKIP("Could not test: qputenv did not do its job", SkipAll); + + QProcessEnvironment eAfter = QProcessEnvironment::systemEnvironment(); + + QVERIFY(!eBefore.contains(envname)); + QVERIFY(eAfter.contains(envname)); + QCOMPARE(eAfter.value(envname), QString("Hello, World")); + +# ifdef Q_OS_WIN + // check case-insensitive too + QString lower = envname; + lower = lower.toLower(); + QVERIFY(!eBefore.contains(lower)); + QVERIFY(eAfter.contains(lower)); + QCOMPARE(eAfter.value(lower), QString("Hello, World")); +# endif +#endif +} + +QTEST_MAIN(tst_QProcessEnvironment) + +#include "tst_qprocessenvironment.moc" -- cgit v0.12 From 6db96dcd4acccbc13161f85adf3164907b7b5cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 10 Dec 2009 12:52:10 +0100 Subject: Fix redraw bugs when using graphics effects in device coordinate mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QGraphicsEffect::boundingRectFor() needs the source bounding rect in device coordinates. This patch fixes the documentation to reflect this, and fixes some internal usage of boundingRectFor() to ensure it always gets the device rect of the source. Task-number: QTBUG-5918 Reviewed-by: Bjørn Erik Nilsen --- src/gui/effects/qgraphicseffect.cpp | 14 +++++-- src/gui/graphicsview/qgraphicsitem.cpp | 54 +++++++++++++++++++++----- src/gui/graphicsview/qgraphicsitem_p.h | 2 + src/gui/graphicsview/qgraphicsview.cpp | 26 +++++++++++++ src/gui/graphicsview/qgraphicsview.h | 1 + src/gui/graphicsview/qgraphicsview_p.h | 3 ++ tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 9 ++++- 7 files changed, 95 insertions(+), 14 deletions(-) diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index 239e29c..d6cabaa 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -160,6 +160,10 @@ QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const /*! Returns the bounding rectangle of the source mapped to the given \a system. + Calling this function with Qt::DeviceCoordinates outside of + QGraphicsEffect::draw() will give undefined results, as there is no device + context available. + \sa draw() */ QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const @@ -348,6 +352,10 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse The returned pixmap is clipped to the current painter's device rectangle when \a system is Qt::DeviceCoordinates. + Calling this function with Qt::DeviceCoordinates outside of + QGraphicsEffect::draw() will give undefined results, as there is no device + context available. + \sa draw(), boundingRect() */ QPixmap QGraphicsEffect::sourcePixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const @@ -398,8 +406,8 @@ QGraphicsEffect::~QGraphicsEffect() /*! Returns the effective bounding rectangle for this effect, i.e., the - bounding rectangle of the source, adjusted by any margins applied by - the effect itself. + bounding rectangle of the source in device coordinates, adjusted by + any margins applied by the effect itself. \sa boundingRectFor(), updateBoundingRect() */ @@ -413,7 +421,7 @@ QRectF QGraphicsEffect::boundingRect() const /*! Returns the effective bounding rectangle for this effect, given the - provided \a rect in the source's coordinate space. When writing + provided \a rect in the device coordinates. When writing you own custom effect, you must call updateBoundingRect() whenever any parameters are changed that may cause this this function to return a different value. diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 90cc132..8bbe929 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2584,6 +2584,35 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) /*! \internal \since 4.6 + Returns the effective bounding rect of the given item space rect. + If the item has no effect, the rect is returned unmodified. + If the item has an effect, the effective rect can be extend beyond the + item's bounding rect, depending on the effect. + + \sa boundingRect() +*/ +QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const +{ +#ifndef QT_NO_GRAPHICSEFFECT + Q_Q(const QGraphicsItem); + QGraphicsEffect *effect = graphicsEffect; + if (scene && effect && effect->isEnabled()) { + QRectF sceneRect = q->mapRectToScene(rect); + QRectF sceneEffectRect; + foreach (QGraphicsView *view, scene->views()) { + QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect); + QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect(); + sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect); + } + return q->mapRectFromScene(sceneEffectRect); + } +#endif //QT_NO_GRAPHICSEFFECT + return rect; +} + +/*! + \internal + \since 4.6 Returns the effective bounding rect of the item. If the item has no effect, this is the same as the item's bounding rect. If the item has an effect, the effective rect can be larger than the item's @@ -2594,16 +2623,19 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) QRectF QGraphicsItemPrivate::effectiveBoundingRect() const { #ifndef QT_NO_GRAPHICSEFFECT - QGraphicsEffect *effect = graphicsEffect; - QRectF brect = effect && effect->isEnabled() ? effect->boundingRect() : q_ptr->boundingRect(); + Q_Q(const QGraphicsItem); + QRectF brect = effectiveBoundingRect(q_ptr->boundingRect()); if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) return brect; const QGraphicsItem *effectParent = parent; while (effectParent) { - effect = effectParent->d_ptr->graphicsEffect; - if (effect && effect->isEnabled()) - brect = effect->boundingRectFor(brect); + QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect; + if (scene && effect && effect->isEnabled()) { + const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect); + const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace); + brect = effectParent->mapRectToItem(q, effectRectInParentSpace); + } if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) return brect; effectParent = effectParent->d_ptr->parent; @@ -10649,17 +10681,21 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func(); const QRectF sourceRect = boundingRect(system); - QRect effectRect; + QRectF effectRectF; if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) { - effectRect = item->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect(); + effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates)); + if (system == Qt::LogicalCoordinates) + effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF); } else if (mode == QGraphicsEffect::PadToTransparentBorder) { // adjust by 1.5 to account for cosmetic pens - effectRect = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5).toAlignedRect(); + effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5); } else { - effectRect = sourceRect.toAlignedRect(); + effectRectF = sourceRect; } + QRect effectRect = effectRectF.toAlignedRect(); + if (offset) *offset = effectRect.topLeft(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 8f9fe54..2d8de65 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -236,6 +236,8 @@ public: QRectF effectiveBoundingRect() const; QRectF sceneEffectiveBoundingRect() const; + QRectF effectiveBoundingRect(const QRectF &rect) const; + virtual void resolveFont(uint inheritedMask) { for (int i = 0; i < children.size(); ++i) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 3f9f443..ffe64aa 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -545,6 +545,32 @@ qint64 QGraphicsViewPrivate::verticalScroll() const /*! \internal + + Maps the given rectangle to the scene using QTransform::mapRect() +*/ +QRectF QGraphicsViewPrivate::mapRectToScene(const QRect &rect) const +{ + if (dirtyScroll) + const_cast(this)->updateScroll(); + QRectF scrolled = QRectF(rect.translated(scrollX, scrollY)); + return identityMatrix ? scrolled : matrix.inverted().mapRect(scrolled); +} + + +/*! + \internal + + Maps the given rectangle from the scene using QTransform::mapRect() +*/ +QRectF QGraphicsViewPrivate::mapRectFromScene(const QRectF &rect) const +{ + if (dirtyScroll) + const_cast(this)->updateScroll(); + return (identityMatrix ? rect : matrix.mapRect(rect)).translated(-scrollX, -scrollY); +} + +/*! + \internal */ void QGraphicsViewPrivate::updateScroll() { diff --git a/src/gui/graphicsview/qgraphicsview.h b/src/gui/graphicsview/qgraphicsview.h index 2aed0e6..90576e5 100644 --- a/src/gui/graphicsview/qgraphicsview.h +++ b/src/gui/graphicsview/qgraphicsview.h @@ -278,6 +278,7 @@ private: friend class QGraphicsSceneWidget; friend class QGraphicsScene; friend class QGraphicsScenePrivate; + friend class QGraphicsItemPrivate; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsView::CacheMode) diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index cd161ad..d4b718e 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -86,6 +86,9 @@ public: qint64 horizontalScroll() const; qint64 verticalScroll() const; + QRectF mapRectToScene(const QRect &rect) const; + QRectF mapRectFromScene(const QRectF &rect) const; + QPointF mousePressItemPoint; QPointF mousePressScenePoint; QPoint mousePressViewPoint; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 6266933..3e7a2eb 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -233,6 +233,7 @@ public: void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { hints = painter->renderHints(); + painter->setBrush(brush); painter->drawRect(boundingRect()); ++repaints; } @@ -247,6 +248,7 @@ public: QPainter::RenderHints hints; int repaints; QRectF br; + QBrush brush; }; class tst_QGraphicsItem : public QObject @@ -7646,17 +7648,20 @@ void tst_QGraphicsItem::hitTestGraphicsEffectItem() EventTester *item1 = new EventTester; item1->br = itemBoundingRect; item1->setPos(-200, -200); + item1->brush = Qt::red; EventTester *item2 = new EventTester; item2->br = itemBoundingRect; item2->setFlag(QGraphicsItem::ItemIgnoresTransformations); item2->setParentItem(item1); item2->setPos(200, 200); + item2->brush = Qt::green; EventTester *item3 = new EventTester; item3->br = itemBoundingRect; item3->setParentItem(item2); item3->setPos(80, 80); + item3->brush = Qt::blue; scene.addItem(item1); QTest::qWait(100); @@ -7671,8 +7676,8 @@ void tst_QGraphicsItem::hitTestGraphicsEffectItem() item1->setGraphicsEffect(shadow); QTest::qWait(50); - // Make sure all items are repainted. - QCOMPARE(item1->repaints, 1); + // Make sure all visible items are repainted. + QCOMPARE(item1->repaints, 0); QCOMPARE(item2->repaints, 1); QCOMPARE(item3->repaints, 1); -- cgit v0.12 From bf9456c5a2d8dfe9a35a2175186630cb426858ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Thu, 10 Dec 2009 17:38:30 +0100 Subject: Optimize our GL extension checks to avoid mallocs. We want to avoid any unnecessary mallocs when checking GL/GLX extensions. The GL extension string can be quite long and contain several hundred extensions. The old code forced one malloc for each extension + 1 extra malloc for the extension string itself when it was copied into the QByteArray. Reviewed-by: Kim --- src/opengl/qgl.cpp | 47 ++++++++++++++++++++++++----------------------- src/opengl/qgl_p.h | 43 +++++++++++++++++++++++++++++++++++++++++++ src/opengl/qgl_x11.cpp | 24 ++++++++++++------------ 3 files changed, 79 insertions(+), 35 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index dcf8c00..b6f8919 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4822,38 +4822,39 @@ QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, void QGLExtensions::init_extensions() { - QList extensions = QByteArray(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); - if (extensions.contains("GL_ARB_texture_rectangle")) + QGLExtensionMatcher extensions(reinterpret_cast(glGetString(GL_EXTENSIONS))); + + if (extensions.match("GL_ARB_texture_rectangle")) glExtensions |= TextureRectangle; - if (extensions.contains("GL_ARB_multisample")) + if (extensions.match("GL_ARB_multisample")) glExtensions |= SampleBuffers; - if (extensions.contains("GL_SGIS_generate_mipmap")) + if (extensions.match("GL_SGIS_generate_mipmap")) glExtensions |= GenerateMipmap; - if (extensions.contains("GL_ARB_texture_compression")) + if (extensions.match("GL_ARB_texture_compression")) glExtensions |= TextureCompression; - if (extensions.contains("GL_EXT_texture_compression_s3tc")) + if (extensions.match("GL_EXT_texture_compression_s3tc")) glExtensions |= DDSTextureCompression; - if (extensions.contains("GL_OES_compressed_ETC1_RGB8_texture")) + if (extensions.match("GL_OES_compressed_ETC1_RGB8_texture")) glExtensions |= ETC1TextureCompression; - if (extensions.contains("GL_IMG_texture_compression_pvrtc")) + if (extensions.match("GL_IMG_texture_compression_pvrtc")) glExtensions |= PVRTCTextureCompression; - if (extensions.contains("GL_ARB_fragment_program")) + if (extensions.match("GL_ARB_fragment_program")) glExtensions |= FragmentProgram; - if (extensions.contains("GL_ARB_fragment_shader")) + if (extensions.match("GL_ARB_fragment_shader")) glExtensions |= FragmentShader; - if (extensions.contains("GL_ARB_texture_mirrored_repeat")) + if (extensions.match("GL_ARB_texture_mirrored_repeat")) glExtensions |= MirroredRepeat; - if (extensions.contains("GL_EXT_framebuffer_object")) + if (extensions.match("GL_EXT_framebuffer_object")) glExtensions |= FramebufferObject; - if (extensions.contains("GL_EXT_stencil_two_side")) + if (extensions.match("GL_EXT_stencil_two_side")) glExtensions |= StencilTwoSide; - if (extensions.contains("GL_EXT_stencil_wrap")) + if (extensions.match("GL_EXT_stencil_wrap")) glExtensions |= StencilWrap; - if (extensions.contains("GL_EXT_packed_depth_stencil")) + if (extensions.match("GL_EXT_packed_depth_stencil")) glExtensions |= PackedDepthStencil; - if (extensions.contains("GL_NV_float_buffer")) + if (extensions.match("GL_NV_float_buffer")) glExtensions |= NVFloatBuffer; - if (extensions.contains("GL_ARB_pixel_buffer_object")) + if (extensions.match("GL_ARB_pixel_buffer_object")) glExtensions |= PixelBufferObject; #if defined(QT_OPENGL_ES_2) glExtensions |= FramebufferObject; @@ -4861,26 +4862,26 @@ void QGLExtensions::init_extensions() glExtensions |= FragmentShader; #endif #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL) - if (extensions.contains("GL_OES_framebuffer_object")) + if (extensions.match("GL_OES_framebuffer_object")) glExtensions |= FramebufferObject; #endif #if defined(QT_OPENGL_ES) - if (extensions.contains("GL_OES_packed_depth_stencil")) + if (extensions.match("GL_OES_packed_depth_stencil")) glExtensions |= PackedDepthStencil; #endif - if (extensions.contains("GL_ARB_framebuffer_object")) { + if (extensions.match("GL_ARB_framebuffer_object")) { // ARB_framebuffer_object also includes EXT_framebuffer_blit. glExtensions |= FramebufferObject; glExtensions |= FramebufferBlit; } - if (extensions.contains("GL_EXT_framebuffer_blit")) + if (extensions.match("GL_EXT_framebuffer_blit")) glExtensions |= FramebufferBlit; - if (extensions.contains("GL_ARB_texture_non_power_of_two")) + if (extensions.match("GL_ARB_texture_non_power_of_two")) glExtensions |= NPOTTextures; - if (extensions.contains("GL_EXT_bgra")) + if (extensions.match("GL_EXT_bgra")) glExtensions |= BGRATextureFormat; } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 8a0b31f..11770d3 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -610,6 +610,49 @@ private: friend class QGLContextGroup; }; + +// This class can be used to match GL extensions with doing any mallocs. The +// class assumes that the GL extension string ends with a space character, +// which it should do on all conformant platforms. Create the object and pass +// in a pointer to the extension string, then call match() on each extension +// that should be matched. The match() function takes the extension name +// *without* the terminating space character as input. + +class QGLExtensionMatcher +{ +public: + QGLExtensionMatcher(const char *str) + : gl_extensions(str), gl_extensions_length(qstrlen(str)) + {} + + bool match(const char *str) { + int str_length = qstrlen(str); + const char *extensions = gl_extensions; + int extensions_length = gl_extensions_length; + + while (1) { + // the total length that needs to be matched is the str_length + + // the space character that terminates the extension name + if (extensions_length < str_length + 1) + return false; + if (qstrncmp(extensions, str, str_length) == 0 && extensions[str_length] == ' ') + return true; + + int split_pos = 0; + while (split_pos < extensions_length && extensions[split_pos] != ' ') + ++split_pos; + ++split_pos; // added for the terminating space character + extensions += split_pos; + extensions_length -= split_pos; + } + return false; + } + +private: + const char *gl_extensions; + int gl_extensions_length; +}; + QT_END_NAMESPACE #endif // QGL_P_H diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index a037282..9c3fc79 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -343,8 +343,8 @@ void* qglx_getProcAddress(const char* procName) static bool triedResolvingGlxGetProcAddress = false; if (!triedResolvingGlxGetProcAddress) { triedResolvingGlxGetProcAddress = true; - QList glxExt = QByteArray(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)).split(' '); - if (glxExt.contains("GLX_ARB_get_proc_address")) { + QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); + if (extensions.match("GLX_ARB_get_proc_address")) { #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) void *handle = dlopen(NULL, RTLD_LAZY); if (handle) { @@ -523,8 +523,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) if (!d->gpm) return false; } - QList glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' '); - if (glxExt.contains("GLX_SGI_video_sync")) { + QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); + if (extensions.match("GLX_SGI_video_sync")) { if (d->glFormat.swapInterval() == -1) d->glFormat.setSwapInterval(0); } else { @@ -630,8 +630,8 @@ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) static bool useTranspExt = false; static bool useTranspExtChecked = false; if (f.plane() && !useTranspExtChecked && d->paintDevice) { - QByteArray estr(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); - useTranspExt = estr.contains("GLX_EXT_visual_info"); + QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); + useTranspExt = extensions.match("GLX_EXT_visual_info"); //# (A bit simplistic; that could theoretically be a substring) if (useTranspExt) { QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); @@ -875,8 +875,8 @@ void QGLContext::swapBuffers() const static bool resolved = false; if (!resolved) { const QX11Info *xinfo = qt_x11Info(d->paintDevice); - QList glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' '); - if (glxExt.contains("GLX_SGI_video_sync")) { + QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); + if (extensions.match("GLX_SGI_video_sync")) { glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI"); glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI"); } @@ -1107,8 +1107,8 @@ void *QGLContext::getProcAddress(const QString &proc) const if (resolved && !glXGetProcAddressARB) return 0; if (!glXGetProcAddressARB) { - QList glxExt = QByteArray(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)).split(' '); - if (glxExt.contains("GLX_ARB_get_proc_address")) { + QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); + if (extensions.match("GLX_ARB_get_proc_address")) { #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) void *handle = dlopen(NULL, RTLD_LAZY); if (handle) { @@ -1609,8 +1609,8 @@ static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice) return false; // Can't use TFP without NPOT } const QX11Info *xinfo = qt_x11Info(paintDevice); - QList glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' '); - if (glxExt.contains("GLX_EXT_texture_from_pixmap")) { + QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); + if (extensions.match("GLX_EXT_texture_from_pixmap")) { glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT"); glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT"); } -- cgit v0.12 From 3a8a1f83d60ec16e4c61e2b0a327a5af02917a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 10 Dec 2009 17:22:53 +0100 Subject: Prevented leak of keys in QPixmapCache. Removing a pixmap from the pixmap cache using the new QPixmapCache::Key API left the keys dangling in the QCache's internal QHash. The problem is that the Key is invalidated as soon as the QPixmapCacheEntry is destroyed, thus removing it from the hash failed. Reordering the destruction of the object and the removal of the key in QHash fixes the problem. Reviewed-by: Alexis Reviewed-by: Thiago --- src/corelib/tools/qcache.h | 2 +- src/gui/image/qpixmapcache.cpp | 5 +++++ tests/auto/qpixmapcache/tst_qpixmapcache.cpp | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h index 46e20b1..ee9523f 100644 --- a/src/corelib/tools/qcache.h +++ b/src/corelib/tools/qcache.h @@ -70,8 +70,8 @@ class QCache if (l == &n) l = n.p; if (f == &n) f = n.n; total -= n.c; - delete n.t; hash.remove(*n.keyPtr); + delete n.t; } inline T *relink(const Key &key) { typename QHash::iterator i = hash.find(key); diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index b0b7d72..b7b29d7 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -424,6 +424,11 @@ QPixmapCache::KeyData* QPMCache::getKeyData(QPixmapCache::Key *key) Q_GLOBAL_STATIC(QPMCache, pm_cache) +int Q_AUTOTEST_EXPORT q_QPixmapCache_keyHashSize() +{ + return pm_cache()->size(); +} + QPixmapCacheEntry::~QPixmapCacheEntry() { pm_cache()->releaseKey(key); diff --git a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp index 9775d36..c89a182 100644 --- a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp @@ -70,6 +70,7 @@ private slots: void remove(); void clear(); void pixmapKey(); + void noLeak(); }; static QPixmapCache::KeyData* getPrivate(QPixmapCache::Key &key) @@ -482,5 +483,23 @@ void tst_QPixmapCache::pixmapKey() QVERIFY(!getPrivate(key8)); } +extern int q_QPixmapCache_keyHashSize(); + +void tst_QPixmapCache::noLeak() +{ + QPixmapCache::Key key; + + int oldSize = q_QPixmapCache_keyHashSize(); + for (int i = 0; i < 100; ++i) { + QPixmap pm(128, 128); + pm.fill(Qt::transparent); + key = QPixmapCache::insert(pm); + QPixmapCache::remove(key); + } + int newSize = q_QPixmapCache_keyHashSize(); + + QCOMPARE(oldSize, newSize); +} + QTEST_MAIN(tst_QPixmapCache) #include "tst_qpixmapcache.moc" -- cgit v0.12 From 6c161d6cca6c08843b479c00fffb9c7217aec505 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 10 Dec 2009 16:39:46 +1000 Subject: Install private headers when configuring Qt with -developer-build. Many Qt autotests require both private symbols and private headers. Private symbols are turned on using -developer-build. However, prior to this commit there was no way to install private headers into the Qt install directory. This is particularly relevant for packaging systems which use `make install' to determine what should be packaged. For example, Qt for Maemo debian packages are effectively unusable for Qt autotests without this commit. Reviewed-by: Michael Goddard --- bin/syncqt | 6 ++++++ src/qt_install.pri | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/bin/syncqt b/bin/syncqt index a14a82d..629e124 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -666,6 +666,7 @@ foreach (@modules_to_sync) { #information used after the syncing my $pri_install_classes = ""; my $pri_install_files = ""; + my $pri_install_pfiles = ""; my $libcapitals = $lib; $libcapitals =~ y/a-z/A-Z/; @@ -834,6 +835,10 @@ foreach (@modules_to_sync) { $pri_install_files.= "$pri_install_iheader ";; } } + else { + my $pri_install_iheader = fixPaths($iheader, $current_dir); + $pri_install_pfiles.= "$pri_install_iheader ";; + } } print "header created for $iheader ($header_copies)\n" if($header_copies > 0); } @@ -878,6 +883,7 @@ foreach (@modules_to_sync) { my $headers_pri_contents = ""; $headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n"; $headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n"; + $headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n"; my $headers_pri_file = "$out_basedir/include/$lib/headers.pri"; if(-e "$headers_pri_file") { open HEADERS_PRI_FILE, "<$headers_pri_file"; diff --git a/src/qt_install.pri b/src/qt_install.pri index ebeac8d..5b29942 100644 --- a/src/qt_install.pri +++ b/src/qt_install.pri @@ -30,6 +30,12 @@ qt_install_headers { targ_headers.files = $$INSTALL_HEADERS targ_headers.path = $$[QT_INSTALL_HEADERS]/$$TARGET INSTALLS += targ_headers + + contains(QT_CONFIG,private_tests) { + private_headers.files = $$SYNCQT.PRIVATE_HEADER_FILES + private_headers.path = $$[QT_INSTALL_HEADERS]/$$TARGET/private + INSTALLS += private_headers + } } embedded:equals(TARGET, QtGui) { -- cgit v0.12 From 343de9228ae65c36c4a9a45297d45cdeb04a8e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 11 Dec 2009 11:06:03 +0100 Subject: Fixed qgraphicseffectsource autotest. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent crashing when asking for a source pixmap in logical coordinates and PadToEffectiveBoundingRect mode. Also, change the expected values for the test that uses LogicalCoordinates and PadToEffectiveBoundingRect mode to reflect that the boundingRectFor() function applies padding in device coordinates (and in this case there is a scale by 2 when drawing the effect). Reviewed-by: Bjørn Erik Nilsen --- src/gui/graphicsview/qgraphicsitem.cpp | 11 ++++++++--- .../auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 8bbe929..c879c5c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -10684,9 +10684,14 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP QRectF effectRectF; if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) { - effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates)); - if (system == Qt::LogicalCoordinates) - effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF); + if (info) { + effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates)); + if (info && system == Qt::LogicalCoordinates) + effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF); + } else { + // no choice but to send a logical coordinate bounding rect to boundingRectFor + effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect); + } } else if (mode == QGraphicsEffect::PadToTransparentBorder) { // adjust by 1.5 to account for cosmetic pens effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5); diff --git a/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp b/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp index 9991ab4..7a0d40a 100644 --- a/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp +++ b/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp @@ -352,7 +352,7 @@ void tst_QGraphicsEffectSource::pixmapPadding_data() QTest::newRow("log,effectrect") << int(Qt::LogicalCoordinates) << int(QGraphicsEffect::PadToEffectiveBoundingRect) - << QSize(30, 30) << QPoint(-10, -10) + << QSize(20, 20) << QPoint(-5, -5) << 0x00000000u; QTest::newRow("dev,nopad") << int(Qt::DeviceCoordinates) -- cgit v0.12 From 669cb438384f1ceafd4b2ee783b9a52d7110ccf7 Mon Sep 17 00:00:00 2001 From: Anders Ahlen Date: Fri, 11 Dec 2009 12:00:47 +0100 Subject: Document QTextEncoder::fromUnicode as QT3 support member Make deprecated QTextEncoder::fromUnicode ( const QString & uc, int & lenInOut ) documented as QT3 support member Task-number: QTBUG-6614 Merge-request: 399 Reviewed-by: Thiago Macieira --- src/corelib/codecs/qtextcodec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index f831700..6170272 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -161,7 +161,7 @@ public: QByteArray fromUnicode(const QString& str); QByteArray fromUnicode(const QChar *uc, int len); #ifdef QT3_SUPPORT - QByteArray fromUnicode(const QString& uc, int& lenInOut); + QT3_SUPPORT QByteArray fromUnicode(const QString& uc, int& lenInOut); #endif bool hasFailure() const; private: -- cgit v0.12 From 664c78144754c499d07a95c3914fd34202bf4b98 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 11 Dec 2009 12:05:00 +0100 Subject: Initial documentation for the performance characteristics of QPainter. Reviewed-by: Tom --- src/gui/painting/qpainter.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 66bf4f7..13d9a04 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1317,6 +1317,84 @@ void QPainterPrivate::updateState(QPainterState *newState) Another workaround is to convert the paths to polygons first and then draw the polygons instead. + \section1 Performance + + QPainter is a rich framework that allows developers to do a great + variety of graphical operations, such as gradients, composition + modes and vector graphcis. And QPainter can do this across a + variety of different hardware and software stack. Naturally the + underlying combination of hardware and software has some + implications for performance, and ensuring that every single + operation is fast in combination with all the various combinations + of composition modes, brushes, clipping, transformation, etc, is + close to an impossible task because of the number of + permutations. As a compromise we have selected a subset of the + QPainter API and backends, were performance is guaranteed to be as + good as we can sensibly get it for the given combination of + hardware and software. + + The backends we focus on as high-performance engines are: + + \list + + \o Raster - This backend implements all rendering in pure software + and is always used to render into QImages. For optimal performance + only use the format types QImage::Format_ARGB32_Premultiplied, + QImage::Format_RGB32 or QImage::Format_RGB16. Any other format, + including QImage::Format_ARGB32, has significantly worse + performance. This engine is also used by default on Windows and on + QWS. It can be used as default graphics system on any + OS/hardware/software combination by passing \c {-graphcissystem + raster} on the command line + + \o OpenGL 2.0 (ES) - This backend is the primary backend for + hardware accellerated graphics. It can be run on desktop machines + and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0 + spesification. This includes most graphics chips produced in the + last couple of years. The engine can be enabled by using QPainter + onto a QGLWidget or by passing \c {-graphicssystem opengl} on the + command line when the underlying system supports it. + + \endlist + + These operations are: + + \list + + \o Simple transformations, meaning translation and scaling, pluss + 0, 90, 180, 270 degree rotations. + + \o \c drawPixmap() in combination with simple transformations and + opacity with non-smooth transformation mode + (\c QPainter::SmoothPixmapTransform not enabled as a render hint); + + \o Text drawing with regular font sizes with simple + transformations with solid colors using no or 8-bit antialiasing. + + \o Rectangle fills with solid color, two-color linear gradients + and simple transforms. + + \o Rectangular clipping with simple transformations and intersect + clip. + + \o Composition Modes \c QPainter::CompositionMode_Source and + QPainter::CompositionMode_SourceOver + + \o Rounded rectangle filling using solid color and two-color + linear gradients fills. + + \o 3x3 patched pixmaps, via qDrawBorderPixmap. + + \endlist + + This list gives an indication of which features to safely use in + an application where performance is critical. For certain setups, + other operations may be fast too, but before making extensive use + of them, it is recommended to benchmark and verify them on the + system where the software will run in the end. There are also + cases where expensive operations are ok to use, for instance when + the result is cached in a QPixmap. + \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example}, {Drawing Utility Functions} */ -- cgit v0.12 From bafc505ea03ff423c02e0380ba6f255e160483a1 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 11 Dec 2009 11:35:57 +0100 Subject: Fix tst_QTouchEvent::touchUpdateAndEndNeverPropagate() QGrahpicsItem behaves similarly to QWidget; if the TouchUpdate or TouchEnd event is ignored, then the event sent to the view and scene will also be ignored. Reviewed-by: Trust me --- tests/auto/qtouchevent/tst_qtouchevent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qtouchevent/tst_qtouchevent.cpp b/tests/auto/qtouchevent/tst_qtouchevent.cpp index f95a5c6..98af4fb 100644 --- a/tests/auto/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/qtouchevent/tst_qtouchevent.cpp @@ -496,7 +496,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); QVERIFY(res); // the scene accepts the event, since it found an item to send the event to - QVERIFY(touchUpdateEvent.isAccepted()); + QVERIFY(!touchUpdateEvent.isAccepted()); QVERIFY(child.seenTouchUpdate); QVERIFY(!root.seenTouchUpdate); @@ -510,7 +510,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() res = QApplication::sendEvent(view.viewport(), &touchEndEvent); QVERIFY(res); // the scene accepts the event, since it found an item to send the event to - QVERIFY(touchEndEvent.isAccepted()); + QVERIFY(!touchEndEvent.isAccepted()); QVERIFY(child.seenTouchEnd); QVERIFY(!root.seenTouchEnd); } -- cgit v0.12 From 05ba6bad6c0927d22ccf026446dfdb9d85b3f03e Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 11 Dec 2009 11:38:19 +0100 Subject: Fix crashes when deleting QWidgets and QGraphicsItems in touch event handlers. Use QWeakPointer to bail out early if a widget is deleted while we are delivering/propagating a TouchBegin event. In QGraphicsScene, we need to make sure that we clear the scene's active touch points for items that are removed from the scene. This allows us to detect when an item is removed during TouchBegin event delivery/propagation. Unlike QWidget, propagation continues since we use a hit-test instead of the item's hierarchy for propagation. Task-number: QTBUG-6654 Reviewed-by: bnilsen --- src/gui/graphicsview/qgraphicsscene.cpp | 24 ++- src/gui/kernel/qapplication.cpp | 10 +- tests/auto/qtouchevent/tst_qtouchevent.cpp | 246 ++++++++++++++++++++++++++++- 3 files changed, 274 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 27ebb79..2a53456 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -613,6 +613,19 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) if (item == lastActivePanel) lastActivePanel = 0; + // Cancel active touches + { + QMap::iterator it = itemForTouchPointId.begin(); + while (it != itemForTouchPointId.end()) { + if (it.value() == item) { + sceneCurrentTouchPoints.remove(it.key()); + it = itemForTouchPointId.erase(it); + } else { + ++it; + } + } + } + // Disable selectionChanged() for individual items ++selectionChanging; int oldSelectedItemsSize = selectedItems.size(); @@ -5679,17 +5692,22 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve touchEvent->setAccepted(acceptTouchEvents); res = acceptTouchEvents && sendEvent(item, touchEvent); eventAccepted = touchEvent->isAccepted(); - item->d_ptr->acceptedTouchBeginEvent = (res && eventAccepted); + if (itemForTouchPointId.value(touchEvent->touchPoints().first().id()) == 0) { + // item was deleted + item = 0; + } else { + item->d_ptr->acceptedTouchBeginEvent = (res && eventAccepted); + } touchEvent->spont = false; if (res && eventAccepted) { // the first item to accept the TouchBegin gets an implicit grab. for (int i = 0; i < touchEvent->touchPoints().count(); ++i) { const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i); - itemForTouchPointId[touchPoint.id()] = item; + itemForTouchPointId[touchPoint.id()] = item; // can be zero } break; } - if (item->isPanel()) + if (item && item->isPanel()) break; } diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 9f4cd0c..8c63968 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -4092,9 +4092,15 @@ bool QApplication::notify(QObject *receiver, QEvent *e) bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents); touchEvent->setWidget(widget); touchEvent->setAccepted(acceptTouchEvents); + QWeakPointer p = widget; res = acceptTouchEvents && d->notify_helper(widget, touchEvent); eventAccepted = touchEvent->isAccepted(); - widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted); + if (p.isNull()) { + // widget was deleted + widget = 0; + } else { + widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted); + } touchEvent->spont = false; if (res && eventAccepted) { // the first widget to accept the TouchBegin gets an implicit grab. @@ -4103,7 +4109,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) d->widgetForTouchPointId[touchPoint.id()] = widget; } break; - } else if (widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) { + } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) { break; } QPoint offset = widget->pos(); diff --git a/tests/auto/qtouchevent/tst_qtouchevent.cpp b/tests/auto/qtouchevent/tst_qtouchevent.cpp index 98af4fb..da8721c 100644 --- a/tests/auto/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/qtouchevent/tst_qtouchevent.cpp @@ -48,6 +48,7 @@ public: QList touchBeginPoints, touchUpdatePoints, touchEndPoints; bool seenTouchBegin, seenTouchUpdate, seenTouchEnd; bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd; + bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd; tst_QTouchEventWidget() : QWidget() @@ -62,6 +63,7 @@ public: touchEndPoints.clear(); seenTouchBegin = seenTouchUpdate = seenTouchEnd = false; acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true; + deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } bool event(QEvent *event) @@ -74,6 +76,8 @@ public: seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd; touchBeginPoints = static_cast(event)->touchPoints(); event->setAccepted(acceptTouchBegin); + if (deleteInTouchBegin) + delete this; break; case QEvent::TouchUpdate: if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin"); @@ -81,6 +85,8 @@ public: seenTouchUpdate = seenTouchBegin && !seenTouchEnd; touchUpdatePoints = static_cast(event)->touchPoints(); event->setAccepted(acceptTouchUpdate); + if (deleteInTouchUpdate) + delete this; break; case QEvent::TouchEnd: if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin"); @@ -88,6 +94,8 @@ public: seenTouchEnd = seenTouchBegin && !seenTouchEnd; touchEndPoints = static_cast(event)->touchPoints(); event->setAccepted(acceptTouchEnd); + if (deleteInTouchEnd) + delete this; break; default: return QWidget::event(event); @@ -102,13 +110,21 @@ public: QList touchBeginPoints, touchUpdatePoints, touchEndPoints; bool seenTouchBegin, seenTouchUpdate, seenTouchEnd; bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd; + bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd; + tst_QTouchEventGraphicsItem **weakpointer; tst_QTouchEventGraphicsItem() - : QGraphicsItem() + : QGraphicsItem(), weakpointer(0) { reset(); } + ~tst_QTouchEventGraphicsItem() + { + if (weakpointer) + *weakpointer = 0; + } + void reset() { touchBeginPoints.clear(); @@ -116,6 +132,7 @@ public: touchEndPoints.clear(); seenTouchBegin = seenTouchUpdate = seenTouchEnd = false; acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true; + deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } QRectF boundingRect() const { return QRectF(0, 0, 10, 10); } @@ -131,6 +148,8 @@ public: seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd; touchBeginPoints = static_cast(event)->touchPoints(); event->setAccepted(acceptTouchBegin); + if (deleteInTouchBegin) + delete this; break; case QEvent::TouchUpdate: if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin"); @@ -138,6 +157,8 @@ public: seenTouchUpdate = seenTouchBegin && !seenTouchEnd; touchUpdatePoints = static_cast(event)->touchPoints(); event->setAccepted(acceptTouchUpdate); + if (deleteInTouchUpdate) + delete this; break; case QEvent::TouchEnd: if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin"); @@ -145,6 +166,8 @@ public: seenTouchEnd = seenTouchBegin && !seenTouchEnd; touchEndPoints = static_cast(event)->touchPoints(); event->setAccepted(acceptTouchEnd); + if (deleteInTouchEnd) + delete this; break; default: return QGraphicsItem::sceneEvent(event); @@ -168,6 +191,8 @@ private slots: void basicRawEventTranslation(); void multiPointRawEventTranslationOnTouchScreen(); void multiPointRawEventTranslationOnTouchPad(); + void deleteInEventHandler(); + void deleteInRawEventTranslation(); }; void tst_QTouchEvent::touchDisabledByDefault() @@ -1059,6 +1084,225 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() } } +void tst_QTouchEvent::deleteInEventHandler() +{ + // QWidget + { + QWidget window; + tst_QTouchEventWidget *child1, *child2, *child3; + child1 = new tst_QTouchEventWidget; + child2 = new tst_QTouchEventWidget; + child3 = new tst_QTouchEventWidget; + child1->setParent(&window); + child2->setParent(&window); + child3->setParent(&window); + child1->setAttribute(Qt::WA_AcceptTouchEvents); + child2->setAttribute(Qt::WA_AcceptTouchEvents); + child3->setAttribute(Qt::WA_AcceptTouchEvents); + child1->deleteInTouchBegin = true; + child2->deleteInTouchUpdate = true; + child3->deleteInTouchEnd = true; + + QList touchPoints; + touchPoints.append(QTouchEvent::TouchPoint(0)); + QTouchEvent touchBeginEvent(QEvent::TouchBegin, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointPressed, + touchPoints); + QTouchEvent touchUpdateEvent(QEvent::TouchUpdate, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointStationary, + touchPoints); + QTouchEvent touchEndEvent(QEvent::TouchEnd, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointReleased, + touchPoints); + QWeakPointer p; + bool res; + + touchBeginEvent.ignore(); + p = child1; + res = QApplication::sendEvent(child1, &touchBeginEvent); + // event is handled, but widget should be deleted + QVERIFY(res && touchBeginEvent.isAccepted() && p.isNull()); + + touchBeginEvent.ignore(); + p = child2; + res = QApplication::sendEvent(child2, &touchBeginEvent); + QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull()); + touchUpdateEvent.ignore(); + res = QApplication::sendEvent(child2, &touchUpdateEvent); + QVERIFY(res && touchUpdateEvent.isAccepted() && p.isNull()); + + touchBeginEvent.ignore(); + p = child3; + res = QApplication::sendEvent(child3, &touchBeginEvent); + QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull()); + touchUpdateEvent.ignore(); + res = QApplication::sendEvent(child3, &touchUpdateEvent); + QVERIFY(res && touchUpdateEvent.isAccepted() && !p.isNull()); + touchEndEvent.ignore(); + res = QApplication::sendEvent(child3, &touchEndEvent); + QVERIFY(res && touchEndEvent.isAccepted() && p.isNull()); + } + + // QGraphicsView + { + QGraphicsScene scene; + QGraphicsView view(&scene); + tst_QTouchEventGraphicsItem *root, *child1, *child2, *child3; + root = new tst_QTouchEventGraphicsItem; + child1 = new tst_QTouchEventGraphicsItem; + child2 = new tst_QTouchEventGraphicsItem; + child3 = new tst_QTouchEventGraphicsItem; + child1->setParentItem(root); + child2->setParentItem(root); + child3->setParentItem(root); + child1->setZValue(1.); + child2->setZValue(0.); + child3->setZValue(-1.); + child1->setAcceptTouchEvents(true); + child2->setAcceptTouchEvents(true); + child3->setAcceptTouchEvents(true); + child1->deleteInTouchBegin = true; + child2->deleteInTouchUpdate = true; + child3->deleteInTouchEnd = true; + + scene.addItem(root); + view.resize(200, 200); + view.fitInView(scene.sceneRect()); + + QTouchEvent::TouchPoint touchPoint(0); + touchPoint.setState(Qt::TouchPointPressed); + touchPoint.setPos(view.mapFromScene(child1->mapToScene(child1->boundingRect().center()))); + touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint())); + touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint())); + QList touchPoints; + touchPoints.append(touchPoint); + QTouchEvent touchBeginEvent(QEvent::TouchBegin, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointPressed, + touchPoints); + touchPoints[0].setState(Qt::TouchPointMoved); + QTouchEvent touchUpdateEvent(QEvent::TouchUpdate, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointMoved, + touchPoints); + touchPoints[0].setState(Qt::TouchPointReleased); + QTouchEvent touchEndEvent(QEvent::TouchEnd, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointReleased, + touchPoints); + bool res; + + child1->weakpointer = &child1; + touchBeginEvent.ignore(); + res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); + QVERIFY(res && touchBeginEvent.isAccepted() && !child1); + touchUpdateEvent.ignore(); + res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); + QVERIFY(res && touchUpdateEvent.isAccepted() && !child1); + touchEndEvent.ignore(); + res = QApplication::sendEvent(view.viewport(), &touchEndEvent); + QVERIFY(res && touchUpdateEvent.isAccepted() && !child1); + + child2->weakpointer = &child2; + touchBeginEvent.ignore(); + res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); + QVERIFY(res && touchBeginEvent.isAccepted() && child2); + touchUpdateEvent.ignore(); + res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); + QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2); + touchEndEvent.ignore(); + res = QApplication::sendEvent(view.viewport(), &touchEndEvent); + QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2); + + child3->weakpointer = &child3; + res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); + QVERIFY(res && touchBeginEvent.isAccepted() && child3); + res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); + QVERIFY(res && !touchUpdateEvent.isAccepted() && child3); + res = QApplication::sendEvent(view.viewport(), &touchEndEvent); + QVERIFY(res && !touchEndEvent.isAccepted() && !child3); + + delete root; + } +} + +void tst_QTouchEvent::deleteInRawEventTranslation() +{ + tst_QTouchEventWidget touchWidget; + touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); + touchWidget.setGeometry(100, 100, 300, 300); + + tst_QTouchEventWidget *leftWidget = new tst_QTouchEventWidget; + leftWidget->setParent(&touchWidget); + leftWidget->setAttribute(Qt::WA_AcceptTouchEvents); + leftWidget->setGeometry(0, 100, 100, 100); + leftWidget->deleteInTouchBegin = true; + leftWidget->show(); + + tst_QTouchEventWidget *centerWidget = new tst_QTouchEventWidget; + centerWidget->setParent(&touchWidget); + centerWidget->setAttribute(Qt::WA_AcceptTouchEvents); + centerWidget->setGeometry(100, 100, 100, 100); + centerWidget->deleteInTouchUpdate = true; + centerWidget->show(); + + tst_QTouchEventWidget *rightWidget = new tst_QTouchEventWidget; + rightWidget->setParent(&touchWidget); + rightWidget->setAttribute(Qt::WA_AcceptTouchEvents); + rightWidget->setGeometry(200, 100, 100, 100); + rightWidget->deleteInTouchEnd = true; + rightWidget->show(); + + QPointF leftPos = leftWidget->rect().center(); + QPointF centerPos = centerWidget->rect().center(); + QPointF rightPos = rightWidget->rect().center(); + QPointF leftScreenPos = leftWidget->mapToGlobal(leftPos.toPoint()); + QPointF centerScreenPos = centerWidget->mapToGlobal(centerPos.toPoint()); + QPointF rightScreenPos = rightWidget->mapToGlobal(rightPos.toPoint()); + QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + + QWeakPointer pl = leftWidget, pc = centerWidget, pr = rightWidget; + + QList rawTouchPoints; + rawTouchPoints.append(QTouchEvent::TouchPoint(0)); + rawTouchPoints.append(QTouchEvent::TouchPoint(1)); + rawTouchPoints.append(QTouchEvent::TouchPoint(2)); + rawTouchPoints[0].setState(Qt::TouchPointPressed); + rawTouchPoints[0].setScreenPos(leftScreenPos); + rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry)); + rawTouchPoints[1].setState(Qt::TouchPointPressed); + rawTouchPoints[1].setScreenPos(centerScreenPos); + rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); + rawTouchPoints[2].setState(Qt::TouchPointPressed); + rawTouchPoints[2].setScreenPos(rightScreenPos); + rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry)); + + // generate begin events on all widgets, the left widget should die + qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints); + QVERIFY(pl.isNull() && !pc.isNull() && !pr.isNull()); + + // generate update events on all widget, the center widget should die + rawTouchPoints[0].setState(Qt::TouchPointMoved); + rawTouchPoints[1].setState(Qt::TouchPointMoved); + rawTouchPoints[2].setState(Qt::TouchPointMoved); + qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints); + + // generate end events on all widget, the right widget should die + rawTouchPoints[0].setState(Qt::TouchPointReleased); + rawTouchPoints[1].setState(Qt::TouchPointReleased); + rawTouchPoints[2].setState(Qt::TouchPointReleased); + qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints); +} + QTEST_MAIN(tst_QTouchEvent) #include "tst_qtouchevent.moc" -- cgit v0.12 From d8b7b7278987462791488f756edd26842d059074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 11 Dec 2009 14:23:34 +0100 Subject: Fixed invalid read in QCache::unlink after recent change. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to store a pointer to the object in order to delete it later, since the node containing the pointer will be deleted when removing it from the hash. Reviewed-by: Jan-Arve Sæther --- src/corelib/tools/qcache.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h index ee9523f..086a52f 100644 --- a/src/corelib/tools/qcache.h +++ b/src/corelib/tools/qcache.h @@ -70,8 +70,9 @@ class QCache if (l == &n) l = n.p; if (f == &n) f = n.n; total -= n.c; + T *object = n.t; hash.remove(*n.keyPtr); - delete n.t; + delete object; } inline T *relink(const Key &key) { typename QHash::iterator i = hash.find(key); -- cgit v0.12 From 9aa60dfdf5b4837b9ceb15d8fcbc96f37dce7b5a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 11 Dec 2009 15:19:30 +0100 Subject: Check if the timeout expired during the time update in qt_safe_select It can happen that select(2) returns -1 with EINTR, but the time remaining was too small for us to update the time. Our own processing (plus the syscall to clock_gettime(2)) leads us past the timeout, so we get a negative timeval. Task-number: QTBUG-6755 Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qcore_unix.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index 5885591..d0dc7be 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -129,7 +129,7 @@ static inline bool time_update(struct timeval *tv, const struct timeval &start, // clock source is monotonic, so we can recalculate how much timeout is left struct timeval now = qt_gettime(); *tv = timeout + start - now; - return true; + return tv->tv_sec >= 0; } int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, @@ -154,7 +154,8 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, // recalculate the timeout if (!time_update(&timeout, start, *orig_timeout)) { - // clock reset, fake timeout error + // timeout during update + // or clock reset, fake timeout error return 0; } } -- cgit v0.12 From 0fecf4184e888b202766210b235fde09a81c5257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 11 Dec 2009 15:36:13 +0100 Subject: Add a simple check for a common wrong usage to avoid infinite recursion Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 23 ++++++++++++---------- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 7 +++++++ .../tst_qgraphicsanchorlayout.cpp | 20 +++++++++++++++++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 6718a28..f504c54 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -321,14 +321,14 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem, // Horizontal anchor Qt::AnchorPoint firstEdge = (firstCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft); Qt::AnchorPoint secondEdge = (secondCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft); - d->addAnchor(firstItem, firstEdge, secondItem, secondEdge); + if (d->addAnchor(firstItem, firstEdge, secondItem, secondEdge)) { + // Vertical anchor + firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop); + secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop); + d->addAnchor(firstItem, firstEdge, secondItem, secondEdge); - // Vertical anchor - firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop); - secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop); - d->addAnchor(firstItem, firstEdge, secondItem, secondEdge); - - invalidate(); + invalidate(); + } } /*! @@ -351,11 +351,14 @@ void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem, QGraphicsLayoutItem *secondItem, Qt::Orientations orientations) { + bool ok = true; if (orientations & Qt::Horizontal) { - addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft); - addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight); + // Currently, if the first is ok, then the rest of the calls should be ok + ok = addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft) != 0; + if (ok) + addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight); } - if (orientations & Qt::Vertical) { + if (orientations & Qt::Vertical && ok) { addAnchor(secondItem, Qt::AnchorTop, firstItem, Qt::AnchorTop); addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom); } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 03ed63d..1dc6873 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1666,6 +1666,13 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi return 0; } + const QGraphicsLayoutItem *parentWidget = q->parentLayoutItem(); + if (firstItem == parentWidget || secondItem == parentWidget) { + qWarning("QGraphicsAnchorLayout::addAnchor(): " + "You cannot add the parent of the layout to the layout."); + return 0; + } + // In QGraphicsAnchorLayout, items are represented in its internal // graph as four anchors that connect: // - Left -> HCenter diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 6e78522..1cb9f0d 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -90,6 +90,7 @@ private slots: void parallelToHalfLayout(); void globalSpacing(); void graphicsAnchorHandling(); + void invalidHierarchyCheck(); }; class RectWidget : public QGraphicsWidget @@ -2058,5 +2059,24 @@ void tst_QGraphicsAnchorLayout::graphicsAnchorHandling() delete a; } +void tst_QGraphicsAnchorLayout::invalidHierarchyCheck() +{ + QGraphicsWidget window(0, Qt::Window); + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + window.setLayout(l); + + QCOMPARE(l->count(), 0); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): " + "You cannot add the parent of the layout to the layout."); + QVERIFY(!l->addAnchor(l, Qt::AnchorLeft, &window, Qt::AnchorLeft)); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): " + "You cannot add the parent of the layout to the layout."); + l->addAnchors(l, &window); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): " + "You cannot add the parent of the layout to the layout."); + l->addCornerAnchors(l, Qt::TopLeftCorner, &window, Qt::TopLeftCorner); + QCOMPARE(l->count(), 0); +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From 6a1cff7c47e1f47161f765ba2f7094b55aaa13c5 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 11 Dec 2009 16:41:00 +0100 Subject: Fixes Graphicsitem transformation problems when grouping/ungrouping. New transformation properties added in 4.6, such as rotation or transformOriginPoint were not taken into account in addTogroup and removeFromGroup. Autotest and manual test included. Task-number: QTBUG-5071 Reviewed-by: bnilsen --- src/gui/graphicsview/qgraphicsitem.cpp | 46 ++- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 30 ++ tests/manual/qgraphicsitemgroup/customitem.cpp | 107 +++++++ tests/manual/qgraphicsitemgroup/customitem.h | 77 +++++ tests/manual/qgraphicsitemgroup/main.cpp | 51 ++++ .../qgraphicsitemgroup/qgraphicsitemgroup.pro | 8 + tests/manual/qgraphicsitemgroup/widget.cpp | 260 +++++++++++++++++ tests/manual/qgraphicsitemgroup/widget.h | 93 ++++++ tests/manual/qgraphicsitemgroup/widget.ui | 319 +++++++++++++++++++++ 9 files changed, 989 insertions(+), 2 deletions(-) create mode 100644 tests/manual/qgraphicsitemgroup/customitem.cpp create mode 100644 tests/manual/qgraphicsitemgroup/customitem.h create mode 100644 tests/manual/qgraphicsitemgroup/main.cpp create mode 100644 tests/manual/qgraphicsitemgroup/qgraphicsitemgroup.pro create mode 100644 tests/manual/qgraphicsitemgroup/widget.cpp create mode 100644 tests/manual/qgraphicsitemgroup/widget.h create mode 100644 tests/manual/qgraphicsitemgroup/widget.ui diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c879c5c..d955f16 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -10537,6 +10537,20 @@ void QGraphicsItemGroup::addToGroup(QGraphicsItem *item) if (!item->pos().isNull()) newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y()); + // removing additional transformations properties applied with itemTransform() + QPointF origin = item->transformOriginPoint(); + QMatrix4x4 m; + QList transformList = item->transformations(); + for (int i = 0; i < transformList.size(); ++i) + transformList.at(i)->applyTo(&m); + newItemTransform *= m.toTransform().inverted(); + newItemTransform.translate(origin.x(), origin.y()); + newItemTransform.rotate(-item->rotation()); + newItemTransform.scale(1/item->scale(), 1/item->scale()); + newItemTransform.translate(-origin.x(), -origin.y()); + + // ### Expensive, we could maybe use dirtySceneTransform bit for optimization + item->setTransform(newItemTransform); item->d_func()->setIsMemberOfGroup(true); prepareGeometryChange(); @@ -10561,11 +10575,39 @@ void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item) } QGraphicsItem *newParent = d_ptr->parent; + + // COMBINE + bool ok; + QTransform itemTransform; + if (newParent) + itemTransform = item->itemTransform(newParent, &ok); + else + itemTransform = item->sceneTransform(); + QPointF oldPos = item->mapToItem(newParent, 0, 0); item->setParentItem(newParent); - // ### This function should remap the item's matrix to keep the item's - // transformation unchanged relative to the scene. item->setPos(oldPos); + + // removing position from translation component of the new transform + if (!item->pos().isNull()) + itemTransform *= QTransform::fromTranslate(-item->x(), -item->y()); + + // removing additional transformations properties applied + // with itemTransform() or sceneTransform() + QPointF origin = item->transformOriginPoint(); + QMatrix4x4 m; + QList transformList = item->transformations(); + for (int i = 0; i < transformList.size(); ++i) + transformList.at(i)->applyTo(&m); + itemTransform *= m.toTransform().inverted(); + itemTransform.translate(origin.x(), origin.y()); + itemTransform.rotate(-item->rotation()); + itemTransform.scale(1 / item->scale(), 1 / item->scale()); + itemTransform.translate(-origin.x(), -origin.y()); + + // ### Expensive, we could maybe use dirtySceneTransform bit for optimization + + item->setTransform(itemTransform); item->d_func()->setIsMemberOfGroup(item->group() != 0); // ### Quite expensive. But removeFromGroup() isn't called very often. diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 3e7a2eb..a4931ab 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -318,6 +318,7 @@ private slots: void childrenBoundingRect3(); void group(); void setGroup(); + void setGroup2(); void nestedGroups(); void warpChildrenIntoGroup(); void removeFromGroup(); @@ -3345,6 +3346,35 @@ void tst_QGraphicsItem::setGroup() QCOMPARE(rect->parentItem(), (QGraphicsItem *)0); } +void tst_QGraphicsItem::setGroup2() +{ + QGraphicsScene scene; + QGraphicsItemGroup group; + scene.addItem(&group); + + QGraphicsRectItem *rect = scene.addRect(50,50,50,50,Qt::NoPen,Qt::black); + rect->setTransformOriginPoint(50,50); + rect->setRotation(45); + rect->setScale(1.5); + rect->translate(20,20); + group.translate(-30,-40); + group.setRotation(180); + group.setScale(0.5); + + QTransform oldSceneTransform = rect->sceneTransform(); + rect->setGroup(&group); + QCOMPARE(rect->sceneTransform(), oldSceneTransform); + + group.setRotation(20); + group.setScale(2); + rect->setRotation(90); + rect->setScale(0.8); + + oldSceneTransform = rect->sceneTransform(); + rect->setGroup(0); + QCOMPARE(rect->sceneTransform(), oldSceneTransform); +} + void tst_QGraphicsItem::nestedGroups() { QGraphicsItemGroup *group1 = new QGraphicsItemGroup; diff --git a/tests/manual/qgraphicsitemgroup/customitem.cpp b/tests/manual/qgraphicsitemgroup/customitem.cpp new file mode 100644 index 0000000..16da0c5 --- /dev/null +++ b/tests/manual/qgraphicsitemgroup/customitem.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "customitem.h" + +#include +#include +#include + +QList CustomScene::selectedCustomGroups() const +{ + QList all = selectedItems(); + QList groups; + + foreach (QGraphicsItem *item, all) { + CustomGroup* group = dynamic_cast(item); + if (group) + groups.append(group); + } + + return groups; +} + +QList CustomScene::selectedCustomItems() const +{ + QList all = selectedItems(); + QList items; + + foreach (QGraphicsItem *item, all) { + CustomItem* citem = dynamic_cast(item); + if (citem) + items.append(citem); + } + + return items; +} + +CustomGroup::CustomGroup() : + QGraphicsItemGroup() +{ + setFlag(QGraphicsItem::ItemIsMovable); + setFlag(QGraphicsItem::ItemIsSelectable); +} + +void CustomGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + if (option->state & QStyle::State_Selected) + painter->setOpacity(1.); + else + painter->setOpacity(0.2); + + painter->setPen(QPen(QColor(100, 100, 100), 2, Qt::DashLine)); + painter->drawRect(boundingRect().adjusted(-2, -2, 2, 2)); +} + +QRectF CustomGroup::boundingRect() const +{ + return QGraphicsItemGroup::boundingRect().adjusted(-4, -4, 4 ,4); +} + +CustomItem::CustomItem(qreal x, qreal y, qreal width, qreal height, const QBrush &brush) : + QGraphicsRectItem(x, y, width, height) +{ + setFlag(QGraphicsItem::ItemIsMovable); + setFlag(QGraphicsItem::ItemIsSelectable); + setBrush(brush); + setPen(Qt::NoPen); + setTransformOriginPoint(boundingRect().center()); +} diff --git a/tests/manual/qgraphicsitemgroup/customitem.h b/tests/manual/qgraphicsitemgroup/customitem.h new file mode 100644 index 0000000..387c8ce --- /dev/null +++ b/tests/manual/qgraphicsitemgroup/customitem.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUSTOMITEM_H +#define CUSTOMITEM_H + +#include +#include +#include + +class CustomGroup : public QGraphicsItemGroup +{ +public: + CustomGroup(); + virtual ~CustomGroup() { } + +protected: + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual QRectF boundingRect() const; +}; + +class CustomItem : public QGraphicsRectItem +{ +public: + CustomItem(qreal x, qreal y, qreal width, qreal height, const QBrush & brush = QBrush()); + virtual ~CustomItem() { } +}; + +class CustomScene : public QGraphicsScene +{ + Q_OBJECT +public: + CustomScene() : QGraphicsScene() { } + + QList selectedCustomItems() const; + QList selectedCustomGroups() const; +}; + +#endif // CUSTOMITEM_H diff --git a/tests/manual/qgraphicsitemgroup/main.cpp b/tests/manual/qgraphicsitemgroup/main.cpp new file mode 100644 index 0000000..e7a6e11 --- /dev/null +++ b/tests/manual/qgraphicsitemgroup/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "widget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + w.show(); + return a.exec(); +} diff --git a/tests/manual/qgraphicsitemgroup/qgraphicsitemgroup.pro b/tests/manual/qgraphicsitemgroup/qgraphicsitemgroup.pro new file mode 100644 index 0000000..6676a2e --- /dev/null +++ b/tests/manual/qgraphicsitemgroup/qgraphicsitemgroup.pro @@ -0,0 +1,8 @@ +TARGET = qgraphicsitemgroup +TEMPLATE = app +SOURCES += main.cpp \ + widget.cpp \ + customitem.cpp +HEADERS += widget.h \ + customitem.h +FORMS += widget.ui diff --git a/tests/manual/qgraphicsitemgroup/widget.cpp b/tests/manual/qgraphicsitemgroup/widget.cpp new file mode 100644 index 0000000..23bee3f --- /dev/null +++ b/tests/manual/qgraphicsitemgroup/widget.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "widget.h" +#include "ui_widget.h" +#include +#include + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget), + previousSelectionCount(0) +{ + ui->setupUi(this); + + effect = new QGraphicsOpacityEffect; + effect->setOpacity(0.3); + ui->groupBox->setGraphicsEffect(effect); + + fadeIn = new QPropertyAnimation(effect, "opacity"); + fadeIn->setDuration(200); + fadeIn->setStartValue(0.3); + fadeIn->setEndValue(1.); + + fadeOut = new QPropertyAnimation(effect, "opacity"); + fadeOut->setDuration(200); + fadeOut->setStartValue(1.); + fadeOut->setEndValue(0.3); + + scene = new CustomScene; + scene->setSceneRect(-250,-250,500,500); + ui->view->setScene(scene); + scene->setBackgroundBrush(Qt::white); + ui->view->setInteractive(true); + ui->view->setDragMode(QGraphicsView::RubberBandDrag); + ui->view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + ui->view->setRenderHints( QPainter::SmoothPixmapTransform | + QPainter::TextAntialiasing | + QPainter::Antialiasing ); + + rectBlue = new CustomItem(-100, -100, 50, 50, QColor(80, 80, 200)); + scene->addItem(rectBlue); + rectGreen = new CustomItem(100, -100, 50, 50, QColor(80, 200, 80)); + scene->addItem(rectGreen); + rectRed = new CustomItem(-100, 100, 50, 50, QColor(200, 80, 80)); + scene->addItem(rectRed); + rectYellow = new CustomItem(100, 100, 50, 50, QColor(200, 200, 20)); + scene->addItem(rectYellow); + + connect(scene, SIGNAL(selectionChanged()), this, SLOT(onSceneSelectionChanged())); +} + +Widget::~Widget() +{ + delete ui; + delete fadeIn; + delete fadeOut; +} + +void Widget::on_rotate_valueChanged(int value) +{ + if (scene->selectedItems().count() != 1) + return; + + QGraphicsItem *item = scene->selectedItems().at(0); + item->setRotation(value); + ui->rotateItem->setValue(checkedItem()->rotation()); +} + +void Widget::on_scale_valueChanged(int value) +{ + if (scene->selectedItems().count() != 1) + return; + + QGraphicsItem *item = scene->selectedItems().at(0); + item->setScale(value / 10.); + ui->scaleItem->setValue(checkedItem()->scale() * 10); +} + +void Widget::on_rotateItem_valueChanged(int value) +{ + if (!scene->selectedItems().empty() && scene->selectedItems().at(0) == checkedItem()) + ui->rotate->setValue(value); + else + checkedItem()->setRotation(value); +} + +void Widget::on_scaleItem_valueChanged(int value) +{ + if (!scene->selectedItems().empty() && scene->selectedItems().at(0) == checkedItem()) + ui->scale->setValue(value); + else + checkedItem()->setScale(value / 10.); +} + +void Widget::on_group_clicked() +{ + QList all = scene->selectedItems(); + if (all.size() < 2) + return; + + QList items = scene->selectedCustomItems(); + QList groups = scene->selectedCustomGroups(); + + if (groups.size() == 1) { + foreach (CustomItem *item, items) { + item->setSelected(false); + groups[0]->addToGroup(item); + } + + return; + } + + CustomGroup* group = new CustomGroup; + scene->addItem(group); + foreach (QGraphicsItem *item, all) { + item->setSelected(false); + group->addToGroup(item); + } + group->setSelected(true); + + updateUngroupButton(); +} + +void Widget::on_dismantle_clicked() +{ + QList groups = scene->selectedCustomGroups(); + + foreach (CustomGroup *group, groups) { + foreach (QGraphicsItem *item, group->childItems()) + group->removeFromGroup(item); + + delete group; + } + + updateUngroupButton(); +} + +void Widget::on_merge_clicked() +{ + QList groups = scene->selectedCustomGroups(); + if (groups.size() < 2) + return; + + CustomGroup *newBigGroup = groups.takeFirst(); + foreach (CustomGroup *group, groups) { + foreach (QGraphicsItem *item, group->childItems()) + item->setGroup(newBigGroup); + + delete group; + } +} + +void Widget::onSceneSelectionChanged() +{ + QList all = scene->selectedItems(); + QList groups = scene->selectedCustomGroups(); + + if (all.empty() && all.count() != previousSelectionCount) { + fadeOut->start(); + } else if (previousSelectionCount == 0) { + fadeIn->start(); + } + + if (all.count() == 1) { + QGraphicsItem *item = all.at(0); + ui->rotate->setValue(item->rotation()); + ui->scale->setValue(item->scale() * 10); + } else { + ui->rotate->setValue(ui->rotate->minimum()); + ui->scale->setValue(ui->scale->minimum()); + } + + ui->rotate->setEnabled(all.size() == 1); + ui->scale->setEnabled(all.size() == 1); + ui->group->setEnabled(all.size() > 1); + ui->dismantle->setEnabled(!groups.empty()); + ui->merge->setEnabled(groups.size() > 1); + + previousSelectionCount = all.size(); + + updateUngroupButton(); +} + +void Widget::on_ungroup_clicked() +{ + QGraphicsItemGroup *oldGroup = checkedItem()->group(); + checkedItem()->setGroup(0); + if (oldGroup && oldGroup->childItems().empty()) + delete oldGroup; + + updateUngroupButton(); +} + +void Widget::updateUngroupButton() +{ + ui->ungroup->setEnabled(checkedItem()->group() != 0); +} + +CustomItem * Widget::checkedItem() const +{ + CustomItem *item; + + if (ui->blue->isChecked()) + item = rectBlue; + else if (ui->red->isChecked()) + item = rectRed; + else if (ui->green->isChecked()) + item = rectGreen; + else if (ui->yellow->isChecked()) + item = rectYellow; + + return item; +} + +void Widget::on_buttonGroup_buttonClicked() +{ + ui->rotateItem->setValue(checkedItem()->rotation()); + ui->scaleItem->setValue(checkedItem()->scale() * 10); + + updateUngroupButton(); +} diff --git a/tests/manual/qgraphicsitemgroup/widget.h b/tests/manual/qgraphicsitemgroup/widget.h new file mode 100644 index 0000000..affc436 --- /dev/null +++ b/tests/manual/qgraphicsitemgroup/widget.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WIDGET_H +#define WIDGET_H + +#include "customitem.h" + +#include +#include +#include + +namespace Ui { + class Widget; +} + +class QGraphicsOpacityEffect; +class QPropertyAnimation; + +class Widget : public QWidget +{ + Q_OBJECT +public: + Widget(QWidget *parent = 0); + ~Widget(); + +protected Q_SLOTS: + void on_rotate_valueChanged(int value); + void on_scale_valueChanged(int value); + void on_rotateItem_valueChanged(int value); + void on_scaleItem_valueChanged(int value); + void on_group_clicked(); + void on_dismantle_clicked(); + void on_merge_clicked(); + void onSceneSelectionChanged(); + void on_ungroup_clicked(); + void on_buttonGroup_buttonClicked(); + +private: + void updateUngroupButton(); + CustomItem * checkedItem() const; + + Ui::Widget *ui; + CustomScene *scene; + CustomItem *rectBlue; + CustomItem *rectRed; + CustomItem *rectGreen; + CustomItem *rectYellow; + QGraphicsOpacityEffect* effect; + QPropertyAnimation *fadeIn; + QPropertyAnimation *fadeOut; + int previousSelectionCount; +}; + +#endif // WIDGET_H diff --git a/tests/manual/qgraphicsitemgroup/widget.ui b/tests/manual/qgraphicsitemgroup/widget.ui new file mode 100644 index 0000000..7e3a4df --- /dev/null +++ b/tests/manual/qgraphicsitemgroup/widget.ui @@ -0,0 +1,319 @@ + + + Widget + + + + 0 + 0 + 782 + 695 + + + + Widget + + + + + + + + Items + + + + + + + + + + Blue + + + true + + + buttonGroup + + + + + + + Red + + + buttonGroup + + + + + + + Green + + + buttonGroup + + + + + + + Yellow + + + buttonGroup + + + + + + + + + + + Rotate + + + + + + + true + + + + 120 + 0 + + + + 360 + + + Qt::Horizontal + + + + + + + Scale + + + + + + + true + + + + 120 + 0 + + + + 5 + + + 30 + + + 10 + + + Qt::Horizontal + + + + + + + + + + + false + + + Ungroup + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 50 + 20 + + + + + + + + true + + + + 300 + 164 + + + + + 300 + 164 + + + + Selection + + + + + + + + false + + + Rotate + + + + + + + false + + + + 120 + 0 + + + + 360 + + + Qt::Horizontal + + + + + + + false + + + Scale + + + + + + + false + + + + 120 + 0 + + + + 5 + + + 30 + + + 10 + + + Qt::Horizontal + + + + + + + + + + + false + + + Group + + + + + + + false + + + Merge Groups + + + + + + + false + + + Dismantle Group + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + -- cgit v0.12 From 4e9063d7a8fc79d1cfee71d2c889877264d44086 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 11 Dec 2009 17:10:18 +0100 Subject: Itemviews: we needed to call ensurePolishedwhen asking for sizehints Reviewed-by: Pierre Rossi --- src/gui/itemviews/qabstractitemview.cpp | 4 ++++ src/gui/itemviews/qtreeview.cpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index de6e6cb..4a450b7 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -2867,6 +2867,8 @@ int QAbstractItemView::sizeHintForRow(int row) const if (row < 0 || row >= d->model->rowCount() || !model()) return -1; + ensurePolished(); + QStyleOptionViewItemV4 option = d->viewOptionsV4(); int height = 0; int colCount = d->model->columnCount(d->root); @@ -2896,6 +2898,8 @@ int QAbstractItemView::sizeHintForColumn(int column) const if (column < 0 || column >= d->model->columnCount() || !model()) return -1; + ensurePolished(); + QStyleOptionViewItemV4 option = d->viewOptionsV4(); int width = 0; int rows = d->model->rowCount(d->root); diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 3ad9fbb..bcf9cfb 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2774,6 +2774,7 @@ int QTreeView::sizeHintForColumn(int column) const d->executePostedLayout(); if (d->viewItems.isEmpty()) return -1; + ensurePolished(); int w = 0; QStyleOptionViewItemV4 option = d->viewOptionsV4(); const QVector viewItems = d->viewItems; -- cgit v0.12 From f555e06c3e8eee7cc67218331562c11ad77ec9c4 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 10 Dec 2009 15:33:21 +0100 Subject: Add missing benchmark to the benchmarks.pro This does not add the benchmark that runs too slowly. Reviewed-by: jasplin --- tests/benchmarks/benchmarks.pro | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 9170039..bffa009 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -20,6 +20,24 @@ SUBDIRS = containers-associative \ qregion \ qvariant \ qwidget \ - qtwidgets + qtwidgets \ + qapplication \ + qdir \ + qdiriterator \ + qgraphicsanchorlayout \ + qgraphicsitem \ + qgraphicswidget \ + qmetaobject \ + qpixmapcache \ + qquaternion \ + qscriptclass \ + qscriptengine \ + qscriptvalue \ + qstringbuilder \ + qstylesheetstyle \ + qsvgrenderer \ + qtableview + + contains(QT_CONFIG, opengl): SUBDIRS += opengl -- cgit v0.12 From c15c9cd2356eaeba33a5f8e62a90b0aeb45284e1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 11 Dec 2009 17:18:54 +0100 Subject: Fixes cursor blinking in the QComboBox when it becomes editable while having the focus. The lineedit has the focus because it becomes focusproxy of the QComboBox. But the focusInEvent is not called because the combobox has already the focus when setFocusProxy is called. Workaround that in the show event. Task-number: QTBUG-1949 Reviewed-by: Thierry --- src/gui/widgets/qlineedit.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 2c1acdb..15dcda2 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1445,6 +1445,16 @@ bool QLineEdit::event(QEvent * e) d->control->processEvent(e); } else if (e->type() == QEvent::KeyRelease) { d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); + } else if (e->type() == QEvent::Show) { + //In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus + if (hasFocus()) { + d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); + QStyleOptionFrameV2 opt; + initStyleOption(&opt); + if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty()) + || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this)) + d->setCursorVisible(true); + } } #ifdef QT_KEYPAD_NAVIGATION -- cgit v0.12 From 4879551f72a377e0816164ce1762eb646839f4a6 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 14 Dec 2009 14:46:52 +1000 Subject: OpenVG .def file updates. --- src/s60installs/eabi/QtGuiu.def | 41 ++++++++++++++++++++++++++++++++++++++ src/s60installs/eabi/QtOpenVGu.def | 8 ++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 429ca79..bfad2e7 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -11741,4 +11741,45 @@ EXPORTS _ZN11QVectorPathD2Ev @ 11740 NONAME _ZNK11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS1_S2_E @ 11741 NONAME _ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbb @ 11742 NONAME + _ZN11QEglContext10extensionsEv @ 11743 NONAME + _ZN11QEglContext10getDisplayEP12QPaintDevice @ 11744 NONAME + _ZN11QEglContext10waitClientEv @ 11745 NONAME + _ZN11QEglContext10waitNativeEv @ 11746 NONAME + _ZN11QEglContext11doneCurrentEv @ 11747 NONAME + _ZN11QEglContext11errorStringEi @ 11748 NONAME + _ZN11QEglContext11makeCurrentEi @ 11749 NONAME + _ZN11QEglContext11openDisplayEP12QPaintDevice @ 11750 NONAME + _ZN11QEglContext11swapBuffersEi @ 11751 NONAME + _ZN11QEglContext12chooseConfigERK14QEglPropertiesN4QEgl16PixelFormatMatchE @ 11752 NONAME + _ZN11QEglContext12hasExtensionEPKc @ 11753 NONAME + _ZN11QEglContext13createContextEPS_PK14QEglProperties @ 11754 NONAME + _ZN11QEglContext13createSurfaceEP12QPaintDevicePK14QEglProperties @ 11755 NONAME + _ZN11QEglContext14currentContextEN4QEgl3APIE @ 11756 NONAME + _ZN11QEglContext14defaultDisplayEP12QPaintDevice @ 11757 NONAME + _ZN11QEglContext14destroySurfaceEi @ 11758 NONAME + _ZN11QEglContext14dumpAllConfigsEv @ 11759 NONAME + _ZN11QEglContext15lazyDoneCurrentEv @ 11760 NONAME + _ZN11QEglContext17setCurrentContextEN4QEgl3APIEPS_ @ 11761 NONAME + _ZN11QEglContext7destroyEv @ 11762 NONAME + _ZN11QEglContextC1Ev @ 11763 NONAME + _ZN11QEglContextC2Ev @ 11764 NONAME + _ZN11QEglContextD1Ev @ 11765 NONAME + _ZN11QEglContextD2Ev @ 11766 NONAME + _ZN14QEglProperties11removeValueEi @ 11767 NONAME + _ZN14QEglProperties14dumpAllConfigsEv @ 11768 NONAME + _ZN14QEglProperties14setPixelFormatEN6QImage6FormatE @ 11769 NONAME + _ZN14QEglProperties17setRenderableTypeEN4QEgl3APIE @ 11770 NONAME + _ZN14QEglProperties19reduceConfigurationEv @ 11771 NONAME + _ZN14QEglProperties20setPaintDeviceFormatEP12QPaintDevice @ 11772 NONAME + _ZN14QEglProperties8setValueEii @ 11773 NONAME + _ZN14QEglPropertiesC1Ei @ 11774 NONAME + _ZN14QEglPropertiesC1Ev @ 11775 NONAME + _ZN14QEglPropertiesC2Ei @ 11776 NONAME + _ZN14QEglPropertiesC2Ev @ 11777 NONAME + _ZNK11QEglContext12configAttribEiPi @ 11778 NONAME + _ZNK11QEglContext16configPropertiesEi @ 11779 NONAME + _ZNK11QEglContext7isValidEv @ 11780 NONAME + _ZNK11QEglContext9isCurrentEv @ 11781 NONAME + _ZNK14QEglProperties5valueEi @ 11782 NONAME + _ZNK14QEglProperties8toStringEv @ 11783 NONAME diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def index 8458983..7526632 100644 --- a/src/s60installs/eabi/QtOpenVGu.def +++ b/src/s60installs/eabi/QtOpenVGu.def @@ -1,8 +1,8 @@ EXPORTS _Z16qPixmapToVGImageRK7QPixmap @ 1 NONAME - _Z20qt_vg_create_contextP12QPaintDevice @ 2 NONAME + _Z20qt_vg_create_contextP12QPaintDevice @ 2 NONAME ABSENT _Z20qt_vg_shared_surfacev @ 3 NONAME - _Z21qt_vg_destroy_contextP11QEglContext @ 4 NONAME + _Z21qt_vg_destroy_contextP11QEglContext @ 4 NONAME ABSENT _Z24qt_vg_image_to_vg_formatN6QImage6FormatE @ 5 NONAME _Z25qt_vg_config_to_vg_formatP11QEglContext @ 6 NONAME _Z25qt_vg_create_paint_enginev @ 7 NONAME @@ -169,4 +169,8 @@ EXPORTS _ZThn8_NK16QVGWindowSurface6metricEN12QPaintDevice17PaintDeviceMetricE @ 168 NONAME _ZN14QVGPaintEngine10fillRegionERK7QRegionRK6QColorRK5QSize @ 169 NONAME _ZN20QVGCompositionHelper10blitWindowEmRK5QSizeRK5QRectRK6QPointi @ 170 NONAME + _Z20qt_vg_create_contextP12QPaintDevicei @ 171 NONAME + _Z21qt_vg_destroy_contextP11QEglContexti @ 172 NONAME + _ZN13QVGPixmapData22destroyImageAndContextEv @ 173 NONAME + _ZN13QVGPixmapData9hibernateEv @ 174 NONAME -- cgit v0.12 From 006b48d5f998d0beba9431a7688c928f0f5f9ad6 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 14 Dec 2009 09:11:36 +0100 Subject: Fixed spelling in docs --- src/gui/painting/qpainter.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 13d9a04..33496a9 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1321,8 +1321,8 @@ void QPainterPrivate::updateState(QPainterState *newState) QPainter is a rich framework that allows developers to do a great variety of graphical operations, such as gradients, composition - modes and vector graphcis. And QPainter can do this across a - variety of different hardware and software stack. Naturally the + modes and vector graphics. And QPainter can do this across a + variety of different hardware and software stacks. Naturally the underlying combination of hardware and software has some implications for performance, and ensuring that every single operation is fast in combination with all the various combinations @@ -1344,13 +1344,13 @@ void QPainterPrivate::updateState(QPainterState *newState) including QImage::Format_ARGB32, has significantly worse performance. This engine is also used by default on Windows and on QWS. It can be used as default graphics system on any - OS/hardware/software combination by passing \c {-graphcissystem + OS/hardware/software combination by passing \c {-graphicssystem raster} on the command line \o OpenGL 2.0 (ES) - This backend is the primary backend for - hardware accellerated graphics. It can be run on desktop machines + hardware accelerated graphics. It can be run on desktop machines and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0 - spesification. This includes most graphics chips produced in the + specification. This includes most graphics chips produced in the last couple of years. The engine can be enabled by using QPainter onto a QGLWidget or by passing \c {-graphicssystem opengl} on the command line when the underlying system supports it. @@ -1366,7 +1366,7 @@ void QPainterPrivate::updateState(QPainterState *newState) \o \c drawPixmap() in combination with simple transformations and opacity with non-smooth transformation mode - (\c QPainter::SmoothPixmapTransform not enabled as a render hint); + (\c QPainter::SmoothPixmapTransform not enabled as a render hint). \o Text drawing with regular font sizes with simple transformations with solid colors using no or 8-bit antialiasing. -- cgit v0.12 From 76213ac8028079a9933548625bd917f49862f4c1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 14 Dec 2009 10:31:21 +0100 Subject: Fix warning in public header qcache.h:73: warning: declaration of 'object' shadows a member of this Spotted by compilerwarnings autotest Reviewed-by: Thiago --- src/corelib/tools/qcache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h index 086a52f..66f9f73 100644 --- a/src/corelib/tools/qcache.h +++ b/src/corelib/tools/qcache.h @@ -70,9 +70,9 @@ class QCache if (l == &n) l = n.p; if (f == &n) f = n.n; total -= n.c; - T *object = n.t; + T *obj = n.t; hash.remove(*n.keyPtr); - delete object; + delete obj; } inline T *relink(const Key &key) { typename QHash::iterator i = hash.find(key); -- cgit v0.12 From 8b46b4cc0e1df56d40535b381986eb455806c589 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 14 Dec 2009 10:51:25 +0100 Subject: Stabilize test --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 1 + tests/auto/qsharedmemory/tst_qsharedmemory.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index a4931ab..03a587a 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -1354,6 +1354,7 @@ void tst_QGraphicsItem::selected() view.setFixedSize(250, 250); view.show(); + QTest::qWaitForWindowShown(&view); qApp->processEvents(); qApp->processEvents(); diff --git a/tests/auto/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/qsharedmemory/tst_qsharedmemory.cpp index f72b6f7..4148594 100644 --- a/tests/auto/qsharedmemory/tst_qsharedmemory.cpp +++ b/tests/auto/qsharedmemory/tst_qsharedmemory.cpp @@ -756,12 +756,12 @@ void tst_QSharedMemory::simpleProcessProducerConsumer() ++failedProcesses; } - producer.waitForFinished(5000); + QVERIFY(producer.waitForFinished(5000)); bool consumerFailed = false; while (!consumers.isEmpty()) { - consumers.first()->waitForFinished(2000); + QVERIFY(consumers.first()->waitForFinished(3000)); if (consumers.first()->state() == QProcess::Running || consumers.first()->exitStatus() != QProcess::NormalExit || consumers.first()->exitCode() != 0) { -- cgit v0.12 From 08da5b53b6f4564057b99bf9076ec350b4ebeb35 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 14 Dec 2009 13:11:20 +0100 Subject: Added vg to the performance section of the QPainter docs --- src/gui/painting/qpainter.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 33496a9..8ed126f 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1355,6 +1355,12 @@ void QPainterPrivate::updateState(QPainterState *newState) onto a QGLWidget or by passing \c {-graphicssystem opengl} on the command line when the underlying system supports it. + \o OpenVG - This backend implements the Khronos standard for 2D + and Vector Graphics. It is primarily for embedded devices with + hardware support for OpenVG. The engine can be enabled by + passing \c {-graphicssystem openvg} on the command line when + the underlying system supports it. + \endlist These operations are: -- cgit v0.12 From 0295f8da10d6c920511d09f9e506b8bed8c444c3 Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 6 Oct 2009 21:39:02 +0200 Subject: Determine QPrinterInfo's supportedPaperSizes on demand. The paper size determination requires a cupsGetPPD(), which can be a slow HTTP download. So doing it on demand makes QPrinterInfo::defaultPrinter() much faster, because it doesn't actually need the paper sizes at all. Before this fix, it was requesting the PPD file of every known CUPS printer, every time it was called. My battery of unittests for code that uses QPrinter went from 19 minutes when the cups print server is switched off, to 13 seconds! This fix also removes some code duplication, which is always nice. Task-number: 232664, QTBUG-3033 Reviewed-by: Trond --- src/gui/painting/qprinterinfo_unix.cpp | 50 ++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index 6684ff7..930785b 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -75,7 +75,9 @@ private: QString m_name; bool m_isNull; bool m_default; - QList m_paperSizes; + mutable bool m_mustGetPaperSizes; + mutable QList m_paperSizes; + int m_cupsPrinterIndex; QPrinterInfo* q_ptr; }; @@ -838,16 +840,7 @@ QList QPrinterInfo::availablePrinters() list.append(QPrinterInfo(printerName)); if (cupsPrinters[i].is_default) list[i].d_ptr->m_default = true; - // Find paper sizes. - cups.setCurrentPrinter(i); - const ppd_option_t* sizes = cups.pageSizes(); - if (sizes) { - for (int j = 0; j < sizes->num_choices; ++j) { - list[i].d_ptr->m_paperSizes.append( - QPrinterInfoPrivate::string2PaperSize( - QLatin1String(sizes->choices[j].choice))); - } - } + list[i].d_ptr->m_cupsPrinterIndex = i; } } else { #endif @@ -909,16 +902,7 @@ QPrinterInfo::QPrinterInfo(const QPrinter& printer) if (printerName == printer.printerName()) { if (cupsPrinters[i].is_default) d->m_default = true; - // Find paper sizes. - cups.setCurrentPrinter(i); - const ppd_option_t* sizes = cups.pageSizes(); - if (sizes) { - for (int j = 0; j < sizes->num_choices; ++j) { - d->m_paperSizes.append( - QPrinterInfoPrivate::string2PaperSize( - QLatin1String(sizes->choices[j].choice))); - } - } + d->m_cupsPrinterIndex = i; return; } } @@ -983,6 +967,26 @@ bool QPrinterInfo::isDefault() const QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const { const Q_D(QPrinterInfo); + if (d->m_mustGetPaperSizes) { + d->m_mustGetPaperSizes = false; + +#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) + QCUPSSupport cups; + if (QCUPSSupport::isAvailable()) { + // Find paper sizes from CUPS. + cups.setCurrentPrinter(d->m_cupsPrinterIndex); + const ppd_option_t* sizes = cups.pageSizes(); + if (sizes) { + for (int j = 0; j < sizes->num_choices; ++j) { + d->m_paperSizes.append( + QPrinterInfoPrivate::string2PaperSize( + QLatin1String(sizes->choices[j].choice))); + } + } + } +#endif + + } return d->m_paperSizes; } @@ -993,6 +997,8 @@ QPrinterInfoPrivate::QPrinterInfoPrivate() { m_isNull = true; m_default = false; + m_mustGetPaperSizes = true; + m_cupsPrinterIndex = 0; q_ptr = 0; } @@ -1001,6 +1007,8 @@ QPrinterInfoPrivate::QPrinterInfoPrivate(const QString& name) m_name = name; m_isNull = false; m_default = false; + m_mustGetPaperSizes = true; + m_cupsPrinterIndex = 0; q_ptr = 0; } -- cgit v0.12 From 504d6d4ac0d782c1fbca1f2dc1e8425dac773113 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Tue, 15 Dec 2009 11:59:56 +1000 Subject: Fixed compile for S60 (.def file updates). More private API changes, and mark QEgl symbols as ABSENT so compilation is not broken when OpenVG is disabled. --- src/s60installs/eabi/QtGuiu.def | 92 +++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index bfad2e7..b6862e5 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -698,13 +698,13 @@ EXPORTS _ZN11QFontDialogD2Ev @ 697 NONAME _ZN11QFontEngine11boundingBoxEjRK10QTransform @ 698 NONAME _ZN11QFontEngine11grayPaletteEv @ 699 NONAME - _ZN11QFontEngine13setGlyphCacheEN21QFontEngineGlyphCache4TypeEPS0_ @ 700 NONAME + _ZN11QFontEngine13setGlyphCacheEN21QFontEngineGlyphCache4TypeEPS0_ @ 700 NONAME ABSENT _ZN11QFontEngine13setGlyphCacheEPvP21QFontEngineGlyphCache @ 701 NONAME _ZN11QFontEngine15addGlyphsToPathEPjP11QFixedPointiP12QPainterPath6QFlagsIN9QTextItem10RenderFlagEE @ 702 NONAME _ZN11QFontEngine16addOutlineToPathEffRK12QGlyphLayoutP12QPainterPath6QFlagsIN9QTextItem10RenderFlagEE @ 703 NONAME _ZN11QFontEngine16alphaMapForGlyphEj @ 704 NONAME _ZN11QFontEngine16alphaMapForGlyphEjRK10QTransform @ 705 NONAME - _ZN11QFontEngine16expireGlyphCacheEv @ 706 NONAME + _ZN11QFontEngine16expireGlyphCacheEv @ 706 NONAME ABSENT _ZN11QFontEngine16getUnscaledGlyphEjP12QPainterPathP15glyph_metrics_t @ 707 NONAME _ZN11QFontEngine16loadKerningPairsE6QFixed @ 708 NONAME _ZN11QFontEngine16tightBoundingBoxERK12QGlyphLayout @ 709 NONAME @@ -7615,8 +7615,8 @@ EXPORTS _ZNK11QFontDialog11currentFontEv @ 7614 NONAME _ZNK11QFontDialog12selectedFontEv @ 7615 NONAME _ZNK11QFontDialog7optionsEv @ 7616 NONAME - _ZNK11QFontEngine10glyphCacheEN21QFontEngineGlyphCache4TypeERK10QTransform @ 7617 NONAME - _ZNK11QFontEngine10glyphCacheEPvRK10QTransform @ 7618 NONAME + _ZNK11QFontEngine10glyphCacheEN21QFontEngineGlyphCache4TypeERK10QTransform @ 7617 NONAME ABSENT + _ZNK11QFontEngine10glyphCacheEPvRK10QTransform @ 7618 NONAME ABSENT _ZNK11QFontEngine10glyphCountEv @ 7619 NONAME _ZNK11QFontEngine10propertiesEv @ 7620 NONAME _ZNK11QFontEngine12getSfntTableEj @ 7621 NONAME @@ -11741,45 +11741,47 @@ EXPORTS _ZN11QVectorPathD2Ev @ 11740 NONAME _ZNK11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS1_S2_E @ 11741 NONAME _ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbb @ 11742 NONAME - _ZN11QEglContext10extensionsEv @ 11743 NONAME - _ZN11QEglContext10getDisplayEP12QPaintDevice @ 11744 NONAME - _ZN11QEglContext10waitClientEv @ 11745 NONAME - _ZN11QEglContext10waitNativeEv @ 11746 NONAME - _ZN11QEglContext11doneCurrentEv @ 11747 NONAME - _ZN11QEglContext11errorStringEi @ 11748 NONAME - _ZN11QEglContext11makeCurrentEi @ 11749 NONAME - _ZN11QEglContext11openDisplayEP12QPaintDevice @ 11750 NONAME - _ZN11QEglContext11swapBuffersEi @ 11751 NONAME - _ZN11QEglContext12chooseConfigERK14QEglPropertiesN4QEgl16PixelFormatMatchE @ 11752 NONAME - _ZN11QEglContext12hasExtensionEPKc @ 11753 NONAME - _ZN11QEglContext13createContextEPS_PK14QEglProperties @ 11754 NONAME - _ZN11QEglContext13createSurfaceEP12QPaintDevicePK14QEglProperties @ 11755 NONAME - _ZN11QEglContext14currentContextEN4QEgl3APIE @ 11756 NONAME - _ZN11QEglContext14defaultDisplayEP12QPaintDevice @ 11757 NONAME - _ZN11QEglContext14destroySurfaceEi @ 11758 NONAME - _ZN11QEglContext14dumpAllConfigsEv @ 11759 NONAME - _ZN11QEglContext15lazyDoneCurrentEv @ 11760 NONAME - _ZN11QEglContext17setCurrentContextEN4QEgl3APIEPS_ @ 11761 NONAME - _ZN11QEglContext7destroyEv @ 11762 NONAME - _ZN11QEglContextC1Ev @ 11763 NONAME - _ZN11QEglContextC2Ev @ 11764 NONAME - _ZN11QEglContextD1Ev @ 11765 NONAME - _ZN11QEglContextD2Ev @ 11766 NONAME - _ZN14QEglProperties11removeValueEi @ 11767 NONAME - _ZN14QEglProperties14dumpAllConfigsEv @ 11768 NONAME - _ZN14QEglProperties14setPixelFormatEN6QImage6FormatE @ 11769 NONAME - _ZN14QEglProperties17setRenderableTypeEN4QEgl3APIE @ 11770 NONAME - _ZN14QEglProperties19reduceConfigurationEv @ 11771 NONAME - _ZN14QEglProperties20setPaintDeviceFormatEP12QPaintDevice @ 11772 NONAME - _ZN14QEglProperties8setValueEii @ 11773 NONAME - _ZN14QEglPropertiesC1Ei @ 11774 NONAME - _ZN14QEglPropertiesC1Ev @ 11775 NONAME - _ZN14QEglPropertiesC2Ei @ 11776 NONAME - _ZN14QEglPropertiesC2Ev @ 11777 NONAME - _ZNK11QEglContext12configAttribEiPi @ 11778 NONAME - _ZNK11QEglContext16configPropertiesEi @ 11779 NONAME - _ZNK11QEglContext7isValidEv @ 11780 NONAME - _ZNK11QEglContext9isCurrentEv @ 11781 NONAME - _ZNK14QEglProperties5valueEi @ 11782 NONAME - _ZNK14QEglProperties8toStringEv @ 11783 NONAME + _ZN11QEglContext10extensionsEv @ 11743 NONAME ABSENT + _ZN11QEglContext10getDisplayEP12QPaintDevice @ 11744 NONAME ABSENT + _ZN11QEglContext10waitClientEv @ 11745 NONAME ABSENT + _ZN11QEglContext10waitNativeEv @ 11746 NONAME ABSENT + _ZN11QEglContext11doneCurrentEv @ 11747 NONAME ABSENT + _ZN11QEglContext11errorStringEi @ 11748 NONAME ABSENT + _ZN11QEglContext11makeCurrentEi @ 11749 NONAME ABSENT + _ZN11QEglContext11openDisplayEP12QPaintDevice @ 11750 NONAME ABSENT + _ZN11QEglContext11swapBuffersEi @ 11751 NONAME ABSENT + _ZN11QEglContext12chooseConfigERK14QEglPropertiesN4QEgl16PixelFormatMatchE @ 11752 NONAME ABSENT + _ZN11QEglContext12hasExtensionEPKc @ 11753 NONAME ABSENT + _ZN11QEglContext13createContextEPS_PK14QEglProperties @ 11754 NONAME ABSENT + _ZN11QEglContext13createSurfaceEP12QPaintDevicePK14QEglProperties @ 11755 NONAME ABSENT + _ZN11QEglContext14currentContextEN4QEgl3APIE @ 11756 NONAME ABSENT + _ZN11QEglContext14defaultDisplayEP12QPaintDevice @ 11757 NONAME ABSENT + _ZN11QEglContext14destroySurfaceEi @ 11758 NONAME ABSENT + _ZN11QEglContext14dumpAllConfigsEv @ 11759 NONAME ABSENT + _ZN11QEglContext15lazyDoneCurrentEv @ 11760 NONAME ABSENT + _ZN11QEglContext17setCurrentContextEN4QEgl3APIEPS_ @ 11761 NONAME ABSENT + _ZN11QEglContext7destroyEv @ 11762 NONAME ABSENT + _ZN11QEglContextC1Ev @ 11763 NONAME ABSENT + _ZN11QEglContextC2Ev @ 11764 NONAME ABSENT + _ZN11QEglContextD1Ev @ 11765 NONAME ABSENT + _ZN11QEglContextD2Ev @ 11766 NONAME ABSENT + _ZN14QEglProperties11removeValueEi @ 11767 NONAME ABSENT + _ZN14QEglProperties14dumpAllConfigsEv @ 11768 NONAME ABSENT + _ZN14QEglProperties14setPixelFormatEN6QImage6FormatE @ 11769 NONAME ABSENT + _ZN14QEglProperties17setRenderableTypeEN4QEgl3APIE @ 11770 NONAME ABSENT + _ZN14QEglProperties19reduceConfigurationEv @ 11771 NONAME ABSENT + _ZN14QEglProperties20setPaintDeviceFormatEP12QPaintDevice @ 11772 NONAME ABSENT + _ZN14QEglProperties8setValueEii @ 11773 NONAME ABSENT + _ZN14QEglPropertiesC1Ei @ 11774 NONAME ABSENT + _ZN14QEglPropertiesC1Ev @ 11775 NONAME ABSENT + _ZN14QEglPropertiesC2Ei @ 11776 NONAME ABSENT + _ZN14QEglPropertiesC2Ev @ 11777 NONAME ABSENT + _ZNK11QEglContext12configAttribEiPi @ 11778 NONAME ABSENT + _ZNK11QEglContext16configPropertiesEi @ 11779 NONAME ABSENT + _ZNK11QEglContext7isValidEv @ 11780 NONAME ABSENT + _ZNK11QEglContext9isCurrentEv @ 11781 NONAME ABSENT + _ZNK14QEglProperties5valueEi @ 11782 NONAME ABSENT + _ZNK14QEglProperties8toStringEv @ 11783 NONAME ABSENT + _ZNK11QFontEngine10glyphCacheEPvN21QFontEngineGlyphCache4TypeERK10QTransform @ 11784 NONAME + _ZNK20QGraphicsItemPrivate21effectiveBoundingRectERK6QRectF @ 11785 NONAME -- cgit v0.12 From 82ec0a6c26c683dedd20fb6dd3923dce98c3f7e3 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 15 Dec 2009 13:09:12 +1000 Subject: (ODBC) Fixes segfault when error string is larger than 256 chars. SqlServer can throw custom error messages (via RaiseError) that can be up to 8000 chars long. Fixed this with a pre-query as to the length of the error string, then allocating enough space to retrieve the whole error string at once. Task-number: QTBUG-6618 Reviewed-by: Derick Hawcroft --- src/sql/drivers/odbc/qsql_odbc.cpp | 23 +++++++++++++++++------ tests/auto/qsqlquery/tst_qsqlquery.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index e686873..fdf0c2c 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -172,28 +172,39 @@ static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode SQLSMALLINT msgLen = 0; SQLRETURN r = SQL_NO_DATA; SQLTCHAR state_[SQL_SQLSTATE_SIZE+1]; - SQLTCHAR description_[SQL_MAX_MESSAGE_LENGTH]; + QVarLengthArray description_(SQL_MAX_MESSAGE_LENGTH); QString result; int i = 1; description_[0] = 0; + r = SQLGetDiagRec(handleType, + handle, + i, + state_, + &nativeCode_, + 0, + NULL, + &msgLen); + if(r == SQL_NO_DATA) + return QString(); + description_.resize(msgLen+1); do { r = SQLGetDiagRec(handleType, handle, i, - (SQLTCHAR*)state_, + state_, &nativeCode_, - (SQLTCHAR*)description_, - SQL_MAX_MESSAGE_LENGTH, /* in bytes, not in characters */ + description_.data(), + description_.size(), &msgLen); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { if (nativeCode) *nativeCode = nativeCode_; QString tmpstore; #ifdef UNICODE - tmpstore = QString((const QChar*)description_, msgLen); + tmpstore = QString((const QChar*)description_.data(), msgLen); #else - tmpstore = QString::fromLocal8Bit((const char*)description_, msgLen); + tmpstore = QString::fromLocal8Bit((const char*)description_.data(), msgLen); #endif if(result != tmpstore) { if(!result.isEmpty()) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index a8908fd..2a55c32 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -201,6 +201,8 @@ private slots: void QTBUG_5251(); void QTBUG_6421_data() { generic_data("QOCI"); } void QTBUG_6421(); + void QTBUG_6618_data() { generic_data("QODBC"); } + void QTBUG_6618(); private: // returns all database connections @@ -2961,5 +2963,27 @@ void tst_QSqlQuery::QTBUG_6421() QCOMPARE(q.value(0).toString(), QLatin1String("\"COL3\"")); } +void tst_QSqlQuery::QTBUG_6618() +{ + QFETCH( QString, dbName ); + QSqlDatabase db = QSqlDatabase::database( dbName ); + CHECK_DATABASE( db ); + if (!tst_Databases::isSqlServer( db )) + QSKIP("SQL Server specific test", SkipSingle); + + QSqlQuery q(db); + q.exec( "drop procedure " + qTableName( "tst_raiseError" ) ); //non-fatal + QString errorString; + for (int i=0;i<110;i++) + errorString+="reallylong"; + errorString+=" error"; + QVERIFY_SQL( q, exec("create procedure " + qTableName( "tst_raiseError" ) + " as\n" + "begin\n" + " raiserror('" + errorString + "', 16, 1)\n" + "end\n" )); + q.exec( "{call " + qTableName( "tst_raiseError" ) + "}" ); + QVERIFY(q.lastError().text().contains(errorString)); +} + QTEST_MAIN( tst_QSqlQuery ) #include "tst_qsqlquery.moc" -- cgit v0.12 From 1a867a3c692e375565618532b8ca686dab7e7d5e Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Tue, 15 Dec 2009 18:54:43 +1000 Subject: def file maintenance. --- src/s60installs/bwins/QtCoreu.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 49c4361..fe752c8 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -2264,7 +2264,7 @@ EXPORTS ?isSequential@QIODevice@@UBE_NXZ @ 2263 NONAME ; bool QIODevice::isSequential(void) const ?isSequential@QIODevicePrivate@@QBE_NXZ @ 2264 NONAME ; bool QIODevicePrivate::isSequential(void) const ?isSequential@QProcess@@UBE_NXZ @ 2265 NONAME ; bool QProcess::isSequential(void) const - ?isSignalConnected@QObjectPrivate@@QBE_NH@Z @ 2266 NONAME ; bool QObjectPrivate::isSignalConnected(int) const + ?isSignalConnected@QObjectPrivate@@QBE_NI@Z @ 2266 NONAME ; bool QObjectPrivate::isSignalConnected(unsigned int) const ?isSimpleText@QString@@QBE_NXZ @ 2267 NONAME ; bool QString::isSimpleText(void) const ?isSingleShot@QTimer@@QBE_NXZ @ 2268 NONAME ; bool QTimer::isSingleShot(void) const ?isSpace@QChar@@QBE_NXZ @ 2269 NONAME ; bool QChar::isSpace(void) const -- cgit v0.12 From e8280d71c1a2f8822d775bbedaecfab42194c218 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Tue, 15 Dec 2009 20:23:17 +1000 Subject: def file maintenance. --- src/s60installs/bwins/QtGuiu.def | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 3371fe0..303c463 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -2503,7 +2503,7 @@ EXPORTS ?cacheMode@QMovie@@QAE?AW4CacheMode@1@XZ @ 2502 NONAME ; enum QMovie::CacheMode QMovie::cacheMode(void) ?cacheMode@QMovie@@QBE?AW4CacheMode@1@XZ @ 2503 NONAME ; enum QMovie::CacheMode QMovie::cacheMode(void) const ?cacheStatistics@QFont@@SAXXZ @ 2504 NONAME ; void QFont::cacheStatistics(void) - ?cacheType@QTextureGlyphCache@@QBE?AW4Type@QFontEngineGlyphCache@@XZ @ 2505 NONAME ; enum QFontEngineGlyphCache::Type QTextureGlyphCache::cacheType(void) const + ?cacheType@QTextureGlyphCache@@QBE?AW4Type@QFontEngineGlyphCache@@XZ @ 2505 NONAME ABSENT ; enum QFontEngineGlyphCache::Type QTextureGlyphCache::cacheType(void) const ?calcEffectiveOpacity@QGraphicsItemPrivate@@QBEMXZ @ 2506 NONAME ; float QGraphicsItemPrivate::calcEffectiveOpacity(void) const ?calculateTabWidth@QTextEngine@@QBE?AUQFixed@@HU2@@Z @ 2507 NONAME ; struct QFixed QTextEngine::calculateTabWidth(int, struct QFixed) const ?calendarPopup@QDateTimeEdit@@QBE_NXZ @ 2508 NONAME ; bool QDateTimeEdit::calendarPopup(void) const @@ -4299,7 +4299,7 @@ EXPORTS ?expandingDirections@QSpacerItem@@UBE?AV?$QFlags@W4Orientation@Qt@@@@XZ @ 4298 NONAME ; class QFlags QSpacerItem::expandingDirections(void) const ?expandingDirections@QWidgetItem@@UBE?AV?$QFlags@W4Orientation@Qt@@@@XZ @ 4299 NONAME ; class QFlags QWidgetItem::expandingDirections(void) const ?expandsOnDoubleClick@QTreeView@@QBE_NXZ @ 4300 NONAME ; bool QTreeView::expandsOnDoubleClick(void) const - ?expireGlyphCache@QFontEngine@@AAEXXZ @ 4301 NONAME ; void QFontEngine::expireGlyphCache(void) + ?expireGlyphCache@QFontEngine@@AAEXXZ @ 4301 NONAME ABSENT ; void QFontEngine::expireGlyphCache(void) ?extension@QDialog@@QBEPAVQWidget@@XZ @ 4302 NONAME ; class QWidget * QDialog::extension(void) const ?extension@QGraphicsEllipseItem@@MBE?AVQVariant@@ABV2@@Z @ 4303 NONAME ; class QVariant QGraphicsEllipseItem::extension(class QVariant const &) const ?extension@QGraphicsItem@@MBE?AVQVariant@@ABV2@@Z @ 4304 NONAME ; class QVariant QGraphicsItem::extension(class QVariant const &) const @@ -4933,8 +4933,8 @@ EXPORTS ?globalY@QMouseEvent@@QBEHXZ @ 4932 NONAME ; int QMouseEvent::globalY(void) const ?globalY@QTabletEvent@@QBEHXZ @ 4933 NONAME ; int QTabletEvent::globalY(void) const ?globalY@QWheelEvent@@QBEHXZ @ 4934 NONAME ; int QWheelEvent::globalY(void) const - ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXABVQTransform@@@Z @ 4935 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, class QTransform const &) const - ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@W4Type@2@ABVQTransform@@@Z @ 4936 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(enum QFontEngineGlyphCache::Type, class QTransform const &) const + ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXABVQTransform@@@Z @ 4935 NONAME ABSENT ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, class QTransform const &) const + ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@W4Type@2@ABVQTransform@@@Z @ 4936 NONAME ABSENT ; class QFontEngineGlyphCache * QFontEngine::glyphCache(enum QFontEngineGlyphCache::Type, class QTransform const &) const ?glyphCount@QFontEngine@@UBEHXZ @ 4937 NONAME ; int QFontEngine::glyphCount(void) const ?glyphMargin@QTextureGlyphCache@@UBEHXZ @ 4938 NONAME ; int QTextureGlyphCache::glyphMargin(void) const ?gotFocus@QFocusEvent@@QBE_NXZ @ 4939 NONAME ; bool QFocusEvent::gotFocus(void) const @@ -9103,7 +9103,7 @@ EXPORTS ?setGestureCancelPolicy@QGesture@@QAEXW4GestureCancelPolicy@1@@Z @ 9102 NONAME ; void QGesture::setGestureCancelPolicy(enum QGesture::GestureCancelPolicy) ?setGlobalStrut@QApplication@@SAXABVQSize@@@Z @ 9103 NONAME ; void QApplication::setGlobalStrut(class QSize const &) ?setGlyphCache@QFontEngine@@QAEXPAXPAVQFontEngineGlyphCache@@@Z @ 9104 NONAME ; void QFontEngine::setGlyphCache(void *, class QFontEngineGlyphCache *) - ?setGlyphCache@QFontEngine@@QAEXW4Type@QFontEngineGlyphCache@@PAV3@@Z @ 9105 NONAME ; void QFontEngine::setGlyphCache(enum QFontEngineGlyphCache::Type, class QFontEngineGlyphCache *) + ?setGlyphCache@QFontEngine@@QAEXW4Type@QFontEngineGlyphCache@@PAV3@@Z @ 9105 NONAME ABSENT ; void QFontEngine::setGlyphCache(enum QFontEngineGlyphCache::Type, class QFontEngineGlyphCache *) ?setGraphicsEffect@QGraphicsItem@@QAEXPAVQGraphicsEffect@@@Z @ 9106 NONAME ; void QGraphicsItem::setGraphicsEffect(class QGraphicsEffect *) ?setGraphicsEffect@QWidget@@QAEXPAVQGraphicsEffect@@@Z @ 9107 NONAME ; void QWidget::setGraphicsEffect(class QGraphicsEffect *) ?setGraphicsEffectSource@QGraphicsEffectPrivate@@QAEXPAVQGraphicsEffectSource@@@Z @ 9108 NONAME ; void QGraphicsEffectPrivate::setGraphicsEffectSource(class QGraphicsEffectSource *) -- cgit v0.12 From 0b402f10a26115332ae72bbf263fd15c8354ecb9 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 15 Dec 2009 13:19:22 +0100 Subject: Fix precision loss warning (qreal vs. float on Windows) Reviewed-by: Oswald Buddenhagen modified: tools/linguist/linguist/messageeditor.h --- tools/linguist/linguist/messageeditor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linguist/linguist/messageeditor.h b/tools/linguist/linguist/messageeditor.h index b69af9c..d73c216 100644 --- a/tools/linguist/linguist/messageeditor.h +++ b/tools/linguist/linguist/messageeditor.h @@ -67,7 +67,7 @@ struct MessageEditorData { QList transTexts; QString invariantForm; QString firstForm; - float fontSize; + qreal fontSize; bool pluralEditMode; }; -- cgit v0.12