From 8c10e0b73c312a6c1aacce11cc8d6f57dc94a09d Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 24 Mar 2010 14:57:11 +0100 Subject: Auto test for commit 4a4458d1cf5ec7885c6f63f739b7ee80c70ad211 Reviewed-by: Trust me Task-number: QTBUG-9216 --- tests/auto/qtreeview/tst_qtreeview.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index bdc0a0c..da99368 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -237,6 +237,7 @@ private slots: void task245654_changeModelAndExpandAll(); void doubleClickedWithSpans(); void taskQTBUG_6450_selectAllWith1stColumnHidden(); + void taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint(); }; class QtTestModel: public QAbstractItemModel @@ -3714,5 +3715,34 @@ void tst_QTreeView::taskQTBUG_6450_selectAllWith1stColumnHidden() QVERIFY(tree.selectionModel()->isRowSelected(i, QModelIndex())); } +class TreeViewQTBUG_9216 : public QTreeView +{ + Q_OBJECT +public: + void paintEvent(QPaintEvent *event) + { + QCOMPARE(event->rect(), viewport()->rect()); + QTreeView::paintEvent(event); + } +}; + +void tst_QTreeView::taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint() +{ + QStandardItemModel model(10, 10, this); + for (int row = 0; row < 10; row++) + for (int col = 0; col < 10; col++) + model.setItem(row, col, new QStandardItem(QString("row %0, col %1").arg(row).arg(col))); + TreeViewQTBUG_9216 view; + view.setUniformRowHeights(true); + view.setModel(&model); + view.resize(800, 800); + view.show(); + QTest::qWaitForWindowShown(&view); + + QTest::qWait(100); // This one is needed to make the test fail before the patch. + model.setData(model.index(0, 5), QVariant(QSize(100,100)), Qt::SizeHintRole); + QTest::qWait(100); +} + QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v0.12 From 6d0002fe9bc91b9901e56050d247fbded09c9c76 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 24 Mar 2010 14:51:13 +0100 Subject: Add QFont::ForceIntegerMetrics style strategy flag WebKit uses integers internally to deal with positioning and sizing of text objects, but on Mac, Qt uses floating point values. This caused a discrepancy between the size used by WebKit to position text objects and the actual size of the objects when rendered by Qt. The problem was so bad that it has been holding back fixes for other bugs in the mac font engine since these would make the WebKit bug more visible. To work around the problem, we introduce a StyleStrategy flag in QFont which allows you to force the use of integers all over the line. This makes text rendering slightly different from native applications, but should fix several issues with WebKit on Mac. The WebKit-part of this patch will be submitted up-stream. Reviewed-by: Simon Hausmann Reviewed-by: Prasanth --- src/gui/text/qfont.cpp | 2 ++ src/gui/text/qfont.h | 23 ++++++++++--------- src/gui/text/qfontengine_mac.mm | 49 ++++++++++++++++++++++++++++++++--------- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 9b85c04..99b9f40 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1297,6 +1297,8 @@ QFont::StyleHint QFont::styleHint() const \value PreferQuality prefer the best quality font. The font matcher will use the nearest standard point size that the font supports. + \value ForceIntegerMetrics forces the use of integer values in font engines that support fractional + font metrics. */ /*! diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index 5adf237..6f62424 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -76,17 +76,18 @@ public: }; enum StyleStrategy { - PreferDefault = 0x0001, - PreferBitmap = 0x0002, - PreferDevice = 0x0004, - PreferOutline = 0x0008, - ForceOutline = 0x0010, - PreferMatch = 0x0020, - PreferQuality = 0x0040, - PreferAntialias = 0x0080, - NoAntialias = 0x0100, - OpenGLCompatible = 0x0200, - NoFontMerging = 0x8000 + PreferDefault = 0x0001, + PreferBitmap = 0x0002, + PreferDevice = 0x0004, + PreferOutline = 0x0008, + ForceOutline = 0x0010, + PreferMatch = 0x0020, + PreferQuality = 0x0040, + PreferAntialias = 0x0080, + NoAntialias = 0x0100, + OpenGLCompatible = 0x0200, + ForceIntegerMetrics = 0x0400, + NoFontMerging = 0x8000 }; enum Weight { diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 8588214..fd662e3 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -303,12 +303,20 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay outGlyphs[idx] = tmpGlyphs[i] | fontIndex; outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x); outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + outAdvances_x[idx] = outAdvances_x[idx].ceil(); + outAdvances_y[idx] = outAdvances_y[idx].ceil(); + } } CGSize lastGlyphAdvance; CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1); outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; - outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width); + outAdvances_x[rtl ? 0 : (glyphCount - 1)] = + (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(lastGlyphAdvance.width).ceil() + : QFixed::fromReal(lastGlyphAdvance.width); } outGlyphs += glyphCount; outAttributes += glyphCount; @@ -378,8 +386,11 @@ bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int * glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) { QFixed w; - for (int i = 0; i < glyphs.numGlyphs; ++i) - w += glyphs.effectiveAdvance(i); + for (int i = 0; i < glyphs.numGlyphs; ++i) { + w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? glyphs.effectiveAdvance(i).ceil() + : glyphs.effectiveAdvance(i); + } return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0); } glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) @@ -393,33 +404,51 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) ret.y = -QFixed::fromReal(rect.origin.y) - ret.height; CGSize advances[1]; CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1); - ret.xoff = QFixed::fromReal(advances[0].width).ceil(); - ret.yoff = QFixed::fromReal(advances[0].height).ceil(); + ret.xoff = QFixed::fromReal(advances[0].width); + ret.yoff = QFixed::fromReal(advances[0].height); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + ret.xoff = ret.xoff.ceil(); + ret.yoff = ret.yoff.ceil(); + } + return ret; } QFixed QCoreTextFontEngine::ascent() const { - return QFixed::fromReal(CTFontGetAscent(ctfont)).ceil(); + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetAscent(ctfont)).ceil() + : QFixed::fromReal(CTFontGetAscent(ctfont)); } QFixed QCoreTextFontEngine::descent() const { + QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont)); + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + d = d.ceil(); + // subtract a pixel to even out the historical +1 in QFontMetrics::height(). // Fix in Qt 5. - return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1; + return d - 1; } QFixed QCoreTextFontEngine::leading() const { - return QFixed::fromReal(CTFontGetLeading(ctfont)).ceil(); + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetLeading(ctfont)).ceil() + : QFixed::fromReal(CTFontGetLeading(ctfont)); } QFixed QCoreTextFontEngine::xHeight() const { - return QFixed::fromReal(CTFontGetXHeight(ctfont)).ceil(); + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetXHeight(ctfont)).ceil() + : QFixed::fromReal(CTFontGetXHeight(ctfont)); } QFixed QCoreTextFontEngine::averageCharWidth() const { // ### Need to implement properly and get the information from the OS/2 Table. - return QFontEngine::averageCharWidth(); + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFontEngine::averageCharWidth().ceil() + : QFontEngine::averageCharWidth(); } qreal QCoreTextFontEngine::maxCharWidth() const -- cgit v0.12 From 490cd29001670b37204dcf5e24398073f610fabd Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 25 Mar 2010 13:50:08 +1000 Subject: Update Phonon core to 4.4.0 --- src/3rdparty/phonon/phonon/CMakeLists.txt | 35 ++ src/3rdparty/phonon/phonon/audiooutput.cpp | 106 +++++- src/3rdparty/phonon/phonon/audiooutput.h | 1 + src/3rdparty/phonon/phonon/audiooutput_p.h | 8 +- src/3rdparty/phonon/phonon/audiooutputinterface.h | 2 +- src/3rdparty/phonon/phonon/backendcapabilities.cpp | 2 +- src/3rdparty/phonon/phonon/factory.cpp | 25 +- src/3rdparty/phonon/phonon/factory_p.h | 7 + src/3rdparty/phonon/phonon/globalconfig.cpp | 358 ++++++++++++++++----- src/3rdparty/phonon/phonon/globalconfig_p.h | 31 +- src/3rdparty/phonon/phonon/mediaobject.cpp | 12 +- src/3rdparty/phonon/phonon/objectdescription.cpp | 44 ++- .../phonon/phonon/objectdescriptionmodel.cpp | 2 + .../phonon/phonon/objectdescriptionmodel.h | 36 +-- src/3rdparty/phonon/phonon/path.cpp | 8 +- src/3rdparty/phonon/phonon/phonondefs.h | 5 + src/3rdparty/phonon/phonon/seekslider.cpp | 4 +- src/3rdparty/phonon/phonon/seekslider_p.h | 4 +- src/3rdparty/phonon/phonon/videowidget.cpp | 16 +- src/3rdparty/phonon/phonon/videowidget.h | 1 + src/3rdparty/phonon/phonon/videowidgetinterface.h | 13 + src/3rdparty/phonon/phonon/volumeslider_p.h | 4 +- src/phonon/phonon.pro | 64 ++-- 23 files changed, 571 insertions(+), 217 deletions(-) diff --git a/src/3rdparty/phonon/phonon/CMakeLists.txt b/src/3rdparty/phonon/phonon/CMakeLists.txt index 11d7913..ace934a 100644 --- a/src/3rdparty/phonon/phonon/CMakeLists.txt +++ b/src/3rdparty/phonon/phonon/CMakeLists.txt @@ -8,6 +8,30 @@ endif (PHONON_BUILD_EXAMPLES) add_subdirectory(experimental) +set(PULSEAUDIO_MINIMUM_VERSION "0.9.15") +macro_optional_find_package(PulseAudio) +if (PULSEAUDIO_FOUND) + # PULSEAUDIO_DEVICE_MANAGER feature check could be moved to FindPulseAudio.cmake, hint hint. -- Rex + macro_ensure_version("0.9.21" "${PULSEAUDIO_VERSION}" PULSEAUDIO_DEVICE_MANAGER) +endif (PULSEAUDIO_FOUND) +macro_log_feature(PULSEAUDIO_FOUND "PulseAudio" "A cross-platform, networked sound server." "http://www.pulseaudio.org" FALSE "" "Allows audio playback via the PulseAudio soundserver when it is running") +macro_optional_find_package(GLIB2) +macro_log_feature(GLIB2_FOUND "GLib2" "GLib 2 is required to compile the pulseaudio for Phonon" "http://www.gtk.org/download/" FALSE) + + +if (GLIB2_FOUND AND PULSEAUDIO_FOUND) + add_definitions(-DHAVE_PULSEAUDIO) + include_directories(${GLIB2_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR}) + if (PULSEAUDIO_DEVICE_MANAGER) + add_definitions(-DHAVE_PULSEAUDIO_DEVICE_MANAGER) + endif(PULSEAUDIO_DEVICE_MANAGER) +else(GLIB2_FOUND AND PULSEAUDIO_FOUND) + set(PULSEAUDIO_INCLUDE_DIR "") + set(PULSEAUDIO_LIBRARY "") + set(PULSEAUDIO_MAINLOOP_LIBRARY "") +endif(GLIB2_FOUND AND PULSEAUDIO_FOUND) + + set(phonon_LIB_SRCS objectdescription.cpp objectdescriptionmodel.cpp @@ -35,9 +59,12 @@ set(phonon_LIB_SRCS videowidget.cpp videoplayer.cpp seekslider.cpp + swiftslider.cpp volumeslider.cpp effectwidget.cpp iodevicestream.cpp + audiodataoutput.cpp + pulsesupport.cpp ) if (QT_QTDBUS_FOUND) @@ -50,6 +77,10 @@ endif (QT_QTDBUS_FOUND) add_definitions(-DPHONON_LIBRARY_PATH="${PLUGIN_INSTALL_DIR}/plugins") automoc4_add_library(phonon SHARED ${phonon_LIB_SRCS}) target_link_libraries(phonon ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY}) +if (GLIB2_FOUND AND PULSEAUDIO_FOUND) +target_link_libraries(phonon ${GLIB2_LIBRARIES} ${GOBJECT_LIBRARIES} ${PULSEAUDIO_LIBRARY} ${PULSEAUDIO_MAINLOOP_LIBRARY}) +endif (GLIB2_FOUND AND PULSEAUDIO_FOUND) + if (QT_QTDBUS_FOUND) target_link_libraries(phonon ${QT_QTDBUS_LIBRARY}) endif (QT_QTDBUS_FOUND) @@ -99,6 +130,10 @@ install(FILES volumeslider.h effectwidget.h platformplugin.h + audiodataoutput.h + audiodataoutputinterface.h + globalconfig.h + pulsesupport.h DESTINATION ${INCLUDE_INSTALL_DIR}/phonon COMPONENT Devel) install(FILES org.kde.Phonon.AudioOutput.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}) diff --git a/src/3rdparty/phonon/phonon/audiooutput.cpp b/src/3rdparty/phonon/phonon/audiooutput.cpp index 0f6a49b..932a875 100644 --- a/src/3rdparty/phonon/phonon/audiooutput.cpp +++ b/src/3rdparty/phonon/phonon/audiooutput.cpp @@ -24,10 +24,11 @@ #include "factory_p.h" #include "objectdescription.h" #include "audiooutputadaptor_p.h" -#include "globalconfig_p.h" +#include "globalconfig.h" #include "audiooutputinterface.h" #include "phononnamespace_p.h" #include "platform_p.h" +#include "pulsesupport.h" #include @@ -42,8 +43,12 @@ QT_BEGIN_NAMESPACE namespace Phonon { -static inline bool callSetOutputDevice(MediaNodePrivate *const d, int index) +static inline bool callSetOutputDevice(AudioOutputPrivate *const d, int index) { + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) + return pulse->setOutputDevice(d->getStreamUuid(), index); + Iface iface(d); if (iface) { return iface->setOutputDevice(AudioOutputDevice::fromIndex(index)); @@ -51,8 +56,12 @@ static inline bool callSetOutputDevice(MediaNodePrivate *const d, int index) return Iface::cast(d)->setOutputDevice(index); } -static inline bool callSetOutputDevice(MediaNodePrivate *const d, const AudioOutputDevice &dev) +static inline bool callSetOutputDevice(AudioOutputPrivate *const d, const AudioOutputDevice &dev) { + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) + return pulse->setOutputDevice(d->getStreamUuid(), dev.index()); + Iface iface(d); if (iface) { return iface->setOutputDevice(dev); @@ -89,16 +98,20 @@ void AudioOutputPrivate::init(Phonon::Category c) #endif category = c; - - // select hardware device according to the category - device = AudioOutputDevice::fromIndex(GlobalConfig().audioOutputDeviceFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices)); + streamUuid = QUuid::createUuid().toString(); + PulseSupport *pulse = PulseSupport::getInstance(); + pulse->setStreamPropList(category, streamUuid); + q->connect(pulse, SIGNAL(usingDevice(QString,int)), SLOT(_k_deviceChanged(QString,int))); createBackendObject(); q->connect(Factory::sender(), SIGNAL(availableAudioOutputDevicesChanged()), SLOT(_k_deviceListChanged())); } - +QString AudioOutputPrivate::getStreamUuid() +{ + return streamUuid; +} void AudioOutputPrivate::createBackendObject() { @@ -106,6 +119,7 @@ void AudioOutputPrivate::createBackendObject() return; Q_Q(AudioOutput); m_backendObject = Factory::createAudioOutput(q); + device = AudioOutputDevice::fromIndex(GlobalConfig().audioOutputDeviceFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices)); if (m_backendObject) { setupBackendObject(); } @@ -220,21 +234,21 @@ bool AudioOutput::setOutputDevice(const AudioOutputDevice &newAudioOutputDevice) { K_D(AudioOutput); if (!newAudioOutputDevice.isValid()) { - d->outputDeviceOverridden = false; + d->outputDeviceOverridden = d->forceMove = false; const int newIndex = GlobalConfig().audioOutputDeviceFor(d->category); if (newIndex == d->device.index()) { return true; } d->device = AudioOutputDevice::fromIndex(newIndex); } else { - d->outputDeviceOverridden = true; + d->outputDeviceOverridden = d->forceMove = true; if (d->device == newAudioOutputDevice) { return true; } d->device = newAudioOutputDevice; } if (k_ptr->backendObject()) { - return callSetOutputDevice(k_ptr, d->device.index()); + return callSetOutputDevice(d, d->device.index()); } return true; } @@ -261,7 +275,10 @@ void AudioOutputPrivate::setupBackendObject() #ifndef QT_NO_PHONON_SETTINGSGROUP // if the output device is not available and the device was not explicitly set - if (!callSetOutputDevice(this, device) && !outputDeviceOverridden) { + // There is no need to set the output device initially if PA is used as + // we know it will not work (stream doesn't exist yet) and that this will be + // handled by _k_deviceChanged() + if (!PulseSupport::getInstance()->isActive() && !callSetOutputDevice(this, device) && !outputDeviceOverridden) { // fall back in the preference list of output devices QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); if (deviceList.isEmpty()) { @@ -306,10 +323,14 @@ void AudioOutputPrivate::_k_revertFallback() void AudioOutputPrivate::_k_audioDeviceFailed() { + if (PulseSupport::getInstance()->isActive()) + return; + +#ifndef QT_NO_PHONON_SETTINGSGROUP + pDebug() << Q_FUNC_INFO; // outputDeviceIndex identifies a failing device // fall back in the preference list of output devices -#ifndef QT_NO_PHONON_SETTINGSGROUP const QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); for (int i = 0; i < deviceList.count(); ++i) { const int devIndex = deviceList.at(i); @@ -331,8 +352,15 @@ void AudioOutputPrivate::_k_audioDeviceFailed() void AudioOutputPrivate::_k_deviceListChanged() { - pDebug() << Q_FUNC_INFO; + if (PulseSupport::getInstance()->isActive()) + return; + #ifndef QT_NO_PHONON_SETTINGSGROUP + pDebug() << Q_FUNC_INFO; + // Check to see if we have an override and do not change to a higher priority device if the overridden device is still present. + if (outputDeviceOverridden && device.property("available").toBool()) { + return; + } // let's see if there's a usable device higher in the preference list const QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings); DeviceChangeType changeType = HigherPreferenceChange; @@ -361,6 +389,36 @@ void AudioOutputPrivate::_k_deviceListChanged() #endif //QT_NO_PHONON_SETTINGSGROUP } +void AudioOutputPrivate::_k_deviceChanged(QString inStreamUuid, int deviceIndex) +{ + // Note that this method is only used by PulseAudio at present. + if (inStreamUuid == streamUuid) { + // 1. Check to see if we are overridden. If we are, and devices do not match, + // then try and apply our own device as the output device. + // We only do this the first time + if (outputDeviceOverridden && forceMove) { + forceMove = false; + const AudioOutputDevice ¤tDevice = AudioOutputDevice::fromIndex(deviceIndex); + if (currentDevice != device) { + if (!callSetOutputDevice(this, device)) { + // What to do if we are overridden and cannot change to our preferred device? + } + } + } + // 2. If we are not overridden, then we need to update our perception of what + // device we are using. If the devices do not match, something lower in the + // stack is overriding our preferences (e.g. a per-application stream preference, + // specific application move, priority list changed etc. etc.) + else if (!outputDeviceOverridden) { + const AudioOutputDevice ¤tDevice = AudioOutputDevice::fromIndex(deviceIndex); + if (currentDevice != device) { + // The device is not what we think it is, so lets say what is happening. + handleAutomaticDeviceChange(currentDevice, SoundSystemChange); + } + } + } +} + static struct { int first; @@ -405,11 +463,33 @@ void AudioOutputPrivate::handleAutomaticDeviceChange(const AudioOutputDevice &de g_lastFallback.second = 0; } break; + case SoundSystemChange: + { +#ifndef QT_NO_PHONON_PLATFORMPLUGIN + if (device1.property("available").toBool()) { + const QString text = AudioOutput::tr("Switching to the audio playback device %1
" + "which has higher preference or is specifically configured for this stream.").arg(device2.name()); + Platform::notification("AudioDeviceFallback", text, + QStringList(AudioOutput::tr("Revert back to device '%1'").arg(device1.name())), + q, SLOT(_k_revertFallback())); + } else { + const QString &text = + AudioOutput::tr("The audio playback device %1 does not work.
" + "Falling back to %2.").arg(device1.name()).arg(device2.name()); + Platform::notification("AudioDeviceFallback", text); + } +#endif //QT_NO_PHONON_PLATFORMPLUGIN + //outputDeviceOverridden = true; + g_lastFallback.first = 0; + g_lastFallback.second = 0; + } + break; } } AudioOutputPrivate::~AudioOutputPrivate() { + PulseSupport::getInstance()->clearStreamCache(streamUuid); #ifndef QT_NO_DBUS if (adaptor) { emit adaptor->outputDestroyed(); diff --git a/src/3rdparty/phonon/phonon/audiooutput.h b/src/3rdparty/phonon/phonon/audiooutput.h index 4edf135..513a863 100644 --- a/src/3rdparty/phonon/phonon/audiooutput.h +++ b/src/3rdparty/phonon/phonon/audiooutput.h @@ -169,6 +169,7 @@ namespace Phonon Q_PRIVATE_SLOT(k_func(), void _k_revertFallback()) Q_PRIVATE_SLOT(k_func(), void _k_audioDeviceFailed()) Q_PRIVATE_SLOT(k_func(), void _k_deviceListChanged()) + Q_PRIVATE_SLOT(k_func(), void _k_deviceChanged(QString streamUuid, int device)) }; } //namespace Phonon diff --git a/src/3rdparty/phonon/phonon/audiooutput_p.h b/src/3rdparty/phonon/phonon/audiooutput_p.h index fdee299..01dc48f 100644 --- a/src/3rdparty/phonon/phonon/audiooutput_p.h +++ b/src/3rdparty/phonon/phonon/audiooutput_p.h @@ -46,6 +46,7 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate return 0; } void init(Phonon::Category c); + QString getStreamUuid(); protected: @@ -58,6 +59,7 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate #endif deviceBeforeFallback(-1), outputDeviceOverridden(false), + forceMove(false), muted(false) { } @@ -66,7 +68,8 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate enum DeviceChangeType { FallbackChange, - HigherPreferenceChange + HigherPreferenceChange, + SoundSystemChange }; void handleAutomaticDeviceChange(const AudioOutputDevice &newDev, DeviceChangeType type); @@ -74,17 +77,20 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate void _k_revertFallback(); void _k_audioDeviceFailed(); void _k_deviceListChanged(); + void _k_deviceChanged(QString streamUuid, int deviceIndex); private: QString name; Phonon::AudioOutputDevice device; qreal volume; + QString streamUuid; #ifndef QT_NO_DBUS Phonon::AudioOutputAdaptor *adaptor; #endif Category category; int deviceBeforeFallback; bool outputDeviceOverridden; + bool forceMove; bool muted; }; } //namespace Phonon diff --git a/src/3rdparty/phonon/phonon/audiooutputinterface.h b/src/3rdparty/phonon/phonon/audiooutputinterface.h index 80ba11c..cce12b2 100644 --- a/src/3rdparty/phonon/phonon/audiooutputinterface.h +++ b/src/3rdparty/phonon/phonon/audiooutputinterface.h @@ -64,7 +64,7 @@ class AudioOutputInterface40 * A value of 0.0 means muted, 1.0 means unchanged, 2.0 means double voltage (i.e. all * samples are multiplied by 2). * - * Everytime the volume in the backend changes it should emit volumeChanged(qreal), also + * Every time the volume in the backend changes it should emit volumeChanged(qreal), also * inside this function. */ virtual void setVolume(qreal) = 0; diff --git a/src/3rdparty/phonon/phonon/backendcapabilities.cpp b/src/3rdparty/phonon/phonon/backendcapabilities.cpp index fbeb020..8dad589 100644 --- a/src/3rdparty/phonon/phonon/backendcapabilities.cpp +++ b/src/3rdparty/phonon/phonon/backendcapabilities.cpp @@ -26,7 +26,7 @@ #include "phonondefs_p.h" #include "backendinterface.h" #include "factory_p.h" -#include "globalconfig_p.h" +#include "globalconfig.h" #include "globalstatic_p.h" #include "objectdescription.h" diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp index 9967c971..24be0f3 100644 --- a/src/3rdparty/phonon/phonon/factory.cpp +++ b/src/3rdparty/phonon/phonon/factory.cpp @@ -134,30 +134,24 @@ bool FactoryPrivate::createBackend() continue; } - QStringList plugins(dir.entryList(QDir::Files)); + QStringList plugins(dir.entryList(QDir::Files)); #ifdef Q_OS_SYMBIAN /* On Symbian OS we might have two plugins, one which uses Symbian - * MMF framework("phonon_mmf"), and one which uses Real Networks's + * MMF framework("mmf"), and one which uses Real Networks's * Helix("hxphonon"). We prefer the latter because it's more * sophisticated, so we make sure the Helix backend is attempted * to be loaded first, and the MMF backend is used for backup. */ { - - const int hxphonon = plugins.indexOf(QLatin1String("hxphonon")); - if (hxphonon != -1) - plugins.move(hxphonon, 0); - - // Code for debugging the MMF backend. - if(hxphonon != -1) { - qDebug() << "Found hxphonon backend and removed it from the lookup list."; - plugins.removeAll(QLatin1String("hxphonon")); - } + const int helix = plugins.indexof(QLatin1String("hxphonon")); + if (helix != -1) + plugins.move(helix, 0); } #endif - for (int i = 0; i < plugins.count(); ++i) { - QPluginLoader pluginLoader(libPath + plugins.at(i)); + const QStringList files = dir.entryList(QDir::Files); + for (int i = 0; i < files.count(); ++i) { + QPluginLoader pluginLoader(libPath + files.at(i)); if (!pluginLoader.load()) { pDebug() << Q_FUNC_INFO << " load failed:" << pluginLoader.errorString(); @@ -350,6 +344,7 @@ FACTORY_IMPL(AudioOutput) #ifndef QT_NO_PHONON_VIDEO FACTORY_IMPL(VideoWidget) #endif //QT_NO_PHONON_VIDEO +FACTORY_IMPL(AudioDataOutput) #undef FACTORY_IMPL @@ -469,7 +464,7 @@ GET_STRING_PROPERTY(backendWebsite) QObject *Factory::registerQObject(QObject *o) { if (o) { - QObject::connect(o, SIGNAL(destroyed(QObject*)), globalFactory, SLOT(objectDestroyed(QObject*)), Qt::DirectConnection); + QObject::connect(o, SIGNAL(destroyed(QObject *)), globalFactory, SLOT(objectDestroyed(QObject *)), Qt::DirectConnection); globalFactory->objects.append(o); } return o; diff --git a/src/3rdparty/phonon/phonon/factory_p.h b/src/3rdparty/phonon/phonon/factory_p.h index dee2b56..41b8c5b 100644 --- a/src/3rdparty/phonon/phonon/factory_p.h +++ b/src/3rdparty/phonon/phonon/factory_p.h @@ -122,6 +122,13 @@ namespace Factory #endif //QT_NO_PHONON_VIDEO /** + * Create a new backend object for a AudioDataOutput. + * + * \return a pointer to the AudioDataOutput the backend provides. + */ + PHONON_EXPORT QObject *createAudioDataOutput(QObject *parent = 0); + + /** * \return a pointer to the backend interface. */ PHONON_EXPORT QObject *backend(bool createWhenNull = true); diff --git a/src/3rdparty/phonon/phonon/globalconfig.cpp b/src/3rdparty/phonon/phonon/globalconfig.cpp index 3b77a18..be751ce 100644 --- a/src/3rdparty/phonon/phonon/globalconfig.cpp +++ b/src/3rdparty/phonon/phonon/globalconfig.cpp @@ -20,6 +20,7 @@ */ +#include "globalconfig.h" #include "globalconfig_p.h" #include "factory_p.h" @@ -29,6 +30,7 @@ #include "backendinterface.h" #include "qsettingsgroup_p.h" #include "phononnamespace_p.h" +#include "pulsesupport.h" #include #include @@ -38,15 +40,18 @@ QT_BEGIN_NAMESPACE namespace Phonon { +GlobalConfigPrivate::GlobalConfigPrivate() : config(QLatin1String("kde.org"), QLatin1String("libphonon")) +{ +} + GlobalConfig::GlobalConfig() -#ifndef QT_NO_SETTINGS - : m_config(QLatin1String("kde.org"), QLatin1String("libphonon")) -#endif //QT_NO_SETTINGS + : k_ptr(new GlobalConfigPrivate) { } GlobalConfig::~GlobalConfig() { + delete k_ptr; } enum WhatToFilter { @@ -59,7 +64,11 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q { QMutableListIterator it(*list); while (it.hasNext()) { - const QHash properties = backendIface->objectDescriptionProperties(type, it.next()); + QHash properties; + if (backendIface) + properties = backendIface->objectDescriptionProperties(type, it.next()); + else + properties = PulseSupport::getInstance()->objectDescriptionProperties(type, it.next()); QVariant var; if (whatToFilter & FilterAdvancedDevices) { var = properties.value("isAdvanced"); @@ -73,6 +82,7 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q if (var.isValid() && var.toBool()) { it.remove(); continue; +#ifndef QT_NO_PHONON_SETTINGSGROUP } } if (whatToFilter & FilterUnavailableDevices) { @@ -85,9 +95,12 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q } } -#ifndef QT_NO_PHONON_SETTINGSGROUP -static QList listSortedByConfig(const QSettingsGroup &backendConfig, Phonon::Category category, QList &defaultList) +static QList sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, Phonon::Category category, QList &defaultList) { + Q_ASSERT(config); + Q_ASSERT(backendConfig); + Q_ASSERT(type == AudioOutputDeviceType || type == AudioCaptureDeviceType); + if (defaultList.size() <= 1) { // nothing to sort return defaultList; @@ -104,20 +117,26 @@ static QList listSortedByConfig(const QSettingsGroup &backendConfig, Phonon } } - QString categoryKey = QLatin1String("Category_") + QString::number(static_cast(category)); - if (!backendConfig.hasKey(categoryKey)) { - // no list in config for the given category - categoryKey = QLatin1String("Category_") + QString::number(static_cast(Phonon::NoCategory)); - if (!backendConfig.hasKey(categoryKey)) { - // no list in config for NoCategory - return defaultList; + QList deviceList; + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + deviceList = pulse->objectIndexesByCategory(type, category); + } else { + QString categoryKey = QLatin1String("Category_") + QString::number(static_cast(category)); + if (!backendConfig->hasKey(categoryKey)) { + // no list in config for the given category + categoryKey = QLatin1String("Category_") + QString::number(static_cast(Phonon::NoCategory)); + if (!backendConfig->hasKey(categoryKey)) { + // no list in config for NoCategory + return defaultList; + } } - } - //Now the list from m_config - QList deviceList = backendConfig.value(categoryKey, QList()); + //Now the list from d->config + deviceList = backendConfig->value(categoryKey, QList()); + } - //if there are devices in m_config that the backend doesn't report, remove them from the list + //if there are devices in d->config that the backend doesn't report, remove them from the list QMutableListIterator i(deviceList); while (i.hasNext()) { if (0 == defaultList.removeAll(i.next())) { @@ -125,58 +144,198 @@ static QList listSortedByConfig(const QSettingsGroup &backendConfig, Phonon } } - //if the backend reports more devices that are not in m_config append them to the list + //if the backend reports more devices that are not in d->config append them to the list deviceList += defaultList; return deviceList; } + +bool GlobalConfig::hideAdvancedDevices() const +{ + K_D(const GlobalConfig); + //The devices need to be stored independently for every backend + const QSettingsGroup generalGroup(&d->config, QLatin1String("General")); + return generalGroup.value(QLatin1String("HideAdvancedDevices"), true); +} + +void GlobalConfig::setHideAdvancedDevices(bool hide) +{ + K_D(GlobalConfig); + QSettingsGroup generalGroup(&d->config, QLatin1String("General")); + generalGroup.setValue(QLatin1String("HideAdvancedDevices"), hide); +} + +static bool isHiddenAudioOutputDevice(const GlobalConfig *config, int i) +{ + Q_ASSERT(config); + + if (!config->hideAdvancedDevices()) + return false; + + AudioOutputDevice ad = AudioOutputDevice::fromIndex(i); + const QVariant var = ad.property("isAdvanced"); + return (var.isValid() && var.toBool()); +} + +#ifndef QT_NO_PHONON_AUDIOCAPTURE +static bool isHiddenAudioCaptureDevice(const GlobalConfig *config, int i) +{ + Q_ASSERT(config); + + if (!config->hideAdvancedDevices()) + return false; + + AudioCaptureDevice ad = AudioCaptureDevice::fromIndex(i); + const QVariant var = ad.property("isAdvanced"); + return (var.isValid() && var.toBool()); +} +#endif + +static QList reindexList(const GlobalConfig *config, Phonon::Category category, QListnewOrder, bool output) +{ + Q_ASSERT(config); +#ifdef QT_NO_PHONON_AUDIOCAPTURE + Q_ASSERT(output); +#endif + + /*QString sb; + sb = QString("(Size %1)").arg(currentList.size()); + foreach (int i, currentList) + sb += QString("%1, ").arg(i); + fprintf(stderr, "=== Reindex Current: %s\n", sb.toUtf8().constData()); + sb = QString("(Size %1)").arg(newOrder.size()); + foreach (int i, newOrder) + sb += QString("%1, ").arg(i); + fprintf(stderr, "=== Reindex Before : %s\n", sb.toUtf8().constData());*/ + + QList currentList; + if (output) + currentList = config->audioOutputDeviceListFor(category, GlobalConfig::ShowUnavailableDevices|GlobalConfig::ShowAdvancedDevices); +#ifndef QT_NO_PHONON_AUDIOCAPTURE + else + currentList = config->audioCaptureDeviceListFor(category, GlobalConfig::ShowUnavailableDevices|GlobalConfig::ShowAdvancedDevices); +#endif + + QList newList; + + foreach (int i, newOrder) { + int found = currentList.indexOf(i); + if (found < 0) { + // It's not in the list, so something is odd (e.g. client error). Ignore it. + continue; + } + + // Iterate through the list from this point onward. If there are hidden devices + // immediately following, take them too. + newList.append(currentList.takeAt(found)); + while (found < currentList.size()) { + bool hidden = true; + if (output) + hidden = isHiddenAudioOutputDevice(config, currentList.at(found)); +#ifndef QT_NO_PHONON_AUDIOCAPTURE + else + hidden = isHiddenAudioCaptureDevice(config, currentList.at(found)); +#endif + + if (!hidden) + break; + newList.append(currentList.takeAt(found)); + } + } + + // If there are any devices left in.. just tack them on the end. + if (currentList.size() > 0) + newList += currentList; + + /*sb = QString("(Size %1)").arg(newList.size()); + foreach (int i, newList) + sb += QString("%1, ").arg(i); + fprintf(stderr, "=== Reindex After : %s\n", sb.toUtf8().constData());*/ + return newList; +} + + +void GlobalConfig::setAudioOutputDeviceListFor(Phonon::Category category, QList order) +{ + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + pulse->setOutputDevicePriorityForCategory(category, order); + return; + } + + K_D(GlobalConfig); + QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier()); + + order = reindexList(this, category, order, true); + + const QList noCategoryOrder = audioOutputDeviceListFor(Phonon::NoCategory, ShowUnavailableDevices|ShowAdvancedDevices); + if (category != Phonon::NoCategory && order == noCategoryOrder) { + backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category)); + } else { + backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order); + } +} #endif //QT_NO_PHONON_SETTINGSGROUP #ifndef QT_NO_PHONON_SETTINGSGROUP QList GlobalConfig::audioOutputDeviceListFor(Phonon::Category category, int override) const { - //The devices need to be stored independently for every backend - const QSettingsGroup backendConfig(&m_config, QLatin1String("AudioOutputDevice")); // + Factory::identifier()); - const QSettingsGroup generalGroup(&m_config, QLatin1String("General")); - const bool hideAdvancedDevices = ((override & AdvancedDevicesFromSettings) - ? generalGroup.value(QLatin1String("HideAdvancedDevices"), true) + K_D(const GlobalConfig); + + const bool hide = ((override & AdvancedDevicesFromSettings) + ? hideAdvancedDevices() : static_cast(override & HideAdvancedDevices)); QList defaultList; + + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + defaultList = pulse->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); + if (hide || (override & HideUnavailableDevices)) { + filter(AudioOutputDeviceType, NULL, &defaultList, + (hide ? FilterAdvancedDevices : 0) + | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) + ); + } + } else { + BackendInterface *backendIface = qobject_cast(Factory::backend()); + #ifndef QT_NO_PHONON_PLATFORMPLUGIN - if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { - // the platform plugin lists the audio devices for the platform - // this list already is in default order (as defined by the platform plugin) - defaultList = platformPlugin->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); - if (hideAdvancedDevices) { - QMutableListIterator it(defaultList); - while (it.hasNext()) { - AudioOutputDevice objDesc = AudioOutputDevice::fromIndex(it.next()); - const QVariant var = objDesc.property("isAdvanced"); - if (var.isValid() && var.toBool()) { - it.remove(); + if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { + // the platform plugin lists the audio devices for the platform + // this list already is in default order (as defined by the platform plugin) + defaultList = platformPlugin->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); + if (hide) { + QMutableListIterator it(defaultList); + while (it.hasNext()) { + AudioOutputDevice objDesc = AudioOutputDevice::fromIndex(it.next()); + const QVariant var = objDesc.property("isAdvanced"); + if (var.isValid() && var.toBool()) { + it.remove(); + } } } } - } #endif //QT_NO_PHONON_PLATFORMPLUGIN - // lookup the available devices directly from the backend (mostly for virtual devices) - if (BackendInterface *backendIface = qobject_cast(Factory::backend())) { - // this list already is in default order (as defined by the backend) - QList list = backendIface->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); - if (hideAdvancedDevices || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { - filter(AudioOutputDeviceType, backendIface, &list, - (hideAdvancedDevices ? FilterAdvancedDevices : 0) - // the platform plugin already provided the hardware devices - | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) - | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) - ); + // lookup the available devices directly from the backend + if (backendIface) { + // this list already is in default order (as defined by the backend) + QList list = backendIface->objectDescriptionIndexes(Phonon::AudioOutputDeviceType); + if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { + filter(AudioOutputDeviceType, backendIface, &list, + (hide ? FilterAdvancedDevices : 0) + // the platform plugin maybe already provided the hardware devices? + | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) + | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) + ); + } + defaultList += list; } - defaultList += list; } - return listSortedByConfig(backendConfig, category, defaultList); + const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier()); + return sortDevicesByCategoryPriority(this, &backendConfig, AudioOutputDeviceType, category, defaultList); } #endif //QT_NO_PHONON_SETTINGSGROUP int GlobalConfig::audioOutputDeviceFor(Phonon::Category category, int override) const @@ -190,54 +349,89 @@ int GlobalConfig::audioOutputDeviceFor(Phonon::Category category, int override) } #ifndef QT_NO_PHONON_AUDIOCAPTURE -QList GlobalConfig::audioCaptureDeviceListFor(Phonon::Category category, int override) const +void GlobalConfig::setAudioCaptureDeviceListFor(Phonon::Category category, QList order) { #ifndef QT_NO_PHONON_SETTINGSGROUP - //The devices need to be stored independently for every backend - const QSettingsGroup backendConfig(&m_config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); - const QSettingsGroup generalGroup(&m_config, QLatin1String("General")); - const bool hideAdvancedDevices = ((override & AdvancedDevicesFromSettings) - ? generalGroup.value(QLatin1String("HideAdvancedDevices"), true) + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + pulse->setCaptureDevicePriorityForCategory(category, order); + return; + } + + K_D(GlobalConfig); + QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); + + order = reindexList(this, category, order, false); + + const QList noCategoryOrder = audioCaptureDeviceListFor(Phonon::NoCategory, ShowUnavailableDevices|ShowAdvancedDevices); + if (category != Phonon::NoCategory && order == noCategoryOrder) { + backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category)); + } else { + backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order); + } +} + +QList GlobalConfig::audioCaptureDeviceListFor(Phonon::Category category, int override) const +{ + K_D(const GlobalConfig); + + const bool hide = ((override & AdvancedDevicesFromSettings) + ? hideAdvancedDevices() : static_cast(override & HideAdvancedDevices)); QList defaultList; + + PulseSupport *pulse = PulseSupport::getInstance(); + if (pulse->isActive()) { + defaultList = pulse->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); + if (hide || (override & HideUnavailableDevices)) { + filter(AudioCaptureDeviceType, NULL, &defaultList, + (hide ? FilterAdvancedDevices : 0) + | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) + ); + } + } else { + BackendInterface *backendIface = qobject_cast(Factory::backend()); + #ifndef QT_NO_PHONON_PLATFORMPLUGIN - if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { - // the platform plugin lists the audio devices for the platform - // this list already is in default order (as defined by the platform plugin) - defaultList = platformPlugin->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); - if (hideAdvancedDevices) { - QMutableListIterator it(defaultList); - while (it.hasNext()) { - AudioCaptureDevice objDesc = AudioCaptureDevice::fromIndex(it.next()); - const QVariant var = objDesc.property("isAdvanced"); - if (var.isValid() && var.toBool()) { - it.remove(); +#else //QT_NO_SETTINGSGROUP + return QList(); +#endif //QT_NO_SETTINGSGROUP + if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) { + // the platform plugin lists the audio devices for the platform + // this list already is in default order (as defined by the platform plugin) + defaultList = platformPlugin->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); + if (hide) { + QMutableListIterator it(defaultList); + while (it.hasNext()) { + AudioCaptureDevice objDesc = AudioCaptureDevice::fromIndex(it.next()); + const QVariant var = objDesc.property("isAdvanced"); + if (var.isValid() && var.toBool()) { + it.remove(); + } } } } - } #endif //QT_NO_PHONON_PLATFORMPLUGIN - // lookup the available devices directly from the backend (mostly for virtual devices) - if (BackendInterface *backendIface = qobject_cast(Factory::backend())) { - // this list already is in default order (as defined by the backend) - QList list = backendIface->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); - if (hideAdvancedDevices || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { - filter(AudioCaptureDeviceType, backendIface, &list, - (hideAdvancedDevices ? FilterAdvancedDevices : 0) - // the platform plugin already provided the hardware devices - | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) - | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) - ); + // lookup the available devices directly from the backend + if (backendIface) { + // this list already is in default order (as defined by the backend) + QList list = backendIface->objectDescriptionIndexes(Phonon::AudioCaptureDeviceType); + if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) { + filter(AudioCaptureDeviceType, backendIface, &list, + (hide ? FilterAdvancedDevices : 0) + // the platform plugin maybe already provided the hardware devices? + | (defaultList.isEmpty() ? 0 : FilterHardwareDevices) + | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) + ); + } + defaultList += list; } - defaultList += list; } - return listSortedByConfig(backendConfig, category, defaultList); -#else //QT_NO_SETTINGSGROUP - return QList(); -#endif //QT_NO_SETTINGSGROUP + const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier()); + return sortDevicesByCategoryPriority(this, &backendConfig, AudioCaptureDeviceType, category, defaultList); } int GlobalConfig::audioCaptureDeviceFor(Phonon::Category category, int override) const diff --git a/src/3rdparty/phonon/phonon/globalconfig_p.h b/src/3rdparty/phonon/phonon/globalconfig_p.h index ec70b6f..090ca6b 100644 --- a/src/3rdparty/phonon/phonon/globalconfig_p.h +++ b/src/3rdparty/phonon/phonon/globalconfig_p.h @@ -26,40 +26,19 @@ Copyright (C) 2006-2008 Matthias Kretz #include #include "phonon_export.h" -#include "phononnamespace.h" QT_BEGIN_HEADER QT_BEGIN_NAMESPACE namespace Phonon { - class PHONON_EXPORT GlobalConfig + class GlobalConfigPrivate { - public: - GlobalConfig(); - virtual ~GlobalConfig(); + public: + GlobalConfigPrivate(); + virtual ~GlobalConfigPrivate() {} - enum DevicesToHideFlag { - ShowUnavailableDevices = 0, - ShowAdvancedDevices = 0, - HideAdvancedDevices = 1, - AdvancedDevicesFromSettings = 2, - HideUnavailableDevices = 4 - }; -#ifndef QT_NO_PHONON_SETTINGSGROUP - QList audioOutputDeviceListFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; -#endif //QT_NO_PHONON_SETTINGSGROUP - int audioOutputDeviceFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; - -#ifndef QT_NO_PHONON_AUDIOCAPTURE - QList audioCaptureDeviceListFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; - int audioCaptureDeviceFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; -#endif //QT_NO_PHONON_AUDIOCAPTURE - - protected: -#ifndef QT_NO_SETTINGS - QSettings m_config; -#endif //QT_NO_SETTINGS + QSettings config; }; } // namespace Phonon diff --git a/src/3rdparty/phonon/phonon/mediaobject.cpp b/src/3rdparty/phonon/phonon/mediaobject.cpp index 41e8dc2..13d303c 100644 --- a/src/3rdparty/phonon/phonon/mediaobject.cpp +++ b/src/3rdparty/phonon/phonon/mediaobject.cpp @@ -453,9 +453,9 @@ void MediaObjectPrivate::setupBackendObject() //pDebug() << Q_FUNC_INFO; #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM - QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), q, SLOT(_k_stateChanged(Phonon::State,Phonon::State))); + QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), q, SLOT(_k_stateChanged(Phonon::State, Phonon::State))); #else - QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), q, SIGNAL(stateChanged(Phonon::State,Phonon::State))); + QObject::connect(m_backendObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), q, SIGNAL(stateChanged(Phonon::State, Phonon::State))); #endif // QT_NO_PHONON_ABSTRACTMEDIASTREAM QObject::connect(m_backendObject, SIGNAL(tick(qint64)), q, SIGNAL(tick(qint64))); QObject::connect(m_backendObject, SIGNAL(seekableChanged(bool)), q, SIGNAL(seekableChanged(bool))); @@ -467,10 +467,10 @@ void MediaObjectPrivate::setupBackendObject() QObject::connect(m_backendObject, SIGNAL(aboutToFinish()), q, SLOT(_k_aboutToFinish())); QObject::connect(m_backendObject, SIGNAL(prefinishMarkReached(qint32)), q, SIGNAL(prefinishMarkReached(qint32))); QObject::connect(m_backendObject, SIGNAL(totalTimeChanged(qint64)), q, SIGNAL(totalTimeChanged(qint64))); - QObject::connect(m_backendObject, SIGNAL(metaDataChanged(QMultiMap)), - q, SLOT(_k_metaDataChanged(QMultiMap))); - QObject::connect(m_backendObject, SIGNAL(currentSourceChanged(MediaSource)), - q, SLOT(_k_currentSourceChanged(MediaSource))); + QObject::connect(m_backendObject, SIGNAL(metaDataChanged(const QMultiMap &)), + q, SLOT(_k_metaDataChanged(const QMultiMap &))); + QObject::connect(m_backendObject, SIGNAL(currentSourceChanged(const MediaSource&)), + q, SLOT(_k_currentSourceChanged(const MediaSource&))); // set up attributes pINTERFACE_CALL(setTickInterval(tickInterval)); diff --git a/src/3rdparty/phonon/phonon/objectdescription.cpp b/src/3rdparty/phonon/phonon/objectdescription.cpp index e058b89..55e74b5 100644 --- a/src/3rdparty/phonon/phonon/objectdescription.cpp +++ b/src/3rdparty/phonon/phonon/objectdescription.cpp @@ -29,6 +29,7 @@ #include #include "backendinterface.h" #include "platformplugin.h" +#include "pulsesupport.h" QT_BEGIN_NAMESPACE @@ -108,27 +109,38 @@ bool ObjectDescriptionData::isValid() const ObjectDescriptionData *ObjectDescriptionData::fromIndex(ObjectDescriptionType type, int index) { - // prefer to get the ObjectDescriptionData from the platform plugin for audio devices + bool is_audio_device = (AudioOutputDeviceType == type || AudioCaptureDeviceType == type); + + PulseSupport *pulse = PulseSupport::getInstance(); + if (is_audio_device && pulse->isActive()) { + QList indexes = pulse->objectDescriptionIndexes(type); + if (indexes.contains(index)) { + QHash properties = pulse->objectDescriptionProperties(type, index); + return new ObjectDescriptionData(index, properties); + } + } else { + BackendInterface *iface = qobject_cast(Factory::backend()); + + // prefer to get the ObjectDescriptionData from the platform plugin for audio devices #ifndef QT_NO_PHONON_PLATFORMPLUGIN - if (type == AudioOutputDeviceType || type == AudioCaptureDeviceType) { - PlatformPlugin *platformPlugin = Factory::platformPlugin(); - if (platformPlugin) { - QList indexes = platformPlugin->objectDescriptionIndexes(type); - if (indexes.contains(index)) { - QHash properties = platformPlugin->objectDescriptionProperties(type, index); - return new ObjectDescriptionData(index, properties); + if (is_audio_device) { + PlatformPlugin *platformPlugin = Factory::platformPlugin(); + if (platformPlugin) { + QList indexes = platformPlugin->objectDescriptionIndexes(type); + if (indexes.contains(index)) { + QHash properties = platformPlugin->objectDescriptionProperties(type, index); + return new ObjectDescriptionData(index, properties); + } } } - } #endif //QT_NO_PHONON_PLATFORMPLUGIN - QObject *b = Factory::backend(); - BackendInterface *iface = qobject_cast(b); - if (iface) { - QList indexes = iface->objectDescriptionIndexes(type); - if (indexes.contains(index)) { - QHash properties = iface->objectDescriptionProperties(type, index); - return new ObjectDescriptionData(index, properties); + if (iface) { + QList indexes = iface->objectDescriptionIndexes(type); + if (indexes.contains(index)) { + QHash properties = iface->objectDescriptionProperties(type, index); + return new ObjectDescriptionData(index, properties); + } } } return new ObjectDescriptionData(0); // invalid diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp b/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp index bf5be6d..741a74c 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp @@ -362,6 +362,7 @@ QStringList ObjectDescriptionModelData::mimeTypes(ObjectDescriptionType type) co return QStringList(QLatin1String("application/x-phonon-objectdescription") + QString::number(static_cast(type))); } +#if !defined(Q_CC_MSVC) || _MSC_VER > 1300 || defined(Q_CC_INTEL) || defined(Q_CC_MINGW) #define INSTANTIATE_META_FUNCTIONS(type) \ template const QMetaObject *ObjectDescriptionModel::metaObject() const; \ template void *ObjectDescriptionModel::qt_metacast(const char *) @@ -371,6 +372,7 @@ INSTANTIATE_META_FUNCTIONS(AudioCaptureDeviceType); INSTANTIATE_META_FUNCTIONS(EffectType); INSTANTIATE_META_FUNCTIONS(AudioChannelType); INSTANTIATE_META_FUNCTIONS(SubtitleType); +#endif /*INSTANTIATE_META_FUNCTIONS(VideoOutputDeviceType); INSTANTIATE_META_FUNCTIONS(VideoCaptureDeviceType); INSTANTIATE_META_FUNCTIONS(AudioCodecType); diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h index 8fd622f..a1540e8 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h @@ -35,6 +35,18 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_PHONON_OBJECTDESCRIPTIONMODEL +/* MinGW 3.4.x gives an ICE when trying to instantiate one of the + ObjectDescriptionModel classes because it can't handle + half exported classes correct. gcc 4.3.x has a fix for this but + we currently there's no official gcc 4.3 on windows available. + Because of this we need this little hack + */ +#if defined(Q_CC_MINGW) +#define PHONON_EXPORT_ODM +#else +#define PHONON_EXPORT_ODM PHONON_EXPORT +#endif + namespace Phonon { class ObjectDescriptionModelDataPrivate; @@ -139,21 +151,6 @@ namespace Phonon ObjectDescriptionModelDataPrivate *const d; }; -/* Required to ensure template class vtables are exported on both symbian -and existing builds. */ -#if defined(Q_OS_SYMBIAN) && defined(Q_CC_RVCT) -// RVCT compiler (2.2.686) requires the export declaration to be on the class to export vtables -// MWC compiler works both ways -// GCCE compiler is unknown (it can't compile QtCore yet) -#define PHONON_TEMPLATE_CLASS_EXPORT PHONON_EXPORT -#define PHONON_TEMPLATE_CLASS_MEMBER_EXPORT -#else -// Windows builds (at least) do not support export declaration on templated class -// But if you export a member function, the vtable is implicitly exported -#define PHONON_TEMPLATE_CLASS_EXPORT -#define PHONON_TEMPLATE_CLASS_MEMBER_EXPORT PHONON_EXPORT -#endif - /** \class ObjectDescriptionModel objectdescriptionmodel.h Phonon/ObjectDescriptionModel * \short The ObjectDescriptionModel class provides a model from * a list of ObjectDescription objects. @@ -190,17 +187,16 @@ and existing builds. */ * \author Matthias Kretz */ template - class PHONON_TEMPLATE_CLASS_EXPORT ObjectDescriptionModel : public QAbstractListModel + class ObjectDescriptionModel : public QAbstractListModel { public: Q_OBJECT_CHECK - /** \internal */ - static PHONON_TEMPLATE_CLASS_MEMBER_EXPORT const QMetaObject staticMetaObject; + static PHONON_EXPORT const QMetaObject staticMetaObject; /** \internal */ - PHONON_TEMPLATE_CLASS_MEMBER_EXPORT const QMetaObject *metaObject() const; + PHONON_EXPORT_ODM const QMetaObject *metaObject() const; /** \internal */ - PHONON_TEMPLATE_CLASS_MEMBER_EXPORT void *qt_metacast(const char *_clname); + PHONON_EXPORT_ODM void *qt_metacast(const char *_clname); //int qt_metacall(QMetaObject::Call _c, int _id, void **_a); /** diff --git a/src/3rdparty/phonon/phonon/path.cpp b/src/3rdparty/phonon/phonon/path.cpp index 51c33b2..1c25b89 100644 --- a/src/3rdparty/phonon/phonon/path.cpp +++ b/src/3rdparty/phonon/phonon/path.cpp @@ -310,8 +310,8 @@ bool PathPrivate::executeTransaction( const QList &disconnections, if (!transaction) return false; - QList::const_iterator it = disconnections.constBegin(); - for(;it != disconnections.constEnd();++it) { + QList::const_iterator it = disconnections.begin(); + for(;it != disconnections.end();++it) { const QObjectPair &pair = *it; if (!backend->disconnectNodes(pair.first, pair.second)) { @@ -327,8 +327,8 @@ bool PathPrivate::executeTransaction( const QList &disconnections, } } - for(it = connections.constBegin(); it != connections.constEnd(); ++it) { - const QObjectPair pair = *it; + for(it = connections.begin(); it != connections.end();++it) { + const QObjectPair &pair = *it; if (!backend->connectNodes(pair.first, pair.second)) { //Error: a connection failed QList::const_iterator it2 = connections.begin(); diff --git a/src/3rdparty/phonon/phonon/phonondefs.h b/src/3rdparty/phonon/phonon/phonondefs.h index 15a1815..765eb1c 100644 --- a/src/3rdparty/phonon/phonon/phonondefs.h +++ b/src/3rdparty/phonon/phonon/phonondefs.h @@ -29,6 +29,11 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +#ifdef PHONON_BACKEND_VERSION_4_4 +# ifndef PHONON_BACKEND_VERSION_4_3 +# define PHONON_BACKEND_VERSION_4_3 +# endif +#endif #ifdef PHONON_BACKEND_VERSION_4_3 # ifndef PHONON_BACKEND_VERSION_4_2 # define PHONON_BACKEND_VERSION_4_2 diff --git a/src/3rdparty/phonon/phonon/seekslider.cpp b/src/3rdparty/phonon/phonon/seekslider.cpp index 41baf2d..b5b25f0 100644 --- a/src/3rdparty/phonon/phonon/seekslider.cpp +++ b/src/3rdparty/phonon/phonon/seekslider.cpp @@ -72,12 +72,12 @@ void SeekSlider::setMediaObject(MediaObject *media) d->media = media; if (media) { - connect(media, SIGNAL(stateChanged(Phonon::State,Phonon::State)), + connect(media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), SLOT(_k_stateChanged(Phonon::State))); connect(media, SIGNAL(totalTimeChanged(qint64)), SLOT(_k_length(qint64))); connect(media, SIGNAL(tick(qint64)), SLOT(_k_tick(qint64))); connect(media, SIGNAL(seekableChanged(bool)), SLOT(_k_seekableChanged(bool))); - connect(media, SIGNAL(currentSourceChanged(Phonon::MediaSource)), SLOT(_k_currentSourceChanged())); + connect(media, SIGNAL(currentSourceChanged(const Phonon::MediaSource&)), SLOT(_k_currentSourceChanged())); d->_k_stateChanged(media->state()); d->_k_seekableChanged(media->isSeekable()); d->_k_length(media->totalTime()); diff --git a/src/3rdparty/phonon/phonon/seekslider_p.h b/src/3rdparty/phonon/phonon/seekslider_p.h index c87a4b0..911ab25 100644 --- a/src/3rdparty/phonon/phonon/seekslider_p.h +++ b/src/3rdparty/phonon/phonon/seekslider_p.h @@ -24,8 +24,8 @@ #define SEEKSLIDER_P_H #include "seekslider.h" +#include "swiftslider_p.h" #include -#include #include #include #include @@ -84,7 +84,7 @@ class SeekSliderPrivate void _k_currentSourceChanged(); QBoxLayout layout; - QSlider slider; + SwiftSlider slider; QLabel iconLabel; QPointer media; bool ticking; diff --git a/src/3rdparty/phonon/phonon/videowidget.cpp b/src/3rdparty/phonon/phonon/videowidget.cpp index a9e83a6..4575dfd 100644 --- a/src/3rdparty/phonon/phonon/videowidget.cpp +++ b/src/3rdparty/phonon/phonon/videowidget.cpp @@ -28,8 +28,9 @@ #include "phononnamespace_p.h" #include - -#define PHONON_INTERFACENAME VideoWidgetInterface +#define IFACES4 VideoWidgetInterface44 +#define IFACES0 VideoWidgetInterface, IFACES4 +#define PHONON_INTERFACENAME IFACES0 QT_BEGIN_NAMESPACE @@ -48,6 +49,8 @@ VideoWidget::VideoWidget(QWidget *parent) setMouseTracking(true); } + + VideoWidget::VideoWidget(VideoWidgetPrivate &dd, QWidget *parent) : QWidget(parent), Phonon::AbstractVideoOutput(dd) @@ -98,6 +101,15 @@ PHONON_INTERFACE_SETTER(setHue, hue, qreal) PHONON_INTERFACE_GETTER(qreal, saturation, d->saturation) PHONON_INTERFACE_SETTER(setSaturation, saturation, qreal) + +QImage VideoWidget::snapshot() const { + K_D(const VideoWidget); + ConstIface iface(d); + if(iface) return iface->snapshot(); + return QImage(); // TODO not implemented in VideoInterface +} + + void VideoWidget::setFullScreen(bool newFullScreen) { pDebug() << Q_FUNC_INFO << newFullScreen; diff --git a/src/3rdparty/phonon/phonon/videowidget.h b/src/3rdparty/phonon/phonon/videowidget.h index 1d95490..804e61a 100644 --- a/src/3rdparty/phonon/phonon/videowidget.h +++ b/src/3rdparty/phonon/phonon/videowidget.h @@ -172,6 +172,7 @@ class AbstractVideoOutput; qreal contrast() const; qreal hue() const; qreal saturation() const; + QImage snapshot() const; //TODO: bar colors property public Q_SLOTS: diff --git a/src/3rdparty/phonon/phonon/videowidgetinterface.h b/src/3rdparty/phonon/phonon/videowidgetinterface.h index 3e6fd22..0c33956 100644 --- a/src/3rdparty/phonon/phonon/videowidgetinterface.h +++ b/src/3rdparty/phonon/phonon/videowidgetinterface.h @@ -53,8 +53,21 @@ class VideoWidgetInterface //X virtual int overlayCapabilities() const = 0; //X virtual bool createOverlay(QWidget *widget, int type) = 0; }; + +class VideoWidgetInterface44 : public VideoWidgetInterface +{ + public: + virtual QImage snapshot() const = 0; +}; } +#ifdef PHONON_BACKEND_VERSION_4_4 +namespace Phonon { typedef VideoWidgetInterface44 VideoWidgetInterfaceLatest; } +#else +namespace Phonon { typedef VideoWidgetInterface VideoWidgetInterfaceLatest; } +#endif + +Q_DECLARE_INTERFACE(Phonon::VideoWidgetInterface44, "VideoWidgetInterface44.phonon.kde.org") Q_DECLARE_INTERFACE(Phonon::VideoWidgetInterface, "VideoWidgetInterface3.phonon.kde.org") #endif //QT_NO_PHONON_VIDEO diff --git a/src/3rdparty/phonon/phonon/volumeslider_p.h b/src/3rdparty/phonon/phonon/volumeslider_p.h index 3827659..623275f 100644 --- a/src/3rdparty/phonon/phonon/volumeslider_p.h +++ b/src/3rdparty/phonon/phonon/volumeslider_p.h @@ -24,8 +24,8 @@ #define VOLUMESLIDER_P_H #include "volumeslider.h" +#include "swiftslider_p.h" #include -#include #include #include #include @@ -83,7 +83,7 @@ class VolumeSliderPrivate private: QBoxLayout layout; - QSlider slider; + SwiftSlider slider; QToolButton muteButton; QIcon volumeIcon; QIcon mutedIcon; diff --git a/src/phonon/phonon.pro b/src/phonon/phonon.pro index 0469839..7f79d0b 100644 --- a/src/phonon/phonon.pro +++ b/src/phonon/phonon.pro @@ -2,8 +2,8 @@ TARGET = phonon include(../qbase.pri) PHONON_MAJOR_VERSION = $${QT_MAJOR_VERSION} -PHONON_MINOR_VERSION = 3 -PHONON_PATCH_VERSION = 1 +PHONON_MINOR_VERSION = 4 +PHONON_PATCH_VERSION = 0 VERSION = $${PHONON_MAJOR_VERSION}.$${PHONON_MINOR_VERSION}.$${PHONON_PATCH_VERSION} DEPENDPATH += . @@ -21,6 +21,9 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/abstractvideooutput.h \ $$PHONON_DIR/abstractvideooutput_p.h \ $$PHONON_DIR/addoninterface.h \ + $$PHONON_DIR/audiodataoutput_p.h \ + $$PHONON_DIR/audiodataoutput.h \ + $$PHONON_DIR/audiodataoutputinterface.h \ $$PHONON_DIR/audiooutput.h \ $$PHONON_DIR/audiooutput_p.h \ $$PHONON_DIR/audiooutputinterface.h \ @@ -36,6 +39,7 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/effectwidget_p.h \ $$PHONON_DIR/factory_p.h \ $$PHONON_DIR/frontendinterface_p.h \ + $$PHONON_DIR/globalconfig.h \ $$PHONON_DIR/globalconfig_p.h \ $$PHONON_DIR/iodevicestream_p.h \ $$PHONON_DIR/mediacontroller.h \ @@ -53,6 +57,7 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/objectdescriptionmodel_p.h \ $$PHONON_DIR/path.h \ $$PHONON_DIR/path_p.h \ + $$PHONON_DIR/pulsesupport.h \ $$PHONON_DIR/phonondefs.h \ $$PHONON_DIR/phonondefs_p.h \ $$PHONON_DIR/phononnamespace.h \ @@ -64,6 +69,7 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/seekslider_p.h \ $$PHONON_DIR/streaminterface.h \ $$PHONON_DIR/streaminterface_p.h \ + $$PHONON_DIR/swiftslider_p.h \ $$PHONON_DIR/videoplayer.h \ $$PHONON_DIR/videowidget.h \ $$PHONON_DIR/videowidget_p.h \ @@ -73,35 +79,39 @@ HEADERS += $$PHONON_DIR/abstractaudiooutput.h \ $$PHONON_DIR/volumefaderinterface.h \ $$PHONON_DIR/volumeslider.h \ $$PHONON_DIR/volumeslider_p.h -SOURCES += $$PHONON_DIR/objectdescription.cpp \ - $$PHONON_DIR/objectdescriptionmodel.cpp \ - $$PHONON_DIR/phononnamespace.cpp \ - $$PHONON_DIR/mediasource.cpp \ - $$PHONON_DIR/abstractmediastream.cpp \ - $$PHONON_DIR/streaminterface.cpp \ - $$PHONON_DIR/mediaobject.cpp \ - $$PHONON_DIR/medianode.cpp \ - $$PHONON_DIR/path.cpp \ - $$PHONON_DIR/effectparameter.cpp \ - $$PHONON_DIR/effect.cpp \ - $$PHONON_DIR/volumefadereffect.cpp \ - $$PHONON_DIR/abstractaudiooutput.cpp \ + +SOURCES += $$PHONON_DIR/abstractaudiooutput.cpp \ $$PHONON_DIR/abstractaudiooutput_p.cpp \ - $$PHONON_DIR/audiooutput.cpp \ - $$PHONON_DIR/audiooutputinterface.cpp \ + $$PHONON_DIR/abstractmediastream.cpp \ $$PHONON_DIR/abstractvideooutput.cpp \ $$PHONON_DIR/abstractvideooutput_p.cpp \ + $$PHONON_DIR/audiodataoutput.cpp \ + $$PHONON_DIR/audiooutput.cpp \ + $$PHONON_DIR/audiooutputinterface.cpp \ $$PHONON_DIR/backendcapabilities.cpp \ - $$PHONON_DIR/globalconfig.cpp \ + $$PHONON_DIR/effect.cpp \ + $$PHONON_DIR/effectparameter.cpp \ + $$PHONON_DIR/effectwidget.cpp \ $$PHONON_DIR/factory.cpp \ - $$PHONON_DIR/platform.cpp \ + $$PHONON_DIR/globalconfig.cpp \ + $$PHONON_DIR/iodevicestream.cpp \ $$PHONON_DIR/mediacontroller.cpp \ - $$PHONON_DIR/videowidget.cpp \ - $$PHONON_DIR/videoplayer.cpp \ + $$PHONON_DIR/medianode.cpp \ + $$PHONON_DIR/mediaobject.cpp \ + $$PHONON_DIR/mediasource.cpp \ + $$PHONON_DIR/objectdescription.cpp \ + $$PHONON_DIR/objectdescriptionmodel.cpp \ + $$PHONON_DIR/path.cpp \ + $$PHONON_DIR/phononnamespace.cpp \ + $$PHONON_DIR/platform.cpp \ + $$PHONON_DIR/pulsesupport.cpp \ $$PHONON_DIR/seekslider.cpp \ - $$PHONON_DIR/volumeslider.cpp \ - $$PHONON_DIR/effectwidget.cpp \ - $$PHONON_DIR/iodevicestream.cpp + $$PHONON_DIR/streaminterface.cpp \ + $$PHONON_DIR/swiftslider.cpp \ + $$PHONON_DIR/videoplayer.cpp \ + $$PHONON_DIR/videowidget.cpp \ + $$PHONON_DIR/volumefadereffect.cpp \ + $$PHONON_DIR/volumeslider.cpp contains(QT_CONFIG, dbus) { QT += dbus @@ -114,6 +124,12 @@ contains(QT_CONFIG, dbus) { contains(QT_CONFIG, reduce_exports): CONFIG += hide_symbols +unix:!isEmpty(QT_CFLAGS_PULSEAUDIO) { + DEFINES += HAVE_PULSEAUDIO + QMAKE_CXXFLAGS += $$QT_CFLAGS_PULSEAUDIO + LIBS += $$QT_LIBS_PULSEAUDIO +} + symbian: { # Phonon depends on numeric_limits. Enabling STL support in Qt # would bring in link dependencies, and we don't need that for -- cgit v0.12 From edb67f204302fff4f1e46676112931ea054deb88 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 25 Mar 2010 13:57:36 +1000 Subject: Update Phonon GStreamer backend to 4.4.0. --- src/3rdparty/phonon/gstreamer/CMakeLists.txt | 18 +- .../phonon/gstreamer/ConfigureChecks.cmake | 7 +- src/3rdparty/phonon/gstreamer/audiodataoutput.cpp | 143 ++++++++++ src/3rdparty/phonon/gstreamer/audiodataoutput.h | 84 ++++++ src/3rdparty/phonon/gstreamer/audiooutput.cpp | 16 +- src/3rdparty/phonon/gstreamer/backend.cpp | 46 ++-- src/3rdparty/phonon/gstreamer/backend.h | 1 - src/3rdparty/phonon/gstreamer/devicemanager.cpp | 70 +++-- src/3rdparty/phonon/gstreamer/devicemanager.h | 6 +- src/3rdparty/phonon/gstreamer/effectmanager.cpp | 2 +- src/3rdparty/phonon/gstreamer/glrenderer.cpp | 2 +- src/3rdparty/phonon/gstreamer/gsthelper.cpp | 2 +- src/3rdparty/phonon/gstreamer/gstreamer.desktop | 57 ++++ src/3rdparty/phonon/gstreamer/medianode.cpp | 4 +- src/3rdparty/phonon/gstreamer/mediaobject.cpp | 296 ++++++++++++++++----- src/3rdparty/phonon/gstreamer/mediaobject.h | 12 +- src/3rdparty/phonon/gstreamer/qwidgetvideosink.h | 1 + src/3rdparty/phonon/gstreamer/videowidget.h | 1 + src/3rdparty/phonon/gstreamer/x11renderer.cpp | 3 +- src/plugins/phonon/gstreamer/gstreamer.pro | 22 +- 20 files changed, 651 insertions(+), 142 deletions(-) create mode 100644 src/3rdparty/phonon/gstreamer/audiodataoutput.cpp create mode 100644 src/3rdparty/phonon/gstreamer/audiodataoutput.h diff --git a/src/3rdparty/phonon/gstreamer/CMakeLists.txt b/src/3rdparty/phonon/gstreamer/CMakeLists.txt index 08f892a..2249ac3 100644 --- a/src/3rdparty/phonon/gstreamer/CMakeLists.txt +++ b/src/3rdparty/phonon/gstreamer/CMakeLists.txt @@ -19,7 +19,7 @@ include(ConfigureChecks.cmake) if (BUILD_PHONON_GSTREAMER) include_directories( ${CMAKE_CURRENT_BINARY_DIR} - ${GSTREAMER_INCLUDE_DIR} + ${GSTREAMER_INCLUDE_DIR} ${GLIB2_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ${X11_X11_INCLUDE_PATH}) @@ -34,7 +34,6 @@ if (BUILD_PHONON_GSTREAMER) set(phonon_gstreamer_SRCS audiooutput.cpp - artssink.cpp backend.cpp devicemanager.cpp effectmanager.cpp @@ -50,14 +49,20 @@ if (BUILD_PHONON_GSTREAMER) message.cpp audioeffect.cpp abstractrenderer.cpp - x11renderer.cpp widgetrenderer.cpp glrenderer.cpp volumefadereffect.cpp + audiodataoutput.cpp ) - find_package(Alsa) - macro_ensure_version("0.10.22" ${GSTREAMER_VERSION} GSTREAMER_HAS_NONBLOCKING_ALSASINK) + if(NOT WIN32) + set(phonon_gstreamer_SRCS + ${phonon_gstreamer_SRCS} + artssink.cpp + x11renderer.cpp) + macro_optional_find_package(Alsa) + macro_ensure_version("0.10.22" ${GSTREAMER_VERSION} GSTREAMER_HAS_NONBLOCKING_ALSASINK) + endif(NOT WIN32) if(ALSA_FOUND AND NOT GSTREAMER_HAS_NONBLOCKING_ALSASINK) add_definitions(-DUSE_ALSASINK2) include_directories(${ALSA_INCLUDES}) @@ -78,6 +83,9 @@ if (BUILD_PHONON_GSTREAMER) if(ALSA_FOUND) target_link_libraries(phonon_gstreamer ${ASOUND_LIBRARY}) endif(ALSA_FOUND) + if(USE_INSTALL_PLUGIN) + target_link_libraries(phonon_gstreamer ${GSTREAMER_PLUGIN_PBUTILS_LIBRARIES}) + endif(USE_INSTALL_PLUGIN) install(TARGETS phonon_gstreamer DESTINATION ${PLUGIN_INSTALL_DIR}/plugins/phonon_backend) install(FILES gstreamer.desktop DESTINATION ${SERVICES_INSTALL_DIR}/phononbackends) diff --git a/src/3rdparty/phonon/gstreamer/ConfigureChecks.cmake b/src/3rdparty/phonon/gstreamer/ConfigureChecks.cmake index f2922e1..eaf5b99 100644 --- a/src/3rdparty/phonon/gstreamer/ConfigureChecks.cmake +++ b/src/3rdparty/phonon/gstreamer/ConfigureChecks.cmake @@ -17,6 +17,7 @@ macro_log_feature(GSTREAMER_FOUND "GStreamer" "gstreamer 0.10 is required for th macro_optional_find_package(GStreamerPlugins) macro_log_feature(GSTREAMER_PLUGIN_VIDEO_LIBRARIES "GStreamer video plugin" "The gstreamer video plugin (part of gstreamer-plugins-base 0.10) is required for the multimedia gstreamer backend" "http://gstreamer.freedesktop.org/modules/" FALSE "0.10") +macro_log_feature(GSTREAMER_PLUGIN_AUDIO_LIBRARIES "GStreamer audio plugin" "The gstreamer audio plugin (part of gstreamer-plugins-base 0.10) is required for the multimedia gstreamer backend" "http://gstreamer.freedesktop.org/modules/" FALSE "0.10") macro_optional_find_package(GLIB2) macro_log_feature(GLIB2_FOUND "GLib2" "GLib 2 is required to compile the gstreamer backend for Phonon" "http://www.gtk.org/download/" FALSE) @@ -30,8 +31,8 @@ macro_log_feature(LIBXML2_FOUND "LibXml2" "LibXml2 is required to compile the gs macro_optional_find_package(OpenGL) macro_log_feature(OPENGL_FOUND "OpenGL" "OpenGL support is required to compile the gstreamer backend for Phonon" "" FALSE) -if (GSTREAMER_FOUND AND GSTREAMER_PLUGIN_VIDEO_LIBRARIES AND GLIB2_FOUND AND GOBJECT_FOUND AND LIBXML2_FOUND AND OPENGL_FOUND) +if (GSTREAMER_FOUND AND GSTREAMER_PLUGIN_VIDEO_LIBRARIES AND GSTREAMER_PLUGIN_AUDIO_LIBRARIES AND GLIB2_FOUND AND GOBJECT_FOUND AND LIBXML2_FOUND AND OPENGL_FOUND) set(BUILD_PHONON_GSTREAMER TRUE) -else (GSTREAMER_FOUND AND GSTREAMER_PLUGIN_VIDEO_LIBRARIES AND GLIB2_FOUND AND GOBJECT_FOUND AND LIBXML2_FOUND AND OPENGL_FOUND) +else (GSTREAMER_FOUND AND GSTREAMER_PLUGIN_VIDEO_LIBRARIES AND GSTREAMER_PLUGIN_AUDIO_LIBRARIES AND GLIB2_FOUND AND GOBJECT_FOUND AND LIBXML2_FOUND AND OPENGL_FOUND) set(BUILD_PHONON_GSTREAMER FALSE) -endif (GSTREAMER_FOUND AND GSTREAMER_PLUGIN_VIDEO_LIBRARIES AND GLIB2_FOUND AND GOBJECT_FOUND AND LIBXML2_FOUND AND OPENGL_FOUND) +endif (GSTREAMER_FOUND AND GSTREAMER_PLUGIN_VIDEO_LIBRARIES AND GSTREAMER_PLUGIN_AUDIO_LIBRARIES AND GLIB2_FOUND AND GOBJECT_FOUND AND LIBXML2_FOUND AND OPENGL_FOUND) diff --git a/src/3rdparty/phonon/gstreamer/audiodataoutput.cpp b/src/3rdparty/phonon/gstreamer/audiodataoutput.cpp new file mode 100644 index 0000000..30dabdf --- /dev/null +++ b/src/3rdparty/phonon/gstreamer/audiodataoutput.cpp @@ -0,0 +1,143 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Matthias Kretz + Copyright (C) 2009 Martin Sandsmark + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#include "audiodataoutput.h" +#include "gsthelper.h" +#include "medianode.h" +#include "mediaobject.h" +#include +#include +#include + +namespace Phonon +{ +namespace Gstreamer +{ +AudioDataOutput::AudioDataOutput(Backend *backend, QObject *parent) + : QObject(parent), + MediaNode(backend, AudioSink | AudioSource) +{ + static int count = 0; + m_name = "AudioDataOutput" + QString::number(count++); + + m_queue = gst_element_factory_make ("identity", NULL); + gst_object_ref(m_queue); + m_isValid = true; +} + +AudioDataOutput::~AudioDataOutput() +{ + gst_element_set_state(m_queue, GST_STATE_NULL); + gst_object_unref(m_queue); +} + +int AudioDataOutput::dataSize() const +{ + return m_dataSize; +} + +int AudioDataOutput::sampleRate() const +{ + return 44100; +} + +void AudioDataOutput::setDataSize(int size) +{ + m_dataSize = size; +} + +typedef QMap > FloatMap; +typedef QMap > IntMap; + +inline void AudioDataOutput::convertAndEmit(const QVector &leftBuffer, const QVector &rightBuffer) +{ + //TODO: Floats + IntMap map; + map.insert(Phonon::AudioDataOutput::LeftChannel, leftBuffer); + map.insert(Phonon::AudioDataOutput::RightChannel, rightBuffer); + emit dataReady(map); +} + +void AudioDataOutput::processBuffer(GstPad*, GstBuffer* buffer, gpointer gThat) +{ + // TODO emit endOfMedia + AudioDataOutput *that = reinterpret_cast(gThat); + + // determine the number of channels + GstStructure* structure = gst_caps_get_structure (GST_BUFFER_CAPS(buffer), 0); + gst_structure_get_int (structure, "channels", &that->m_channels); + + if (that->m_channels > 2 || that->m_channels < 0) { + qWarning() << Q_FUNC_INFO << ": Number of channels not supported: " << that->m_channels; + return; + } + + gint16 *data = reinterpret_cast(GST_BUFFER_DATA(buffer)); + guint size = GST_BUFFER_SIZE(buffer) / sizeof(gint16); + + that->m_pendingData.reserve(that->m_pendingData.size() + size); + + for (uint i=0; im_pendingData.append(data[i]); + } + + while (that->m_pendingData.size() > that->m_dataSize * that->m_channels) { + if (that->m_channels == 1) { + QVector intBuffer(that->m_dataSize); + memcpy(intBuffer.data(), that->m_pendingData.constData(), that->m_dataSize * sizeof(qint16)); + + that->convertAndEmit(intBuffer, intBuffer); + int newSize = that->m_pendingData.size() - that->m_dataSize; + memmove(that->m_pendingData.data(), that->m_pendingData.constData() + that->m_dataSize, newSize * sizeof(qint16)); + that->m_pendingData.resize(newSize); + } else { + QVector left(that->m_dataSize), right(that->m_dataSize); + for (int i=0; im_dataSize; i++) { + left[i] = that->m_pendingData[i*2]; + right[i] = that->m_pendingData[i*2+1]; + } + that->m_pendingData.resize(that->m_pendingData.size() - that->m_dataSize*2); + that->convertAndEmit(left, right); + } + } +} + +void AudioDataOutput::mediaNodeEvent(const MediaNodeEvent *event) +{ + if (event->type() == MediaNodeEvent::MediaObjectConnected && root()) { + g_object_set(G_OBJECT(audioElement()), "sync", true, (const char*)NULL); + GstPad *audiopad = gst_element_get_pad (audioElement(), "src"); + gst_pad_add_buffer_probe (audiopad, G_CALLBACK(processBuffer), this); + gst_object_unref (audiopad); + return; + } + + MediaNode::mediaNodeEvent(event); +} + +}} //namespace Phonon::Gstreamer + +#include "moc_audiodataoutput.cpp" +// vim: sw=4 ts=4 + diff --git a/src/3rdparty/phonon/gstreamer/audiodataoutput.h b/src/3rdparty/phonon/gstreamer/audiodataoutput.h new file mode 100644 index 0000000..5e30a1d --- /dev/null +++ b/src/3rdparty/phonon/gstreamer/audiodataoutput.h @@ -0,0 +1,84 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Matthias Kretz + Copyright (C) 2009 Martin Sandsmark + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef Phonon_GSTREAMER_AUDIODATAOUTPUT_H +#define Phonon_GSTREAMER_AUDIODATAOUTPUT_H + +#include "abstractaudiooutput.h" +#include "backend.h" +#include "medianode.h" +#include +#include + +namespace Phonon +{ +namespace Gstreamer +{ + /** + * \author Martin Sandsmark + */ + class AudioDataOutput : public QObject, + public AudioDataOutputInterface, + public MediaNode + { + Q_OBJECT + Q_INTERFACES(Phonon::AudioDataOutputInterface Phonon::Gstreamer::MediaNode) + + public: + AudioDataOutput(Backend *, QObject *); + ~AudioDataOutput(); + + public Q_SLOTS: + int dataSize() const; + int sampleRate() const; + void setDataSize(int size); + + public: + /// callback function for handling new audio data + static void processBuffer(GstPad*, GstBuffer*, gpointer); + + Phonon::AudioDataOutput* frontendObject() const { return m_frontend; } + void setFrontendObject(Phonon::AudioDataOutput *frontend) { m_frontend = frontend; } + + GstElement *audioElement() { return m_queue; } + + void mediaNodeEvent(const MediaNodeEvent *event); + + + signals: + void dataReady(const QMap > &data); + void dataReady(const QMap > &data); + void endOfMedia(int remainingSamples); + + private: + void convertAndEmit(const QVector&, const QVector&); + + GstElement *m_queue; + int m_dataSize; + QVector m_pendingData; + Phonon::AudioDataOutput *m_frontend; + int m_channels; + }; +}} //namespace Phonon::Gstreamer + +// vim: sw=4 ts=4 tw=80 +#endif // Phonon_FAKE_AUDIODATAOUTPUT_H diff --git a/src/3rdparty/phonon/gstreamer/audiooutput.cpp b/src/3rdparty/phonon/gstreamer/audiooutput.cpp index 641ff6b..f3137b2 100644 --- a/src/3rdparty/phonon/gstreamer/audiooutput.cpp +++ b/src/3rdparty/phonon/gstreamer/audiooutput.cpp @@ -125,6 +125,7 @@ void AudioOutput::setVolume(qreal newVolume) bool AudioOutput::setOutputDevice(int newDevice) { m_backend->logMessage(Q_FUNC_INFO + QString::number(newDevice), Backend::Info, this); + if (newDevice == m_device) return true; @@ -135,20 +136,11 @@ bool AudioOutput::setOutputDevice(int newDevice) } bool success = false; - const QList deviceList = m_backend->deviceManager()->audioOutputDevices(); - int deviceIdx = -1; - for (int i=0; i= 0) { + if (m_audioSink && newDevice >= 0) { // Save previous state GstState oldState = GST_STATE(m_audioSink); const QByteArray oldDeviceValue = GstHelper::property(m_audioSink, "device"); - const QByteArray deviceId = deviceList.at(deviceIdx).gstId; + const QByteArray deviceId = m_backend->deviceManager()->gstId(newDevice); m_device = newDevice; // We test if the device can be opened by checking if it can go from NULL to READY state @@ -170,7 +162,7 @@ bool AudioOutput::setOutputDevice(int newDevice) deviceId, Backend::Info, this); } - // Note the stopped state should not really be neccessary, but seems to be required to + // Note the stopped state should not really be necessary, but seems to be required to // properly reset after changing the audio state if (root()) { QMetaObject::invokeMethod(root(), "setState", Qt::QueuedConnection, Q_ARG(State, StoppedState)); diff --git a/src/3rdparty/phonon/gstreamer/backend.cpp b/src/3rdparty/phonon/gstreamer/backend.cpp index dab6f35..8c2b42f 100644 --- a/src/3rdparty/phonon/gstreamer/backend.cpp +++ b/src/3rdparty/phonon/gstreamer/backend.cpp @@ -18,6 +18,7 @@ #include "common.h" #include "backend.h" #include "audiooutput.h" +#include "audiodataoutput.h" #include "audioeffect.h" #include "mediaobject.h" #include "videowidget.h" @@ -26,6 +27,7 @@ #include "message.h" #include "volumefadereffect.h" #include +#include #include #include @@ -49,13 +51,17 @@ Backend::Backend(QObject *parent, const QVariantList &) , m_debugLevel(Warning) , m_isValid(false) { + // Initialise PulseAudio support + PulseSupport *pulse = PulseSupport::getInstance(); + pulse->enable(); + connect(pulse, SIGNAL(objectDescriptionChanged(ObjectDescriptionType)), SIGNAL(objectDescriptionChanged(ObjectDescriptionType))); + // In order to support reloading, we only set the app name once... static bool first = true; if (first) { first = false; g_set_application_name(qApp->applicationName().toUtf8()); } - GError *err = 0; bool wasInit = gst_init_check(0, 0, &err); //init gstreamer: must be called before any gst-related functions if (err) @@ -92,6 +98,9 @@ Backend::Backend(QObject *parent, const QVariantList &) Backend::~Backend() { + delete m_effectManager; + delete m_deviceManager; + PulseSupport::shutdown(); } gboolean Backend::busCall(GstBus *bus, GstMessage *msg, gpointer data) @@ -119,18 +128,15 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const case MediaObjectClass: return new MediaObject(this, parent); - case AudioOutputClass: { - AudioOutput *ao = new AudioOutput(this, parent); - m_audioOutputs.append(ao); - return ao; - } + case AudioOutputClass: + return new AudioOutput(this, parent); + #ifndef QT_NO_PHONON_EFFECT case EffectClass: return new AudioEffect(this, args[0].toInt(), parent); #endif //QT_NO_PHONON_EFFECT case AudioDataOutputClass: - logMessage("createObject() : AudioDataOutput not implemented"); - break; + return new AudioDataOutput(this, parent); #ifndef QT_NO_PHONON_VIDEO case VideoDataOutputClass: @@ -244,6 +250,15 @@ QStringList Backend::availableMimeTypes() const } } g_list_free(factoryList); + if (availableMimeTypes.contains("audio/x-vorbis") + && availableMimeTypes.contains("application/x-ogm-audio")) { + if (!availableMimeTypes.contains("audio/x-vorbis+ogg")) + availableMimeTypes.append("audio/x-vorbis+ogg"); + if (!availableMimeTypes.contains("application/ogg")) /* *.ogg */ + availableMimeTypes.append("application/ogg"); + if (!availableMimeTypes.contains("audio/ogg")) /* *.oga */ + availableMimeTypes.append("audio/ogg"); + } availableMimeTypes.sort(); return availableMimeTypes; } @@ -293,14 +308,11 @@ QHash Backend::objectDescriptionProperties(ObjectDescripti switch (type) { case Phonon::AudioOutputDeviceType: { - QList audioDevices = deviceManager()->audioOutputDevices(); - foreach(const AudioDevice &device, audioDevices) { - if (device.id == index) { - ret.insert("name", device.gstId); - ret.insert("description", device.description); - ret.insert("icon", QLatin1String("audio-card")); - break; - } + AudioDevice* ad; + if ((ad = deviceManager()->audioDevice(index))) { + ret.insert("name", ad->gstId); + ret.insert("description", ad->description); + ret.insert("icon", ad->icon); } } break; @@ -429,7 +441,7 @@ EffectManager* Backend::effectManager() const /** * Returns a debuglevel that is determined by the - * PHONON_GSTREAMER_DEBUG environment variable. + * PHONON_GST_DEBUG environment variable. * * Warning - important warnings * Info - general info diff --git a/src/3rdparty/phonon/gstreamer/backend.h b/src/3rdparty/phonon/gstreamer/backend.h index 2aab6fa..d157f11 100644 --- a/src/3rdparty/phonon/gstreamer/backend.h +++ b/src/3rdparty/phonon/gstreamer/backend.h @@ -86,7 +86,6 @@ private Q_SLOTS: private: static gboolean busCall(GstBus *bus, GstMessage *msg, gpointer data); - QList > m_audioOutputs; DeviceManager *m_deviceManager; EffectManager *m_effectManager; diff --git a/src/3rdparty/phonon/gstreamer/devicemanager.cpp b/src/3rdparty/phonon/gstreamer/devicemanager.cpp index 60e860f..c3826eb 100644 --- a/src/3rdparty/phonon/gstreamer/devicemanager.cpp +++ b/src/3rdparty/phonon/gstreamer/devicemanager.cpp @@ -24,6 +24,7 @@ #include "widgetrenderer.h" #include "x11renderer.h" #include "artssink.h" +#include "pulsesupport.h" #ifdef USE_ALSASINK2 #include "alsasink2.h" @@ -44,9 +45,12 @@ namespace Gstreamer AudioDevice::AudioDevice(DeviceManager *manager, const QByteArray &gstId) : gstId(gstId) { - //get an id - static int counter = 0; - id = counter++; + // This should never be called when PulseAudio is active. + Q_ASSERT(!PulseSupport::getInstance()->isActive()); + + id = manager->allocateDeviceId(); + icon = "audio-card"; + //get name from device if (gstId == "default") { description = "Default audio device"; @@ -71,22 +75,25 @@ AudioDevice::AudioDevice(DeviceManager *manager, const QByteArray &gstId) DeviceManager::DeviceManager(Backend *backend) : QObject(backend) , m_backend(backend) + , m_audioDeviceCounter(0) { - m_audioSink = qgetenv("PHONON_GST_AUDIOSINK"); - m_videoSinkWidget = qgetenv("PHONON_GST_VIDEOMODE"); - -#ifndef QT_NO_SETTINGS QSettings settings(QLatin1String("Trolltech")); settings.beginGroup(QLatin1String("Qt")); + PulseSupport *pulse = PulseSupport::getInstance(); + m_audioSink = qgetenv("PHONON_GST_AUDIOSINK"); if (m_audioSink.isEmpty()) { m_audioSink = settings.value(QLatin1String("audiosink"), "Auto").toByteArray().toLower(); + if (m_audioSink == "auto" && pulse->isActive()) + m_audioSink = "pulsesink"; } + if ("pulsesink" != m_audioSink) + pulse->enable(false); + m_videoSinkWidget = qgetenv("PHONON_GST_VIDEOMODE"); if (m_videoSinkWidget.isEmpty()) { m_videoSinkWidget = settings.value(QLatin1String("videomode"), "Auto").toByteArray().toLower(); } -#endif //QT_NO_SETTINGS if (m_backend->isValid()) updateDeviceList(); @@ -271,9 +278,17 @@ AbstractRenderer *DeviceManager::createVideoRenderer(VideoWidget *parent) } #endif //QT_NO_PHONON_VIDEO -/* - * Returns a positive device id or -1 if device - * does not exist +/** + * Allocate a device id for a new audio device + */ +int DeviceManager::allocateDeviceId() +{ + return m_audioDeviceCounter++; +} + + +/** + * Returns a positive device id or -1 if device does not exist * * The gstId is typically in the format hw:1,0 */ @@ -288,16 +303,30 @@ int DeviceManager::deviceId(const QByteArray &gstId) const } /** - * Get a human-readable description from a device id + * Returns a gstId or "default" if device does not exist + * + * The gstId is typically in the format hw:1,0 */ -QByteArray DeviceManager::deviceDescription(int id) const +const QByteArray DeviceManager::gstId(int deviceId) +{ + if (!PulseSupport::getInstance()->isActive()) { + AudioDevice *ad = audioDevice(deviceId); + if (ad) + return QByteArray(ad->gstId); + } + return QByteArray("default"); +} + +/** +* Get the AudioDevice for a given device id +*/ +AudioDevice* DeviceManager::audioDevice(int id) { for (int i = 0 ; i < m_audioDeviceList.size() ; ++i) { - if (m_audioDeviceList[i].id == id) { - return m_audioDeviceList[i].description; - } + if (m_audioDeviceList[i].id == id) + return &m_audioDeviceList[i]; } - return QByteArray(); + return NULL; } /** @@ -311,8 +340,11 @@ void DeviceManager::updateDeviceList() QList list; if (audioSink) { - list = GstHelper::extractProperties(audioSink, "device"); - list.prepend("default"); + if (!PulseSupport::getInstance()->isActive()) { + // If we're using pulse, the PulseSupport class takes care of things for us. + list = GstHelper::extractProperties(audioSink, "device"); + list.prepend("default"); + } for (int i = 0 ; i < list.size() ; ++i) { QByteArray gstId = list.at(i); diff --git a/src/3rdparty/phonon/gstreamer/devicemanager.h b/src/3rdparty/phonon/gstreamer/devicemanager.h index a5e8289..9c6aa8d 100644 --- a/src/3rdparty/phonon/gstreamer/devicemanager.h +++ b/src/3rdparty/phonon/gstreamer/devicemanager.h @@ -42,6 +42,7 @@ public : int id; QByteArray gstId; QByteArray description; + QString icon; }; class DeviceManager : public QObject { @@ -51,8 +52,10 @@ public: virtual ~DeviceManager(); const QList audioOutputDevices() const; GstPad *requestPad(int device) const; + int allocateDeviceId(); int deviceId(const QByteArray &gstId) const; - QByteArray deviceDescription(int id) const; + const QByteArray gstId(int id); + AudioDevice* audioDevice(int id); GstElement *createGNOMEAudioSink(Category category); GstElement *createAudioSink(Category category = NoCategory); AbstractRenderer *createVideoRenderer(VideoWidget *parent); @@ -68,6 +71,7 @@ private: bool canOpenDevice(GstElement *element) const; Backend *m_backend; QList m_audioDeviceList; + int m_audioDeviceCounter; QTimer m_devicePollTimer; QByteArray m_audioSink; QByteArray m_videoSinkWidget; diff --git a/src/3rdparty/phonon/gstreamer/effectmanager.cpp b/src/3rdparty/phonon/gstreamer/effectmanager.cpp index 563e6fc..6c88148 100644 --- a/src/3rdparty/phonon/gstreamer/effectmanager.cpp +++ b/src/3rdparty/phonon/gstreamer/effectmanager.cpp @@ -54,7 +54,7 @@ EffectManager::EffectManager(Backend *backend) // "volume" not needed // "equalizer-nbands" not really useful at the moment - // These plugins simply dont work or have major stability issues: + // These plugins simply don't work or have major stability issues: // "iir" Does not seem to do much at the moment // "audioinvert" Only works for some streams, should be invesigated // "lpwsinc" Crashes for large values of filter kernel diff --git a/src/3rdparty/phonon/gstreamer/glrenderer.cpp b/src/3rdparty/phonon/gstreamer/glrenderer.cpp index 6cf3459..c72780a 100644 --- a/src/3rdparty/phonon/gstreamer/glrenderer.cpp +++ b/src/3rdparty/phonon/gstreamer/glrenderer.cpp @@ -266,7 +266,7 @@ GLRenderWidgetImplementation::GLRenderWidgetImplementation(VideoWidget*videoWidg palette.setColor(QPalette::Background, Qt::black); setPalette(palette); setAutoFillBackground(true); - // Videowidget allways have this property to allow hiding the mouse cursor + // Videowidget always have this property to allow hiding the mouse cursor setMouseTracking(true); } diff --git a/src/3rdparty/phonon/gstreamer/gsthelper.cpp b/src/3rdparty/phonon/gstreamer/gsthelper.cpp index 34d99fa..69bb75c 100644 --- a/src/3rdparty/phonon/gstreamer/gsthelper.cpp +++ b/src/3rdparty/phonon/gstreamer/gsthelper.cpp @@ -121,7 +121,7 @@ GstElement* GstHelper::createPluggablePlaybin() { GstElement *playbin = 0; //init playbin and add to our pipeline - playbin = gst_element_factory_make("playbin", NULL); + playbin = gst_element_factory_make("playbin2", NULL); //Create an identity element to redirect sound GstElement *audioSinkBin = gst_bin_new (NULL); diff --git a/src/3rdparty/phonon/gstreamer/gstreamer.desktop b/src/3rdparty/phonon/gstreamer/gstreamer.desktop index b62472b..0861762 100644 --- a/src/3rdparty/phonon/gstreamer/gstreamer.desktop +++ b/src/3rdparty/phonon/gstreamer/gstreamer.desktop @@ -10,28 +10,81 @@ Icon=phonon-gstreamer InitialPreference=10 Name=GStreamer +Name[bg]=GStreamer +Name[ca]=GStreamer +Name[ca@valencia]=GStreamer +Name[cs]=GStreamer +Name[da]=GStreamer +Name[de]=GStreamer +Name[el]=GStreamer +Name[en_GB]=GStreamer +Name[es]=GStreamer +Name[et]=GStreamer +Name[eu]=GStreamer +Name[fi]=GStreamer +Name[fr]=GStreamer +Name[ga]=GStreamer +Name[gl]=GStreamer +Name[hsb]=GStreamer +Name[hu]=GStreamer +Name[id]=GStreamer +Name[is]=GStreamer +Name[it]=GStreamer +Name[ja]=GStreamer +Name[ko]=GStreamer +Name[ku]=GStreamer +Name[lt]=GStreamer +Name[lv]=GStreamer +Name[nb]=GStreamer +Name[nds]=GStreamer +Name[nl]=GStreamer +Name[nn]=GStreamer Name[pa]=ਜੀਸਟੀਰਮਰ +Name[pl]=GStreamer +Name[pt]=GStreamer +Name[pt_BR]=GStreamer +Name[ru]=GStreamer +Name[se]=GStreamer +Name[sk]=GStreamer +Name[sl]=GStreamer Name[sr]=ГÑтример +Name[sr@ijekavian]=ГÑтример +Name[sr@ijekavianlatin]=GStreamer +Name[sr@latin]=GStreamer Name[sv]=Gstreamer +Name[tr]=GStreamer +Name[uk]=GStreamer Name[x-test]=xxGStreamerxx +Name[zh_CN]=GStreamer +Name[zh_TW]=GStreamer Comment=Phonon GStreamer backend Comment[bg]=Phonon GStreamer Comment[ca]=Dorsal GStreamer del Phonon +Comment[ca@valencia]=Dorsal GStreamer del Phonon +Comment[cs]=Phonon GStreamer backend Comment[da]=GStreamer-backend til Phonon Comment[de]=Phonon-Treiber für GStreamer Comment[el]=ΣÏστημα υποστήÏιξης GStreamer του Phonon +Comment[en_GB]=Phonon GStreamer backend Comment[es]=Motor GStreamer para Phonon Comment[et]=Phononi GStreameri taustaprogramm +Comment[eu]=Phonon GStreamer backend +Comment[fi]=Phonon GStreamer-taustaohjelma Comment[fr]=Système de gestion GStreamer pour Phonon Comment[ga]=Inneall GStreamer le haghaidh Phonon Comment[gl]=Infraestrutura de GStreamer para Phonon +Comment[hsb]=Phonon GStreamer backend +Comment[hu]=Phonon GStreamer modul +Comment[id]=Phonon GStreamer backend Comment[is]=Phonon GStreamer bakendi Comment[it]=Motore Gstreamer di Phonon Comment[ja]=Phonon GStreamer ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ Comment[ko]=Phonon GStreamer 백엔드 Comment[ku]=Binesaza Phonon GStreamer +Comment[lt]=Phonon GStreamer galinÄ— sÄ…saja Comment[lv]=Phonon GStreamer aizmugure +Comment[nb]=Phonon-motor for GStreamer Comment[nds]=Phonon-Hülpprogramm GStreamer Comment[nl]=GStreamer-backend (Phonon) Comment[nn]=Phonon-motor for GStreamer @@ -39,9 +92,13 @@ Comment[pa]=ਫੋਨੋਨ ਜਸਟੀਰਮਰ ਬੈਕà¨à¨‚ਡ Comment[pl]=ObsÅ‚uga GStreamera przez Phonon Comment[pt]=Infra-estrutura do GStreamer para o Phonon Comment[pt_BR]=Infraestrutura Phonon GStreamer +Comment[ru]=Механизм GStreamer Ð´Ð»Ñ Phonon +Comment[se]=Phonon GStreamer duogášmohtor Comment[sk]=GStreamer podsystém Comment[sl]=Phononova hrbtenica GStreamer Comment[sr]=ГÑтример као позадина Фонона +Comment[sr@ijekavian]=ГÑтример као позадина Фонона +Comment[sr@ijekavianlatin]=GStreamer kao pozadina Phonona Comment[sr@latin]=GStreamer kao pozadina Phonona Comment[sv]=Phonon Gstreamer-gränssnitt Comment[tr]=Phonon GStreamer arka ucu diff --git a/src/3rdparty/phonon/gstreamer/medianode.cpp b/src/3rdparty/phonon/gstreamer/medianode.cpp index 7257972..1a84592 100644 --- a/src/3rdparty/phonon/gstreamer/medianode.cpp +++ b/src/3rdparty/phonon/gstreamer/medianode.cpp @@ -198,9 +198,9 @@ bool MediaNode::disconnectNode(QObject *obj) // Disconnecting elements while playing or paused seems to cause // potential deadlock. Hence we force the pipeline into ready state // before any nodes are disconnected. - gst_element_set_state(root()->pipeline(), GST_STATE_READY); + gst_element_set_state(root()->pipeline(), GST_STATE_READY); - Q_ASSERT(sink->root()); //sink has to have a root since it is onnected + Q_ASSERT(sink->root()); //sink has to have a root since it is connected if (sink->description() & (AudioSink)) { GstPad *sinkPad = gst_element_get_pad(sink->audioElement(), "sink"); diff --git a/src/3rdparty/phonon/gstreamer/mediaobject.cpp b/src/3rdparty/phonon/gstreamer/mediaobject.cpp index b6d23ec..3e0addc 100644 --- a/src/3rdparty/phonon/gstreamer/mediaobject.cpp +++ b/src/3rdparty/phonon/gstreamer/mediaobject.cpp @@ -16,6 +16,7 @@ */ #include #include +#include #include "common.h" #include "mediaobject.h" #include "videowidget.h" @@ -53,6 +54,7 @@ MediaObject::MediaObject(Backend *backend, QObject *parent) , m_tickTimer(new QTimer(this)) , m_prefinishMark(0) , m_transitionTime(0) + , m_isStream(false) , m_posAtSeek(-1) , m_prefinishMarkReachedNotEmitted(true) , m_aboutToFinishEmitted(false) @@ -79,6 +81,7 @@ MediaObject::MediaObject(Backend *backend, QObject *parent) , m_autoplayTitles(true) , m_availableTitles(0) , m_currentTitle(1) + , m_pendingTitle(1) { qRegisterMetaType("GstCaps*"); qRegisterMetaType("State"); @@ -95,8 +98,8 @@ MediaObject::MediaObject(Backend *backend, QObject *parent) m_backend->addBusWatcher(this); connect(m_tickTimer, SIGNAL(timeout()), SLOT(emitTick())); } - connect(this, SIGNAL(stateChanged(Phonon::State,Phonon::State)), - this, SLOT(notifyStateChange(Phonon::State,Phonon::State))); + connect(this, SIGNAL(stateChanged(Phonon::State, Phonon::State)), + this, SLOT(notifyStateChange(Phonon::State, Phonon::State))); } @@ -136,6 +139,14 @@ QString stateString(const Phonon::State &state) return QString(); } +void +pluginInstallationDone( GstInstallPluginsReturn res, gpointer userData ) +{ + // Nothing inside yet + Q_UNUSED(res); + Q_UNUSED(userData); +} + void MediaObject::saveState() { //Only first resumeState is respected @@ -195,13 +206,35 @@ void MediaObject::noMorePadsAvailable () if (m_missingCodecs.size() > 0) { bool canPlay = (m_hasAudio || m_videoStreamFound); Phonon::ErrorType error = canPlay ? Phonon::NormalError : Phonon::FatalError; +#ifdef PLUGIN_INSTALL_API + GstInstallPluginsContext *ctx = gst_install_plugins_context_new (); + gchar *details[2]; + details[0] = m_missingCodecs[0].toLocal8Bit().data(); + details[1] = NULL; + GstInstallPluginsReturn status; + + status = gst_install_plugins_async( details, ctx, pluginInstallationDone, NULL ); + gst_install_plugins_context_free ( ctx ); + + if ( status != GST_INSTALL_PLUGINS_STARTED_OK ) + { + if( status == GST_INSTALL_PLUGINS_HELPER_MISSING ) + setError(QString(tr("Missing codec helper script assistant.")), Phonon::FatalError ); + else + setError(QString(tr("Plugin codec installation failed for codec: %0")) + .arg(m_missingCodecs[0].split("|")[3]), error); + } + m_missingCodecs.clear(); +#else + QString codecs = m_missingCodecs.join(", "); + if (error == Phonon::NormalError && m_hasVideo && !m_videoStreamFound) { m_hasVideo = false; emit hasVideoChanged(false); } - QString codecs = m_missingCodecs.join(", "); setError(QString(tr("A required codec is missing. You need to install the following codec(s) to play this content: %0")).arg(codecs), error); m_missingCodecs.clear(); +#endif } } @@ -248,7 +281,16 @@ void MediaObject::cb_unknown_type (GstElement *decodebin, GstPad *pad, GstCaps * value = QString::fromUtf8(gst_structure_get_name (str)); } - media->addMissingCodecName(value); + +#ifdef PLUGIN_INSTALL_API + QString plugins = QString("gstreamer|0.10|%0|%1|decoder-%2") + .arg( qApp->applicationName() ) + .arg( value ) + .arg( QString::fromUtf8(gst_caps_to_string (caps) ) ); + media->addMissingCodecName( plugins ); +#else + media->addMissingCodecName( value ); +#endif } static void notifyVideoCaps(GObject *obj, GParamSpec *, gpointer data) @@ -309,7 +351,7 @@ void MediaObject::connectVideo(GstPad *pad) m_backend->logMessage("Video track connected", Backend::Info, this); // Note that the notify::caps _must_ be installed after linking to work with Dapper m_capsHandler = g_signal_connect(pad, "notify::caps", G_CALLBACK(notifyVideoCaps), this); - + if (!m_loading && !m_hasVideo) { m_hasVideo = m_videoStreamFound; emit hasVideoChanged(m_hasVideo); @@ -368,7 +410,10 @@ bool MediaObject::createPipefromURL(const QUrl &url) } // Create a new datasource based on the input URL - QByteArray encoded_cstr_url = url.toEncoded(); + // add the 'file' scheme if it's missing; the double '/' is needed! + QByteArray encoded_cstr_url = (url.scheme() == QLatin1String("") ? + "file://" + url.toEncoded() : + url.toEncoded()); m_datasource = gst_element_make_from_uri(GST_URI_SRC, encoded_cstr_url.constData(), (const char*)NULL); if (!m_datasource) return false; @@ -388,6 +433,14 @@ bool MediaObject::createPipefromURL(const QUrl &url) g_object_set (G_OBJECT (m_datasource), "read-speed", 2, (const char*)NULL); m_backend->logMessage(QString("new device speed : 2X"), Backend::Info, this); } + } + + /* make HTTP sources send extra headers so we get icecast + * metadata in case the stream is an icecast stream */ + if (encoded_cstr_url.startsWith("http://") + && g_object_class_find_property (G_OBJECT_GET_CLASS (m_datasource), "iradio-mode")) { + g_object_set (m_datasource, "iradio-mode", TRUE, NULL); + m_isStream = true; } // Link data source into pipeline @@ -442,7 +495,7 @@ void MediaObject::createPipeline() gst_object_ref (GST_OBJECT (m_pipeline)); gst_object_sink (GST_OBJECT (m_pipeline)); - m_decodebin = gst_element_factory_make ("decodebin", NULL); + m_decodebin = gst_element_factory_make ("decodebin2", NULL); g_signal_connect (m_decodebin, "new-decoded-pad", G_CALLBACK (&cb_newpad), this); g_signal_connect (m_decodebin, "unknown-type", G_CALLBACK (&cb_unknown_type), this); g_signal_connect (m_decodebin, "no-more-pads", G_CALLBACK (&cb_no_more_pads), this); @@ -646,7 +699,7 @@ void MediaObject::setState(State newstate) m_backend->logMessage("EOS already reached", Backend::Info, this); } else if (currentState == GST_STATE_PLAYING) { changeState(Phonon::PlayingState); - } else if (!m_atEndOfStream && gst_element_set_state(m_pipeline, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE) { + } else if (gst_element_set_state(m_pipeline, GST_STATE_PLAYING) != GST_STATE_CHANGE_FAILURE) { m_pendingState = Phonon::PlayingState; } else { m_backend->logMessage("phonon state request failed", Backend::Info, this); @@ -676,7 +729,7 @@ void MediaObject::changeState(State newstate) return; Phonon::State oldState = m_state; - m_state = newstate; // m_state must be set before emitting, since + m_state = newstate; // m_state must be set before emitting, since // Error state requires that state() will return the new value m_pendingState = newstate; emit stateChanged(newstate, oldState); @@ -696,6 +749,8 @@ void MediaObject::changeState(State newstate) case Phonon::StoppedState: m_backend->logMessage("phonon state changed: Stopped", Backend::Info, this); + // We must reset the pipeline when playing again + m_resetNeeded = true; m_tickTimer->stop(); break; @@ -861,7 +916,7 @@ void MediaObject::setSource(const MediaSource &source) // such as failing duration queries etc GstState state; gst_element_set_state(m_pipeline, GST_STATE_NULL); - gst_element_get_state (m_pipeline, &state, NULL, 2000); + gst_element_get_state(m_pipeline, &state, NULL, 2000); m_source = source; emit currentSourceChanged(m_source); @@ -871,7 +926,9 @@ void MediaObject::setSource(const MediaSource &source) // Go into to loading state changeState(Phonon::LoadingState); m_loading = true; - m_resetNeeded = false; + // IMPORTANT: Honor the m_resetNeeded flag as it currently stands. + // See https://qa.mandriva.com/show_bug.cgi?id=56807 + //m_resetNeeded = false; m_resumeState = false; m_pendingState = Phonon::StoppedState; @@ -884,8 +941,8 @@ void MediaObject::setSource(const MediaSource &source) // Clear any existing errors m_aboutToFinishEmitted = false; m_error = NoError; - m_errorString = QString(); - + m_errorString.clear(); + m_bufferPercent = 0; m_prefinishMarkReachedNotEmitted = true; m_aboutToFinishEmitted = false; @@ -894,22 +951,23 @@ void MediaObject::setSource(const MediaSource &source) setTotalTime(-1); m_atEndOfStream = false; - // Clear exising meta tags + m_availableTitles = 0; + m_pendingTitle = 1; + m_currentTitle = 1; + + // Clear existing meta tags m_metaData.clear(); + m_isStream = false; switch (source.type()) { - case MediaSource::Url: { - if (createPipefromURL(source.url())) - m_loading = true; - else + case MediaSource::Url: { + if (!createPipefromURL(source.url())) setError(tr("Could not open media source.")); } break; case MediaSource::LocalFile: { - if (createPipefromURL(QUrl::fromLocalFile(source.fileName()))) - m_loading = true; - else + if (!createPipefromURL(QUrl::fromLocalFile(source.fileName()))) setError(tr("Could not open media source.")); } break; @@ -922,17 +980,15 @@ void MediaObject::setSource(const MediaSource &source) break; case MediaSource::Stream: - if (createPipefromStream(source)) - m_loading = true; - else + if (!createPipefromStream(source)) setError(tr("Could not open media source.")); break; case MediaSource::Disc: { - QString mediaUrl; - switch (source.discType()) { - case Phonon::NoDisc: + QString mediaUrl; + switch (source.discType()) { + case Phonon::NoDisc: qWarning() << "I should never get to see a MediaSource that is a disc but doesn't specify which one"; return; case Phonon::Cd: // CD tracks can be specified by setting the url in the following way uri=cdda:4 @@ -948,9 +1004,7 @@ void MediaObject::setSource(const MediaSource &source) qWarning() << "media " << source.discType() << " not implemented"; return; } - if (!mediaUrl.isEmpty() && createPipefromURL(QUrl(mediaUrl))) - m_loading = true; - else + if (mediaUrl.isEmpty() || !createPipefromURL(QUrl(mediaUrl))) setError(tr("Could not open media source.")); } break; @@ -966,8 +1020,7 @@ void MediaObject::setSource(const MediaSource &source) // We need to link this node to ensure that fake sinks are connected // before loading, otherwise the stream will be blocked - if (m_loading) - link(); + link(); beginLoad(); } @@ -1004,22 +1057,22 @@ void MediaObject::getStreamInfo() emit hasVideoChanged(m_hasVideo); } - m_availableTitles = 1; - gint64 titleCount; - GstFormat format = gst_format_get_by_nick("track"); - if (gst_element_query_duration (m_pipeline, &format, &titleCount)) { + if (m_source.discType() == Phonon::Cd) { + gint64 titleCount; + GstFormat format = gst_format_get_by_nick("track"); + if (gst_element_query_duration (m_pipeline, &format, &titleCount)) { //check if returned format is still "track", //gstreamer sometimes returns the total time, if tracks information is not available. - if (qstrcmp(gst_format_get_name(format), "track") == 0) { - int oldAvailableTitles = m_availableTitles; - m_availableTitles = (int)titleCount; - if (m_availableTitles != oldAvailableTitles) { - emit availableTitlesChanged(m_availableTitles); - m_backend->logMessage(QString("Available titles changed: %0").arg(m_availableTitles), Backend::Info, this); + if (qstrcmp(gst_format_get_name(format), "track") == 0) { + int oldAvailableTitles = m_availableTitles; + m_availableTitles = (int)titleCount; + if (m_availableTitles != oldAvailableTitles) { + emit availableTitlesChanged(m_availableTitles); + m_backend->logMessage(QString("Available titles changed: %0").arg(m_availableTitles), Backend::Info, this); + } } } } - } void MediaObject::setPrefinishMark(qint32 newPrefinishMark) @@ -1077,7 +1130,7 @@ void MediaObject::seek(qint64 time) } quint64 current = currentTime(); - quint64 total = totalTime(); + quint64 total = totalTime(); if (current < total - m_prefinishMark) m_prefinishMarkReachedNotEmitted = true; @@ -1098,7 +1151,7 @@ void MediaObject::emitTick() if (m_tickInterval > 0 && currentTime != m_previousTickTime) { emit tick(currentTime); - m_previousTickTime = currentTime; + m_previousTickTime = currentTime; } if (m_state == Phonon::PlayingState) { if (currentTime >= totalTime - m_prefinishMark) { @@ -1109,7 +1162,12 @@ void MediaObject::emitTick() } // Prepare load of next source if (currentTime >= totalTime - ABOUT_TO_FINNISH_TIME) { - if (!m_aboutToFinishEmitted) { + if (m_source.type() == MediaSource::Disc && + m_autoplayTitles && + m_availableTitles > 1 && + m_currentTitle < m_availableTitles) { + m_aboutToFinishEmitted = false; + } else if (!m_aboutToFinishEmitted) { m_aboutToFinishEmitted = true; // track is about to finish emit aboutToFinish(); } @@ -1213,8 +1271,8 @@ void MediaObject::handleBusMessage(const Message &message) switch (GST_MESSAGE_TYPE (gstMessage)) { - case GST_MESSAGE_EOS: - m_backend->logMessage("EOS recieved", Backend::Info, this); + case GST_MESSAGE_EOS: + m_backend->logMessage("EOS received", Backend::Info, this); handleEndOfStream(); break; @@ -1222,14 +1280,98 @@ void MediaObject::handleBusMessage(const Message &message) GstTagList* tag_list = 0; gst_message_parse_tag(gstMessage, &tag_list); if (tag_list) { + TagMap newTags; + gst_tag_list_foreach (tag_list, &foreach_tag_function, &newTags); + gst_tag_list_free(tag_list); + + // Determine if we should no fake the album/artist tags. + // This is a little confusing as we want to fake it on initial + // connection where title, album and artist are all missing. + // There are however times when we get just other information, + // e.g. codec, and so we want to only do clever stuff if we + // have a commonly available tag (ORGANIZATION) or we have a + // change in title + bool fake_it = + (m_isStream + && ((!newTags.contains("TITLE") + && newTags.contains("ORGANIZATION")) + || (newTags.contains("TITLE") + && m_metaData.value("TITLE") != newTags.value("TITLE"))) + && !newTags.contains("ALBUM") + && !newTags.contains("ARTIST")); + TagMap oldMap = m_metaData; // Keep a copy of the old one for reference - // Append any new meta tags to the existing tag list - gst_tag_list_foreach (tag_list, &foreach_tag_function, &m_metaData); + + // Now we've checked the new data, append any new meta tags to the existing tag list + // We cannot use TagMap::iterator as this is a multimap and when streaming data + // could in theory be lost. + QList keys = newTags.keys(); + for (QList::iterator i = keys.begin(); i != keys.end(); ++i) { + QString key = *i; + if (m_isStream) { + // If we're streaming, we need to remove data in m_metaData + // in order to stop it filling up indefinitely (as it's a multimap) + m_metaData.remove(key); + } + QList values = newTags.values(key); + for (QList::iterator j = values.begin(); j != values.end(); ++j) { + QString value = *j; + QString currVal = m_metaData.value(key); + if (!m_metaData.contains(key) || currVal != value) { + m_metaData.insert(key, value); + } + } + } + m_backend->logMessage("Meta tags found", Backend::Info, this); - if (oldMap != m_metaData && !m_loading) - emit metaDataChanged(m_metaData); - gst_tag_list_free(tag_list); - } + if (oldMap != m_metaData) { + // This is a bit of a hack to ensure that stream metadata is + // returned. We get as much as we can from the Shoutcast server's + // StreamTitle= header. If further info is decoded from the stream + // itself later, then it will overwrite this info. + if (m_isStream && fake_it) { + m_metaData.remove("ALBUM"); + m_metaData.remove("ARTIST"); + + // Detect whether we want to "fill in the blanks" + QString str; + if (m_metaData.contains("TITLE")) + { + str = m_metaData.value("TITLE"); + int splitpoint; + // Check to see if our title matches "%s - %s" + // Where neither %s are empty... + if ((splitpoint = str.indexOf(" - ")) > 0 + && str.size() > (splitpoint+3)) { + m_metaData.insert("ARTIST", str.left(splitpoint)); + m_metaData.replace("TITLE", str.mid(splitpoint+3)); + } + } else { + str = m_metaData.value("GENRE"); + if (!str.isEmpty()) + m_metaData.insert("TITLE", str); + else + m_metaData.insert("TITLE", "Streaming Data"); + } + if (!m_metaData.contains("ARTIST")) { + str = m_metaData.value("LOCATION"); + if (!str.isEmpty()) + m_metaData.insert("ARTIST", str); + else + m_metaData.insert("ARTIST", "Streaming Data"); + } + str = m_metaData.value("ORGANIZATION"); + if (!str.isEmpty()) + m_metaData.insert("ALBUM", str); + else + m_metaData.insert("ALBUM", "Streaming Data"); + } + // As we manipulate the title, we need to recompare + // oldMap and m_metaData here... + if (oldMap != m_metaData && !m_loading) + emit metaDataChanged(m_metaData); + } + } } break; @@ -1255,6 +1397,9 @@ void MediaObject::handleBusMessage(const Message &message) m_backend->logMessage("gstreamer: pipeline state set to playing", Backend::Info, this); m_tickTimer->start(); changeState(Phonon::PlayingState); + if ((m_source.type() == MediaSource::Disc) && (m_currentTitle != m_pendingTitle)) { + setTrack(m_pendingTitle); + } if (m_resumeState && m_oldState == Phonon::PlayingState) { seek(m_oldPos); m_resumeState = false; @@ -1290,6 +1435,9 @@ void MediaObject::handleBusMessage(const Message &message) changeState(Phonon::StoppedState); m_backend->logMessage("gstreamer: pipeline state set to ready", Backend::Debug, this); m_tickTimer->stop(); + if ((m_source.type() == MediaSource::Disc) && (m_currentTitle != m_pendingTitle)) { + setTrack(m_pendingTitle); + } break; case GST_STATE_VOID_PENDING : @@ -1328,7 +1476,7 @@ void MediaObject::handleBusMessage(const Message &message) setError(err->message, Phonon::FatalError); gst_caps_unref (caps); gst_object_unref (sinkPad); - } + } } else { setError(QString(err->message), Phonon::FatalError); } @@ -1400,8 +1548,8 @@ void MediaObject::handleBusMessage(const Message &message) //case GST_MESSAGE_STEP_DONE: //case GST_MESSAGE_LATENCY: only from 0.10.12 //case GST_MESSAGE_ASYNC_DONE: only from 0.10.13 - default: - break; + default: + break; } } @@ -1417,7 +1565,8 @@ void MediaObject::handleEndOfStream() if (!m_seekable) m_atEndOfStream = true; - if (m_autoplayTitles && + if (m_source.type() == MediaSource::Disc && + m_autoplayTitles && m_availableTitles > 1 && m_currentTitle < m_availableTitles) { _iface_setCurrentTitle(m_currentTitle + 1); @@ -1444,6 +1593,14 @@ void MediaObject::handleEndOfStream() } } +void MediaObject::invalidateGraph() +{ + m_resetNeeded = true; + if (m_state == Phonon::PlayingState || m_state == Phonon::PausedState) { + changeState(Phonon::StoppedState); + } +} + // Notifes the pipeline about state changes in the media object void MediaObject::notifyStateChange(Phonon::State newstate, Phonon::State oldstate) { @@ -1502,15 +1659,30 @@ int MediaObject::_iface_currentTitle() const void MediaObject::_iface_setCurrentTitle(int title) { - GstFormat trackFormat = gst_format_get_by_nick("track"); m_backend->logMessage(QString("setCurrentTitle %0").arg(title), Backend::Info, this); - if ((title == m_currentTitle) || (title < 1) || (title > m_availableTitles)) + if ((title == m_currentTitle) || (title == m_pendingTitle)) + return; + + m_pendingTitle = title; + + if (m_state == Phonon::PlayingState || m_state == Phonon::StoppedState) { + setTrack(m_pendingTitle); + } else { + setState(Phonon::StoppedState); + } +} + +void MediaObject::setTrack(int title) +{ + if (((m_state != Phonon::PlayingState) && (m_state != Phonon::StoppedState)) || (title < 1) || (title > m_availableTitles)) return; - m_currentTitle = title; //let's seek to the beginning of the song - if (gst_element_seek_simple(m_pipeline, trackFormat, GST_SEEK_FLAG_FLUSH, m_currentTitle - 1)) { + GstFormat trackFormat = gst_format_get_by_nick("track"); + m_backend->logMessage(QString("setTrack %0").arg(title), Backend::Info, this); + if (gst_element_seek_simple(m_pipeline, trackFormat, GST_SEEK_FLAG_FLUSH, title - 1)) { + m_currentTitle = title; updateTotalTime(); m_atEndOfStream = false; emit titleChanged(title); diff --git a/src/3rdparty/phonon/gstreamer/mediaobject.h b/src/3rdparty/phonon/gstreamer/mediaobject.h index 64b3510..d588ffc 100644 --- a/src/3rdparty/phonon/gstreamer/mediaobject.h +++ b/src/3rdparty/phonon/gstreamer/mediaobject.h @@ -55,6 +55,7 @@ class MediaObject : public QObject, public MediaObjectInterface , public MediaNode { friend class Stream; + friend class AudioDataOutput; Q_OBJECT Q_INTERFACES(Phonon::MediaObjectInterface #ifndef QT_NO_PHONON_MEDIACONTROLLER @@ -144,12 +145,8 @@ public: void handleBusMessage(const Message &msg); void handleEndOfStream(); void addMissingCodecName(const QString &codec) { m_missingCodecs.append(codec); } - void invalidateGraph() { - m_resetNeeded = true; - if (m_state == Phonon::PlayingState || m_state == Phonon::PausedState) { - changeState(Phonon::StoppedState); - } - } + void invalidateGraph(); + static void cb_newpad (GstElement *decodebin, GstPad *pad, gboolean last, gpointer data); static void cb_pad_added (GstElement *decodebin, GstPad *pad, gpointer data); static void cb_unknown_type (GstElement *decodebin, GstPad *pad, GstCaps *caps, gpointer data); @@ -236,6 +233,7 @@ private: int _iface_availableTitles() const; int _iface_currentTitle() const; void _iface_setCurrentTitle(int title); + void setTrack(int title); bool m_resumeState; State m_oldState; @@ -250,6 +248,7 @@ private: MediaSource m_nextSource; qint32 m_prefinishMark; qint32 m_transitionTime; + bool m_isStream; qint64 m_posAtSeek; @@ -285,6 +284,7 @@ private: bool m_autoplayTitles; int m_availableTitles; int m_currentTitle; + int m_pendingTitle; }; } } //namespace Phonon::Gstreamer diff --git a/src/3rdparty/phonon/gstreamer/qwidgetvideosink.h b/src/3rdparty/phonon/gstreamer/qwidgetvideosink.h index 73a494a..f83dba5 100644 --- a/src/3rdparty/phonon/gstreamer/qwidgetvideosink.h +++ b/src/3rdparty/phonon/gstreamer/qwidgetvideosink.h @@ -19,6 +19,7 @@ #define Phonon_GSTREAMER_VIDEOSINK_H #include "common.h" +#include "qwidgetvideosink.h" #include #include diff --git a/src/3rdparty/phonon/gstreamer/videowidget.h b/src/3rdparty/phonon/gstreamer/videowidget.h index dc0754d..8603f6a 100644 --- a/src/3rdparty/phonon/gstreamer/videowidget.h +++ b/src/3rdparty/phonon/gstreamer/videowidget.h @@ -25,6 +25,7 @@ #include "common.h" #include "medianode.h" #include "abstractrenderer.h" +#include "videowidget.h" #include diff --git a/src/3rdparty/phonon/gstreamer/x11renderer.cpp b/src/3rdparty/phonon/gstreamer/x11renderer.cpp index 73877a8..968f3a8 100644 --- a/src/3rdparty/phonon/gstreamer/x11renderer.cpp +++ b/src/3rdparty/phonon/gstreamer/x11renderer.cpp @@ -90,7 +90,7 @@ GstElement* X11Renderer::createVideoSink() gst_object_unref(GST_OBJECT(videoSink)); videoSink = 0; } else { - // Note that this should not really be neccessary as these are + // Note that this should not really be necessary as these are // default values, though under certain conditions values are retained // even between application instances. (reproducible on 0.10.16/Gutsy) g_object_set(G_OBJECT(videoSink), "brightness", 0, (const char*)NULL); @@ -138,6 +138,7 @@ void X11Renderer::scaleModeChanged(Phonon::VideoWidget::ScaleMode) void X11Renderer::movieSizeChanged(const QSize &movieSize) { Q_UNUSED(movieSize); + if (m_renderWidget) { m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect()); } diff --git a/src/plugins/phonon/gstreamer/gstreamer.pro b/src/plugins/phonon/gstreamer/gstreamer.pro index ae597fa..1013205 100644 --- a/src/plugins/phonon/gstreamer/gstreamer.pro +++ b/src/plugins/phonon/gstreamer/gstreamer.pro @@ -15,6 +15,7 @@ PHONON_GSTREAMER_DIR = $$QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer HEADERS += $$PHONON_GSTREAMER_DIR/common.h \ $$PHONON_GSTREAMER_DIR/audiooutput.h \ + $$PHONON_GSTREAMER_DIR/audiodataoutput.h \ $$PHONON_GSTREAMER_DIR/artssink.h \ $$PHONON_GSTREAMER_DIR/abstractrenderer.h \ $$PHONON_GSTREAMER_DIR/backend.h \ @@ -35,26 +36,27 @@ HEADERS += $$PHONON_GSTREAMER_DIR/common.h \ $$PHONON_GSTREAMER_DIR/audioeffect.h \ $$PHONON_GSTREAMER_DIR/volumefadereffect.h -SOURCES += $$PHONON_GSTREAMER_DIR/audiooutput.cpp \ - $$PHONON_GSTREAMER_DIR/abstractrenderer.cpp \ +SOURCES += $$PHONON_GSTREAMER_DIR/abstractrenderer.cpp \ $$PHONON_GSTREAMER_DIR/artssink.cpp \ + $$PHONON_GSTREAMER_DIR/audioeffect.cpp \ + $$PHONON_GSTREAMER_DIR/audiooutput.cpp \ + $$PHONON_GSTREAMER_DIR/audiodataoutput.cpp \ $$PHONON_GSTREAMER_DIR/backend.cpp \ $$PHONON_GSTREAMER_DIR/devicemanager.cpp \ $$PHONON_GSTREAMER_DIR/effect.cpp \ $$PHONON_GSTREAMER_DIR/effectmanager.cpp \ + $$PHONON_GSTREAMER_DIR/glrenderer.cpp \ $$PHONON_GSTREAMER_DIR/gsthelper.cpp \ - $$PHONON_GSTREAMER_DIR/mediaobject.cpp \ $$PHONON_GSTREAMER_DIR/medianode.cpp \ $$PHONON_GSTREAMER_DIR/medianodeevent.cpp \ - $$PHONON_GSTREAMER_DIR/widgetrenderer.cpp \ - $$PHONON_GSTREAMER_DIR/videowidget.cpp \ - $$PHONON_GSTREAMER_DIR/glrenderer.cpp \ - $$PHONON_GSTREAMER_DIR/qwidgetvideosink.cpp \ + $$PHONON_GSTREAMER_DIR/mediaobject.cpp \ + $$PHONON_GSTREAMER_DIR/message.cpp \ $$PHONON_GSTREAMER_DIR/phononsrc.cpp \ + $$PHONON_GSTREAMER_DIR/qwidgetvideosink.cpp \ $$PHONON_GSTREAMER_DIR/streamreader.cpp \ - $$PHONON_GSTREAMER_DIR/message.cpp \ - $$PHONON_GSTREAMER_DIR/audioeffect.cpp \ - $$PHONON_GSTREAMER_DIR/volumefadereffect.cpp + $$PHONON_GSTREAMER_DIR/videowidget.cpp \ + $$PHONON_GSTREAMER_DIR/volumefadereffect.cpp \ + $$PHONON_GSTREAMER_DIR/widgetrenderer.cpp !embedded { HEADERS += $$PHONON_GSTREAMER_DIR/x11renderer.h -- cgit v0.12 From 19a3fc3bd817628070e5637caf158b0be79eee82 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 25 Mar 2010 14:00:31 +1000 Subject: Update Phonon ds9 backend to 4.4.0. --- src/3rdparty/phonon/ds9/abstractvideorenderer.cpp | 4 +- src/3rdparty/phonon/ds9/backend.cpp | 14 +- src/3rdparty/phonon/ds9/backend.h | 4 - src/3rdparty/phonon/ds9/backendnode.cpp | 19 -- src/3rdparty/phonon/ds9/ds9.desktop | 17 +- src/3rdparty/phonon/ds9/effect.cpp | 4 +- src/3rdparty/phonon/ds9/fakesource.cpp | 34 +++- src/3rdparty/phonon/ds9/iodevicereader.cpp | 92 ++++++--- src/3rdparty/phonon/ds9/iodevicereader.h | 1 + src/3rdparty/phonon/ds9/mediagraph.cpp | 38 ++-- src/3rdparty/phonon/ds9/mediaobject.cpp | 201 +++++++++++--------- src/3rdparty/phonon/ds9/mediaobject.h | 8 +- src/3rdparty/phonon/ds9/qasyncreader.cpp | 72 +++++--- src/3rdparty/phonon/ds9/qasyncreader.h | 6 +- src/3rdparty/phonon/ds9/qaudiocdreader.cpp | 54 ++++-- src/3rdparty/phonon/ds9/qaudiocdreader.h | 2 +- src/3rdparty/phonon/ds9/qbasefilter.cpp | 33 ++-- src/3rdparty/phonon/ds9/qbasefilter.h | 4 +- src/3rdparty/phonon/ds9/qevr9.h | 143 -------------- src/3rdparty/phonon/ds9/qmeminputpin.cpp | 113 ++++++++---- src/3rdparty/phonon/ds9/qmeminputpin.h | 9 +- src/3rdparty/phonon/ds9/qpin.cpp | 73 +++++--- src/3rdparty/phonon/ds9/qpin.h | 7 +- src/3rdparty/phonon/ds9/videorenderer_default.cpp | 153 --------------- src/3rdparty/phonon/ds9/videorenderer_default.h | 55 ------ src/3rdparty/phonon/ds9/videorenderer_evr.cpp | 215 ---------------------- src/3rdparty/phonon/ds9/videorenderer_evr.h | 56 ------ src/3rdparty/phonon/ds9/videorenderer_soft.cpp | 15 +- src/3rdparty/phonon/ds9/videorenderer_vmr9.cpp | 113 +++++++++++- src/3rdparty/phonon/ds9/videorenderer_vmr9.h | 1 + src/3rdparty/phonon/ds9/videowidget.cpp | 50 +---- src/3rdparty/phonon/ds9/volumeeffect.cpp | 5 +- src/3rdparty/phonon/ds9/volumeeffect.h | 2 +- 33 files changed, 621 insertions(+), 996 deletions(-) delete mode 100644 src/3rdparty/phonon/ds9/qevr9.h delete mode 100644 src/3rdparty/phonon/ds9/videorenderer_default.cpp delete mode 100644 src/3rdparty/phonon/ds9/videorenderer_default.h delete mode 100644 src/3rdparty/phonon/ds9/videorenderer_evr.cpp delete mode 100644 src/3rdparty/phonon/ds9/videorenderer_evr.h diff --git a/src/3rdparty/phonon/ds9/abstractvideorenderer.cpp b/src/3rdparty/phonon/ds9/abstractvideorenderer.cpp index a9d0694..e932e70 100644 --- a/src/3rdparty/phonon/ds9/abstractvideorenderer.cpp +++ b/src/3rdparty/phonon/ds9/abstractvideorenderer.cpp @@ -99,8 +99,8 @@ namespace Phonon m_dstX = m_dstY = 0; if (ratio > 0) { - if ((realWidth / realHeight > ratio && scaleMode == Phonon::VideoWidget::FitInView) - || (realWidth / realHeight < ratio && scaleMode == Phonon::VideoWidget::ScaleAndCrop)) { + if (realWidth / realHeight > ratio && scaleMode == Phonon::VideoWidget::FitInView + || realWidth / realHeight < ratio && scaleMode == Phonon::VideoWidget::ScaleAndCrop) { //the height is correct, let's change the width m_dstWidth = qRound(realHeight * ratio); m_dstX = qRound((realWidth - realHeight * ratio) / 2.); diff --git a/src/3rdparty/phonon/ds9/backend.cpp b/src/3rdparty/phonon/ds9/backend.cpp index fbc4bdc..2c56af7 100644 --- a/src/3rdparty/phonon/ds9/backend.cpp +++ b/src/3rdparty/phonon/ds9/backend.cpp @@ -41,8 +41,6 @@ namespace Phonon { namespace DS9 { - QMutex *Backend::directShowMutex = 0; - bool Backend::AudioMoniker::operator==(const AudioMoniker &other) { return other->IsEqual(*this) == S_OK; @@ -52,8 +50,6 @@ namespace Phonon Backend::Backend(QObject *parent, const QVariantList &) : QObject(parent) { - directShowMutex = &m_directShowMutex; - ::CoInitialize(0); //registering meta types @@ -66,8 +62,6 @@ namespace Phonon m_audioOutputs.clear(); m_audioEffects.clear(); ::CoUninitialize(); - - directShowMutex = 0; } QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList &args) @@ -137,7 +131,6 @@ namespace Phonon QList Backend::objectDescriptionIndexes(Phonon::ObjectDescriptionType type) const { - QMutexLocker locker(&m_directShowMutex); QList ret; switch(type) @@ -164,7 +157,7 @@ namespace Phonon while (S_OK == enumMon->Next(1, mon.pparam(), 0)) { LPOLESTR str = 0; mon->GetDisplayName(0,0,&str); - const QString name = QString::fromWCharArray(str); + const QString name = QString::fromUtf16((unsigned short*)str); ComPointer alloc; ::CoGetMalloc(1, alloc.pparam()); alloc->Free(str); @@ -211,7 +204,6 @@ namespace Phonon QHash Backend::objectDescriptionProperties(Phonon::ObjectDescriptionType type, int index) const { - QMutexLocker locker(&m_directShowMutex); QHash ret; switch (type) { @@ -224,7 +216,7 @@ namespace Phonon LPOLESTR str = 0; HRESULT hr = mon->GetDisplayName(0,0, &str); if (SUCCEEDED(hr)) { - QString name = QString::fromWCharArray(str); + QString name = QString::fromUtf16((unsigned short*)str); ComPointer alloc; ::CoGetMalloc(1, alloc.pparam()); alloc->Free(str); @@ -239,7 +231,7 @@ namespace Phonon WCHAR name[80]; // 80 is clearly stated in the MSDN doc HRESULT hr = ::DMOGetName(m_audioEffects[index], name); if (SUCCEEDED(hr)) { - ret["name"] = QString::fromWCharArray(name); + ret["name"] = QString::fromUtf16((unsigned short*)name); } } break; diff --git a/src/3rdparty/phonon/ds9/backend.h b/src/3rdparty/phonon/ds9/backend.h index 7c3c109..ad638f2 100644 --- a/src/3rdparty/phonon/ds9/backend.h +++ b/src/3rdparty/phonon/ds9/backend.h @@ -23,7 +23,6 @@ along with this library. If not, see . #include #include -#include #include "compointer.h" #include "backendnode.h" @@ -64,8 +63,6 @@ namespace Phonon Filter getAudioOutputFilter(int index) const; - static QMutex *directShowMutex; - Q_SIGNALS: void objectDescriptionChanged(ObjectDescriptionType); @@ -77,7 +74,6 @@ namespace Phonon }; mutable QVector m_audioOutputs; mutable QVector m_audioEffects; - mutable QMutex m_directShowMutex; }; } } diff --git a/src/3rdparty/phonon/ds9/backendnode.cpp b/src/3rdparty/phonon/ds9/backendnode.cpp index 737ab7b..7e0b3cd 100644 --- a/src/3rdparty/phonon/ds9/backendnode.cpp +++ b/src/3rdparty/phonon/ds9/backendnode.cpp @@ -57,25 +57,6 @@ namespace Phonon BackendNode::~BackendNode() { - //this will remove the filter from the graph - FILTER_INFO info; - for(int i = 0; i < FILTER_COUNT; ++i) { - const Filter &filter = m_filters[i]; - if (!filter) - continue; - filter->QueryFilterInfo(&info); - if (info.pGraph) { - HRESULT hr = info.pGraph->RemoveFilter(filter); - - if (FAILED(hr) && m_mediaObject) { - m_mediaObject->ensureStopped(); - - hr = info.pGraph->RemoveFilter(filter); - } - Q_ASSERT(SUCCEEDED(hr)); - info.pGraph->Release(); - } - } } void BackendNode::setMediaObject(MediaObject *mo) diff --git a/src/3rdparty/phonon/ds9/ds9.desktop b/src/3rdparty/phonon/ds9/ds9.desktop index 764390e..1bc3451 100644 --- a/src/3rdparty/phonon/ds9/ds9.desktop +++ b/src/3rdparty/phonon/ds9/ds9.desktop @@ -5,12 +5,13 @@ MimeType=application/x-annodex;video/quicktime;video/x-quicktime;audio/x-m4a;app X-KDE-Library=phonon_ds9 X-KDE-PhononBackendInfo-InterfaceVersion=1 X-KDE-PhononBackendInfo-Version=0.1 -X-KDE-PhononBackendInfo-Website=http://qt.nokia.com/ +X-KDE-PhononBackendInfo-Website=http://www.trolltech.com/ InitialPreference=15 Name=DirectShow9 Name[bg]=DirectShow9 Name[ca]=DirectShow9 +Name[ca@valencia]=DirectShow9 Name[cs]=DirectShow9 Name[da]=DirectShow9 Name[de]=DirectShow9 @@ -19,11 +20,14 @@ Name[en_GB]=DirectShow9 Name[es]=DirectShow9 Name[et]=DirectShow9 Name[eu]=DirectShow9 +Name[fi]=DirectShow9 Name[fr]=DirectShow9 Name[ga]=DirectShow9 Name[gl]=DirectShow9 +Name[hr]=DirectShow9 Name[hsb]=DirectShow9 Name[hu]=DirectShow9 +Name[id]=DirectShow9 Name[is]=DirectShow9 Name[it]=DirectShow9 Name[ja]=DirectShow9 @@ -31,6 +35,7 @@ Name[ko]=DirectShow9 Name[ku]=DirectShow9 Name[lt]=DirectShow9 Name[lv]=DirectShow9 +Name[nb]=DirectShow9 Name[nds]=DirectShow9 Name[nl]=DirectShow9 Name[nn]=DirectShow9 @@ -38,10 +43,13 @@ Name[pa]=ਡਾਇਰੈਕਸ਼ੋ9 Name[pl]=DirectShow9 Name[pt]=DirectShow9 Name[pt_BR]=DirectShow9 +Name[ru]=DirectShow9 Name[se]=DirectShow9 Name[sk]=DirectShow 9 Name[sl]=DirectShow 9 Name[sr]=Директшоу‑9 +Name[sr@ijekavian]=Директшоу‑9 +Name[sr@ijekavianlatin]=DirectShow‑9 Name[sr@latin]=DirectShow‑9 Name[sv]=Directshow 9 Name[tr]=DirectShow9 @@ -53,6 +61,7 @@ Name[zh_TW]=DirectShow9 Comment=Phonon DirectShow9 backend Comment[bg]=Phonon DirectShow9 Comment[ca]=Dorsal DirectShow9 del Phonon +Comment[ca@valencia]=Dorsal DirectShow9 del Phonon Comment[cs]=Phonon DirectShow9 backend Comment[da]=DirectShow9-backend til Phonon Comment[de]=Phonon-Treiber für DirectShow9 @@ -61,11 +70,13 @@ Comment[en_GB]=Phonon DirectShow9 backend Comment[es]=Motor DirectShow9 para Phonon Comment[et]=Phononi DirectShow9 taustaprogramm Comment[eu]=Phonon DirectShow9 backend +Comment[fi]=Phonon DirectShow9-taustaohjelma Comment[fr]=Système de gestion DirectShow9 pour Phonon Comment[ga]=Inneall DirectShow9 le haghaidh Phonon Comment[gl]=Infraestrutura de DirectShow9 para Phonon Comment[hsb]=Phonon DirectShow9 backend Comment[hu]=Phonon DirectShow9 modul +Comment[id]=Phonon DirectShow9 backend Comment[is]=Phonon DirectShow9 bakendi Comment[it]=Motore DirectShow9 di Phonon Comment[ja]=Phonon DirectShow9 ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ @@ -73,6 +84,7 @@ Comment[ko]=Phonon DirectShow9 백엔드 Comment[ku]=Binesaza Phonon DirectShow9 Comment[lt]=Phonon DirectShow9 galinÄ— sÄ…saja Comment[lv]=Phonon DirectShow9 aizmugure +Comment[nb]=Phonon-motor for DirectShow9 Comment[nds]=Phonon-Hülpprogrmm DirectShow9 Comment[nl]=DirectShow9-backend (Phonon) Comment[nn]=Phonon-motor for DirectShow9 @@ -80,10 +92,13 @@ Comment[pa]=ਫੋਨੋਨ ਡਾਇਰੈਕਟਸ਼ੋ9 ਬੈਕà¨à¨‚ਡ Comment[pl]=ObsÅ‚uga DirectShow9 przez Phonon Comment[pt]=Infra-estrutura do DirectShow9 para o Phonon Comment[pt_BR]=Infraestrutura Phonon DirectShow9 +Comment[ru]=Механизм DirectShow9 Ð´Ð»Ñ Phonon Comment[se]=Phonon DirectShow9 duogášmohtor Comment[sk]=Phonon DirectShow 9 podsystém Comment[sl]=Phononova Hrbtenica DirectShow 9 Comment[sr]=Директшоу‑9 као позадина Фонона +Comment[sr@ijekavian]=Директшоу‑9 као позадина Фонона +Comment[sr@ijekavianlatin]=DirectShow‑9 kao pozadina Phonona Comment[sr@latin]=DirectShow‑9 kao pozadina Phonona Comment[sv]=Phonon Directshow 9-gränssnitt Comment[tr]=Phonon DirectShow9 arka ucu diff --git a/src/3rdparty/phonon/ds9/effect.cpp b/src/3rdparty/phonon/ds9/effect.cpp index ebe976b..104a3c1 100644 --- a/src/3rdparty/phonon/ds9/effect.cpp +++ b/src/3rdparty/phonon/ds9/effect.cpp @@ -82,7 +82,7 @@ namespace Phonon current += wcslen(current) + 1; //skip the name current += wcslen(current) + 1; //skip the unit for(; *current; current += wcslen(current) + 1) { - values.append( QString::fromWCharArray(current) ); + values.append( QString::fromUtf16((unsigned short*)current) ); } } //FALLTHROUGH @@ -107,7 +107,7 @@ namespace Phonon Phonon::EffectParameter::Hints hint = info.mopCaps == MP_CAPS_CURVE_INVSQUARE ? Phonon::EffectParameter::LogarithmicHint : Phonon::EffectParameter::Hints(0); - const QString n = QString::fromWCharArray(name); + const QString n = QString::fromUtf16((unsigned short*)name); ret.append(Phonon::EffectParameter(i, n, hint, def, min, max, values)); ::CoTaskMemFree(name); //let's free the memory } diff --git a/src/3rdparty/phonon/ds9/fakesource.cpp b/src/3rdparty/phonon/ds9/fakesource.cpp index 4dce138..9a61a2e 100644 --- a/src/3rdparty/phonon/ds9/fakesource.cpp +++ b/src/3rdparty/phonon/ds9/fakesource.cpp @@ -29,10 +29,8 @@ namespace Phonon namespace DS9 { static WAVEFORMATEX g_defaultWaveFormat = {WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0}; - static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0} }; - - static const AM_MEDIA_TYPE g_fakeAudioType = {MEDIATYPE_Audio, MEDIASUBTYPE_PCM, 0, 0, 2, FORMAT_WaveFormatEx, 0, sizeof(WAVEFORMATEX), reinterpret_cast(&g_defaultWaveFormat)}; - static const AM_MEDIA_TYPE g_fakeVideoType = {MEDIATYPE_Video, MEDIASUBTYPE_RGB32, TRUE, FALSE, 0, FORMAT_VideoInfo2, 0, sizeof(VIDEOINFOHEADER2), reinterpret_cast(&g_defaultVideoInfo)}; + static BITMAPINFOHEADER g_defautBitmapHeader = { sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}; + static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; class FakePin : public QPin { @@ -130,12 +128,36 @@ namespace Phonon void FakeSource::createFakeAudioPin() { - new FakePin(this, g_fakeAudioType); + AM_MEDIA_TYPE mt; + qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); + mt.majortype = MEDIATYPE_Audio; + mt.subtype = MEDIASUBTYPE_PCM; + mt.formattype = FORMAT_WaveFormatEx; + mt.lSampleSize = 2; + + //fake the format (stereo 44.1 khz stereo 16 bits) + mt.cbFormat = sizeof(WAVEFORMATEX); + mt.pbFormat = reinterpret_cast(&g_defaultWaveFormat); + + new FakePin(this, mt); } void FakeSource::createFakeVideoPin() { - new FakePin(this, g_fakeVideoType); + AM_MEDIA_TYPE mt; + qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); + mt.majortype = MEDIATYPE_Video; + mt.subtype = MEDIASUBTYPE_RGB32; + mt.formattype = FORMAT_VideoInfo2; + mt.bFixedSizeSamples = 1; + + g_defaultVideoInfo.bmiHeader = g_defautBitmapHeader; + + //fake the format + mt.cbFormat = sizeof(VIDEOINFOHEADER2); + mt.pbFormat = reinterpret_cast(&g_defaultVideoInfo); + + new FakePin(this, mt); } } diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index 695af59..2dff1fe 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -36,20 +36,18 @@ namespace Phonon //these mediatypes define a stream, its type will be autodetected by DirectShow static QVector getMediaTypes() { - //the order here is important because otherwise, - //directshow might not be able to detect the stream type correctly - - AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_Avi, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; + AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; QVector ret; + //normal auto-detect stream + mt.subtype = MEDIASUBTYPE_NULL; + ret << mt; //AVI stream + mt.subtype = MEDIASUBTYPE_Avi; ret << mt; //WAVE stream mt.subtype = MEDIASUBTYPE_WAVE; ret << mt; - //normal auto-detect stream (must be at the end!) - mt.subtype = MEDIASUBTYPE_NULL; - ret << mt; return ret; } @@ -66,6 +64,7 @@ namespace Phonon //for Phonon::StreamInterface void writeData(const QByteArray &data) { + QWriteLocker locker(&m_lock); m_pos += data.size(); m_buffer += data; } @@ -76,22 +75,54 @@ namespace Phonon void setStreamSize(qint64 newSize) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_size = newSize; } + qint64 streamSize() const + { + QReadLocker locker(&m_lock); + return m_size; + } + void setStreamSeekable(bool s) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_seekable = s; } + bool streamSeekable() const + { + QReadLocker locker(&m_lock); + return m_seekable; + } + + void setCurrentPos(qint64 pos) + { + QWriteLocker locker(&m_lock); + m_pos = pos; + seekStream(pos); + m_buffer.clear(); + } + + qint64 currentPos() const + { + QReadLocker locker(&m_lock); + return m_pos; + } + + int currentBufferSize() const + { + QReadLocker locker(&m_lock); + return m_buffer.size(); + } + //virtual pure members //implementation from IAsyncReader STDMETHODIMP Length(LONGLONG *total, LONGLONG *available) { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (total) { *total = m_size; } @@ -106,42 +137,44 @@ namespace Phonon HRESULT read(LONGLONG pos, LONG length, BYTE *buffer, LONG *actual) { - Q_ASSERT(!m_mutex.tryLock()); + QMutexLocker locker(&m_mutexRead); + if (m_mediaGraph->isStopping()) { return VFW_E_WRONG_STATE; } - if(m_size != 1 && pos + length > m_size) { + if(streamSize() != 1 && pos + length > streamSize()) { //it tries to read outside of the boundaries return E_FAIL; } - if (m_pos - m_buffer.size() != pos) { - if (!m_seekable) { + if (currentPos() - currentBufferSize() != pos) { + if (!streamSeekable()) { return S_FALSE; } - m_pos = pos; - seekStream(pos); - m_buffer.clear(); + setCurrentPos(pos); } - int oldSize = m_buffer.size(); - while (m_buffer.size() < int(length)) { + int oldSize = currentBufferSize(); + while (currentBufferSize() < int(length)) { needData(); if (m_mediaGraph->isStopping()) { return VFW_E_WRONG_STATE; } - if (oldSize == m_buffer.size()) { + if (oldSize == currentBufferSize()) { break; //we didn't get any data } - oldSize = m_buffer.size(); + oldSize = currentBufferSize(); } - int bytesRead = qMin(m_buffer.size(), int(length)); - qMemCopy(buffer, m_buffer.data(), bytesRead); - //truncate the buffer - m_buffer = m_buffer.mid(bytesRead); + DWORD bytesRead = qMin(currentBufferSize(), int(length)); + { + QWriteLocker locker(&m_lock); + qMemCopy(buffer, m_buffer.data(), bytesRead); + //truncate the buffer + m_buffer = m_buffer.mid(bytesRead); + } if (actual) { *actual = bytesRead; //initialization @@ -157,6 +190,7 @@ namespace Phonon qint64 m_pos; qint64 m_size; + QMutex m_mutexRead; const MediaGraph *m_mediaGraph; }; @@ -170,6 +204,14 @@ namespace Phonon IODeviceReader::~IODeviceReader() { } + + STDMETHODIMP IODeviceReader::Stop() + { + HRESULT hr = QBaseFilter::Stop(); + m_streamReader->enoughData(); //this asks to cancel any blocked call to needData + return hr; + } + } } diff --git a/src/3rdparty/phonon/ds9/iodevicereader.h b/src/3rdparty/phonon/ds9/iodevicereader.h index c8b91c3..af4b271 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.h +++ b/src/3rdparty/phonon/ds9/iodevicereader.h @@ -41,6 +41,7 @@ namespace Phonon public: IODeviceReader(const MediaSource &source, const MediaGraph *); ~IODeviceReader(); + STDMETHODIMP Stop(); private: StreamReader *m_streamReader; diff --git a/src/3rdparty/phonon/ds9/mediagraph.cpp b/src/3rdparty/phonon/ds9/mediagraph.cpp index 3e7a68b..db0ec84 100644 --- a/src/3rdparty/phonon/ds9/mediagraph.cpp +++ b/src/3rdparty/phonon/ds9/mediagraph.cpp @@ -68,8 +68,6 @@ namespace Phonon return ret; } - -/* static HRESULT saveToFile(Graph graph, const QString &filepath) { const WCHAR wszStreamName[] = L"ActiveMovieGraph"; @@ -105,7 +103,7 @@ namespace Phonon return hr; } -*/ + MediaGraph::MediaGraph(MediaObject *mo, short index) : m_graph(CLSID_FilterGraph, IID_IGraphBuilder), @@ -379,12 +377,11 @@ namespace Phonon FILTER_INFO info; filter->QueryFilterInfo(&info); #ifdef GRAPH_DEBUG - qDebug() << "removeFilter" << QString((const QChar *)info.achName); + qDebug() << "removeFilter" << QString::fromUtf16(info.achName); #endif if (info.pGraph) { info.pGraph->Release(); - if (info.pGraph == m_graph) - return m_graph->RemoveFilter(filter); + return m_graph->RemoveFilter(filter); } //already removed @@ -540,11 +537,11 @@ namespace Phonon const QList outputs = BackendNode::pins(filter, PINDIR_OUTPUT); for(int i = 0; i < outputs.count(); ++i) { const OutputPin &pin = outputs.at(i); - if (HRESULT(VFW_E_NOT_CONNECTED) == pin->ConnectedTo(inPin.pparam())) { + if (VFW_E_NOT_CONNECTED == pin->ConnectedTo(inPin.pparam())) { return SUCCEEDED(pin->Connect(newIn, 0)); } } - //we shoud never go here + //we should never go here return false; } else { QAMMediaType type; @@ -682,6 +679,7 @@ namespace Phonon #ifndef QT_NO_PHONON_MEDIACONTROLLER } else if (source.discType() == Phonon::Cd) { m_realSource = Filter(new QAudioCDPlayer); + m_result = m_graph->AddFilter(m_realSource, 0); #endif //QT_NO_PHONON_MEDIACONTROLLER } else { @@ -811,7 +809,7 @@ namespace Phonon for (int i = 0; i < outputs.count(); ++i) { const OutputPin &out = outputs.at(i); InputPin pin; - if (out->ConnectedTo(pin.pparam()) == HRESULT(VFW_E_NOT_CONNECTED)) { + if (out->ConnectedTo(pin.pparam()) == VFW_E_NOT_CONNECTED) { m_decoderPins += out; //unconnected outputs can be decoded outputs } } @@ -822,7 +820,7 @@ namespace Phonon //let's reestablish the connections for (int i = 0; i < connections.count(); ++i) { const GraphConnection &connection = connections.at(i); - //check if we shoud transfer the sink node + //check if we should transfer the sink node grabFilter(connection.input); grabFilter(connection.output); @@ -875,7 +873,7 @@ namespace Phonon { FILTER_INFO info; filter->QueryFilterInfo(&info); - qDebug() << Q_FUNC_INFO << QString((const QChar *)info.achName); + qDebug() << Q_FUNC_INFO << QString::fromUtf16(info.achName); if (info.pGraph) { info.pGraph->Release(); } @@ -921,7 +919,7 @@ namespace Phonon { FILTER_INFO info; filter->QueryFilterInfo(&info); - qDebug() << "found a decoder filter" << QString((const QChar *)info.achName); + qDebug() << "found a decoder filter" << QString::fromUtf16(info.achName); if (info.pGraph) { info.pGraph->Release(); } @@ -937,7 +935,7 @@ namespace Phonon { FILTER_INFO info; filter->QueryFilterInfo(&info); - qDebug() << Q_FUNC_INFO << QString((const QChar *)info.achName); + qDebug() << Q_FUNC_INFO << QString::fromUtf16(info.achName); if (info.pGraph) { info.pGraph->Release(); } @@ -956,7 +954,7 @@ namespace Phonon { FILTER_INFO info; filter->QueryFilterInfo(&info); - qDebug() << Q_FUNC_INFO << QString((const QChar *)info.achName); + qDebug() << Q_FUNC_INFO << QString::fromUtf16(info.achName); if (info.pGraph) { info.pGraph->Release(); } @@ -990,7 +988,7 @@ namespace Phonon { FILTER_INFO info; filter->QueryFilterInfo(&info); - qDebug() << "found a demuxer filter" << QString((const QChar *)info.achName); + qDebug() << "found a demuxer filter" << QString::fromUtf16(info.achName); if (info.pGraph) { info.pGraph->Release(); } @@ -1008,27 +1006,27 @@ namespace Phonon BSTR str; HRESULT hr = mediaContent->get_AuthorName(&str); if (SUCCEEDED(hr)) { - ret.insert(QLatin1String("ARTIST"), QString::fromWCharArray(str)); + ret.insert(QLatin1String("ARTIST"), QString::fromUtf16((const unsigned short*)str)); SysFreeString(str); } hr = mediaContent->get_Title(&str); if (SUCCEEDED(hr)) { - ret.insert(QLatin1String("TITLE"), QString::fromWCharArray(str)); + ret.insert(QLatin1String("TITLE"), QString::fromUtf16((const unsigned short*)str)); SysFreeString(str); } hr = mediaContent->get_Description(&str); if (SUCCEEDED(hr)) { - ret.insert(QLatin1String("DESCRIPTION"), QString::fromWCharArray(str)); + ret.insert(QLatin1String("DESCRIPTION"), QString::fromUtf16((const unsigned short*)str)); SysFreeString(str); } hr = mediaContent->get_Copyright(&str); if (SUCCEEDED(hr)) { - ret.insert(QLatin1String("COPYRIGHT"), QString::fromWCharArray(str)); + ret.insert(QLatin1String("COPYRIGHT"), QString::fromUtf16((const unsigned short*)str)); SysFreeString(str); } hr = mediaContent->get_MoreInfoText(&str); if (SUCCEEDED(hr)) { - ret.insert(QLatin1String("MOREINFO"), QString::fromWCharArray(str)); + ret.insert(QLatin1String("MOREINFO"), QString::fromUtf16((const unsigned short*)str)); SysFreeString(str); } } diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index 34f92c2..d1e15c0 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -23,10 +23,11 @@ along with this library. If not, see . #ifndef Q_CC_MSVC #include -#endif +#endif //Q_CC_MSVC #include #include #include +#include #include #include "mediaobject.h" @@ -49,7 +50,7 @@ namespace Phonon //first the definition of the WorkerThread class WorkerThread::WorkerThread() - : QThread(), m_finished(false), m_currentWorkId(1) + : QThread(), m_currentRenderId(0), m_finished(false), m_currentWorkId(1) { } @@ -57,6 +58,24 @@ namespace Phonon { } + WorkerThread::Work WorkerThread::dequeueWork() + { + QMutexLocker locker(&m_mutex); + if (m_finished) { + return Work(); + } + Work ret = m_queue.dequeue(); + + //we ensure to have the wait condition in the right state + if (m_queue.isEmpty()) { + m_waitCondition.reset(); + } else { + m_waitCondition.set(); + } + + return ret; + } + void WorkerThread::run() { while (m_finished == false) { @@ -70,6 +89,11 @@ namespace Phonon } DWORD result = ::WaitForMultipleObjects(count, handles, FALSE, INFINITE); if (result == WAIT_OBJECT_0) { + if (m_finished) { + //that's the end of the thread execution + return; + } + handleTask(); } else { //this is the event management @@ -157,7 +181,6 @@ namespace Phonon //we create a new graph w.graph = Graph(CLSID_FilterGraph, IID_IGraphBuilder); w.filter = filter; - w.graph->AddFilter(filter, 0); w.id = m_currentWorkId++; m_queue.enqueue(w); m_waitCondition.set(); @@ -177,29 +200,23 @@ namespace Phonon void WorkerThread::handleTask() { - QMutexLocker locker(Backend::directShowMutex); - { - QMutexLocker locker(&m_mutex); - if (m_finished || m_queue.isEmpty()) { - return; - } - - m_currentWork = m_queue.dequeue(); + const Work w = dequeueWork(); - //we ensure to have the wait condition in the right state - if (m_queue.isEmpty()) { - m_waitCondition.reset(); - } else { - m_waitCondition.set(); - } + if (m_finished) { + return; } HRESULT hr = S_OK; - if (m_currentWork.task == ReplaceGraph) { + m_currentRender = w.graph; + m_currentRenderId = w.id; + if (w.task == ReplaceGraph) { + QMutexLocker locker(&m_mutex); + HANDLE h; + int index = -1; for(int i = 0; i < FILTER_COUNT; ++i) { - if (m_graphHandle[i].graph == m_currentWork.oldGraph) { + if (m_graphHandle[i].graph == w.oldGraph) { m_graphHandle[i].graph = Graph(); index = i; break; @@ -212,40 +229,51 @@ namespace Phonon Q_ASSERT(index != -1); //add the new graph - HANDLE h; - if (SUCCEEDED(ComPointer(m_currentWork.graph, IID_IMediaEvent) + if (SUCCEEDED(ComPointer(w.graph, IID_IMediaEvent) ->GetEventHandle(reinterpret_cast(&h)))) { - m_graphHandle[index].graph = m_currentWork.graph; + m_graphHandle[index].graph = w.graph; m_graphHandle[index].handle = h; } - } else if (m_currentWork.task == Render) { - if (m_currentWork.filter) { + } else if (w.task == Render) { + if (w.filter) { //let's render pins - const QList outputs = BackendNode::pins(m_currentWork.filter, PINDIR_OUTPUT); - for (int i = 0; SUCCEEDED(hr) && i < outputs.count(); ++i) { - hr = m_currentWork.graph->Render(outputs.at(i)); + w.graph->AddFilter(w.filter, 0); + const QList outputs = BackendNode::pins(w.filter, PINDIR_OUTPUT); + for (int i = 0; i < outputs.count(); ++i) { + //blocking call + hr = w.graph->Render(outputs.at(i)); + if (FAILED(hr)) { + break; + } } - } else if (!m_currentWork.url.isEmpty()) { + } else if (!w.url.isEmpty()) { //let's render a url (blocking call) - hr = m_currentWork.graph->RenderFile(reinterpret_cast(m_currentWork.url.utf16()), 0); + hr = w.graph->RenderFile(reinterpret_cast(w.url.utf16()), 0); } if (hr != E_ABORT) { - emit asyncRenderFinished(m_currentWork.id, hr, m_currentWork.graph); + emit asyncRenderFinished(w.id, hr, w.graph); } - } else if (m_currentWork.task == Seek) { + } else if (w.task == Seek) { //that's a seekrequest - ComPointer mediaSeeking(m_currentWork.graph, IID_IMediaSeeking); - qint64 newtime = m_currentWork.time * 10000; + ComPointer mediaSeeking(w.graph, IID_IMediaSeeking); + qint64 newtime = w.time * 10000; hr = mediaSeeking->SetPositions(&newtime, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning); - emit asyncSeekingFinished(m_currentWork.id, newtime / 10000); + qint64 currentTime = -1; + if (SUCCEEDED(hr)) { + hr = mediaSeeking->GetCurrentPosition(¤tTime); + if (SUCCEEDED(hr)) { + currentTime /= 10000; //convert to ms + } + } + emit asyncSeekingFinished(w.id, currentTime); hr = E_ABORT; //to avoid emitting asyncRenderFinished - } else if (m_currentWork.task == ChangeState) { + } else if (w.task == ChangeState) { //remove useless decoders QList unused; - for (int i = 0; i < m_currentWork.decoders.count(); ++i) { - const Filter &filter = m_currentWork.decoders.at(i); + for (int i = 0; i < w.decoders.count(); ++i) { + const Filter &filter = w.decoders.at(i); bool used = false; const QList pins = BackendNode::pins(filter, PINDIR_OUTPUT); for( int i = 0; i < pins.count(); ++i) { @@ -262,15 +290,15 @@ namespace Phonon //we can get the state for (int i = 0; i < unused.count(); ++i) { //we should remove this filter from the graph - m_currentWork.graph->RemoveFilter(unused.at(i)); + w.graph->RemoveFilter(unused.at(i)); } //we can get the state - ComPointer mc(m_currentWork.graph, IID_IMediaControl); + ComPointer mc(w.graph, IID_IMediaControl); //we change the state here - switch(m_currentWork.state) + switch(w.state) { case State_Stopped: mc->Stop(); @@ -288,38 +316,36 @@ namespace Phonon if (SUCCEEDED(hr)) { if (s == State_Stopped) { - emit stateReady(m_currentWork.graph, Phonon::StoppedState); + emit stateReady(w.graph, Phonon::StoppedState); } else if (s == State_Paused) { - emit stateReady(m_currentWork.graph, Phonon::PausedState); + emit stateReady(w.graph, Phonon::PausedState); } else /*if (s == State_Running)*/ { - emit stateReady(m_currentWork.graph, Phonon::PlayingState); + emit stateReady(w.graph, Phonon::PlayingState); } } } - { - QMutexLocker locker(&m_mutex); - m_currentWork = Work(); //reinitialize - } + m_currentRender = Graph(); + m_currentRenderId = 0; + } - void WorkerThread::abortCurrentRender(qint16 renderId) - { + void WorkerThread::abortCurrentRender(qint16 renderId) + { QMutexLocker locker(&m_mutex); - if (m_currentWork.id == renderId) { - m_currentWork.graph->Abort(); - } bool found = false; + //we try to see if there is already an attempt to seek and we remove it for(int i = 0; !found && i < m_queue.size(); ++i) { const Work &w = m_queue.at(i); if (w.id == renderId) { found = true; m_queue.removeAt(i); - if (m_queue.isEmpty()) { - m_waitCondition.reset(); - } } } + + if (m_currentRender && m_currentRenderId == renderId) { + m_currentRender->Abort(); + } } //tells the thread to stop processing @@ -327,9 +353,9 @@ namespace Phonon { QMutexLocker locker(&m_mutex); m_queue.clear(); - if (m_currentWork.graph) { + if (m_currentRender) { //in case we're currently rendering something - m_currentWork.graph->Abort(); + m_currentRender->Abort(); } @@ -361,17 +387,17 @@ namespace Phonon m_graphs[i] = new MediaGraph(this, i); } - connect(&m_thread, SIGNAL(stateReady(Graph,Phonon::State)), - SLOT(slotStateReady(Graph,Phonon::State))); + connect(&m_thread, SIGNAL(stateReady(Graph, Phonon::State)), + SLOT(slotStateReady(Graph, Phonon::State))); - connect(&m_thread, SIGNAL(eventReady(Graph,long,long)), - SLOT(handleEvents(Graph,long,long))); + connect(&m_thread, SIGNAL(eventReady(Graph, long, long)), + SLOT(handleEvents(Graph, long, long))); - connect(&m_thread, SIGNAL(asyncRenderFinished(quint16,HRESULT,Graph)), - SLOT(finishLoading(quint16,HRESULT,Graph))); + connect(&m_thread, SIGNAL(asyncRenderFinished(quint16, HRESULT, Graph)), + SLOT(finishLoading(quint16, HRESULT, Graph))); - connect(&m_thread, SIGNAL(asyncSeekingFinished(quint16,qint64)), - SLOT(finishSeeking(quint16,qint64))); + connect(&m_thread, SIGNAL(asyncSeekingFinished(quint16, qint64)), + SLOT(finishSeeking(quint16, qint64))); //really special case m_mediaObject = this; m_thread.start(); @@ -494,18 +520,6 @@ namespace Phonon qSwap(m_graphs[0], m_graphs[1]); //swap the graphs - if (m_transitionTime >= 0) - m_graphs[1]->stop(); //make sure we stop the previous graph - - if (currentGraph()->mediaSource().type() != Phonon::MediaSource::Invalid && - catchComError(currentGraph()->renderResult())) { - setState(Phonon::ErrorState); - return; - } - - //we need to play the next media - play(); - //we tell the video widgets to switch now to the new source #ifndef QT_NO_PHONON_VIDEO for (int i = 0; i < m_videoWidgets.count(); ++i) { @@ -514,6 +528,15 @@ namespace Phonon #endif //QT_NO_PHONON_VIDEO emit currentSourceChanged(currentGraph()->mediaSource()); + + if (currentGraph()->isLoading()) { + //will simply tell that when loading is finished + //it should start the playback + play(); + } + + + emit metaDataChanged(currentGraph()->metadata()); if (nextGraph()->hasVideo() != currentGraph()->hasVideo()) { @@ -526,6 +549,15 @@ namespace Phonon #ifndef QT_NO_PHONON_MEDIACONTROLLER setTitles(currentGraph()->titles()); #endif //QT_NO_PHONON_MEDIACONTROLLER + + //this manages only gapless transitions + if (currentGraph()->mediaSource().type() != Phonon::MediaSource::Invalid) { + if (catchComError(currentGraph()->renderResult())) { + setState(Phonon::ErrorState); + } else { + play(); + } + } } Phonon::State MediaObject::state() const @@ -760,16 +792,15 @@ namespace Phonon case Phonon::PausedState: pause(); break; + case Phonon::StoppedState: + stop(); + break; case Phonon::PlayingState: play(); break; case Phonon::ErrorState: setState(Phonon::ErrorState); break; - case Phonon::StoppedState: - default: - stop(); - break; } } } @@ -817,11 +848,11 @@ namespace Phonon #endif LPAMGETERRORTEXT getErrorText = (LPAMGETERRORTEXT)QLibrary::resolve(QLatin1String("quartz"), "AMGetErrorTextW"); - WCHAR buffer[MAX_ERROR_TEXT_LEN]; - if (getErrorText && getErrorText(hr, buffer, MAX_ERROR_TEXT_LEN)) { - m_errorString = QString::fromWCharArray(buffer); + ushort buffer[MAX_ERROR_TEXT_LEN]; + if (getErrorText && getErrorText(hr, (WCHAR*)buffer, MAX_ERROR_TEXT_LEN)) { + m_errorString = QString::fromUtf16(buffer); } else { - m_errorString = QString::fromLatin1("Unknown error"); + m_errorString = QString::fromUtf16((ushort*)_com_error(hr).ErrorMessage()); } const QString comError = QString::number(uint(hr), 16); if (!m_errorString.toLower().contains(comError.toLower())) { diff --git a/src/3rdparty/phonon/ds9/mediaobject.h b/src/3rdparty/phonon/ds9/mediaobject.h index 34aa666..2c34ffc 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.h +++ b/src/3rdparty/phonon/ds9/mediaobject.h @@ -114,7 +114,6 @@ namespace Phonon enum Task { - None, Render, Seek, ChangeState, @@ -123,7 +122,6 @@ namespace Phonon struct Work { - Work() : task(None), id(0), time(0) { } Task task; quint16 id; Graph graph; @@ -137,14 +135,16 @@ namespace Phonon }; QList decoders; //for the state change requests }; + Work dequeueWork(); void handleTask(); - Work m_currentWork; + Graph m_currentRender; + qint16 m_currentRenderId; QQueue m_queue; bool m_finished; quint16 m_currentWorkId; QWinWaitCondition m_waitCondition; - QMutex m_mutex; // mutex for the m_queue, m_finished and m_currentWorkId + QMutex m_mutex; //this is for WaitForMultipleObjects struct diff --git a/src/3rdparty/phonon/ds9/qasyncreader.cpp b/src/3rdparty/phonon/ds9/qasyncreader.cpp index a3f9cda..68ec1f8 100644 --- a/src/3rdparty/phonon/ds9/qasyncreader.cpp +++ b/src/3rdparty/phonon/ds9/qasyncreader.cpp @@ -15,6 +15,8 @@ You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ +#include + #include "qasyncreader.h" #include "qbasefilter.h" @@ -78,7 +80,8 @@ namespace Phonon STDMETHODIMP QAsyncReader::Request(IMediaSample *sample,DWORD_PTR user) { - QMutexLocker locker(&m_mutex); + QMutexLocker mutexLocker(&m_mutexWait); + QWriteLocker locker(&m_lock); if (m_flushing) { return VFW_E_WRONG_STATE; } @@ -90,28 +93,33 @@ namespace Phonon STDMETHODIMP QAsyncReader::WaitForNext(DWORD timeout, IMediaSample **sample, DWORD_PTR *user) { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_mutexWait); if (!sample ||!user) { return E_POINTER; } - //msdn says to return immediately if we're flushing but that doesn't seem to be true - //since it triggers a dead-lock somewhere inside directshow (see task 258830) - *sample = 0; *user = 0; - if (m_requestQueue.isEmpty()) { - if (m_requestWait.wait(&m_mutex, timeout) == false) { - return VFW_E_TIMEOUT; - } - if (m_requestQueue.isEmpty()) { + AsyncRequest r = getNextRequest(); + + if (r.sample == 0) { + //there is no request in the queue + if (isFlushing()) { return VFW_E_WRONG_STATE; + } else { + //First we need to lock the mutex + if (m_requestWait.wait(&m_mutexWait, timeout) == false) { + return VFW_E_TIMEOUT; + } + if (isFlushing()) { + return VFW_E_WRONG_STATE; + } + + r = getNextRequest(); } } - AsyncRequest r = m_requestQueue.dequeue(); - //at this point we're sure to have a request to proceed if (r.sample == 0) { return E_FAIL; @@ -119,12 +127,14 @@ namespace Phonon *sample = r.sample; *user = r.user; - return syncReadAlignedUnlocked(r.sample); + + return SyncReadAligned(r.sample); } STDMETHODIMP QAsyncReader::BeginFlush() { - QMutexLocker locker(&m_mutex); + QMutexLocker mutexLocker(&m_mutexWait); + QWriteLocker locker(&m_lock); m_flushing = true; m_requestWait.wakeOne(); return S_OK; @@ -132,28 +142,13 @@ namespace Phonon STDMETHODIMP QAsyncReader::EndFlush() { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_flushing = false; return S_OK; } STDMETHODIMP QAsyncReader::SyncReadAligned(IMediaSample *sample) { - QMutexLocker locker(&m_mutex); - return syncReadAlignedUnlocked(sample); - } - - STDMETHODIMP QAsyncReader::SyncRead(LONGLONG pos, LONG length, BYTE *buffer) - { - QMutexLocker locker(&m_mutex); - return read(pos, length, buffer, 0); - } - - - STDMETHODIMP QAsyncReader::syncReadAlignedUnlocked(IMediaSample *sample) - { - Q_ASSERT(!m_mutex.tryLock()); - if (!sample) { return E_POINTER; } @@ -180,6 +175,23 @@ namespace Phonon return sample->SetActualDataLength(actual); } + STDMETHODIMP QAsyncReader::SyncRead(LONGLONG pos, LONG length, BYTE *buffer) + { + return read(pos, length, buffer, 0); + } + + + //addition + QAsyncReader::AsyncRequest QAsyncReader::getNextRequest() + { + QWriteLocker locker(&m_lock); + AsyncRequest ret; + if (!m_requestQueue.isEmpty()) { + ret = m_requestQueue.dequeue(); + } + + return ret; + } } } diff --git a/src/3rdparty/phonon/ds9/qasyncreader.h b/src/3rdparty/phonon/ds9/qasyncreader.h index 95872f9..cb789ee 100644 --- a/src/3rdparty/phonon/ds9/qasyncreader.h +++ b/src/3rdparty/phonon/ds9/qasyncreader.h @@ -48,12 +48,11 @@ namespace Phonon STDMETHODIMP WaitForNext(DWORD,IMediaSample **,DWORD_PTR *); STDMETHODIMP SyncReadAligned(IMediaSample *); STDMETHODIMP SyncRead(LONGLONG,LONG,BYTE *); - STDMETHODIMP Length(LONGLONG *,LONGLONG *) = 0; + virtual STDMETHODIMP Length(LONGLONG *,LONGLONG *) = 0; STDMETHODIMP BeginFlush(); STDMETHODIMP EndFlush(); protected: - STDMETHODIMP syncReadAlignedUnlocked(IMediaSample *); virtual HRESULT read(LONGLONG pos, LONG length, BYTE *buffer, LONG *actual) = 0; private: @@ -63,6 +62,9 @@ namespace Phonon IMediaSample *sample; DWORD_PTR user; }; + AsyncRequest getNextRequest(); + + QMutex m_mutexWait; QQueue m_requestQueue; QWaitCondition m_requestWait; diff --git a/src/3rdparty/phonon/ds9/qaudiocdreader.cpp b/src/3rdparty/phonon/ds9/qaudiocdreader.cpp index 6d0f335..b9f9fd6 100644 --- a/src/3rdparty/phonon/ds9/qaudiocdreader.cpp +++ b/src/3rdparty/phonon/ds9/qaudiocdreader.cpp @@ -103,8 +103,8 @@ namespace Phonon private: HANDLE m_cddrive; - CDROM_TOC m_toc; - WaveStructure m_waveHeader; + CDROM_TOC *m_toc; + WaveStructure *m_waveHeader; qint64 m_trackAddress; }; @@ -112,8 +112,19 @@ namespace Phonon #define SECTOR_SIZE 2352 #define NB_SECTORS_READ 20 - static const AM_MEDIA_TYPE audioCDMediaType = { MEDIATYPE_Stream, MEDIASUBTYPE_WAVE, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; - + static AM_MEDIA_TYPE getAudioCDMediaType() + { + AM_MEDIA_TYPE mt; + qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); + mt.majortype = MEDIATYPE_Stream; + mt.subtype = MEDIASUBTYPE_WAVE; + mt.bFixedSizeSamples = TRUE; + mt.bTemporalCompression = FALSE; + mt.lSampleSize = 1; + mt.formattype = GUID_NULL; + return mt; + } + int addressToSectors(UCHAR address[4]) { return ((address[0] * 60 + address[1]) * 60 + address[2]) * 75 + address[3] - 150; @@ -130,8 +141,11 @@ namespace Phonon } - QAudioCDReader::QAudioCDReader(QBaseFilter *parent, QChar drive) : QAsyncReader(parent, QVector() << audioCDMediaType) + QAudioCDReader::QAudioCDReader(QBaseFilter *parent, QChar drive) : QAsyncReader(parent, QVector() << getAudioCDMediaType()) { + m_toc = new CDROM_TOC; + m_waveHeader = new WaveStructure; + //now open the cd-drive QString path; if (drive.isNull()) { @@ -140,30 +154,36 @@ namespace Phonon path = QString::fromLatin1("\\\\.\\%1:").arg(drive); } - m_cddrive = ::CreateFile((const wchar_t *)path.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + m_cddrive = QT_WA_INLINE ( + ::CreateFile( (TCHAR*)path.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ), + ::CreateFileA( path.toLocal8Bit().constData(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ) + ); - qMemSet(&m_toc, 0, sizeof(CDROM_TOC)); + qMemSet(m_toc, 0, sizeof(CDROM_TOC)); //read the TOC DWORD bytesRead = 0; - bool tocRead = ::DeviceIoControl(m_cddrive, IOCTL_CDROM_READ_TOC, 0, 0, &m_toc, sizeof(CDROM_TOC), &bytesRead, 0); + bool tocRead = ::DeviceIoControl(m_cddrive, IOCTL_CDROM_READ_TOC, 0, 0, m_toc, sizeof(CDROM_TOC), &bytesRead, 0); if (!tocRead) { qWarning("unable to load the TOC from the CD"); return; } - m_trackAddress = addressToSectors(m_toc.TrackData[0].Address); - const qint32 nbSectorsToRead = (addressToSectors(m_toc.TrackData[m_toc.LastTrack + 1 - m_toc.FirstTrack].Address) + m_trackAddress = addressToSectors(m_toc->TrackData[0].Address); + const qint32 nbSectorsToRead = (addressToSectors(m_toc->TrackData[m_toc->LastTrack + 1 - m_toc->FirstTrack].Address) - m_trackAddress); const qint32 dataLength = nbSectorsToRead * SECTOR_SIZE; - m_waveHeader.chunksize = 4 + (8 + m_waveHeader.chunksize2) + (8 + dataLength); - m_waveHeader.dataLength = dataLength; + m_waveHeader->chunksize = 4 + (8 + m_waveHeader->chunksize2) + (8 + dataLength); + m_waveHeader->dataLength = dataLength; } QAudioCDReader::~QAudioCDReader() { ::CloseHandle(m_cddrive); + delete m_toc; + delete m_waveHeader; + } STDMETHODIMP_(ULONG) QAudioCDReader::AddRef() @@ -179,7 +199,7 @@ namespace Phonon STDMETHODIMP QAudioCDReader::Length(LONGLONG *total,LONGLONG *available) { - const LONGLONG length = sizeof(WaveStructure) + m_waveHeader.dataLength; + const LONGLONG length = sizeof(WaveStructure) + m_waveHeader->dataLength; if (total) { *total = length; } @@ -218,11 +238,11 @@ namespace Phonon if (pos < sizeof(WaveStructure)) { //we first copy the content of the structure nbRead = qMin(LONG(sizeof(WaveStructure) - pos), length); - qMemCopy(buffer, reinterpret_cast(&m_waveHeader) + pos, nbRead); + qMemCopy(buffer, reinterpret_cast(m_waveHeader) + pos, nbRead); } const LONGLONG posInTrack = pos - sizeof(WaveStructure) + nbRead; - const int bytesLeft = qMin(m_waveHeader.dataLength - posInTrack, LONGLONG(length - nbRead)); + const int bytesLeft = qMin(m_waveHeader->dataLength - posInTrack, LONGLONG(length - nbRead)); if (bytesLeft > 0) { @@ -277,8 +297,8 @@ namespace Phonon { QList ret; ret << 0; - for(int i = m_toc.FirstTrack; i <= m_toc.LastTrack ; ++i) { - const uchar *address = m_toc.TrackData[i].Address; + for(int i = m_toc->FirstTrack; i <= m_toc->LastTrack ; ++i) { + const uchar *address = m_toc->TrackData[i].Address; ret << ((address[0] * 60 + address[1]) * 60 + address[2]) * 1000 + address[3]*1000/75 - 2000; } diff --git a/src/3rdparty/phonon/ds9/qaudiocdreader.h b/src/3rdparty/phonon/ds9/qaudiocdreader.h index eff845d..9049b66 100644 --- a/src/3rdparty/phonon/ds9/qaudiocdreader.h +++ b/src/3rdparty/phonon/ds9/qaudiocdreader.h @@ -31,7 +31,7 @@ namespace Phonon { struct CDROM_TOC; struct WaveStructure; - EXTERN_C const IID IID_ITitleInterface; + extern const IID IID_ITitleInterface; //interface for the Titles struct ITitleInterface : public IUnknown diff --git a/src/3rdparty/phonon/ds9/qbasefilter.cpp b/src/3rdparty/phonon/ds9/qbasefilter.cpp index 78b8b8f..95cab92 100644 --- a/src/3rdparty/phonon/ds9/qbasefilter.cpp +++ b/src/3rdparty/phonon/ds9/qbasefilter.cpp @@ -92,8 +92,8 @@ namespace Phonon return E_POINTER; } - uint nbfetched = 0; - while (nbfetched < count && m_index < m_pins.count()) { + int nbfetched = 0; + while (nbfetched < int(count) && m_index < m_pins.count()) { IPin *current = m_pins[m_index]; current->AddRef(); ret[nbfetched] = current; @@ -166,19 +166,19 @@ namespace Phonon const QList QBaseFilter::pins() const { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); return m_pins; } void QBaseFilter::addPin(QPin *pin) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_pins.append(pin); } void QBaseFilter::removePin(QPin *pin) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_pins.removeAll(pin); } @@ -211,8 +211,7 @@ namespace Phonon } else if (iid == IID_IMediaPosition || iid == IID_IMediaSeeking) { if (inputPins().isEmpty()) { - *out = getUpStreamInterface(iid); - if (*out) { + if (*out = getUpStreamInterface(iid)) { return S_OK; //we return here to avoid adding a reference } else { hr = E_NOINTERFACE; @@ -251,35 +250,35 @@ namespace Phonon STDMETHODIMP QBaseFilter::GetClassID(CLSID *clsid) { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); *clsid = m_clsid; return S_OK; } STDMETHODIMP QBaseFilter::Stop() { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_state = State_Stopped; return S_OK; } STDMETHODIMP QBaseFilter::Pause() { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_state = State_Paused; return S_OK; } STDMETHODIMP QBaseFilter::Run(REFERENCE_TIME) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_state = State_Running; return S_OK; } STDMETHODIMP QBaseFilter::GetState(DWORD, FILTER_STATE *state) { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (!state) { return E_POINTER; } @@ -290,7 +289,7 @@ namespace Phonon STDMETHODIMP QBaseFilter::SetSyncSource(IReferenceClock *clock) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); if (clock) { clock->AddRef(); } @@ -303,7 +302,7 @@ namespace Phonon STDMETHODIMP QBaseFilter::GetSyncSource(IReferenceClock **clock) { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (!clock) { return E_POINTER; } @@ -342,7 +341,7 @@ namespace Phonon STDMETHODIMP QBaseFilter::QueryFilterInfo(FILTER_INFO *info ) { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (!info) { return E_POINTER; } @@ -356,9 +355,9 @@ namespace Phonon STDMETHODIMP QBaseFilter::JoinFilterGraph(IFilterGraph *graph, LPCWSTR name) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_graph = graph; - m_name = QString::fromWCharArray(name); + m_name = QString::fromUtf16((const unsigned short*)name); return S_OK; } diff --git a/src/3rdparty/phonon/ds9/qbasefilter.h b/src/3rdparty/phonon/ds9/qbasefilter.h index a72d6fe..85f1431 100644 --- a/src/3rdparty/phonon/ds9/qbasefilter.h +++ b/src/3rdparty/phonon/ds9/qbasefilter.h @@ -22,7 +22,7 @@ along with this library. If not, see . #include #include -#include +#include #include @@ -127,7 +127,7 @@ namespace Phonon IFilterGraph *m_graph; FILTER_STATE m_state; QList m_pins; - mutable QMutex m_mutex; + mutable QReadWriteLock m_lock; }; } } diff --git a/src/3rdparty/phonon/ds9/qevr9.h b/src/3rdparty/phonon/ds9/qevr9.h deleted file mode 100644 index 8599fce..0000000 --- a/src/3rdparty/phonon/ds9/qevr9.h +++ /dev/null @@ -1,143 +0,0 @@ -/* This file is part of the KDE project. - -Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 or 3 of the License. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this library. If not, see . -*/ - -#include - -#define DXVA2_ProcAmp_Brightness 1 -#define DXVA2_ProcAmp_Contrast 2 -#define DXVA2_ProcAmp_Hue 4 -#define DXVA2_ProcAmp_Saturation 8 - -typedef enum { - MFVideoARMode_None = 0x00000000, - MFVideoARMode_PreservePicture = 0x00000001, - MFVideoARMode_PreservePixel = 0x00000002, - MFVideoARMode_NonLinearStretch = 0x00000004, - MFVideoARMode_Mask = 0x00000007 -} MFVideoAspectRatioMode; - -typedef struct { - float left; - float top; - float right; - float bottom; -} MFVideoNormalizedRect; - -typedef struct { - UINT DeviceCaps; - D3DPOOL InputPool; - UINT NumForwardRefSamples; - UINT NumBackwardRefSamples; - UINT Reserved; - UINT DeinterlaceTechnology; - UINT ProcAmpControlCaps; - UINT VideoProcessorOperations; - UINT NoiseFilterTechnology; - UINT DetailFilterTechnology; -} DXVA2_VideoProcessorCaps; - -typedef struct { - union { - struct { - USHORT Fraction; - SHORT Value; - }; - LONG ll; - }; -} DXVA2_Fixed32; - -typedef struct { - DXVA2_Fixed32 MinValue; - DXVA2_Fixed32 MaxValue; - DXVA2_Fixed32 DefaultValue; - DXVA2_Fixed32 StepSize; -} DXVA2_ValueRange; - -typedef struct { - DXVA2_Fixed32 Brightness; - DXVA2_Fixed32 Contrast; - DXVA2_Fixed32 Hue; - DXVA2_Fixed32 Saturation; -} DXVA2_ProcAmpValues; - -DXVA2_Fixed32 DXVA2FloatToFixed(const float _float_) -{ - DXVA2_Fixed32 _fixed_; - _fixed_.Fraction = LOWORD(_float_ * 0x10000); - _fixed_.Value = HIWORD(_float_ * 0x10000); - return _fixed_; -} - -float DXVA2FixedToFloat(const DXVA2_Fixed32 _fixed_) -{ - return (FLOAT)_fixed_.Value + (FLOAT)_fixed_.Fraction / 0x10000; -} - -#undef INTERFACE -#define INTERFACE IMFVideoDisplayControl -DECLARE_INTERFACE_(IMFVideoDisplayControl, IUnknown) -{ - STDMETHOD(GetNativeVideoSize)(THIS_ SIZE* pszVideo, SIZE* pszARVideo) PURE; - STDMETHOD(GetIdealVideoSize)(THIS_ SIZE* pszMin, SIZE* pszMax) PURE; - STDMETHOD(SetVideoPosition)(THIS_ const MFVideoNormalizedRect* pnrcSource, const LPRECT prcDest) PURE; - STDMETHOD(GetVideoPosition)(THIS_ MFVideoNormalizedRect* pnrcSource, LPRECT prcDest) PURE; - STDMETHOD(SetAspectRatioMode)(THIS_ DWORD dwAspectRatioMode) PURE; - STDMETHOD(GetAspectRatioMode)(THIS_ DWORD* pdwAspectRatioMode) PURE; - STDMETHOD(SetVideoWindow)(THIS_ HWND hwndVideo) PURE; - STDMETHOD(GetVideoWindow)(THIS_ HWND* phwndVideo) PURE; - STDMETHOD(RepaintVideo)(THIS_) PURE; - STDMETHOD(GetCurrentImage)(THIS_ BITMAPINFOHEADER* pBih, BYTE** pDib, DWORD* pcbDib, LONGLONG* pTimeStamp) PURE; - STDMETHOD(SetBorderColor)(THIS_ COLORREF Clr) PURE; - STDMETHOD(GetBorderColor)(THIS_ COLORREF* pClr) PURE; - STDMETHOD(SetRenderingPrefs)(THIS_ DWORD dwRenderFlags) PURE; - STDMETHOD(GetRenderingPrefs)(THIS_ DWORD* pdwRenderFlags) PURE; - STDMETHOD(SetFullScreen)(THIS_ BOOL fFullscreen) PURE; - STDMETHOD(GetFullScreen)(THIS_ BOOL* pfFullscreen) PURE; -}; -#undef INTERFACE -#define INTERFACE IMFVideoMixerControl -DECLARE_INTERFACE_(IMFVideoMixerControl, IUnknown) -{ - STDMETHOD(SetStreamZOrder)(THIS_ DWORD dwStreamID, DWORD dwZ) PURE; - STDMETHOD(GetStreamZOrder)(THIS_ DWORD dwStreamID, DWORD* pdwZ) PURE; - STDMETHOD(SetStreamOutputRect)(THIS_ DWORD dwStreamID, const MFVideoNormalizedRect* pnrcOutput) PURE; - STDMETHOD(GetStreamOutputRect)(THIS_ DWORD dwStreamID, MFVideoNormalizedRect* pnrcOutput) PURE; -}; -#undef INTERFACE -#define INTERFACE IMFVideoProcessor -DECLARE_INTERFACE_(IMFVideoProcessor, IUnknown) -{ - STDMETHOD(GetAvailableVideoProcessorModes)(THIS_ UINT* lpdwNumProcessingModes, GUID** ppVideoProcessingModes) PURE; - STDMETHOD(GetVideoProcessorCaps)(THIS_ LPGUID lpVideoProcessorMode, DXVA2_VideoProcessorCaps* lpVideoProcessorCaps) PURE; - STDMETHOD(GetVideoProcessorMode)(THIS_ LPGUID lpMode) PURE; - STDMETHOD(SetVideoProcessorMode)(THIS_ LPGUID lpMode) PURE; - STDMETHOD(GetProcAmpRange)(THIS_ DWORD dwProperty, DXVA2_ValueRange* pPropRange) PURE; - STDMETHOD(GetProcAmpValues)(THIS_ DWORD dwFlags, DXVA2_ProcAmpValues* Values) PURE; - STDMETHOD(SetProcAmpValues)(THIS_ DWORD dwFlags, DXVA2_ProcAmpValues* pValues) PURE; - STDMETHOD(GetFilteringRange)(THIS_ DWORD dwProperty, DXVA2_ValueRange* pPropRange) PURE; - STDMETHOD(GetFilteringValue)(THIS_ DWORD dwProperty, DXVA2_Fixed32* pValue) PURE; - STDMETHOD(SetFilteringValue)(THIS_ DWORD dwProperty, DXVA2_Fixed32* pValue) PURE; - STDMETHOD(GetBackgroundColor)(THIS_ COLORREF* lpClrBkg) PURE; - STDMETHOD(SetBackgroundColor)(THIS_ COLORREF ClrBkg) PURE; -}; -#undef INTERFACE -#define INTERFACE IMFGetService -DECLARE_INTERFACE_(IMFGetService, IUnknown) -{ - STDMETHOD(GetService)(THIS_ REFGUID guidService, REFIID riid, LPVOID* ppvObject) PURE; -}; -#undef INTERFACE diff --git a/src/3rdparty/phonon/ds9/qmeminputpin.cpp b/src/3rdparty/phonon/ds9/qmeminputpin.cpp index a21fbe7..dca99db 100644 --- a/src/3rdparty/phonon/ds9/qmeminputpin.cpp +++ b/src/3rdparty/phonon/ds9/qmeminputpin.cpp @@ -28,8 +28,8 @@ namespace Phonon namespace DS9 { - QMemInputPin::QMemInputPin(QBaseFilter *parent, const QVector &mt, bool transform, QPin *output) : - QPin(parent, PINDIR_INPUT, mt), m_shouldDuplicateSamples(true), m_transform(transform), m_output(output) + QMemInputPin::QMemInputPin(QBaseFilter *parent, const QVector &mt, bool transform) : + QPin(parent, PINDIR_INPUT, mt), m_shouldDuplicateSamples(true), m_transform(transform) { } @@ -66,9 +66,11 @@ namespace Phonon { //this allows to serialize with Receive calls QMutexLocker locker(&m_mutexReceive); - IPin *conn = m_output ? m_output->connected() : 0; - if (conn) { - conn->EndOfStream(); + for(int i = 0; i < m_outputs.count(); ++i) { + IPin *conn = m_outputs.at(i)->connected(); + if (conn) { + conn->EndOfStream(); + } } return S_OK; } @@ -76,11 +78,13 @@ namespace Phonon STDMETHODIMP QMemInputPin::BeginFlush() { //pass downstream - IPin *conn = m_output ? m_output->connected() : 0; - if (conn) { - conn->BeginFlush(); + for(int i = 0; i < m_outputs.count(); ++i) { + IPin *conn = m_outputs.at(i)->connected(); + if (conn) { + conn->BeginFlush(); + } } - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_flushing = true; return S_OK; } @@ -88,19 +92,22 @@ namespace Phonon STDMETHODIMP QMemInputPin::EndFlush() { //pass downstream - IPin *conn = m_output ? m_output->connected() : 0; - if (conn) { - conn->EndFlush(); + for(int i = 0; i < m_outputs.count(); ++i) { + IPin *conn = m_outputs.at(i)->connected(); + if (conn) { + conn->EndFlush(); + } } - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_flushing = false; return S_OK; } STDMETHODIMP QMemInputPin::NewSegment(REFERENCE_TIME start, REFERENCE_TIME stop, double rate) { - if (m_output) - m_output->NewSegment(start, stop, rate); + for(int i = 0; i < m_outputs.count(); ++i) { + m_outputs.at(i)->NewSegment(start, stop, rate); + } return S_OK; } @@ -112,9 +119,14 @@ namespace Phonon if (hr == S_OK && mt->majortype != MEDIATYPE_NULL && mt->subtype != MEDIASUBTYPE_NULL && - mt->formattype != GUID_NULL && m_output) { - //we tell the output pin that it should connect with this type - hr = m_output->setAcceptedMediaType(connectedType()); + mt->formattype != GUID_NULL) { + //we tell the output pins that they should connect with this type + for(int i = 0; i < m_outputs.count(); ++i) { + hr = m_outputs.at(i)->setAcceptedMediaType(connectedType()); + if (FAILED(hr)) { + break; + } + } } return hr; } @@ -125,8 +137,7 @@ namespace Phonon return E_POINTER; } - *alloc = memoryAllocator(true); - if (*alloc) { + if (*alloc = memoryAllocator(true)) { return S_OK; } @@ -140,15 +151,18 @@ namespace Phonon } { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); m_shouldDuplicateSamples = m_transform && readonly; } setMemoryAllocator(alloc); - if (m_output) { - ComPointer input(m_output, IID_IMemInputPin); - input->NotifyAllocator(alloc, m_shouldDuplicateSamples); + for(int i = 0; i < m_outputs.count(); ++i) { + IPin *pin = m_outputs.at(i)->connected(); + if (pin) { + ComPointer input(pin, IID_IMemInputPin); + input->NotifyAllocator(alloc, m_shouldDuplicateSamples); + } } return S_OK; @@ -187,18 +201,22 @@ namespace Phonon } } - if (m_output) { + for (int i = 0; i < m_outputs.count(); ++i) { + QPin *current = m_outputs.at(i); IMediaSample *outSample = m_shouldDuplicateSamples ? - duplicateSampleForOutput(sample, m_output->memoryAllocator()) + duplicateSampleForOutput(sample, current->memoryAllocator()) : sample; if (m_shouldDuplicateSamples) { m_parent->processSample(outSample); } - ComPointer input(m_output->connected(), IID_IMemInputPin); - if (input) { - input->Receive(outSample); + IPin *pin = current->connected(); + if (pin) { + ComPointer input(pin, IID_IMemInputPin); + if (input) { + input->Receive(outSample); + } } if (m_shouldDuplicateSamples) { @@ -229,16 +247,39 @@ namespace Phonon STDMETHODIMP QMemInputPin::ReceiveCanBlock() { - //we test the output to see if it can block - if (m_output) { - ComPointer meminput(m_output->connected(), IID_IMemInputPin); - if (meminput && meminput->ReceiveCanBlock() != S_FALSE) { - return S_OK; + //we test the output to see if they can block + for(int i = 0; i < m_outputs.count(); ++i) { + IPin *input = m_outputs.at(i)->connected(); + if (input) { + ComPointer meminput(input, IID_IMemInputPin); + if (meminput && meminput->ReceiveCanBlock() != S_FALSE) { + return S_OK; + } } } return S_FALSE; } + //addition + //this should be used by the filter to tell its input pins to which output they should route the samples + + void QMemInputPin::addOutput(QPin *output) + { + QWriteLocker locker(&m_lock); + m_outputs += output; + } + + void QMemInputPin::removeOutput(QPin *output) + { + QWriteLocker locker(&m_lock); + m_outputs.removeOne(output); + } + + QList QMemInputPin::outputs() const + { + QReadLocker locker(&m_lock); + return m_outputs; + } ALLOCATOR_PROPERTIES QMemInputPin::getDefaultAllocatorProperties() const { @@ -253,7 +294,7 @@ namespace Phonon LONG length = sample->GetActualDataLength(); HRESULT hr = alloc->Commit(); - if (hr == HRESULT(VFW_E_SIZENOTSET)) { + if (hr == VFW_E_SIZENOTSET) { ALLOCATOR_PROPERTIES prop = getDefaultAllocatorProperties(); prop.cbBuffer = qMax(prop.cbBuffer, length); ALLOCATOR_PROPERTIES actual; @@ -283,7 +324,7 @@ namespace Phonon { LONGLONG start, end; hr = sample->GetMediaTime(&start, &end); - if (hr != HRESULT(VFW_E_MEDIA_TIME_NOT_SET)) { + if (hr != VFW_E_MEDIA_TIME_NOT_SET) { hr = out->SetMediaTime(&start, &end); Q_ASSERT(SUCCEEDED(hr)); } diff --git a/src/3rdparty/phonon/ds9/qmeminputpin.h b/src/3rdparty/phonon/ds9/qmeminputpin.h index d74c451..c449721 100644 --- a/src/3rdparty/phonon/ds9/qmeminputpin.h +++ b/src/3rdparty/phonon/ds9/qmeminputpin.h @@ -37,7 +37,7 @@ namespace Phonon class QMemInputPin : public QPin, public IMemInputPin { public: - QMemInputPin(QBaseFilter *, const QVector &, bool transform, QPin *output); + QMemInputPin(QBaseFilter *, const QVector &, bool transform); ~QMemInputPin(); //reimplementation from IUnknown @@ -60,13 +60,18 @@ namespace Phonon STDMETHODIMP ReceiveMultiple(IMediaSample **,long,long *); STDMETHODIMP ReceiveCanBlock(); + //addition + void addOutput(QPin *output); + void removeOutput(QPin *output); + QList outputs() const; + private: IMediaSample *duplicateSampleForOutput(IMediaSample *, IMemAllocator *); ALLOCATOR_PROPERTIES getDefaultAllocatorProperties() const; bool m_shouldDuplicateSamples; const bool m_transform; //defines if the pin is transforming the samples - QPin* const m_output; + QList m_outputs; QMutex m_mutexReceive; }; } diff --git a/src/3rdparty/phonon/ds9/qpin.cpp b/src/3rdparty/phonon/ds9/qpin.cpp index b4afd10..37fe48d 100644 --- a/src/3rdparty/phonon/ds9/qpin.cpp +++ b/src/3rdparty/phonon/ds9/qpin.cpp @@ -28,7 +28,20 @@ namespace Phonon namespace DS9 { - static const AM_MEDIA_TYPE defaultMediaType = { MEDIATYPE_NULL, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; + static const AM_MEDIA_TYPE defaultMediaType() + { + AM_MEDIA_TYPE ret; + ret.majortype = MEDIATYPE_NULL; + ret.subtype = MEDIASUBTYPE_NULL; + ret.bFixedSizeSamples = TRUE; + ret.bTemporalCompression = FALSE; + ret.lSampleSize = 1; + ret.formattype = GUID_NULL; + ret.pUnk = 0; + ret.cbFormat = 0; + ret.pbFormat = 0; + return ret; + } class QEnumMediaTypes : public IEnumMediaTypes { @@ -91,8 +104,8 @@ namespace Phonon return E_INVALIDARG; } - uint nbFetched = 0; - while (nbFetched < count && m_index < m_pin->mediaTypes().count()) { + int nbFetched = 0; + while (nbFetched < int(count) && m_index < m_pin->mediaTypes().count()) { //the caller will deallocate the memory *out = static_cast(::CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))); const AM_MEDIA_TYPE original = m_pin->mediaTypes().at(m_index); @@ -145,9 +158,9 @@ namespace Phonon QPin::QPin(QBaseFilter *parent, PIN_DIRECTION dir, const QVector &mt) : - m_parent(parent), m_flushing(false), m_refCount(1), m_connected(0), - m_direction(dir), m_mediaTypes(mt), m_connectedType(defaultMediaType), - m_memAlloc(0) + m_memAlloc(0), m_parent(parent), m_refCount(1), m_connected(0), + m_direction(dir), m_mediaTypes(mt), m_connectedType(defaultMediaType()), + m_flushing(false) { Q_ASSERT(m_parent); m_parent->addPin(this); @@ -260,7 +273,7 @@ namespace Phonon if (FAILED(hr)) { setConnected(0); - setConnectedType(defaultMediaType); + setConnectedType(defaultMediaType()); } else { ComPointer input(pin, IID_IMemInputPin); if (input) { @@ -302,8 +315,10 @@ namespace Phonon } setConnected(0); - setConnectedType(defaultMediaType); - setMemoryAllocator(0); + setConnectedType(defaultMediaType()); + if (m_direction == PINDIR_INPUT) { + setMemoryAllocator(0); + } return S_OK; } @@ -323,7 +338,7 @@ namespace Phonon STDMETHODIMP QPin::ConnectionMediaType(AM_MEDIA_TYPE *type) { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (!type) { return E_POINTER; } @@ -338,6 +353,7 @@ namespace Phonon STDMETHODIMP QPin::QueryPinInfo(PIN_INFO *info) { + QReadLocker locker(&m_lock); if (!info) { return E_POINTER; } @@ -345,12 +361,14 @@ namespace Phonon info->dir = m_direction; info->pFilter = m_parent; m_parent->AddRef(); - info->achName[0] = 0; + qMemCopy(info->achName, m_name.utf16(), qMin(MAX_FILTER_NAME, m_name.length()+1) *2); + return S_OK; } STDMETHODIMP QPin::QueryDirection(PIN_DIRECTION *dir) { + QReadLocker locker(&m_lock); if (!dir) { return E_POINTER; } @@ -361,18 +379,20 @@ namespace Phonon STDMETHODIMP QPin::QueryId(LPWSTR *id) { + QReadLocker locker(&m_lock); if (!id) { return E_POINTER; } - *id = static_cast(::CoTaskMemAlloc(2)); - *id[0] = 0; + int nbBytes = (m_name.length()+1)*2; + *id = static_cast(::CoTaskMemAlloc(nbBytes)); + qMemCopy(*id, m_name.utf16(), nbBytes); return S_OK; } STDMETHODIMP QPin::QueryAccept(const AM_MEDIA_TYPE *type) { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (!type) { return E_POINTER; } @@ -419,7 +439,7 @@ namespace Phonon STDMETHODIMP QPin::NewSegment(REFERENCE_TIME start, REFERENCE_TIME stop, double rate) { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (m_direction == PINDIR_OUTPUT && m_connected) { //we deliver this downstream m_connected->NewSegment(start, stop, rate); @@ -436,8 +456,8 @@ namespace Phonon HRESULT QPin::checkOutputMediaTypesConnection(IPin *pin) { - ComPointer emt; - HRESULT hr = pin->EnumMediaTypes(emt.pparam()); + IEnumMediaTypes *emt = 0; + HRESULT hr = pin->EnumMediaTypes(&emt); if (hr != S_OK) { return hr; } @@ -450,7 +470,7 @@ namespace Phonon freeMediaType(type); return S_OK; } else { - setConnectedType(defaultMediaType); + setConnectedType(defaultMediaType()); freeMediaType(type); } } @@ -500,7 +520,7 @@ namespace Phonon void QPin::setConnectedType(const AM_MEDIA_TYPE &type) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); //1st we free memory freeMediaType(m_connectedType); @@ -510,13 +530,13 @@ namespace Phonon const AM_MEDIA_TYPE &QPin::connectedType() const { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); return m_connectedType; } void QPin::setConnected(IPin *pin) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); if (pin) { pin->AddRef(); } @@ -528,7 +548,7 @@ namespace Phonon IPin *QPin::connected(bool addref) const { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (addref && m_connected) { m_connected->AddRef(); } @@ -537,12 +557,13 @@ namespace Phonon bool QPin::isFlushing() const { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); return m_flushing; } FILTER_STATE QPin::filterState() const { + QReadLocker locker(&m_lock); FILTER_STATE fstate = State_Stopped; m_parent->GetState(0, &fstate); return fstate; @@ -550,7 +571,7 @@ namespace Phonon QVector QPin::mediaTypes() const { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); return m_mediaTypes; } @@ -586,7 +607,7 @@ namespace Phonon void QPin::setMemoryAllocator(IMemAllocator *alloc) { - QMutexLocker locker(&m_mutex); + QWriteLocker locker(&m_lock); if (alloc) { alloc->AddRef(); } @@ -598,7 +619,7 @@ namespace Phonon IMemAllocator *QPin::memoryAllocator(bool addref) const { - QMutexLocker locker(&m_mutex); + QReadLocker locker(&m_lock); if (addref && m_memAlloc) { m_memAlloc->AddRef(); } diff --git a/src/3rdparty/phonon/ds9/qpin.h b/src/3rdparty/phonon/ds9/qpin.h index 280ad61..a3287c4 100644 --- a/src/3rdparty/phonon/ds9/qpin.h +++ b/src/3rdparty/phonon/ds9/qpin.h @@ -22,7 +22,7 @@ along with this library. If not, see . #include #include -#include +#include #include @@ -85,8 +85,8 @@ namespace Phonon protected: //this can be used by sub-classes - mutable QMutex m_mutex; - QBaseFilter * const m_parent; + mutable QReadWriteLock m_lock; + QBaseFilter *m_parent; bool m_flushing; private: @@ -98,6 +98,7 @@ namespace Phonon const PIN_DIRECTION m_direction; QVector m_mediaTypes; //accepted media types AM_MEDIA_TYPE m_connectedType; + QString m_name; IMemAllocator *m_memAlloc; }; diff --git a/src/3rdparty/phonon/ds9/videorenderer_default.cpp b/src/3rdparty/phonon/ds9/videorenderer_default.cpp deleted file mode 100644 index 0045a49..0000000 --- a/src/3rdparty/phonon/ds9/videorenderer_default.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* This file is part of the KDE project. - -Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 or 3 of the License. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this library. If not, see . -*/ - - -#include "videorenderer_default.h" - -#ifndef QT_NO_PHONON_VIDEO - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - - -namespace Phonon -{ - namespace DS9 - { - VideoRendererDefault::~VideoRendererDefault() - { - } - - bool VideoRendererDefault::isNative() const - { - return true; - } - - - VideoRendererDefault::VideoRendererDefault(QWidget *target) : m_target(target) - { - m_target->setAttribute(Qt::WA_PaintOnScreen, true); - m_filter = Filter(CLSID_VideoRenderer, IID_IBaseFilter); - } - - QSize VideoRendererDefault::videoSize() const - { - LONG w = 0, - h = 0; - ComPointer basic(m_filter, IID_IBasicVideo); - if (basic) { - basic->GetVideoSize( &w, &h); - } - return QSize(w, h); - } - - void VideoRendererDefault::repaintCurrentFrame(QWidget * /*target*/, const QRect & /*rect*/) - { - //nothing to do here: the renderer paints everything - } - - void VideoRendererDefault::notifyResize(const QSize &size, Phonon::VideoWidget::AspectRatio aspectRatio, - Phonon::VideoWidget::ScaleMode scaleMode) - { - if (!isActive()) { - ComPointer basic(m_filter, IID_IBasicVideo); - if (basic) { - basic->SetDestinationPosition(0, 0, 0, 0); - } - return; - } - - ComPointer video(m_filter, IID_IVideoWindow); - - OAHWND owner; - HRESULT hr = video->get_Owner(&owner); - if (FAILED(hr)) { - return; - } - - const OAHWND newOwner = reinterpret_cast(m_target->winId()); - if (owner != newOwner) { - video->put_Owner(newOwner); - video->put_MessageDrain(newOwner); - video->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - } - - //make sure the widget takes the whole size of the parent - video->SetWindowPosition(0, 0, size.width(), size.height()); - - const QSize vsize = videoSize(); - internalNotifyResize(size, vsize, aspectRatio, scaleMode); - - ComPointer basic(m_filter, IID_IBasicVideo); - if (basic) { - basic->SetDestinationPosition(m_dstX, m_dstY, m_dstWidth, m_dstHeight); - } - } - - void VideoRendererDefault::applyMixerSettings(qreal /*brightness*/, qreal /*contrast*/, qreal /*m_hue*/, qreal /*saturation*/) - { - //this can't be supported for the default renderer - } - - QImage VideoRendererDefault::snapshot() const - { - ComPointer basic(m_filter, IID_IBasicVideo); - if (basic) { - LONG bufferSize = 0; - //1st we get the buffer size - basic->GetCurrentImage(&bufferSize, 0); - - QByteArray buffer; - buffer.resize(bufferSize); - HRESULT hr = basic->GetCurrentImage(&bufferSize, reinterpret_cast(buffer.data())); - - if (SUCCEEDED(hr)) { - - const BITMAPINFOHEADER *bmi = reinterpret_cast(buffer.constData()); - - const int w = qAbs(bmi->biWidth), - h = qAbs(bmi->biHeight); - - // Create image and copy data into image. - QImage ret(w, h, QImage::Format_RGB32); - - if (!ret.isNull()) { - const char *data = buffer.constData() + bmi->biSize; - const int bytes_per_line = w * sizeof(QRgb); - for (int y = h - 1; y >= 0; --y) { - qMemCopy(ret.scanLine(y), //destination - data, //source - bytes_per_line); - data += bytes_per_line; - } - } - return ret; - } - } - return QImage(); - } - - } -} - -QT_END_NAMESPACE - -#endif //QT_NO_PHONON_VIDEO diff --git a/src/3rdparty/phonon/ds9/videorenderer_default.h b/src/3rdparty/phonon/ds9/videorenderer_default.h deleted file mode 100644 index 43768d9..0000000 --- a/src/3rdparty/phonon/ds9/videorenderer_default.h +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of the KDE project. - -Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 or 3 of the License. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this library. If not, see . -*/ - -#ifndef PHONON_VIDEORENDERER_DEFAULT_H -#define PHONON_VIDEORENDERER_DEFAULT_H - -#include "abstractvideorenderer.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PHONON_VIDEO - -namespace Phonon -{ - namespace DS9 - { - class VideoRendererDefault : public AbstractVideoRenderer - { - public: - VideoRendererDefault(QWidget *target); - ~VideoRendererDefault(); - - //Implementation from AbstractVideoRenderer - void repaintCurrentFrame(QWidget *target, const QRect &rect); - void notifyResize(const QSize&, Phonon::VideoWidget::AspectRatio, Phonon::VideoWidget::ScaleMode); - QSize videoSize() const; - QImage snapshot() const; - void applyMixerSettings(qreal brightness, qreal contrast, qreal m_hue, qreal saturation); - bool isNative() const; - private: - QWidget *m_target; - }; - } -} - -#endif //QT_NO_PHONON_VIDEO - -QT_END_NAMESPACE - -#endif - diff --git a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp deleted file mode 100644 index d23d9ce..0000000 --- a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* This file is part of the KDE project. - -Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 or 3 of the License. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this library. If not, see . -*/ - - -#include "videorenderer_evr.h" -#include "qevr9.h" - -#ifndef QT_NO_PHONON_VIDEO - -#include -#include - -QT_BEGIN_NAMESPACE - -namespace Phonon -{ - namespace DS9 - { - //we have to define them here because not all compilers/sdk have them - static const GUID MR_VIDEO_RENDER_SERVICE = {0x1092a86c, 0xab1a, 0x459a, {0xa3, 0x36, 0x83, 0x1f, 0xbc, 0x4d, 0x11, 0xff} }; - static const GUID MR_VIDEO_MIXER_SERVICE = { 0x73cd2fc, 0x6cf4, 0x40b7, {0x88, 0x59, 0xe8, 0x95, 0x52, 0xc8, 0x41, 0xf8} }; - static const IID IID_IMFVideoDisplayControl = {0xa490b1e4, 0xab84, 0x4d31, {0xa1, 0xb2, 0x18, 0x1e, 0x03, 0xb1, 0x07, 0x7a} }; - static const IID IID_IMFVideoMixerControl = {0xA5C6C53F, 0xC202, 0x4aa5, {0x96, 0x95, 0x17, 0x5B, 0xA8, 0xC5, 0x08, 0xA5} }; - static const IID IID_IMFVideoProcessor = {0x6AB0000C, 0xFECE, 0x4d1f, {0xA2, 0xAC, 0xA9, 0x57, 0x35, 0x30, 0x65, 0x6E} }; - static const IID IID_IMFGetService = {0xFA993888, 0x4383, 0x415A, {0xA9, 0x30, 0xDD, 0x47, 0x2A, 0x8C, 0xF6, 0xF7} }; - static const GUID CLSID_EnhancedVideoRenderer = {0xfa10746c, 0x9b63, 0x4b6c, {0xbc, 0x49, 0xfc, 0x30, 0xe, 0xa5, 0xf2, 0x56} }; - - template ComPointer getService(const Filter &filter, REFGUID guidService, REFIID riid) - { - //normally we should use IID_IMFGetService but this introduces another dependency - //so here we simply define our own IId with the same value - ComPointer getService(filter, IID_IMFGetService); - Q_ASSERT(getService); - T *ptr = 0; - HRESULT hr = getService->GetService(guidService, riid, reinterpret_cast(&ptr)); - if (!SUCCEEDED(hr) || ptr == 0) - Q_ASSERT(!SUCCEEDED(hr) && ptr != 0); - ComPointer service(ptr); - return service; - } - - VideoRendererEVR::~VideoRendererEVR() - { - } - - bool VideoRendererEVR::isNative() const - { - return true; - } - - VideoRendererEVR::VideoRendererEVR(QWidget *target) : m_target(target) - { - m_filter = Filter(CLSID_EnhancedVideoRenderer, IID_IBaseFilter); - if (!m_filter) { - return; - } - - ComPointer filterControl = getService(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); - - filterControl->SetVideoWindow(reinterpret_cast(target->winId())); - filterControl->SetAspectRatioMode(MFVideoARMode_None); // We're in control of the size - } - - QImage VideoRendererEVR::snapshot() const - { - // This will always capture black areas where no video is drawn, if any are present. - // Due to the hack in notifyResize() - ComPointer filterControl = getService(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); - if (filterControl) { - BITMAPINFOHEADER bmi; - BYTE *buffer = 0; - DWORD bufferSize; - LONGLONG timeStamp; - - bmi.biSize = sizeof(BITMAPINFOHEADER); - - HRESULT hr = filterControl->GetCurrentImage(&bmi, &buffer, &bufferSize, &timeStamp); - if (SUCCEEDED(hr)) { - - const int w = qAbs(bmi.biWidth), - h = qAbs(bmi.biHeight); - - // Create image and copy data into image. - QImage ret(w, h, QImage::Format_RGB32); - - if (!ret.isNull()) { - uchar *data = buffer; - const int bytes_per_line = w * sizeof(QRgb); - for (int y = h - 1; y >= 0; --y) { - qMemCopy(ret.scanLine(y), //destination - data, //source - bytes_per_line); - data += bytes_per_line; - } - } - ::CoTaskMemFree(buffer); - return ret; - } - } - return QImage(); - } - - QSize VideoRendererEVR::videoSize() const - { - SIZE nativeSize; - SIZE aspectRatioSize; - - ComPointer filterControl = getService(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); - - filterControl->GetNativeVideoSize(&nativeSize, &aspectRatioSize); - - return QSize(nativeSize.cx, nativeSize.cy); - } - - void VideoRendererEVR::repaintCurrentFrame(QWidget *target, const QRect &rect) - { - // repaint the video - ComPointer filterControl = getService(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); - // All failed results can be safely ignored - filterControl->RepaintVideo(); - } - - void VideoRendererEVR::notifyResize(const QSize &size, Phonon::VideoWidget::AspectRatio aspectRatio, - Phonon::VideoWidget::ScaleMode scaleMode) - { - if (!isActive()) { - RECT dummyRect = { 0, 0, 0, 0}; - ComPointer filterControl = getService(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); - filterControl->SetVideoPosition(0, &dummyRect); - return; - } - - const QSize vsize = videoSize(); - internalNotifyResize(size, vsize, aspectRatio, scaleMode); - - RECT dstRectWin = { 0, 0, size.width(), size.height()}; - - // Resize the Stream output rect instead of the destination rect. - // Hacky workaround for flicker in the areas outside of the destination rect - // This way these areas don't exist - MFVideoNormalizedRect streamOutputRect = { float(m_dstX) / float(size.width()), float(m_dstY) / float(size.height()), - float(m_dstWidth + m_dstX) / float(size.width()), float(m_dstHeight + m_dstY) / float(size.height())}; - - ComPointer filterMixer = getService(m_filter, MR_VIDEO_MIXER_SERVICE, IID_IMFVideoMixerControl); - ComPointer filterControl = getService(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); - - filterMixer->SetStreamOutputRect(0, &streamOutputRect); - filterControl->SetVideoPosition(0, &dstRectWin); - } - - void VideoRendererEVR::applyMixerSettings(qreal brightness, qreal contrast, qreal hue, qreal saturation) - { - InputPin sink = BackendNode::pins(m_filter, PINDIR_INPUT).first(); - OutputPin source; - if (FAILED(sink->ConnectedTo(source.pparam()))) { - return; //it must be connected to work - } - - // Get the "Video Processor" (used for brightness/contrast/saturation/hue) - ComPointer processor = getService(m_filter, MR_VIDEO_MIXER_SERVICE, IID_IMFVideoProcessor); - Q_ASSERT(processor); - - DXVA2_ValueRange contrastRange; - DXVA2_ValueRange brightnessRange; - DXVA2_ValueRange saturationRange; - DXVA2_ValueRange hueRange; - - if (FAILED(processor->GetProcAmpRange(DXVA2_ProcAmp_Contrast, &contrastRange))) - return; - if (FAILED(processor->GetProcAmpRange(DXVA2_ProcAmp_Brightness, &brightnessRange))) - return; - if (FAILED(processor->GetProcAmpRange(DXVA2_ProcAmp_Saturation, &saturationRange))) - return; - if (FAILED(processor->GetProcAmpRange(DXVA2_ProcAmp_Hue, &hueRange))) - return; - - DXVA2_ProcAmpValues values; - - values.Contrast = DXVA2FloatToFixed(((contrast < 0 - ? DXVA2FixedToFloat(contrastRange.MinValue) : DXVA2FixedToFloat(contrastRange.MaxValue)) - - DXVA2FixedToFloat(contrastRange.DefaultValue)) * qAbs(contrast) + DXVA2FixedToFloat(contrastRange.DefaultValue)); - values.Brightness = DXVA2FloatToFixed(((brightness < 0 - ? DXVA2FixedToFloat(brightnessRange.MinValue) : DXVA2FixedToFloat(brightnessRange.MaxValue)) - - DXVA2FixedToFloat(brightnessRange.DefaultValue)) * qAbs(brightness) + DXVA2FixedToFloat(brightnessRange.DefaultValue)); - values.Saturation = DXVA2FloatToFixed(((saturation < 0 - ? DXVA2FixedToFloat(saturationRange.MinValue) : DXVA2FixedToFloat(saturationRange.MaxValue)) - - DXVA2FixedToFloat(saturationRange.DefaultValue)) * qAbs(saturation) + DXVA2FixedToFloat(saturationRange.DefaultValue)); - values.Hue = DXVA2FloatToFixed(((hue < 0 - ? DXVA2FixedToFloat(hueRange.MinValue) : DXVA2FixedToFloat(hueRange.MaxValue)) - - DXVA2FixedToFloat(hueRange.DefaultValue)) * qAbs(hue) + DXVA2FixedToFloat(hueRange.DefaultValue)); - - //finally set the settings - processor->SetProcAmpValues(DXVA2_ProcAmp_Contrast | DXVA2_ProcAmp_Brightness | DXVA2_ProcAmp_Saturation | DXVA2_ProcAmp_Hue, &values); - - } - } -} - -QT_END_NAMESPACE - -#endif //QT_NO_PHONON_VIDEO diff --git a/src/3rdparty/phonon/ds9/videorenderer_evr.h b/src/3rdparty/phonon/ds9/videorenderer_evr.h deleted file mode 100644 index 229c36d..0000000 --- a/src/3rdparty/phonon/ds9/videorenderer_evr.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of the KDE project. - -Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - -This library is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 or 3 of the License. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this library. If not, see . -*/ - -#ifndef PHONON_VIDEORENDERER_EVR_H -#define PHONON_VIDEORENDERER_EVR_H - -#include "abstractvideorenderer.h" -#include "compointer.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PHONON_VIDEO - -namespace Phonon -{ - namespace DS9 - { - class VideoRendererEVR : public AbstractVideoRenderer - { - public: - VideoRendererEVR(QWidget *target); - ~VideoRendererEVR(); - - //Implementation from AbstractVideoRenderer - void repaintCurrentFrame(QWidget *target, const QRect &rect); - void notifyResize(const QSize&, Phonon::VideoWidget::AspectRatio, Phonon::VideoWidget::ScaleMode); - QSize videoSize() const; - QImage snapshot() const; - void applyMixerSettings(qreal brightness, qreal contrast, qreal m_hue, qreal saturation); - bool isNative() const; - private: - QWidget *m_target; - }; - } -} - -#endif //QT_NO_PHONON_VIDEO - -QT_END_NAMESPACE - -#endif - diff --git a/src/3rdparty/phonon/ds9/videorenderer_soft.cpp b/src/3rdparty/phonon/ds9/videorenderer_soft.cpp index 9c7993c..491d1bd 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_soft.cpp +++ b/src/3rdparty/phonon/ds9/videorenderer_soft.cpp @@ -194,8 +194,8 @@ namespace Phonon m_sampleBuffer = ComPointer(); #ifndef QT_NO_OPENGL freeGLResources(); - m_textureUploaded = false; #endif // QT_NO_OPENGL + m_textureUploaded = false; } void endOfStream() @@ -314,6 +314,7 @@ namespace Phonon REFERENCE_TIME m_start; HANDLE m_renderEvent, m_receiveCanWait; // Signals sample to render QSize m_size; + bool m_textureUploaded; //mixer settings qreal m_brightness, @@ -355,7 +356,6 @@ namespace Phonon bool m_checkedPrograms; bool m_usingOpenGL; - bool m_textureUploaded; GLuint m_program[2]; GLuint m_texture[3]; #endif @@ -365,7 +365,7 @@ namespace Phonon { public: VideoRendererSoftPin(VideoRendererSoftFilter *parent) : - QMemInputPin(parent, videoMediaTypes(), false /*no transformation of the samples*/, 0), + QMemInputPin(parent, videoMediaTypes(), false /*no transformation of the samples*/), m_renderer(parent) { } @@ -436,7 +436,7 @@ namespace Phonon QBaseFilter(CLSID_NULL), m_inputPin(new VideoRendererSoftPin(this)), m_renderer(renderer), m_start(0) #ifndef QT_NO_OPENGL - , m_checkedPrograms(false), m_usingOpenGL(false), m_textureUploaded(false) + ,m_usingOpenGL(false), m_checkedPrograms(false), m_textureUploaded(false) #endif { m_renderEvent = ::CreateEvent(0, 0, 0, 0); @@ -661,10 +661,7 @@ namespace Phonon #ifndef QT_NO_OPENGL - if (painter.paintEngine() && - (painter.paintEngine()->type() == QPaintEngine::OpenGL || painter.paintEngine()->type() == QPaintEngine::OpenGL2) - && checkGLPrograms()) { - + if (painter.paintEngine() && painter.paintEngine()->type() == QPaintEngine::OpenGL && checkGLPrograms()) { //for now we only support YUV (both YV12 and YUY2) updateTexture(); @@ -676,7 +673,6 @@ namespace Phonon } //let's draw the texture - painter.beginNativePainting(); //Let's pass the other arguments const Program prog = (m_inputPin->connectedType().subtype == MEDIASUBTYPE_YV12) ? YV12toRGB : YUY2toRGB; @@ -726,7 +722,6 @@ namespace Phonon glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_FRAGMENT_PROGRAM_ARB); - painter.endNativePainting(); return; } else #endif diff --git a/src/3rdparty/phonon/ds9/videorenderer_vmr9.cpp b/src/3rdparty/phonon/ds9/videorenderer_vmr9.cpp index 545b31e..298e9fa 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_vmr9.cpp +++ b/src/3rdparty/phonon/ds9/videorenderer_vmr9.cpp @@ -22,9 +22,14 @@ along with this library. If not, see . #include #include +#include +#ifndef Q_OS_WINCE #include #include +#else +#include +#endif QT_BEGIN_NAMESPACE @@ -43,10 +48,116 @@ namespace Phonon } +#ifdef Q_OS_WINCE + VideoRendererVMR9::VideoRendererVMR9(QWidget *target) : m_target(target) + { + m_target->setAttribute(Qt::WA_PaintOnScreen, true); + m_filter = Filter(CLSID_VideoRenderer, IID_IBaseFilter); + } + + QSize VideoRendererVMR9::videoSize() const + { + LONG w = 0, + h = 0; + ComPointer basic(m_filter, IID_IBasicVideo); + if (basic) { + basic->GetVideoSize( &w, &h); + } + return QSize(w, h); + } + + void VideoRendererVMR9::repaintCurrentFrame(QWidget * /*target*/, const QRect & /*rect*/) + { + //nothing to do here: the renderer paints everything + } + + void VideoRendererVMR9::notifyResize(const QSize &size, Phonon::VideoWidget::AspectRatio aspectRatio, + Phonon::VideoWidget::ScaleMode scaleMode) + { + if (!isActive()) { + ComPointer basic(m_filter, IID_IBasicVideo); + if (basic) { + basic->SetDestinationPosition(0, 0, 0, 0); + } + return; + } + + ComPointer video(m_filter, IID_IVideoWindow); + + OAHWND owner; + HRESULT hr = video->get_Owner(&owner); + if (FAILED(hr)) { + return; + } + + const OAHWND newOwner = reinterpret_cast(m_target->winId()); + if (owner != newOwner) { + video->put_Owner(newOwner); + video->put_MessageDrain(newOwner); + video->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + } + + //make sure the widget takes the whole size of the parent + video->SetWindowPosition(0, 0, size.width(), size.height()); + + const QSize vsize = videoSize(); + internalNotifyResize(size, vsize, aspectRatio, scaleMode); + + ComPointer basic(m_filter, IID_IBasicVideo); + if (basic) { + basic->SetDestinationPosition(m_dstX, m_dstY, m_dstWidth, m_dstHeight); + } + } + + void VideoRendererVMR9::applyMixerSettings(qreal /*brightness*/, qreal /*contrast*/, qreal /*m_hue*/, qreal /*saturation*/) + { + //this can't be supported for WinCE + } + + QImage VideoRendererVMR9::snapshot() const + { + ComPointer basic(m_filter, IID_IBasicVideo); + if (basic) { + LONG bufferSize = 0; + //1st we get the buffer size + basic->GetCurrentImage(&bufferSize, 0); + + QByteArray buffer; + buffer.resize(bufferSize); + HRESULT hr = basic->GetCurrentImage(&bufferSize, reinterpret_cast(buffer.data())); + + if (SUCCEEDED(hr)) { + + const BITMAPINFOHEADER *bmi = reinterpret_cast(buffer.constData()); + + const int w = qAbs(bmi->biWidth), + h = qAbs(bmi->biHeight); + + // Create image and copy data into image. + QImage ret(w, h, QImage::Format_RGB32); + + if (!ret.isNull()) { + const char *data = buffer.constData() + bmi->biSize; + const int bytes_per_line = w * sizeof(QRgb); + for (int y = h - 1; y >= 0; --y) { + qMemCopy(ret.scanLine(y), //destination + data, //source + bytes_per_line); + data += bytes_per_line; + } + } + return ret; + } + } + return QImage(); + } + +#else VideoRendererVMR9::VideoRendererVMR9(QWidget *target) : m_target(target) { m_filter = Filter(CLSID_VideoMixingRenderer9, IID_IBaseFilter); if (!m_filter) { + qWarning("the video widget could not be initialized correctly"); return; } @@ -58,7 +169,6 @@ namespace Phonon Q_ASSERT(SUCCEEDED(hr)); ComPointer windowlessControl(m_filter, IID_IVMRWindowlessControl9); windowlessControl->SetVideoClippingWindow(reinterpret_cast(target->winId())); - windowlessControl->SetAspectRatioMode(VMR9ARMode_None); //we're in control of the size } QImage VideoRendererVMR9::snapshot() const @@ -214,6 +324,7 @@ namespace Phonon //finally set the settings mixer->SetProcAmpControl(0, &ctrl); } +#endif } } diff --git a/src/3rdparty/phonon/ds9/videorenderer_vmr9.h b/src/3rdparty/phonon/ds9/videorenderer_vmr9.h index 516d79d..4eb237e 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_vmr9.h +++ b/src/3rdparty/phonon/ds9/videorenderer_vmr9.h @@ -19,6 +19,7 @@ along with this library. If not, see . #define PHONON_VIDEORENDERER_VMR9_H #include "abstractvideorenderer.h" +#include "compointer.h" QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/ds9/videowidget.cpp b/src/3rdparty/phonon/ds9/videowidget.cpp index 09d42a4..de7ce5f 100644 --- a/src/3rdparty/phonon/ds9/videowidget.cpp +++ b/src/3rdparty/phonon/ds9/videowidget.cpp @@ -24,12 +24,7 @@ along with this library. If not, see . #include "mediaobject.h" -#ifndef Q_OS_WINCE -#include "videorenderer_evr.h" #include "videorenderer_vmr9.h" -#else -#include "videorenderer_default.h" -#endif #include "videorenderer_soft.h" QT_BEGIN_NAMESPACE @@ -89,19 +84,7 @@ namespace Phonon void setCurrentRenderer(AbstractVideoRenderer *renderer) { m_currentRenderer = renderer; - //we disallow repaint on that widget for just a fraction of second - //this allows better transition between videos - setUpdatesEnabled(false); - m_flickerFreeTimer.start(20, this); - } - - void timerEvent(QTimerEvent *e) - { - if (e->timerId() == m_flickerFreeTimer.timerId()) { - m_flickerFreeTimer.stop(); - setUpdatesEnabled(true); - } - QWidget::timerEvent(e); + update(); } QSize sizeHint() const @@ -123,8 +106,6 @@ namespace Phonon void paintEvent(QPaintEvent *e) { - if (!updatesEnabled()) - return; //this avoids repaint from native events checkCurrentRenderingMode(); m_currentRenderer->repaintCurrentFrame(this, e->rect()); } @@ -172,14 +153,13 @@ namespace Phonon } } else if (!isEmbedded()) { m_currentRenderer = m_node->switchRendering(m_currentRenderer); - setAttribute(Qt::WA_PaintOnScreen, false); + setAttribute(Qt::WA_PaintOnScreen, true); } } VideoWidget *m_node; AbstractVideoRenderer *m_currentRenderer; QVariant m_restoreScreenSaverActive; - QBasicTimer m_flickerFreeTimer; }; VideoWidget::VideoWidget(QWidget *parent) @@ -223,9 +203,6 @@ namespace Phonon if (toNative && m_noNativeRendererSupported) return current; //no switch here - if (!mediaObject()) - return current; - //firt we delete the renderer //initialization of the widgets for(int i = 0; i < FILTER_COUNT; ++i) { @@ -284,7 +261,6 @@ namespace Phonon { m_aspectRatio = aspectRatio; updateVideoSize(); - m_widget->update(); } Phonon::VideoWidget::ScaleMode VideoWidget::scaleMode() const @@ -303,7 +279,6 @@ namespace Phonon { m_scaleMode = scaleMode; updateVideoSize(); - m_widget->update(); } void VideoWidget::setBrightness(qreal b) @@ -357,29 +332,14 @@ namespace Phonon int index = graphIndex * 2 + type; if (m_renderers[index] == 0 && autoCreate) { AbstractVideoRenderer *renderer = 0; - if (type == Native) { -#ifndef Q_OS_WINCE - renderer = new VideoRendererEVR(m_widget); - if (renderer->getFilter() == 0) { - delete renderer; - //EVR not present, let's try VMR - renderer = new VideoRendererVMR9(m_widget); - if (renderer->getFilter() == 0) { - //instanciating the renderer might fail - m_noNativeRendererSupported = true; - delete renderer; - renderer = 0; - } - } -#else - renderer = new VideoRendererDefault(m_widget); + if (type == Native) { + renderer = new VideoRendererVMR9(m_widget); if (renderer->getFilter() == 0) { - //instanciating the renderer might fail + //instanciating the renderer might fail with error VFW_E_DDRAW_CAPS_NOT_SUITABLE (0x80040273) m_noNativeRendererSupported = true; delete renderer; renderer = 0; } -#endif } if (renderer == 0) { diff --git a/src/3rdparty/phonon/ds9/volumeeffect.cpp b/src/3rdparty/phonon/ds9/volumeeffect.cpp index a93b074..b9a5fce 100644 --- a/src/3rdparty/phonon/ds9/volumeeffect.cpp +++ b/src/3rdparty/phonon/ds9/volumeeffect.cpp @@ -76,7 +76,7 @@ namespace Phonon class VolumeMemInputPin : public QMemInputPin { public: - VolumeMemInputPin(QBaseFilter *parent, const QVector &mt, QPin *output) : QMemInputPin(parent, mt, true /*transform*/, output) + VolumeMemInputPin(QBaseFilter *parent, const QVector &mt) : QMemInputPin(parent, mt, true /*transform*/) { } @@ -139,7 +139,8 @@ namespace Phonon //then creating the input mt << audioMediaType(); - m_input = new VolumeMemInputPin(this, mt, m_output); + m_input = new VolumeMemInputPin(this, mt); + m_input->addOutput(m_output); //make the connection here } void VolumeEffectFilter::treatOneSamplePerChannel(BYTE **buffer, int sampleSize, int channelCount, int frequency) diff --git a/src/3rdparty/phonon/ds9/volumeeffect.h b/src/3rdparty/phonon/ds9/volumeeffect.h index d1b0186..39b20d0 100644 --- a/src/3rdparty/phonon/ds9/volumeeffect.h +++ b/src/3rdparty/phonon/ds9/volumeeffect.h @@ -47,7 +47,7 @@ namespace Phonon private: float m_volume; - //paramaters used to fade + //parameters used to fade Phonon::VolumeFaderEffect::FadeCurve m_fadeCurve; bool m_fading; //determines if we should be fading. -- cgit v0.12 From b7add13a0c363c9ca435256d879b398b15cb8dca Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 25 Mar 2010 14:28:49 +1000 Subject: Update Phonon qt7 backend to 4.4.0. --- src/3rdparty/phonon/qt7/audionode.h | 2 +- src/3rdparty/phonon/qt7/audionode.mm | 16 +- src/3rdparty/phonon/qt7/backendinfo.mm | 1 - src/3rdparty/phonon/qt7/mediaobject.h | 40 +--- src/3rdparty/phonon/qt7/mediaobject.mm | 286 +++++++----------------- src/3rdparty/phonon/qt7/quicktimemetadata.h | 8 +- src/3rdparty/phonon/qt7/quicktimemetadata.mm | 41 ++-- src/3rdparty/phonon/qt7/quicktimevideoplayer.h | 28 +-- src/3rdparty/phonon/qt7/quicktimevideoplayer.mm | 265 +++------------------- src/3rdparty/phonon/qt7/videoframe.mm | 24 +- 10 files changed, 137 insertions(+), 574 deletions(-) diff --git a/src/3rdparty/phonon/qt7/audionode.h b/src/3rdparty/phonon/qt7/audionode.h index 2498e49..dfec817f 100644 --- a/src/3rdparty/phonon/qt7/audionode.h +++ b/src/3rdparty/phonon/qt7/audionode.h @@ -72,7 +72,7 @@ namespace QT7 AudioUnit m_audioUnit; // Only the following methods needs to - // be overidden by only_one-audio-unit nodes: + // be overridden by only_one-audio-unit nodes: virtual ComponentDescription getAudioNodeDescription() const; virtual void initializeAudioUnit(); diff --git a/src/3rdparty/phonon/qt7/audionode.mm b/src/3rdparty/phonon/qt7/audionode.mm index 961230c..cb9e82f 100644 --- a/src/3rdparty/phonon/qt7/audionode.mm +++ b/src/3rdparty/phonon/qt7/audionode.mm @@ -68,15 +68,13 @@ void AudioNode::createAndConnectAUNodes() << QString(!FindNextComponent(0, &description) ? "ERROR: COMPONENT NOT FOUND!" : "OK!")) OSStatus err = noErr; - - // The proper function to call here is AUGraphAddNode() but the type has - // changed between 10.5 and 10.6. it's still OK to call this function, but - // if we want to use the proper thing we need to move over to - // AudioComponentDescription everywhere, which is very similar to the - // ComponentDescription, but a different size. however, - // AudioComponentDescription only exists on 10.6+. More fun than we need to - // deal with at the moment, so we'll take the "deprecated" warning instead. - err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) + err = AUGraphAddNode(m_audioGraph->audioGraphRef(), &description, &m_auNode); + else +#endif + err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode); + BACKEND_ASSERT2(err != kAUGraphErr_OutputNodeErr, "A MediaObject can only be connected to one audio output device.", FATAL_ERROR) BACKEND_ASSERT2(err == noErr, "Could not create new AUNode.", FATAL_ERROR) } diff --git a/src/3rdparty/phonon/qt7/backendinfo.mm b/src/3rdparty/phonon/qt7/backendinfo.mm index 0d51db0..e173f05 100644 --- a/src/3rdparty/phonon/qt7/backendinfo.mm +++ b/src/3rdparty/phonon/qt7/backendinfo.mm @@ -22,7 +22,6 @@ #include #include -#include #import #ifdef QUICKTIME_C_API_AVAILABLE diff --git a/src/3rdparty/phonon/qt7/mediaobject.h b/src/3rdparty/phonon/qt7/mediaobject.h index c93eddc..27949ec 100644 --- a/src/3rdparty/phonon/qt7/mediaobject.h +++ b/src/3rdparty/phonon/qt7/mediaobject.h @@ -25,10 +25,6 @@ #include "medianode.h" -#if QT_ALLOW_QUICKTIME - #include -#endif - QT_BEGIN_NAMESPACE namespace Phonon @@ -42,10 +38,7 @@ namespace QT7 class MediaObjectAudioNode; class MediaObject : public MediaNode, - public Phonon::MediaObjectInterface -#ifndef QT_NO_PHONON_MEDIACONTROLLER - , public Phonon::AddonInterface -#endif + public Phonon::MediaObjectInterface, public Phonon::AddonInterface { Q_OBJECT Q_INTERFACES(Phonon::MediaObjectInterface Phonon::AddonInterface) @@ -99,10 +92,6 @@ namespace QT7 int videoOutputCount(); -#if QT_ALLOW_QUICKTIME - void displayLinkEvent(); -#endif - signals: void stateChanged(Phonon::State,Phonon::State); void tick(qint64); @@ -116,16 +105,6 @@ namespace QT7 void metaDataChanged(QMultiMap); void currentSourceChanged(const MediaSource &newSource); - // Add-on interface: - void availableSubtitlesChanged(); - void availableAudioChannelsChanged(); - void titleChanged(int); - void availableTitlesChanged(int); - void chapterChanged(int); - void availableChaptersChanged(int); - void angleChanged(int); - void availableAnglesChanged(int); - protected: void mediaNodeEvent(const MediaNodeEvent *event); bool event(QEvent *event); @@ -139,14 +118,7 @@ namespace QT7 QuickTimeVideoPlayer *m_nextVideoPlayer; QuickTimeAudioPlayer *m_nextAudioPlayer; MediaObjectAudioNode *m_mediaObjectAudioNode; - -#if QT_ALLOW_QUICKTIME - CVDisplayLinkRef m_displayLink; - QMutex m_displayLinkMutex; - bool m_pendingDisplayLinkEvent; - void startDisplayLink(); - void stopDisplayLink(); -#endif + QuickTimeMetaData *m_metaData; qint32 m_tickInterval; qint32 m_transitionTime; @@ -155,14 +127,12 @@ namespace QT7 float m_percentageLoaded; int m_tickTimer; - int m_videoTimer; - int m_audioTimer; + int m_bufferTimer; int m_rapidTimer; bool m_waitNextSwap; int m_swapTimeLeft; QTime m_swapTime; - bool m_autoplayTitles; void synchAudioVideo(); void updateCurrentTime(); @@ -171,7 +141,8 @@ namespace QT7 void pause_internal(); void play_internal(); void setupAudioSystem(); - void restartAudioVideoTimers(); + void updateTimer(int &timer, int interval); + void bufferAudioVideo(); void updateRapidly(); void updateCrossFade(); void updateAudioBuffers(); @@ -183,7 +154,6 @@ namespace QT7 void inspectVideoGraphRecursive(MediaNode *node, int &effectCount, int &outputCount); void inspectGraph(); bool isCrossFading(); - void setCurrentTrack(int track); QString m_errorString; Phonon::ErrorType m_errorType; diff --git a/src/3rdparty/phonon/qt7/mediaobject.mm b/src/3rdparty/phonon/qt7/mediaobject.mm index 677640c..f8d635a 100644 --- a/src/3rdparty/phonon/qt7/mediaobject.mm +++ b/src/3rdparty/phonon/qt7/mediaobject.mm @@ -46,6 +46,7 @@ MediaObject::MediaObject(QObject *parent) : MediaNode(AudioSource | VideoSource, m_mediaObjectAudioNode = new MediaObjectAudioNode(m_audioPlayer, m_nextAudioPlayer); setAudioNode(m_mediaObjectAudioNode); + m_metaData = new QuickTimeMetaData(); m_audioGraph = new AudioGraph(this); m_tickInterval = 0; @@ -54,7 +55,6 @@ MediaObject::MediaObject(QObject *parent) : MediaNode(AudioSource | VideoSource, m_transitionTime = 0; m_percentageLoaded = 0; m_waitNextSwap = false; - m_autoplayTitles = true; m_audioEffectCount = 0; m_audioOutputCount = 0; m_videoEffectCount = 0; @@ -63,28 +63,20 @@ MediaObject::MediaObject(QObject *parent) : MediaNode(AudioSource | VideoSource, m_errorType = Phonon::NoError; m_tickTimer = 0; - m_videoTimer = 0; - m_audioTimer = 0; + m_bufferTimer = 0; m_rapidTimer = 0; -#if QT_ALLOW_QUICKTIME - m_displayLink = 0; - m_pendingDisplayLinkEvent = false; -#endif - checkForError(); } MediaObject::~MediaObject() -{ - // m_mediaObjectAudioNode is owned by super class. -#if QT_ALLOW_QUICKTIME - stopDisplayLink(); -#endif +{ + // m_mediaObjectAudioNode is owned by super class. m_audioPlayer->unsetVideoPlayer(); m_nextAudioPlayer->unsetVideoPlayer(); delete m_videoPlayer; delete m_nextVideoPlayer; + delete m_metaData; checkForError(); } @@ -222,28 +214,28 @@ void MediaObject::setSource(const MediaSource &source) IMPLEMENTED; PhononAutoReleasePool pool; setState(Phonon::LoadingState); - + // Save current state for event/signal handling below: bool prevHasVideo = m_videoPlayer->hasVideo(); qint64 prevTotalTime = totalTime(); - int prevTrackCount = m_videoPlayer->trackCount(); m_waitNextSwap = false; - + // Cancel cross-fade if any: m_nextVideoPlayer->pause(); m_nextAudioPlayer->pause(); m_mediaObjectAudioNode->cancelCrossFade(); - + // Set new source: m_audioPlayer->unsetVideoPlayer(); m_videoPlayer->setMediaSource(source); m_audioPlayer->setVideoPlayer(m_videoPlayer); + m_metaData->setVideo(m_videoPlayer); - m_audioGraph->updateStreamSpecifications(); + m_audioGraph->updateStreamSpecifications(); m_nextAudioPlayer->unsetVideoPlayer(); - m_nextVideoPlayer->unsetCurrentMediaSource(); + m_nextVideoPlayer->unsetVideo(); m_currentTime = 0; - + // Emit/notify information about the new source: QRect videoRect = m_videoPlayer->videoRect(); MediaNodeEvent e1(MediaNodeEvent::VideoFrameSizeChanged, &videoRect); @@ -254,14 +246,12 @@ void MediaObject::setSource(const MediaSource &source) updateVideo(emptyFrame); emit currentSourceChanged(source); - emit metaDataChanged(m_videoPlayer->metaData()); + emit metaDataChanged(m_metaData->metaData()); if (prevHasVideo != m_videoPlayer->hasVideo()) - emit hasVideoChanged(m_videoPlayer->hasVideo()); + emit hasVideoChanged(m_videoPlayer->hasVideo()); if (prevTotalTime != totalTime()) - emit totalTimeChanged(totalTime()); - if (prevTrackCount != m_videoPlayer->trackCount()) - emit availableTitlesChanged(m_videoPlayer->trackCount()); + emit totalTimeChanged(totalTime()); if (checkForError()) return; if (!m_videoPlayer->isDrmAuthorized()) @@ -297,30 +287,28 @@ void MediaObject::swapCurrentWithNext(qint32 transitionTime) // Save current state for event/signal handling below: bool prevHasVideo = m_videoPlayer->hasVideo(); qint64 prevTotalTime = totalTime(); - int prevTrackCount = m_videoPlayer->trackCount(); qSwap(m_audioPlayer, m_nextAudioPlayer); qSwap(m_videoPlayer, m_nextVideoPlayer); m_mediaObjectAudioNode->startCrossFade(transitionTime); m_audioGraph->updateStreamSpecifications(); + m_metaData->setVideo(m_videoPlayer); m_waitNextSwap = false; m_currentTime = 0; - + // Emit/notify information about the new source: QRect videoRect = m_videoPlayer->videoRect(); MediaNodeEvent e1(MediaNodeEvent::VideoFrameSizeChanged, &videoRect); notify(&e1); emit currentSourceChanged(m_videoPlayer->mediaSource()); - emit metaDataChanged(m_videoPlayer->metaData()); + emit metaDataChanged(m_metaData->metaData()); if (prevHasVideo != m_videoPlayer->hasVideo()) - emit hasVideoChanged(m_videoPlayer->hasVideo()); + emit hasVideoChanged(m_videoPlayer->hasVideo()); if (prevTotalTime != totalTime()) emit totalTimeChanged(totalTime()); - if (prevTrackCount != m_videoPlayer->trackCount()) - emit availableTitlesChanged(m_videoPlayer->trackCount()); if (checkForError()) return; if (!m_videoPlayer->isDrmAuthorized()) @@ -339,107 +327,28 @@ void MediaObject::swapCurrentWithNext(qint32 transitionTime) } } -#if QT_ALLOW_QUICKTIME -static CVReturn displayLinkCallback(CVDisplayLinkRef /*displayLink*/, - const CVTimeStamp */*inNow*/, - const CVTimeStamp */*inOutputTime*/, - CVOptionFlags /*flagsIn*/, - CVOptionFlags */*flagsOut*/, - void *userData) +void MediaObject::updateTimer(int &timer, int interval) { - MediaObject *mediaObject = static_cast(userData); - mediaObject->displayLinkEvent(); - return kCVReturnSuccess; -} - -void MediaObject::displayLinkEvent() -{ - // This function is called from a - // thread != gui thread. So we post the event. - // But we need to make sure that we don't post faster - // than the event loop can eat: - m_displayLinkMutex.lock(); - bool pending = m_pendingDisplayLinkEvent; - m_pendingDisplayLinkEvent = true; - m_displayLinkMutex.unlock(); - - if (!pending) - qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); -} - -void MediaObject::startDisplayLink() -{ - if (m_displayLink) - return; - OSStatus err = CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink); - if (err != noErr) - goto fail; - err = CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay); - if (err != noErr) - goto fail; - err = CVDisplayLinkSetOutputCallback(m_displayLink, displayLinkCallback, this); - if (err != noErr) - goto fail; - err = CVDisplayLinkStart(m_displayLink); - if (err != noErr) - goto fail; - return; -fail: - stopDisplayLink(); -} - -void MediaObject::stopDisplayLink() -{ - if (!m_displayLink) - return; - CVDisplayLinkStop(m_displayLink); - CFRelease(m_displayLink); - m_displayLink = 0; -} -#endif - -void MediaObject::restartAudioVideoTimers() -{ - if (m_videoTimer) - killTimer(m_videoTimer); - if (m_audioTimer) - killTimer(m_audioTimer); - -#if QT_ALLOW_QUICKTIME - // We prefer to use a display link as timer if available, since - // it is more steady, and results in better and smoother frame drawing: - startDisplayLink(); - if (!m_displayLink){ - float fps = m_videoPlayer->staticFps(); - long videoUpdateFrequency = fps ? long(1000.0f / fps) : 0.001; - m_videoTimer = startTimer(videoUpdateFrequency); - } -#else - float fps = m_videoPlayer->staticFps(); - long videoUpdateFrequency = fps ? long(1000.0f / fps) : 0.001; - m_videoTimer = startTimer(videoUpdateFrequency); -#endif - - long audioUpdateFrequency = m_audioPlayer->regularTaskFrequency(); - m_audioTimer = startTimer(audioUpdateFrequency); - updateVideoFrames(); - updateAudioBuffers(); + if (timer) + killTimer(timer); + timer = 0; + if (interval >= 0) + timer = startTimer(interval); } void MediaObject::play_internal() { // Play main audio/video: m_videoPlayer->play(); - m_audioPlayer->play(); + m_audioPlayer->play(); updateLipSynch(0); // Play old audio/video to finish cross-fade: if (m_nextVideoPlayer->currentTime() > 0){ m_nextVideoPlayer->play(); m_nextAudioPlayer->play(); } - restartAudioVideoTimers(); - if (!m_rapidTimer) - m_rapidTimer = startTimer(100); + bufferAudioVideo(); + updateTimer(m_rapidTimer, 100); } void MediaObject::pause_internal() @@ -449,15 +358,9 @@ void MediaObject::pause_internal() m_nextAudioPlayer->pause(); m_videoPlayer->pause(); m_nextVideoPlayer->pause(); - killTimer(m_rapidTimer); - killTimer(m_videoTimer); - killTimer(m_audioTimer); - m_rapidTimer = 0; - m_videoTimer = 0; - m_audioTimer = 0; -#if QT_ALLOW_QUICKTIME - stopDisplayLink(); -#endif + updateTimer(m_rapidTimer, -1); + updateTimer(m_bufferTimer, -1); + if (m_waitNextSwap) m_swapTimeLeft = m_swapTime.msecsTo(QTime::currentTime()); } @@ -520,7 +423,7 @@ void MediaObject::stop() if (!setState(Phonon::StoppedState)) return; m_waitNextSwap = false; - m_nextVideoPlayer->unsetCurrentMediaSource(); + m_nextVideoPlayer->unsetVideo(); m_nextAudioPlayer->unsetVideoPlayer(); pause_internal(); seek(0); @@ -532,9 +435,9 @@ void MediaObject::seek(qint64 milliseconds) IMPLEMENTED; if (m_state == Phonon::ErrorState) return; - + // Stop cross-fade if any: - m_nextVideoPlayer->unsetCurrentMediaSource(); + m_nextVideoPlayer->unsetVideo(); m_nextAudioPlayer->unsetVideoPlayer(); m_mediaObjectAudioNode->cancelCrossFade(); @@ -664,24 +567,19 @@ void MediaObject::updateCurrentTime() m_currentTime = (m_audioSystem == AS_Graph) ? m_audioPlayer->currentTime() : m_videoPlayer->currentTime(); quint64 total = m_videoPlayer->duration(); - if (m_videoPlayer->currentTrack() < m_videoPlayer->trackCount() - 1){ - // There are still more tracks to play after the current track. - if (m_autoplayTitles) { - if (lastUpdateTime < m_currentTime && m_currentTime == total) - setCurrentTrack(m_videoPlayer->currentTrack() + 1); - } - } else if (m_nextVideoPlayer->state() == QuickTimeVideoPlayer::NoMedia){ - // There is no more sources or tracks to play after the current source. - // Check if it's time to emit aboutToFinish: - quint32 mark = qMax(quint64(0), qMin(total, total + m_transitionTime - 2000)); - if (lastUpdateTime < mark && mark <= m_currentTime) - emit aboutToFinish(); - - // Check if it's time to emit prefinishMarkReached: - mark = qMax(quint64(0), total - m_prefinishMark); - if (lastUpdateTime < mark && mark <= m_currentTime) - emit prefinishMarkReached(total - m_currentTime); + // Check if it's time to emit aboutToFinish: + quint32 mark = qMax(quint64(0), qMin(total, total + m_transitionTime - 2000)); + if (lastUpdateTime < mark && mark <= m_currentTime) + emit aboutToFinish(); + + // Check if it's time to emit prefinishMarkReached: + mark = qMax(quint64(0), total - m_prefinishMark); + if (lastUpdateTime < mark && mark <= m_currentTime) + emit prefinishMarkReached(total - m_currentTime); + if (m_nextVideoPlayer->state() == QuickTimeVideoPlayer::NoMedia){ + // There is no next source in que. + // Check if it's time to emit finished: if (lastUpdateTime < m_currentTime && m_currentTime == total){ emit finished(); m_currentTime = (m_audioSystem == AS_Graph) ? m_audioPlayer->currentTime() : m_videoPlayer->currentTime(); @@ -691,7 +589,7 @@ void MediaObject::updateCurrentTime() } else { // We have a next source. // Check if it's time to swap to next source: - quint32 mark = qMax(quint64(0), total + m_transitionTime); + mark = qMax(quint64(0), total + m_transitionTime); if (m_waitNextSwap && m_state == Phonon::PlayingState && m_transitionTime < m_swapTime.msecsTo(QTime::currentTime())){ swapCurrentWithNext(0); @@ -794,14 +692,14 @@ bool MediaObject::setAudioDeviceOnMovie(int id) void MediaObject::updateCrossFade() { - m_mediaObjectAudioNode->updateCrossFade(m_currentTime); + m_mediaObjectAudioNode->updateCrossFade(m_currentTime); // Clean-up previous movie if done fading: if (m_mediaObjectAudioNode->m_fadeDuration == 0){ if (m_nextVideoPlayer->isPlaying() || m_nextAudioPlayer->isPlaying()){ - m_nextVideoPlayer->unsetCurrentMediaSource(); + m_nextVideoPlayer->unsetVideo(); m_nextAudioPlayer->unsetVideoPlayer(); } - } + } } void MediaObject::updateBufferStatus() @@ -830,7 +728,7 @@ void MediaObject::updateVideoFrames() // Draw next frame if awailable: if (m_videoPlayer->videoFrameChanged()){ updateLipSynch(50); - VideoFrame frame(m_videoPlayer); + VideoFrame frame(m_videoPlayer); if (m_nextVideoPlayer->isPlaying() && m_nextVideoPlayer->hasVideo() && isCrossFading()){ @@ -838,9 +736,9 @@ void MediaObject::updateVideoFrames() frame.setBackgroundFrame(bgFrame); frame.setBaseOpacity(m_mediaObjectAudioNode->m_volume1); } - + // Send the frame through the graph: - updateVideo(frame); + updateVideo(frame); checkForError(); } } @@ -851,7 +749,7 @@ void MediaObject::updateLipSynch(int allowedOffset) return; if (m_videoSinkList.isEmpty() || m_audioSinkList.isEmpty()) return; - + if (m_videoPlayer->hasVideo()){ qint64 diff = m_audioPlayer->currentTime() - m_videoPlayer->currentTime(); if (-allowedOffset > diff || diff > allowedOffset) @@ -865,6 +763,16 @@ void MediaObject::updateLipSynch(int allowedOffset) } } +void MediaObject::bufferAudioVideo() +{ + long nextVideoUpdate = m_videoPlayer->hasVideo() ? 30 : INT_MAX; + long nextAudioUpdate = m_audioPlayer->regularTaskFrequency(); + updateAudioBuffers(); + updateVideoFrames(); + if (m_state == Phonon::PlayingState) + updateTimer(m_bufferTimer, qMin(nextVideoUpdate, nextAudioUpdate)); +} + void MediaObject::updateRapidly() { updateCurrentTime(); @@ -889,8 +797,8 @@ void MediaObject::mediaNodeEvent(const MediaNodeEvent *event) synchAudioVideo(); checkForError(); m_mediaObjectAudioNode->setMute(false); - if (m_state == Phonon::PlayingState) - restartAudioVideoTimers(); + if (m_state == Phonon::PlayingState) + bufferAudioVideo(); break; case MediaNodeEvent::AudioGraphCannotPlay: case MediaNodeEvent::AudioGraphInitialized: @@ -901,7 +809,7 @@ void MediaObject::mediaNodeEvent(const MediaNodeEvent *event) checkForError(); m_mediaObjectAudioNode->setMute(false); } - break; + break; default: break; } @@ -910,67 +818,29 @@ void MediaObject::mediaNodeEvent(const MediaNodeEvent *event) bool MediaObject::event(QEvent *event) { switch (event->type()){ -#if QT_ALLOW_QUICKTIME - case QEvent::User:{ - m_displayLinkMutex.lock(); - m_pendingDisplayLinkEvent = false; - m_displayLinkMutex.unlock(); - updateVideoFrames(); - break; } -#endif - case QEvent::Timer:{ - int timerId = static_cast(event)->timerId(); - if (timerId == m_rapidTimer) + case QEvent::Timer: { + QTimerEvent *timerEvent = static_cast(event); + if (timerEvent->timerId() == m_rapidTimer) updateRapidly(); - else if (timerId == m_tickTimer) + else if (timerEvent->timerId() == m_tickTimer) emit tick(currentTime()); - else if (timerId == m_videoTimer) - updateVideoFrames(); - else if (timerId == m_audioTimer) - updateAudioBuffers(); - break; } + else if (timerEvent->timerId() == m_bufferTimer) + bufferAudioVideo(); + } + break; default: break; } return QObject::event(event); } -void MediaObject::setCurrentTrack(int track) -{ - if (track == m_videoPlayer->currentTrack() || track < 0 || track >= m_videoPlayer->trackCount()) - return; - - m_videoPlayer->setCurrentTrack(track); - emit titleChanged(track); - emit metaDataChanged(m_videoPlayer->metaData()); -} - -bool MediaObject::hasInterface(Interface iface) const +bool MediaObject::hasInterface(Interface /*interface*/) const { - return iface == AddonInterface::TitleInterface; + return false; } -QVariant MediaObject::interfaceCall(Interface iface, int command, const QList ¶ms) +QVariant MediaObject::interfaceCall(Interface /*interface*/, int /*command*/, const QList &/*arguments*/) { - switch (iface) { - case TitleInterface: - switch (command) { - case availableTitles: - return m_videoPlayer->trackCount(); - case title: - return m_videoPlayer->currentTrack(); - case setTitle: - setCurrentTrack(params.first().toInt()); - break; - case autoplayTitles: - return m_autoplayTitles; - case setAutoplayTitles: - m_autoplayTitles = params.first().toBool(); - break; - } - default: - break; - } return QVariant(); } diff --git a/src/3rdparty/phonon/qt7/quicktimemetadata.h b/src/3rdparty/phonon/qt7/quicktimemetadata.h index c589535..d524183 100644 --- a/src/3rdparty/phonon/qt7/quicktimemetadata.h +++ b/src/3rdparty/phonon/qt7/quicktimemetadata.h @@ -38,8 +38,10 @@ namespace QT7 class QuickTimeMetaData { public: - QuickTimeMetaData(QuickTimeVideoPlayer *videoPlayer); - void update(); + QuickTimeMetaData(); + virtual ~QuickTimeMetaData(); + + void setVideo(QuickTimeVideoPlayer *videoPlayer); QMultiMap metaData(); private: @@ -47,8 +49,6 @@ namespace QT7 bool m_movieChanged; QuickTimeVideoPlayer *m_videoPlayer; void readMetaData(); - void guessMetaDataForCD(); - void readMetaDataFromMovie(); #ifdef QUICKTIME_C_API_AVAILABLE QString stripCopyRightSymbol(const QString &key); diff --git a/src/3rdparty/phonon/qt7/quicktimemetadata.mm b/src/3rdparty/phonon/qt7/quicktimemetadata.mm index 2dcc152..851e707 100644 --- a/src/3rdparty/phonon/qt7/quicktimemetadata.mm +++ b/src/3rdparty/phonon/qt7/quicktimemetadata.mm @@ -15,7 +15,6 @@ along with this library. If not, see . */ -#include #include "quicktimemetadata.h" #include "quicktimevideoplayer.h" @@ -26,14 +25,19 @@ namespace Phonon namespace QT7 { -QuickTimeMetaData::QuickTimeMetaData(QuickTimeVideoPlayer *videoPlayer) +QuickTimeMetaData::QuickTimeMetaData() { - m_videoPlayer = videoPlayer; + m_videoPlayer = 0; m_movieChanged = false; } -void QuickTimeMetaData::update() +QuickTimeMetaData::~QuickTimeMetaData() { +} + +void QuickTimeMetaData::setVideo(QuickTimeVideoPlayer *videoPlayer) +{ + m_videoPlayer = videoPlayer; m_movieChanged = true; m_metaData.clear(); } @@ -141,22 +145,14 @@ void QuickTimeMetaData::readFormattedData(QTMetaDataRef metaDataRef, OSType form #endif // QUICKTIME_C_API_AVAILABLE -void QuickTimeMetaData::guessMetaDataForCD() -{ - QString album = QFileInfo(m_videoPlayer->movieCompactDiscPath()).fileName(); - QString title = QFileInfo(m_videoPlayer->currentTrackPath()).fileName(); - title = title.left(title.lastIndexOf('.')); - m_metaData.insert(QLatin1String("ALBUM"), album); - m_metaData.insert(QLatin1String("TITLE"), title); - m_metaData.insert(QLatin1String("TRACKNUMBER"), QString::number(m_videoPlayer->currentTrack())); -} - -void QuickTimeMetaData::readMetaDataFromMovie() +void QuickTimeMetaData::readMetaData() { + if (!m_videoPlayer) + return; QMultiMap metaMap; - + #ifdef QUICKTIME_C_API_AVAILABLE - QTMetaDataRef metaDataRef; + QTMetaDataRef metaDataRef; OSStatus err = QTCopyMovieMetaData([m_videoPlayer->qtMovie() quickTimeMovie], &metaDataRef); BACKEND_ASSERT2(err == noErr, "Could not read QuickTime meta data", NORMAL_ERROR) @@ -177,17 +173,6 @@ void QuickTimeMetaData::readMetaDataFromMovie() m_metaData.insert(QLatin1String("DESCRIPTION"), metaMap.value(QLatin1String("des"))); } -void QuickTimeMetaData::readMetaData() -{ - if (!m_videoPlayer) - return; - - if (m_videoPlayer->mediaSource().type() == Phonon::MediaSource::Disc) - guessMetaDataForCD(); - else - readMetaDataFromMovie(); -} - QMultiMap QuickTimeMetaData::metaData() { if (m_videoPlayer && m_videoPlayer->hasMovie() && m_movieChanged) diff --git a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h index 98eacb5..0b3aec2 100644 --- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h +++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h @@ -20,7 +20,6 @@ #include "backendheader.h" -#include #import #import @@ -39,7 +38,6 @@ namespace Phonon namespace QT7 { class QuickTimeStreamReader; - class QuickTimeMetaData; class VideoRenderWidgetQTMovieView; class QuickTimeVideoPlayer : QObject @@ -57,7 +55,7 @@ namespace QT7 void setMediaSource(const MediaSource &source); MediaSource mediaSource() const; - void unsetCurrentMediaSource(); + void unsetVideo(); void play(); void pause(); @@ -68,13 +66,11 @@ namespace QT7 GLuint currentFrameAsGLTexture(); void *currentFrameAsCIImage(); QImage currentFrameAsQImage(); - void releaseImageCache(); QRect videoRect() const; quint64 duration() const; quint64 currentTime() const; long timeScale() const; - float staticFps(); QString currentTimeString(); void setColors(qreal brightness = 0, qreal contrast = 1, qreal hue = 0, qreal saturation = 1); @@ -87,7 +83,6 @@ namespace QT7 bool setAudioDevice(int id); void setPlaybackRate(float rate); QTMovie *qtMovie() const; - QMultiMap metaData(); float playbackRate() const; float prefferedPlaybackRate() const; @@ -107,12 +102,6 @@ namespace QT7 float percentageLoaded(); quint64 timeLoaded(); - int trackCount() const; - int currentTrack() const; - void setCurrentTrack(int track); - QString movieCompactDiscPath() const; - QString currentTrackPath() const; - static QString timeToString(quint64 ms); // Help functions when drawing to more that one widget in cocoa 64: @@ -126,10 +115,6 @@ namespace QT7 QTMovie *m_QTMovie; State m_state; QGLPixelBuffer *m_QImagePixelBuffer; - QuickTimeMetaData *m_metaData; - - CVOpenGLTextureRef m_cachedCVTextureRef; - QImage m_cachedQImage; bool m_playbackRateSat; bool m_isDrmProtected; @@ -140,18 +125,13 @@ namespace QT7 float m_masterVolume; float m_relativeVolume; float m_playbackRate; - float m_staticFps; quint64 m_currentTime; MediaSource m_mediaSource; - void *m_primaryRenderingCIImage; qreal m_brightness; qreal m_contrast; qreal m_hue; qreal m_saturation; - NSArray *m_folderTracks; - int m_currentTrack; - QString m_movieCompactDiscPath; #ifdef QUICKTIME_C_API_AVAILABLE QTVisualContextRef m_visualContext; @@ -159,26 +139,20 @@ namespace QT7 VideoFrame m_currentFrame; QuickTimeStreamReader *m_streamReader; - void prepareCurrentMovieForPlayback(); void createVisualContext(); void openMovieFromCurrentMediaSource(); void openMovieFromDataRef(QTDataReference *dataRef); void openMovieFromFile(); void openMovieFromUrl(); void openMovieFromStream(); - void openMovieFromCompactDisc(); void openMovieFromData(QByteArray *data, char *fileType); void openMovieFromDataGuessType(QByteArray *data); QString mediaSourcePath(); bool codecExistsAccordingToSuffix(const QString &fileName); - NSString* pathToCompactDisc(); - bool isCompactDisc(NSString *path); - NSArray* scanFolder(NSString *path); void setError(NSError *error); bool errorOccured(); void readProtection(); - void calculateStaticFps(); void checkIfVideoAwailable(); bool movieNotLoaded(); void waitStatePlayable(); diff --git a/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm b/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm index 23c76e3..3f76132 100644 --- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm +++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.mm @@ -20,7 +20,6 @@ #include "videowidget.h" #include "audiodevice.h" #include "quicktimestreamreader.h" -#include "quicktimemetadata.h" #include #include @@ -53,7 +52,6 @@ QuickTimeVideoPlayer::QuickTimeVideoPlayer() : QObject(0) { m_state = NoMedia; m_mediaSource = MediaSource(); - m_metaData = new QuickTimeMetaData(this); m_QTMovie = 0; m_streamReader = 0; m_playbackRate = 1.0f; @@ -63,16 +61,12 @@ QuickTimeVideoPlayer::QuickTimeVideoPlayer() : QObject(0) m_mute = false; m_audioEnabled = false; m_hasVideo = false; - m_staticFps = 0; m_playbackRateSat = false; m_isDrmProtected = false; m_isDrmAuthorized = true; m_primaryRenderingTarget = 0; m_primaryRenderingCIImage = 0; m_QImagePixelBuffer = 0; - m_cachedCVTextureRef = 0; - m_folderTracks = 0; - m_currentTrack = 0; #ifdef QUICKTIME_C_API_AVAILABLE OSStatus err = EnterMovies(); @@ -83,9 +77,7 @@ QuickTimeVideoPlayer::QuickTimeVideoPlayer() : QObject(0) QuickTimeVideoPlayer::~QuickTimeVideoPlayer() { - PhononAutoReleasePool pool; - unsetCurrentMediaSource(); - delete m_metaData; + unsetVideo(); [(NSObject*)m_primaryRenderingTarget release]; m_primaryRenderingTarget = 0; #ifdef QUICKTIME_C_API_AVAILABLE @@ -94,15 +86,6 @@ QuickTimeVideoPlayer::~QuickTimeVideoPlayer() #endif } -void QuickTimeVideoPlayer::releaseImageCache() -{ - if (m_cachedCVTextureRef){ - CVOpenGLTextureRelease(m_cachedCVTextureRef); - m_cachedCVTextureRef = 0; - } - m_cachedQImage = QImage(); -} - void QuickTimeVideoPlayer::createVisualContext() { #ifdef QUICKTIME_C_API_AVAILABLE @@ -142,10 +125,7 @@ bool QuickTimeVideoPlayer::videoFrameChanged() return false; QTVisualContextTask(m_visualContext); - bool changed = QTVisualContextIsNewImageAvailable(m_visualContext, 0); - if (changed) - releaseImageCache(); - return changed; + return QTVisualContextIsNewImageAvailable(m_visualContext, 0); #elif defined(QT_MAC_USE_COCOA) return true; @@ -160,11 +140,10 @@ CVOpenGLTextureRef QuickTimeVideoPlayer::currentFrameAsCVTexture() #ifdef QUICKTIME_C_API_AVAILABLE if (!m_visualContext) return 0; - if (!m_cachedCVTextureRef){ - OSStatus err = QTVisualContextCopyImageForTime(m_visualContext, 0, 0, &m_cachedCVTextureRef); - BACKEND_ASSERT3(err == noErr, "Could not copy image for time in QuickTime player", FATAL_ERROR, 0) - } - return m_cachedCVTextureRef; + CVOpenGLTextureRef texture = 0; + OSStatus err = QTVisualContextCopyImageForTime(m_visualContext, 0, 0, &texture); + BACKEND_ASSERT3(err == noErr, "Could not copy image for time in QuickTime player", FATAL_ERROR, 0) + return texture; #else return 0; @@ -173,9 +152,6 @@ CVOpenGLTextureRef QuickTimeVideoPlayer::currentFrameAsCVTexture() QImage QuickTimeVideoPlayer::currentFrameAsQImage() { - if (!m_cachedQImage.isNull()) - return m_cachedQImage; - #ifdef QUICKTIME_C_API_AVAILABLE QGLContext *prevContext = const_cast(QGLContext::currentContext()); CVOpenGLTextureRef texture = currentFrameAsCVTexture(); @@ -205,11 +181,12 @@ QImage QuickTimeVideoPlayer::currentFrameAsQImage() glVertex2i(-1, -1); glEnd(); - m_cachedQImage = m_QImagePixelBuffer->toImage(); + QImage image = m_QImagePixelBuffer->toImage(); + CVOpenGLTextureRelease(texture); // Because of QuickTime, m_QImagePixelBuffer->doneCurrent() will fail. // So we store, and restore, the context our selves: prevContext->makeCurrent(); - return m_cachedQImage; + return image; #else CIImage *img = (CIImage *)currentFrameAsCIImage(); if (!img) @@ -218,10 +195,10 @@ QImage QuickTimeVideoPlayer::currentFrameAsQImage() NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img]; CGRect bounds = [img extent]; QImage qImg([bitmap bitmapData], bounds.size.width, bounds.size.height, QImage::Format_ARGB32); - m_cachedQImage = qImg.rgbSwapped(); + QImage swapped = qImg.rgbSwapped(); [bitmap release]; [img release]; - return m_cachedQImage; + return swapped; #endif } @@ -273,7 +250,8 @@ void *QuickTimeVideoPlayer::currentFrameAsCIImage() #ifdef QUICKTIME_C_API_AVAILABLE CVOpenGLTextureRef cvImg = currentFrameAsCVTexture(); CIImage *img = [[CIImage alloc] initWithCVImageBuffer:cvImg]; - return img; + CVOpenGLTextureRelease(cvImg); + return img; #else return 0; #endif @@ -295,7 +273,7 @@ GLuint QuickTimeVideoPlayer::currentFrameAsGLTexture() int samplesPerPixel = [bitmap samplesPerPixel]; if (![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4)){ - glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, + glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8, [bitmap pixelsWide], [bitmap pixelsHigh], 0, samplesPerPixel == 4 ? GL_RGBA : GL_RGB, @@ -324,7 +302,7 @@ void QuickTimeVideoPlayer::setVolume(float masterVolume, float relativeVolume) m_masterVolume = masterVolume; m_relativeVolume = relativeVolume; if (!m_QTMovie || !m_audioEnabled || m_mute) - return; + return; [m_QTMovie setVolume:(m_masterVolume * m_relativeVolume)]; } @@ -335,7 +313,7 @@ void QuickTimeVideoPlayer::setMute(bool mute) return; // Work-around bug that happends if you set/unset mute - // before movie is playing, and audio is not played + // before movie is playing, and audio is not played // through graph. Then audio is delayed. [m_QTMovie setMuted:mute]; [m_QTMovie setVolume:(mute ? 0 : m_masterVolume * m_relativeVolume)]; @@ -348,7 +326,7 @@ void QuickTimeVideoPlayer::enableAudio(bool enable) return; // Work-around bug that happends if you set/unset mute - // before movie is playing, and audio is not played + // before movie is playing, and audio is not played // through graph. Then audio is delayed. [m_QTMovie setMuted:(!enable || m_mute)]; [m_QTMovie setVolume:((!enable || m_mute) ? 0 : m_masterVolume * m_relativeVolume)]; @@ -367,7 +345,7 @@ bool QuickTimeVideoPlayer::setAudioDevice(int id) #ifdef QUICKTIME_C_API_AVAILABLE // The following code will not work for some media codecs that // typically mingle audio/video frames (e.g mpeg). - CFStringRef idString = PhononCFString::toCFStringRef(AudioDevice::deviceUID(id)); + CFStringRef idString = PhononCFString::toCFStringRef(AudioDevice::deviceUID(id)); QTAudioContextRef context; QTAudioContextCreateForAudioDevice(kCFAllocatorDefault, idString, 0, &context); OSStatus err = SetMovieAudioContext([m_QTMovie quickTimeMovie], context); @@ -391,16 +369,11 @@ void QuickTimeVideoPlayer::setColors(qreal brightness, qreal contrast, qreal hue contrast += 1; saturation += 1; - if (m_brightness == brightness - && m_contrast == contrast - && m_hue == hue - && m_saturation == saturation) - return; - m_brightness = brightness; m_contrast = contrast; m_hue = hue; m_saturation = saturation; + #ifdef QUICKTIME_C_API_AVAILABLE Float32 value; value = brightness; @@ -412,7 +385,6 @@ void QuickTimeVideoPlayer::setColors(qreal brightness, qreal contrast, qreal hue value = saturation; SetMovieVisualSaturation([m_QTMovie quickTimeMovie], value, 0); #endif - releaseImageCache(); } QRect QuickTimeVideoPlayer::videoRect() const @@ -425,7 +397,7 @@ QRect QuickTimeVideoPlayer::videoRect() const return QRect(0, 0, size.width, size.height); } -void QuickTimeVideoPlayer::unsetCurrentMediaSource() +void QuickTimeVideoPlayer::unsetVideo() { if (!m_QTMovie) return; @@ -438,17 +410,11 @@ void QuickTimeVideoPlayer::unsetCurrentMediaSource() m_state = NoMedia; m_isDrmProtected = false; m_isDrmAuthorized = true; - m_hasVideo = false; - m_staticFps = 0; m_mediaSource = MediaSource(); - m_movieCompactDiscPath.clear(); [(CIImage *)m_primaryRenderingCIImage release]; m_primaryRenderingCIImage = 0; delete m_QImagePixelBuffer; m_QImagePixelBuffer = 0; - releaseImageCache(); - [m_folderTracks release]; - m_folderTracks = 0; } QuickTimeVideoPlayer::State QuickTimeVideoPlayer::state() const @@ -558,25 +524,18 @@ bool QuickTimeVideoPlayer::codecExistsAccordingToSuffix(const QString &fileName) void QuickTimeVideoPlayer::setMediaSource(const MediaSource &mediaSource) { PhononAutoReleasePool pool; - unsetCurrentMediaSource(); - + unsetVideo(); m_mediaSource = mediaSource; if (mediaSource.type() == MediaSource::Empty || mediaSource.type() == MediaSource::Invalid){ m_state = NoMedia; return; } - openMovieFromCurrentMediaSource(); if (errorOccured()){ - unsetCurrentMediaSource(); + unsetVideo(); return; } - prepareCurrentMovieForPlayback(); -} - -void QuickTimeVideoPlayer::prepareCurrentMovieForPlayback() -{ #ifdef QUICKTIME_C_API_AVAILABLE if (m_visualContext) SetMovieVisualContext([m_QTMovie quickTimeMovie], m_visualContext); @@ -584,25 +543,23 @@ void QuickTimeVideoPlayer::prepareCurrentMovieForPlayback() waitStatePlayable(); if (errorOccured()){ - unsetCurrentMediaSource(); + unsetVideo(); return; } readProtection(); preRollMovie(); if (errorOccured()){ - unsetCurrentMediaSource(); + unsetVideo(); return; } if (!m_playbackRateSat) m_playbackRate = prefferedPlaybackRate(); checkIfVideoAwailable(); - calculateStaticFps(); enableAudio(m_audioEnabled); setMute(m_mute); setVolume(m_masterVolume, m_relativeVolume); - m_metaData->update(); pause(); } @@ -616,7 +573,7 @@ void QuickTimeVideoPlayer::openMovieFromCurrentMediaSource() openMovieFromUrl(); break; case MediaSource::Disc: - openMovieFromCompactDisc(); + CASE_UNSUPPORTED("Could not open media source.", FATAL_ERROR) break; case MediaSource::Stream: openMovieFromStream(); @@ -678,7 +635,7 @@ void QuickTimeVideoPlayer::openMovieFromDataGuessType(QByteArray *data) // than using e.g [QTMovie movieFileTypes:QTIncludeCommonTypes]. Some // codecs *think* they can decode the stream, and crash... #define TryOpenMovieWithCodec(type) gClearError(); \ - openMovieFromData(data, (char *)"."type); \ + openMovieFromData(data, "."type); \ if (m_QTMovie) return; TryOpenMovieWithCodec("avi"); @@ -718,50 +675,6 @@ void QuickTimeVideoPlayer::openMovieFromStream() openMovieFromDataGuessType(m_streamReader->pointerToData()); } -typedef void (*qt_sighandler_t)(int); -static void sigtest(int) { - qApp->exit(0); -} - -void QuickTimeVideoPlayer::openMovieFromCompactDisc() -{ - // Interrupting the application while the device is open - // causes the application to hang. So we need to handle - // this in a more graceful way: - qt_sighandler_t hndl = signal(SIGINT, sigtest); - if (hndl) - signal(SIGINT, hndl); - - PhononAutoReleasePool pool; - NSString *cd = 0; - QString devName = m_mediaSource.deviceName(); - if (devName.isEmpty()) { - cd = pathToCompactDisc(); - if (!cd) { - SET_ERROR("Could not open media source.", NORMAL_ERROR) - return; - } - m_movieCompactDiscPath = PhononCFString::toQString(reinterpret_cast(cd)); - } else { - if (!QFileInfo(devName).isAbsolute()) - devName = QLatin1String("/Volumes/") + devName; - cd = [reinterpret_cast(PhononCFString::toCFStringRef(devName)) autorelease]; - if (!isCompactDisc(cd)) { - SET_ERROR("Could not open media source.", NORMAL_ERROR) - return; - } - m_movieCompactDiscPath = devName; - } - - m_folderTracks = [scanFolder(cd) retain]; - setCurrentTrack(0); -} - -QString QuickTimeVideoPlayer::movieCompactDiscPath() const -{ - return m_movieCompactDiscPath; -} - MediaSource QuickTimeVideoPlayer::mediaSource() const { return m_mediaSource; @@ -807,44 +720,6 @@ long QuickTimeVideoPlayer::timeScale() const return [[m_QTMovie attributeForKey:@"QTMovieTimeScaleAttribute"] longValue]; } -float QuickTimeVideoPlayer::staticFps() -{ - return m_staticFps; -} - -void QuickTimeVideoPlayer::calculateStaticFps() -{ - if (!m_hasVideo){ - m_staticFps = 0; - return; - } - -#ifdef QT_ALLOW_QUICKTIME - Boolean isMpeg = false; - Track videoTrack = GetMovieIndTrackType([m_QTMovie quickTimeMovie], 1, - FOUR_CHAR_CODE('vfrr'), // 'vfrr' means: has frame rate - movieTrackCharacteristic | movieTrackEnabledOnly); - Media media = GetTrackMedia(videoTrack); - MediaHandler mediaH = GetMediaHandler(media); - MediaHasCharacteristic(mediaH, FOUR_CHAR_CODE('mpeg'), &isMpeg); - - if (isMpeg){ - MHInfoEncodedFrameRateRecord frameRate; - Size frameRateSize = sizeof(frameRate); - MediaGetPublicInfo(mediaH, kMHInfoEncodedFrameRate, &frameRate, &frameRateSize); - m_staticFps = float(Fix2X(frameRate.encodedFrameRate)); - } else { - Media media = GetTrackMedia(videoTrack); - long sampleCount = GetMediaSampleCount(media); - TimeValue64 duration = GetMediaDisplayDuration(media); - TimeValue64 timeScale = GetMediaTimeScale(media); - m_staticFps = float((double)sampleCount * (double)timeScale / (double)duration); - } -#else - m_staticFps = 30.0f; -#endif -} - QString QuickTimeVideoPlayer::timeToString(quint64 ms) { int sec = ms/1000; @@ -1075,94 +950,6 @@ void QuickTimeVideoPlayer::readProtection() } } -QMultiMap QuickTimeVideoPlayer::metaData() -{ - return m_metaData->metaData(); -} - -int QuickTimeVideoPlayer::trackCount() const -{ - if (!m_folderTracks) - return 0; - return [m_folderTracks count]; -} - -int QuickTimeVideoPlayer::currentTrack() const -{ - return m_currentTrack; -} - -QString QuickTimeVideoPlayer::currentTrackPath() const -{ - if (!m_folderTracks) - return QString(); - - PhononAutoReleasePool pool; - NSString *trackPath = [m_folderTracks objectAtIndex:m_currentTrack]; - return PhononCFString::toQString(reinterpret_cast(trackPath)); -} - -NSString* QuickTimeVideoPlayer::pathToCompactDisc() -{ - PhononAutoReleasePool pool; - NSArray *devices = [[NSWorkspace sharedWorkspace] mountedRemovableMedia]; - for (unsigned int i=0; i<[devices count]; ++i) { - NSString *dev = [devices objectAtIndex:i]; - if (isCompactDisc(dev)) - return [dev retain]; - } - return 0; -} - -bool QuickTimeVideoPlayer::isCompactDisc(NSString *path) -{ - PhononAutoReleasePool pool; - NSString *type = [NSString string]; - [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:path - isRemovable:0 - isWritable:0 - isUnmountable:0 - description:0 - type:&type]; - return [type hasPrefix:@"cdd"]; -} - -NSArray* QuickTimeVideoPlayer::scanFolder(NSString *path) -{ - NSMutableArray *tracks = [NSMutableArray arrayWithCapacity:20]; - if (!path) - return tracks; - - NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:path]; - while (NSString *track = [enumerator nextObject]) { - if (![track hasPrefix:@"."]) - [tracks addObject:[path stringByAppendingPathComponent:track]]; - } - return tracks; -} - -void QuickTimeVideoPlayer::setCurrentTrack(int track) -{ - PhononAutoReleasePool pool; - [m_QTMovie release]; - m_QTMovie = 0; - m_currentTime = 0; - m_currentTrack = track; - - if (!m_folderTracks) - return; - if (track < 0 || track >= (int)[m_folderTracks count]) - return; - - NSString *trackPath = [m_folderTracks objectAtIndex:track]; - QTDataReference *dataRef = [QTDataReference dataReferenceWithReferenceToFile:trackPath]; - State currentState = m_state; - openMovieFromDataRef(dataRef); - prepareCurrentMovieForPlayback(); - if (currentState == Playing) - play(); -} - }} QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/qt7/videoframe.mm b/src/3rdparty/phonon/qt7/videoframe.mm index 7b67b5e..92a3cd5 100644 --- a/src/3rdparty/phonon/qt7/videoframe.mm +++ b/src/3rdparty/phonon/qt7/videoframe.mm @@ -20,8 +20,6 @@ #import #import -//#define CACHE_CV_TEXTURE - QT_BEGIN_NAMESPACE namespace Phonon @@ -72,9 +70,7 @@ namespace QT7 void VideoFrame::copyMembers(const VideoFrame& frame) { -#ifdef CACHE_CV_TEXTURE m_cachedCVTextureRef = frame.m_cachedCVTextureRef; -#endif m_cachedCIImage = frame.m_cachedCIImage; m_cachedQImage = frame.m_cachedQImage; m_cachedNSBitmap = frame.m_cachedNSBitmap; @@ -109,20 +105,11 @@ namespace QT7 CVOpenGLTextureRef VideoFrame::cachedCVTexture() const { -#ifdef CACHE_CV_TEXTURE if (!m_cachedCVTextureRef && m_videoPlayer){ m_videoPlayer->setColors(m_brightness, m_contrast, m_hue, m_saturation); (const_cast(this))->m_cachedCVTextureRef = m_videoPlayer->currentFrameAsCVTexture(); - CVOpenGLTextureRetain((const_cast(this))->m_cachedCVTextureRef); } return m_cachedCVTextureRef; -#else - if (m_videoPlayer){ - m_videoPlayer->setColors(m_brightness, m_contrast, m_hue, m_saturation); - return m_videoPlayer->currentFrameAsCVTexture(); - } - return 0; -#endif } void *VideoFrame::cachedCIImage() const @@ -342,12 +329,10 @@ namespace QT7 void VideoFrame::invalidateImage() const { -#ifdef CACHE_CV_TEXTURE if (m_cachedCVTextureRef){ CVOpenGLTextureRelease(m_cachedCVTextureRef); (const_cast(this))->m_cachedCVTextureRef = 0; } -#endif if (m_cachedCIImage){ [(CIImage *) m_cachedCIImage release]; (const_cast(this))->m_cachedCIImage = 0; @@ -361,10 +346,8 @@ namespace QT7 void VideoFrame::retain() const { -#ifdef CACHE_CV_TEXTURE if (m_cachedCVTextureRef) CVOpenGLTextureRetain(m_cachedCVTextureRef); -#endif if (m_cachedCIImage) [(CIImage *) m_cachedCIImage retain]; if (m_backgroundFrame) @@ -375,12 +358,8 @@ namespace QT7 void VideoFrame::release() const { -#ifdef CACHE_CV_TEXTURE - if (m_cachedCVTextureRef){ + if (m_cachedCVTextureRef) CVOpenGLTextureRelease(m_cachedCVTextureRef); - (const_cast(this))->m_cachedCVTextureRef = 0; - } -#endif if (m_cachedCIImage) [(CIImage *) m_cachedCIImage release]; if (m_backgroundFrame) @@ -389,6 +368,7 @@ namespace QT7 [m_cachedNSBitmap release]; (const_cast(this))->m_backgroundFrame = 0; + (const_cast(this))->m_cachedCVTextureRef = 0; (const_cast(this))->m_cachedCIImage = 0; (const_cast(this))->m_cachedNSBitmap = 0; } -- cgit v0.12 From 4931e0657af3f22478df8cb26faf178a9886e2d2 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 25 Mar 2010 14:30:17 +1000 Subject: Update Phonon CMakeLists.txt. --- src/3rdparty/phonon/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/CMakeLists.txt b/src/3rdparty/phonon/CMakeLists.txt index a25ec5d..ff89edb 100644 --- a/src/3rdparty/phonon/CMakeLists.txt +++ b/src/3rdparty/phonon/CMakeLists.txt @@ -149,7 +149,7 @@ set(CMAKE_COLOR_MAKEFILE ON) set(PHONON_LIB_MAJOR_VERSION "4") set(PHONON_LIB_MINOR_VERSION "3") -set(PHONON_LIB_PATCH_VERSION "50") +set(PHONON_LIB_PATCH_VERSION "80") set(PHONON_LIB_VERSION "${PHONON_LIB_MAJOR_VERSION}.4.0") set(PHONON_LIB_SOVERSION ${PHONON_LIB_MAJOR_VERSION}) -- cgit v0.12 From 9c4bfd1dbdda1a073be12cf6212492abc7e9472b Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 25 Mar 2010 16:36:32 +1000 Subject: Unicode fixes for ODBC SQL Driver. Better unicode handling detection, plus turn off unicode if FreeTDS, plus handling of returning strings under non-unicode scenarios. Task-number: QTBUG-8846 Reviewed-by: Justin McPherson --- src/sql/drivers/odbc/qsql_odbc.cpp | 155 ++++++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 38 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index e75c19d..1506c3c 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -131,11 +131,10 @@ class QODBCDriverPrivate public: enum DefaultCase{Lower, Mixed, Upper, Sensitive}; QODBCDriverPrivate() - : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false), - isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false), - isQuoteInitialized(false), quote(QLatin1Char('"')) + : hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), isMySqlServer(false), + isMSSqlServer(false), isFreeTDSDriver(false), hasSQLFetchScroll(true), + hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"')) { - unicode = false; } SQLHANDLE hEnv; @@ -146,6 +145,7 @@ public: int disconnectCount; bool isMySqlServer; bool isMSSqlServer; + bool isFreeTDSDriver; bool hasSQLFetchScroll; bool hasMultiResultSets; @@ -172,7 +172,10 @@ public: QODBCPrivate(QODBCDriverPrivate *dpp) : hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false) { - unicode = false; + unicode = dpp->unicode; + useSchema = dpp->useSchema; + disconnectCount = dpp->disconnectCount; + hasSQLFetchScroll = dpp->hasSQLFetchScroll; } inline void clearValues() @@ -374,44 +377,88 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni } else { colSize++; // make sure there is room for more than the 0 termination } - r = SQLGetData(hStmt, - column+1, - SQL_C_TCHAR, - NULL, - 0, - &lengthIndicator); - if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0) - colSize = lengthIndicator/sizeof(SQLTCHAR) + 1; - QVarLengthArray buf(colSize); - while (true) { + if(unicode) { r = SQLGetData(hStmt, column+1, SQL_C_TCHAR, - (SQLPOINTER)buf.data(), - colSize*sizeof(SQLTCHAR), + NULL, + 0, &lengthIndicator); - if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { - if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) { + if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0) + colSize = lengthIndicator/sizeof(SQLTCHAR) + 1; + QVarLengthArray buf(colSize); + memset(buf.data(), 0, colSize*sizeof(SQLTCHAR)); + while (true) { + r = SQLGetData(hStmt, + column+1, + SQL_C_TCHAR, + (SQLPOINTER)buf.data(), + colSize*sizeof(SQLTCHAR), + &lengthIndicator); + if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { + if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) { + fieldVal.clear(); + break; + } + // if SQL_SUCCESS_WITH_INFO is returned, indicating that + // more data can be fetched, the length indicator does NOT + // contain the number of bytes returned - it contains the + // total number of bytes that CAN be fetched + // colSize-1: remove 0 termination when there is more data to fetch + int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR); + fieldVal += fromSQLTCHAR(buf, rSize); + if (lengthIndicator < (unsigned int)colSize*sizeof(SQLTCHAR)) { + // workaround for Drivermanagers that don't return SQL_NO_DATA + break; + } + } else if (r == SQL_NO_DATA) { + break; + } else { + qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')'; fieldVal.clear(); break; } - // if SQL_SUCCESS_WITH_INFO is returned, indicating that - // more data can be fetched, the length indicator does NOT - // contain the number of bytes returned - it contains the - // total number of bytes that CAN be fetched - // colSize-1: remove 0 termination when there is more data to fetch - int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR); - fieldVal += fromSQLTCHAR(buf, rSize); - if (lengthIndicator < (unsigned int)colSize*sizeof(SQLTCHAR)) { - // workaround for Drivermanagers that don't return SQL_NO_DATA + } + } else { + r = SQLGetData(hStmt, + column+1, + SQL_C_CHAR, + NULL, + 0, + &lengthIndicator); + if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0) + colSize = lengthIndicator + 1; + QVarLengthArray buf(colSize); + while (true) { + r = SQLGetData(hStmt, + column+1, + SQL_C_CHAR, + (SQLPOINTER)buf.data(), + colSize, + &lengthIndicator); + if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { + if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) { + fieldVal.clear(); + break; + } + // if SQL_SUCCESS_WITH_INFO is returned, indicating that + // more data can be fetched, the length indicator does NOT + // contain the number of bytes returned - it contains the + // total number of bytes that CAN be fetched + // colSize-1: remove 0 termination when there is more data to fetch + int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator; + fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize); + if (lengthIndicator < (unsigned int)colSize) { + // workaround for Drivermanagers that don't return SQL_NO_DATA + break; + } + } else if (r == SQL_NO_DATA) { + break; + } else { + qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')'; + fieldVal.clear(); break; } - } else if (r == SQL_NO_DATA) { - break; - } else { - qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')'; - fieldVal.clear(); - break; } } return fieldVal; @@ -866,10 +913,6 @@ QODBCResult::QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p) : QSqlResult(db) { d = new QODBCPrivate(p); - d->unicode = p->unicode; - d->useSchema = p->useSchema; - d->disconnectCount = p->disconnectCount; - d->hasSQLFetchScroll = p->hasSQLFetchScroll; } QODBCResult::~QODBCResult() @@ -1846,6 +1889,7 @@ bool QODBCDriver::open(const QString & db, SQLSMALLINT cb; QVarLengthArray connOut(1024); + memset(connOut.data(), 0, connOut.size() * sizeof(SQLTCHAR)); r = SQLDriverConnect(d->hDbc, NULL, #ifdef UNICODE @@ -1943,6 +1987,7 @@ void QODBCDriverPrivate::checkUnicode() NULL); if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WCHAR)) { unicode = true; + return; } r = SQLGetInfo(hDbc, @@ -1952,6 +1997,7 @@ void QODBCDriverPrivate::checkUnicode() NULL); if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WVARCHAR)) { unicode = true; + return; } r = SQLGetInfo(hDbc, @@ -1961,7 +2007,25 @@ void QODBCDriverPrivate::checkUnicode() NULL); if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WLONGVARCHAR)) { unicode = true; + return; + } + SQLHANDLE hStmt; + r = SQLAllocHandle(SQL_HANDLE_STMT, + hDbc, + &hStmt); + + r = SQLExecDirect(hStmt, toSQLTCHAR(QLatin1String("select 'test'")).data(), SQL_NTS); + if(r == SQL_SUCCESS) { + r = SQLFetch(hStmt); + if(r == SQL_SUCCESS) { + QVarLengthArray buffer(10); + r = SQLGetData(hStmt, 1, SQL_C_WCHAR, buffer.data(), buffer.size() * sizeof(SQLWCHAR), NULL); + if(r == SQL_SUCCESS && fromSQLTCHAR(buffer) == QLatin1String("test")) { + unicode = true; + } + } } + r = SQLFreeHandle(SQL_HANDLE_STMT, hStmt); } bool QODBCDriverPrivate::checkDriver() const @@ -2053,6 +2117,21 @@ void QODBCDriverPrivate::checkSqlServer() isMySqlServer = serverType.contains(QLatin1String("mysql"), Qt::CaseInsensitive); isMSSqlServer = serverType.contains(QLatin1String("Microsoft SQL Server"), Qt::CaseInsensitive); } + r = SQLGetInfo(hDbc, + SQL_DRIVER_NAME, + serverString.data(), + serverString.size() * sizeof(SQLTCHAR), + &t); + if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { + QString serverType; +#ifdef UNICODE + serverType = fromSQLTCHAR(serverString, t/sizeof(SQLTCHAR)); +#else + serverType = QString::fromUtf8((const char *)serverString.constData(), t); +#endif + isFreeTDSDriver = serverType.contains(QLatin1String("tdsodbc"), Qt::CaseInsensitive); + unicode = isFreeTDSDriver == false; + } } void QODBCDriverPrivate::checkHasSQLFetchScroll() -- cgit v0.12 From 194bbeed0152d541527059bb0f1dae60a8573912 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 25 Mar 2010 16:44:32 +1000 Subject: Fix ODBC compilation for ODBC versions < 3.5 Task-number: QTBUG-8488 Reviewed-by: Justin McPherson --- src/sql/drivers/odbc/qsql_odbc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 1506c3c..f41a914 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -352,7 +352,9 @@ static QVariant::Type qDecodeODBCType(SQLSMALLINT sqltype, const T* p, bool isSi #endif case SQL_CHAR: case SQL_VARCHAR: +#if (ODBCVER >= 0x0350) case SQL_GUID: +#endif case SQL_LONGVARCHAR: type = QVariant::String; break; -- cgit v0.12 From 92607e19c79fcdfb82e42fa45353004f85d1adf9 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 25 Mar 2010 16:50:32 +1000 Subject: Sql Autotest cleanup and tweaking. --- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 178 +++++++++++++++-------------- tests/auto/qsqlquery/tst_qsqlquery.cpp | 9 +- 2 files changed, 95 insertions(+), 92 deletions(-) diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index f837564..f3c2c09 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -44,7 +44,7 @@ #include #include #include - +#include #include "../qsqldatabase/tst_databases.h" @@ -122,7 +122,7 @@ void tst_Q3SqlCursor::generic_data(const QString &engine) { if ( dbs.fillTestTable(engine) == 0 ) { if(engine.isEmpty()) - QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); else QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll ); } @@ -131,7 +131,7 @@ void tst_Q3SqlCursor::generic_data(const QString &engine) void tst_Q3SqlCursor::createTestTables( QSqlDatabase db ) { if ( !db.isValid() ) - return; + return; QSqlQuery q( db ); if (tst_Databases::isSqlServer(db)) { @@ -143,20 +143,20 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db ) // please never ever change this table; otherwise fix all tests ;) if ( tst_Databases::isMSAccess( db ) ) { - QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null," - "t_char char(40), t_numeric number, primary key (id, t_varchar) )" )); + QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null," + "t_char char(40), t_numeric number, primary key (id, t_varchar) )" )); } else { - QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null," - "t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar) )" )); + QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null," + "t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar) )" )); } if ( tst_Databases::isSqlServer( db ) ) { - //workaround for SQL SERVER since he can store unicode only in nvarchar fields - QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, " - "t_varchar nvarchar(80) not null, t_char nchar(80) )" )); + //workaround for SQL SERVER since he can store unicode only in nvarchar fields + QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, " + "t_varchar nvarchar(80) not null, t_char nchar(80) )" )); } else { - QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, " - "t_varchar varchar(100) not null," "t_char char(100))" )); + QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, " + "t_varchar varchar(100) not null," "t_char char(100))" )); } if (tst_Databases::isMSAccess(db)) { @@ -169,7 +169,7 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db ) void tst_Q3SqlCursor::dropTestTables( QSqlDatabase db ) { if ( !db.isValid() ) - return; + return; QStringList tableNames; tableNames << qtest << qTableName( "qtest_unicode", __FILE__ ) @@ -183,7 +183,7 @@ void tst_Q3SqlCursor::dropTestTables( QSqlDatabase db ) void tst_Q3SqlCursor::populateTestTables( QSqlDatabase db ) { if (!db.isValid()) - return; + return; QSqlQuery q( db ); q.exec( "delete from " + qtest ); //not fatal @@ -200,21 +200,21 @@ void tst_Q3SqlCursor::initTestCase() dbs.open(); for ( QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it ) { - QSqlDatabase db = QSqlDatabase::database( (*it) ); - CHECK_DATABASE( db ); + QSqlDatabase db = QSqlDatabase::database( (*it) ); + CHECK_DATABASE( db ); - dropTestTables( db ); //in case of leftovers - createTestTables( db ); - populateTestTables( db ); + dropTestTables( db ); //in case of leftovers + createTestTables( db ); + populateTestTables( db ); } } void tst_Q3SqlCursor::cleanupTestCase() { for ( QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it ) { - QSqlDatabase db = QSqlDatabase::database( (*it) ); - CHECK_DATABASE( db ); - dropTestTables( db ); + QSqlDatabase db = QSqlDatabase::database( (*it) ); + CHECK_DATABASE( db ); + dropTestTables( db ); } dbs.close(); @@ -230,9 +230,9 @@ void tst_Q3SqlCursor::cleanup() QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); if ( QTest::currentTestFailed() ) { - //since Oracle ODBC totally craps out on error, we init again - db.close(); - db.open(); + //since Oracle ODBC totally craps out on error, we init again + db.close(); + db.open(); } } @@ -244,10 +244,10 @@ void tst_Q3SqlCursor::copyConstructor() Q3SqlCursor cur2; { - Q3SqlCursor cur( qtest, true, db ); - QVERIFY_SQL(cur, select( cur.index( QString("id") ) )); - cur2 = Q3SqlCursor( cur ); - // let "cur" run out of scope... + Q3SqlCursor cur( qtest, true, db ); + QVERIFY_SQL(cur, select( cur.index( QString("id") ) )); + cur2 = Q3SqlCursor( cur ); + // let "cur" run out of scope... } QSqlRecord* rec = cur2.primeUpdate(); @@ -256,8 +256,8 @@ void tst_Q3SqlCursor::copyConstructor() int i = 0; while ( cur2.next() ) { - QVERIFY( cur2.value("id").toInt() == i ); - i++; + QVERIFY( cur2.value("id").toInt() == i ); + i++; } } @@ -271,8 +271,8 @@ void tst_Q3SqlCursor::value() QVERIFY_SQL(cur, select( cur.index( QString("id") ) )); int i = 0; while ( cur.next() ) { - QCOMPARE(cur.value("id").toInt(), i); - i++; + QCOMPARE(cur.value("id").toInt(), i); + i++; } } @@ -285,11 +285,11 @@ void tst_Q3SqlCursor::primaryIndex() Q3SqlCursor cur( qtest, true, db ); QSqlIndex index = cur.primaryIndex(); if ( tst_Databases::isMSAccess( db ) ) { - QCOMPARE( index.fieldName(1).upper(), QString( "ID" ) ); - QCOMPARE( index.fieldName(0).upper(), QString( "T_VARCHAR" ) ); + QCOMPARE( index.fieldName(1).upper(), QString( "ID" ) ); + QCOMPARE( index.fieldName(0).upper(), QString( "T_VARCHAR" ) ); } else { - QCOMPARE( index.fieldName(0).upper(), QString( "ID" ) ); - QCOMPARE( index.fieldName(1).upper(), QString( "T_VARCHAR" ) ); + QCOMPARE( index.fieldName(0).upper(), QString( "ID" ) ); + QCOMPARE( index.fieldName(1).upper(), QString( "T_VARCHAR" ) ); } QVERIFY(!index.isDescending(0)); QVERIFY(!index.isDescending(1)); @@ -308,10 +308,10 @@ void tst_Q3SqlCursor::insert() // check that primeInsert returns a valid QSqlRecord QCOMPARE( (int)irec->count(), 4 ); if ( ( irec->field( 0 ).type() != QVariant::Int ) && - ( irec->field( 0 ).type() != QVariant::String ) && + ( irec->field( 0 ).type() != QVariant::String ) && ( irec->field( 0 ).type() != QVariant::Double ) ) { - QFAIL( QString( "Wrong datatype %1 for field 'ID'" - " (expected Int or String)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) ); + QFAIL( QString( "Wrong datatype %1 for field 'ID'" + " (expected Int or String)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) ); } QCOMPARE( QVariant::typeToName( irec->field( 1 ).type() ), QVariant::typeToName( QVariant::String ) ); QCOMPARE( QVariant::typeToName( irec->field( 2 ).type() ), QVariant::typeToName( QVariant::String ) ); @@ -327,7 +327,9 @@ void tst_Q3SqlCursor::insert() irec->setValue( "t_char", "SomeChar" ); irec->setValue( "t_numeric", 400.400 ); - QCOMPARE( cur.insert(), 1 ); + QSet validReturns(QSet() << -1 << 1); + + QVERIFY( validReturns.contains(cur.insert()) ); // restore old test-tables populateTestTables( db ); @@ -338,6 +340,7 @@ void tst_Q3SqlCursor::insertSpecial() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); + QSet validReturns(QSet() << -1 << 1); Q3SqlCursor cur( qtest, true, db ); QSqlRecord* irec = cur.primeInsert(); @@ -355,25 +358,25 @@ void tst_Q3SqlCursor::insertSpecial() // INSERT the strings QStringList::Iterator it; for ( it = strings.begin(); it != strings.end(); ++it ) { - QSqlRecord* irec = cur.primeInsert(); - QVERIFY( irec != 0 ); - irec->setValue( "id", i ); - irec->setValue( "t_varchar", (*it) ); - irec->setValue( "t_char", (*it) ); - irec->setValue( "t_numeric", (double)i ); - ++i; - QCOMPARE( cur.insert(), 1 ); + QSqlRecord* irec = cur.primeInsert(); + QVERIFY( irec != 0 ); + irec->setValue( "id", i ); + irec->setValue( "t_varchar", (*it) ); + irec->setValue( "t_char", (*it) ); + irec->setValue( "t_numeric", (double)i ); + ++i; + QVERIFY( validReturns.contains(cur.insert()) ); } QVERIFY( cur.select( "id >= 800 and id < 900" ) ); int i2 = 800; while( cur.next() ) { - QCOMPARE( cur.value( "id" ).toInt(), i2 ); - QCOMPARE( cur.value( "t_varchar" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) ); - QCOMPARE( cur.value( "t_char" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) ); - QCOMPARE( cur.value( "t_numeric" ).toDouble(), (double)i2 ); - ++i2; + QCOMPARE( cur.value( "id" ).toInt(), i2 ); + QCOMPARE( cur.value( "t_varchar" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) ); + QCOMPARE( cur.value( "t_char" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) ); + QCOMPARE( cur.value( "t_numeric" ).toDouble(), (double)i2 ); + ++i2; } QCOMPARE( i, i2 ); @@ -385,6 +388,7 @@ void tst_Q3SqlCursor::batchInsert() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); + QSet validReturns(QSet() << -1 << 1); QSqlQuery q( db ); q.exec( "delete from " + qtest ); @@ -393,16 +397,16 @@ void tst_Q3SqlCursor::batchInsert() int i = 0; for ( ; i < 100; ++i ) { - QSqlRecord* irec = cur.primeInsert(); - Q_ASSERT( irec ); - irec->setValue( "id", i ); - irec->setValue( "t_varchar", "blah" ); - irec->setValue( "t_char", "blah" ); - irec->setValue( "t_numeric", 1.1 ); - if ( db.driverName().startsWith( "QSQLITE" ) ) { - QVERIFY( cur.insert( true ) ); - } else { - QCOMPARE( cur.insert( true ), 1 ); + QSqlRecord* irec = cur.primeInsert(); + Q_ASSERT( irec ); + irec->setValue( "id", i ); + irec->setValue( "t_varchar", "blah" ); + irec->setValue( "t_char", "blah" ); + irec->setValue( "t_numeric", 1.1 ); + if ( db.driverName().startsWith( "QSQLITE" ) ) { + QVERIFY( cur.insert( true ) ); + } else { + QVERIFY( validReturns.contains(cur.insert( true )) ); } } @@ -413,18 +417,18 @@ void tst_Q3SqlCursor::batchInsert() irec->setValue( "t_varchar", "blah" ); irec->setValue( "t_char", "blah" ); irec->setValue( "t_numeric", 1.1 ); - if ( db.driverName().startsWith( "QSQLITE" ) ) { - QVERIFY( cur.insert( false ) ); - } else { - QCOMPARE( cur.insert( false ), 1 ); + if ( db.driverName().startsWith( "QSQLITE" ) ) { + QVERIFY( cur.insert( false ) ); + } else { + QVERIFY( validReturns.contains(cur.insert( false )) ); } } i = 0; QVERIFY_SQL(q, exec( "select * from " + qtest + " order by id" )); while ( q.next() ) { - QCOMPARE( q.value( 0 ).toInt(), i ); - i++; + QCOMPARE( q.value( 0 ).toInt(), i ); + i++; } QCOMPARE( i, 200 ); @@ -436,7 +440,7 @@ static QString dumpUtf8( const QString& str ) { QString res; for ( int i = 0; i < (int)str.length(); ++i ) { - res += "0x" + QString::number( str[ i ].unicode(), 16 ) + ' '; + res += "0x" + QString::number( str[ i ].unicode(), 16 ) + ' '; } return res; } @@ -448,7 +452,7 @@ void tst_Q3SqlCursor::insertORA() CHECK_DATABASE( db ); if (tst_Databases::getOraVersion(db) < 9) - QSKIP("Need Oracle >= 9", SkipSingle); + QSKIP("Need Oracle >= 9", SkipSingle); /****** CHARSET TEST ******/ @@ -466,8 +470,8 @@ void tst_Q3SqlCursor::insertORA() QVERIFY_SQL(cur, select()); QVERIFY( cur.next() ); if ( cur.value( "t_char" ).toString() != val1 ) - qDebug( QString( "Wrong value for t_char: expected '%1', got '%2'" ).arg( val1 ).arg( - cur.value( "t_char" ).toString() ) ); + qDebug( QString( "Wrong value for t_char: expected '%1', got '%2'" ).arg( val1 ).arg( + cur.value( "t_char" ).toString() ) ); static const unsigned short utf8arr[] = { 0xd792,0xd79c,0xd792,0xd79c,0xd799,0x00 }; static const QString utf8str = QString::fromUcs2( utf8arr ); @@ -524,7 +528,7 @@ void tst_Q3SqlCursor::unicode() static const QString utf8str = QString::fromUtf8( "ὕαλον ϕαγεῖν δύναμαι· τοῦτο οὔ με βλάπτει." ); if ( !db.driver()->hasFeature( QSqlDriver::Unicode ) ) { - QSKIP( "DBMS not Unicode capable", SkipSingle ); + QSKIP( "DBMS not Unicode capable", SkipSingle ); } // ascii in the data storage, can't transliterate properly. invalid test. if(db.driverName().startsWith("QIBASE") && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb")) @@ -640,11 +644,11 @@ void tst_Q3SqlCursor::select() QSqlIndex idx = cur4.primaryIndex( false ); QCOMPARE( (int)idx.count(), 2 ); if ( tst_Databases::isMSAccess( db ) ) { - QCOMPARE( idx.field( 1 ).name().upper(), QString("ID") ); - QCOMPARE( idx.field( 0 ).name().upper(), QString("T_VARCHAR") ); + QCOMPARE( idx.field( 1 ).name().upper(), QString("ID") ); + QCOMPARE( idx.field( 0 ).name().upper(), QString("T_VARCHAR") ); } else { - QCOMPARE( idx.field( 0 ).name().upper(), QString("ID") ); - QCOMPARE( idx.field( 1 ).name().upper(), QString("T_VARCHAR") ); + QCOMPARE( idx.field( 0 ).name().upper(), QString("ID") ); + QCOMPARE( idx.field( 1 ).name().upper(), QString("T_VARCHAR") ); } #ifdef QT_DEBUG @@ -688,17 +692,18 @@ void tst_Q3SqlCursor::updateNoPK() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - + QSet validReturns(QSet() << -1 << 1); + QSqlQuery q(db); QVERIFY_SQL(q, exec("create table " + qTableName( "qtestPK", __FILE__ ) + " (id int, name varchar(20), num numeric)")); - + Q3SqlCursor cur(qTableName("qtestPK", __FILE__), true, db); QSqlRecord* rec = cur.primeInsert(); Q_ASSERT(rec); rec->setNull(0); rec->setNull(1); rec->setNull(2); - QVERIFY_SQL(cur, insert() == 1); + QVERIFY(validReturns.contains(cur.insert())); if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) { // Only QPSQL, QMYSQL, QODBC and QOCI drivers currently use escape identifiers for column names @@ -713,8 +718,8 @@ void tst_Q3SqlCursor::updateNoPK() + " values (NULL,NULL,NULL)"); QCOMPARE(cur.lastQuery(), query); } else { - QCOMPARE(cur.lastQuery(), QString::fromLatin1("insert into " + qTableName("qtestPK", __FILE__) + - " (\"id\",\"name\",\"num\") values (NULL,NULL,NULL)")); + QCOMPARE(cur.lastQuery(), QString::fromLatin1("insert into " + qTableName("qtestPK", __FILE__) + + " (\"id\",\"name\",\"num\") values (NULL,NULL,NULL)")); } } @@ -733,7 +738,7 @@ void tst_Q3SqlCursor::updateNoPK() qTableName("qtestPK", __FILE__) + ".num IS NULL"; if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) { if (!db.driverName().startsWith("QSQLITE")) { - QCOMPARE(cur.lastQuery(), expect); + QCOMPARE(cur.lastQuery(), expect); } } QVERIFY(cur.select(cur.index(QString("id")))); @@ -750,6 +755,7 @@ void tst_Q3SqlCursor::insertFieldNameContainsWS() { QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); + QSet validReturns(QSet() << -1 << 1); // The bugfix (and this test) depends on QSqlDriver::escapeIdentifier(...) // to be implemented, which is currently only the case for the @@ -778,7 +784,7 @@ void tst_Q3SqlCursor::insertFieldNameContainsWS() { r->setValue("firsT NaMe", "Kong"); r->setValue("lastNaMe", "Harald"); - QVERIFY(cur.insert() == 1); + QVERIFY(validReturns.contains(cur.insert())); cur.select(); cur.next(); diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index b9ab73f..db3a929 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -1137,17 +1137,14 @@ void tst_QSqlQuery::last() QVERIFY( q.last() ); - if ( !tst_Databases::isMSAccess( db ) ) - // Access doesn't return the correct position - QCOMPARE( q.at(), ( i-1 ) ); + QSet validReturns(QSet() << -1 << i-1); + QVERIFY( validReturns.contains(q.at()) ); QSqlQuery q2( "select * from " + qtest, db ); QVERIFY( q2.last() ); - if ( !tst_Databases::isMSAccess( db ) ) - // Access doesn't return the correct position - QCOMPARE( q.at(), ( i-1 ) ); + QVERIFY( validReturns.contains(q.at()) ); } void tst_QSqlQuery::seek() -- cgit v0.12 From 9d324a07c9c87f972b165a43956424f5c92f80ad Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 25 Mar 2010 16:58:42 +1000 Subject: Phonon; complete integration. --- src/3rdparty/phonon/CMakeLists.txt | 4 + src/3rdparty/phonon/gstreamer/backend.cpp | 27 +- src/3rdparty/phonon/phonon/audiodataoutput.cpp | 68 ++ src/3rdparty/phonon/phonon/audiodataoutput.h | 129 +++ src/3rdparty/phonon/phonon/audiodataoutput_p.h | 48 + .../phonon/phonon/audiodataoutputinterface.h | 44 + src/3rdparty/phonon/phonon/globalconfig.h | 71 ++ src/3rdparty/phonon/phonon/pulsesupport.cpp | 1040 ++++++++++++++++++++ src/3rdparty/phonon/phonon/pulsesupport.h | 78 ++ src/3rdparty/phonon/phonon/swiftslider.cpp | 103 ++ src/3rdparty/phonon/phonon/swiftslider_p.h | 68 ++ src/3rdparty/phonon/qt7/mediaobject.mm | 20 +- 12 files changed, 1678 insertions(+), 22 deletions(-) create mode 100644 src/3rdparty/phonon/phonon/audiodataoutput.cpp create mode 100644 src/3rdparty/phonon/phonon/audiodataoutput.h create mode 100644 src/3rdparty/phonon/phonon/audiodataoutput_p.h create mode 100644 src/3rdparty/phonon/phonon/audiodataoutputinterface.h create mode 100644 src/3rdparty/phonon/phonon/globalconfig.h create mode 100644 src/3rdparty/phonon/phonon/pulsesupport.cpp create mode 100644 src/3rdparty/phonon/phonon/pulsesupport.h create mode 100644 src/3rdparty/phonon/phonon/swiftslider.cpp create mode 100644 src/3rdparty/phonon/phonon/swiftslider_p.h diff --git a/src/3rdparty/phonon/CMakeLists.txt b/src/3rdparty/phonon/CMakeLists.txt index ff89edb..ef7d6f5 100644 --- a/src/3rdparty/phonon/CMakeLists.txt +++ b/src/3rdparty/phonon/CMakeLists.txt @@ -70,6 +70,10 @@ if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(-DQT_NO_DEBUG) endif (MINGW) + if (QT_USE_FRAMEWORKS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F${QT_LIBRARY_DIR}") + endif (QT_USE_FRAMEWORKS) + check_cxx_compiler_flag(-fPIE HAVE_FPIE_SUPPORT) if(KDE4_ENABLE_FPIE) if(HAVE_FPIE_SUPPORT) diff --git a/src/3rdparty/phonon/gstreamer/backend.cpp b/src/3rdparty/phonon/gstreamer/backend.cpp index 8c2b42f..729a1d3 100644 --- a/src/3rdparty/phonon/gstreamer/backend.cpp +++ b/src/3rdparty/phonon/gstreamer/backend.cpp @@ -220,14 +220,14 @@ QStringList Backend::availableMimeTypes() const GstPluginFeature *feature = GST_PLUGIN_FEATURE(iter->data); QString klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature)); - if (klass == QLatin1String("Codec/Decoder") || - klass == QLatin1String("Codec/Decoder/Audio") || - klass == QLatin1String("Codec/Decoder/Video") || - klass == QLatin1String("Codec/Demuxer") || - klass == QLatin1String("Codec/Demuxer/Audio") || - klass == QLatin1String("Codec/Demuxer/Video") || - klass == QLatin1String("Codec/Parser") || - klass == QLatin1String("Codec/Parser/Audio") || + if (klass == QLatin1String("Codec/Decoder") || + klass == QLatin1String("Codec/Decoder/Audio") || + klass == QLatin1String("Codec/Decoder/Video") || + klass == QLatin1String("Codec/Demuxer") || + klass == QLatin1String("Codec/Demuxer/Audio") || + klass == QLatin1String("Codec/Demuxer/Video") || + klass == QLatin1String("Codec/Parser") || + klass == QLatin1String("Codec/Parser/Audio") || klass == QLatin1String("Codec/Parser/Video")) { const GList *static_templates; @@ -240,10 +240,13 @@ QStringList Backend::availableMimeTypes() const GstCaps *caps = gst_static_pad_template_get_caps (padTemplate); if (caps) { - const GstStructure* capsStruct = gst_caps_get_structure (caps, 0); - QString mime = QString::fromUtf8(gst_structure_get_name (capsStruct)); - if (!availableMimeTypes.contains(mime)) - availableMimeTypes.append(mime); + for (unsigned int struct_idx = 0; struct_idx < gst_caps_get_size (caps); struct_idx++) { + + const GstStructure* capsStruct = gst_caps_get_structure (caps, struct_idx); + QString mime = QString::fromUtf8(gst_structure_get_name (capsStruct)); + if (!availableMimeTypes.contains(mime)) + availableMimeTypes.append(mime); + } } } } diff --git a/src/3rdparty/phonon/phonon/audiodataoutput.cpp b/src/3rdparty/phonon/phonon/audiodataoutput.cpp new file mode 100644 index 0000000..6c737c2 --- /dev/null +++ b/src/3rdparty/phonon/phonon/audiodataoutput.cpp @@ -0,0 +1,68 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Matthias Kretz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#include "audiodataoutput.h" +#include "audiodataoutput_p.h" +#include "factory_p.h" + +#define PHONON_CLASSNAME AudioDataOutput + +namespace Phonon +{ + +PHONON_HEIR_IMPL(AbstractAudioOutput) + +PHONON_GETTER(int, dataSize, d->dataSize) +PHONON_GETTER(int, sampleRate, -1) +PHONON_SETTER(setDataSize, dataSize, int) + +bool AudioDataOutputPrivate::aboutToDeleteBackendObject() +{ + Q_ASSERT(m_backendObject); + pBACKEND_GET(int, dataSize, "dataSize"); + + return AbstractAudioOutputPrivate::aboutToDeleteBackendObject(); +} + +void AudioDataOutputPrivate::setupBackendObject() +{ + Q_Q(AudioDataOutput); + Q_ASSERT(m_backendObject); + AbstractAudioOutputPrivate::setupBackendObject(); + + // set up attributes + pBACKEND_CALL1("setDataSize", int, dataSize); + + qRegisterMetaType > >("QMap >"); + + QObject::connect(m_backendObject, + SIGNAL(dataReady(const QMap > &)), + q, SIGNAL(dataReady(const QMap > &))); + QObject::connect(m_backendObject, SIGNAL(endOfMedia(int)), q, SIGNAL(endOfMedia(int))); +} + +} // namespace Phonon + +#include "audiodataoutput.moc" + +#undef PHONON_CLASSNAME +// vim: sw=4 ts=4 tw=80 diff --git a/src/3rdparty/phonon/phonon/audiodataoutput.h b/src/3rdparty/phonon/phonon/audiodataoutput.h new file mode 100644 index 0000000..8e8f8e0 --- /dev/null +++ b/src/3rdparty/phonon/phonon/audiodataoutput.h @@ -0,0 +1,129 @@ +/* This file is part of the KDE project + Copyright (C) 2005-2006 Matthias Kretz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ +#ifndef Phonon_AUDIODATAOUTPUT_H +#define Phonon_AUDIODATAOUTPUT_H + +#include "phonon_export.h" +#include "abstractaudiooutput.h" +#include "phonondefs.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +template class QVector; +template class QMap; +#endif + +namespace Phonon +{ + class AudioDataOutputPrivate; + + /** + * \short This class gives you the audio data (for visualizations). + * + * This class implements a special AbstractAudioOutput that gives your + * application the audio data. Don't expect realtime performance. But + * the latencies should be low enough to use the audio data for + * visualizations. You can also use the audio data for further processing + * (e.g. encoding and saving to a file). + * + * \author Matthias Kretz + */ + class PHONON_EXPORT AudioDataOutput : public AbstractAudioOutput + { + Q_OBJECT + K_DECLARE_PRIVATE(AudioDataOutput) + Q_ENUMS(Channel) + Q_PROPERTY(int dataSize READ dataSize WRITE setDataSize) + PHONON_HEIR(AudioDataOutput) + public: + /** + * Specifies the channel the audio data belongs to. + */ + enum Channel + { + LeftChannel, + RightChannel, + CenterChannel, + LeftSurroundChannel, + RightSurroundChannel, + SubwooferChannel + }; + + /** + * Returns the currently used number of samples passed through + * the signal. + * + * \see setDataSize + */ + int dataSize() const; + + /** + * Returns the sample rate in Hz. Common sample rates are 44100 Hz + * and 48000 Hz. AudioDataOutput will not do any sample rate + * conversion for you. If you need to convert the sample rate you + * might want to take a look at libsamplerate. For visualizations it + * is often enough to do simple interpolation or even drop/duplicate + * samples. + * + * \return The sample rate as reported by the backend. If the + * backend is unavailable -1 is returned. + */ + int sampleRate() const; + + public Q_SLOTS: + /** + * Sets the number of samples to be passed in one signal emission. + * + * Defaults to 512 samples per emitted signal. + * + * \param size the number of samples + */ + void setDataSize(int size); + + Q_SIGNALS: + /** + * Emitted whenever another dataSize number of samples are ready. + * + * \param data A mapping of Channel to a vector holding the audio data. + */ + void dataReady(const QMap > &data); + + + /** + * This signal is emitted before the last dataReady signal of a + * media is emitted. + * + * If, for example, the playback of a media file has finished and the + * last audio data of that file is going to be passed with the next + * dataReady signal, and only the 28 first samples of the data + * vector are from that media file endOfMedia will be emitted right + * before dataReady with \p remainingSamples = 28. + * + * \param remainingSamples The number of samples in the next + * dataReady vector that belong to the media that was playing to + * this point. + */ + void endOfMedia(int remainingSamples); + }; +} // namespace Phonon + +// vim: sw=4 ts=4 tw=80 +#endif // Phonon_AUDIODATAOUTPUT_H diff --git a/src/3rdparty/phonon/phonon/audiodataoutput_p.h b/src/3rdparty/phonon/phonon/audiodataoutput_p.h new file mode 100644 index 0000000..91103a9 --- /dev/null +++ b/src/3rdparty/phonon/phonon/audiodataoutput_p.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Matthias Kretz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#ifndef AUDIODATAOUTPUT_P_H +#define AUDIODATAOUTPUT_P_H + +#include "audiodataoutput.h" +#include "abstractaudiooutput_p.h" + +namespace Phonon +{ + +class AudioDataOutputPrivate : public AbstractAudioOutputPrivate +{ + Q_DECLARE_PUBLIC(AudioDataOutput) + PHONON_PRIVATECLASS + protected: + AudioDataOutputPrivate() + : dataSize(512) + { + } + + int dataSize; +}; + +} // namespace Phonon + +#endif // AUDIODATAOUTPUT_P_H +// vim: sw=4 ts=4 tw=80 diff --git a/src/3rdparty/phonon/phonon/audiodataoutputinterface.h b/src/3rdparty/phonon/phonon/audiodataoutputinterface.h new file mode 100644 index 0000000..bc1aad0 --- /dev/null +++ b/src/3rdparty/phonon/phonon/audiodataoutputinterface.h @@ -0,0 +1,44 @@ +/* This file is part of the KDE project + Copyright (C) 2008 Matthias Kretz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#ifndef PHONON_AUDIODATAOUTPUTINTERFACE_H +#define PHONON_AUDIODATAOUTPUTINTERFACE_H + +namespace Phonon +{ + +class AudioDataOutput; + +class AudioDataOutputInterface +{ + public: + virtual ~AudioDataOutputInterface() {} + + virtual AudioDataOutput *frontendObject() const = 0; + virtual void setFrontendObject(AudioDataOutput *) = 0; +}; + +} // namespace Phonon + +Q_DECLARE_INTERFACE(Phonon::AudioDataOutputInterface, "0AudioDataOutputInterface.phonon.kde.org") + +#endif // PHONON_AUDIODATAOUTPUTINTERFACE_H diff --git a/src/3rdparty/phonon/phonon/globalconfig.h b/src/3rdparty/phonon/phonon/globalconfig.h new file mode 100644 index 0000000..5233c7b --- /dev/null +++ b/src/3rdparty/phonon/phonon/globalconfig.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project +Copyright (C) 2006-2008 Matthias Kretz + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#ifndef PHONON_GLOBALCONFIG_H +#define PHONON_GLOBALCONFIG_H + +#include "phonon_export.h" +#include "phononnamespace.h" +#include "phonondefs.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace Phonon +{ + class GlobalConfigPrivate; + + class PHONON_EXPORT GlobalConfig + { + K_DECLARE_PRIVATE(GlobalConfig) + public: + GlobalConfig(); + virtual ~GlobalConfig(); + + enum DevicesToHideFlag { + ShowUnavailableDevices = 0, + ShowAdvancedDevices = 0, + HideAdvancedDevices = 1, + AdvancedDevicesFromSettings = 2, + HideUnavailableDevices = 4 + }; + bool hideAdvancedDevices() const; + void setHideAdvancedDevices(bool hide = true); + void setAudioOutputDeviceListFor(Phonon::Category category, QList order); + QList audioOutputDeviceListFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; + int audioOutputDeviceFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; + +#ifndef QT_NO_PHONON_AUDIOCAPTURE + void setAudioCaptureDeviceListFor(Phonon::Category category, QList order); + QList audioCaptureDeviceListFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; + int audioCaptureDeviceFor(Phonon::Category category, int override = AdvancedDevicesFromSettings) const; +#endif //QT_NO_PHONON_AUDIOCAPTURE + + protected: + GlobalConfigPrivate *const k_ptr; + }; +} // namespace Phonon + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // PHONON_GLOBALCONFIG_H diff --git a/src/3rdparty/phonon/phonon/pulsesupport.cpp b/src/3rdparty/phonon/phonon/pulsesupport.cpp new file mode 100644 index 0000000..642843f --- /dev/null +++ b/src/3rdparty/phonon/phonon/pulsesupport.cpp @@ -0,0 +1,1040 @@ +/* This file is part of the KDE project + Copyright (C) 2009 Colin Guthrie + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#include +#include +#include +#include + +#ifdef HAVE_PULSEAUDIO +#include +#include +#include +#include +#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER +# include +#endif +#endif // HAVE_PULSEAUDIO + +#include "pulsesupport.h" + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ + +static PulseSupport* s_instance = NULL; + +#ifdef HAVE_PULSEAUDIO +/*** +* Prints a conditional debug message based on the current debug level +* If obj is provided, classname and objectname will be printed as well +* +* see debugLevel() +*/ + +static int debugLevel() { + static int level = -1; + if (level < 1) { + level = 0; + QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DEBUG"); + int l = pulseenv.toInt(); + if (l > 0) + level = (l > 2 ? 2 : l); + } + return level; +} + +static void logMessage(const QString &message, int priority = 2, QObject *obj=0); +static void logMessage(const QString &message, int priority, QObject *obj) +{ + if (debugLevel() > 0) { + QString output; + if (obj) { + // Strip away namespace from className + QString className(obj->metaObject()->className()); + int nameLength = className.length() - className.lastIndexOf(':') - 1; + className = className.right(nameLength); + output.sprintf("%s %s (%s %p)", message.toLatin1().constData(), + obj->objectName().toLatin1().constData(), + className.toLatin1().constData(), obj); + } + else { + output = message; + } + if (priority <= debugLevel()) { + qDebug() << QString("PulseSupport(%1): %2").arg(priority).arg(output); + } + } +} + + +class AudioDevice +{ + public: + inline + AudioDevice(QString name, QString desc, QString icon, uint32_t index) + : pulseName(name), pulseIndex(index) + { + properties["name"] = desc; + properties["description"] = ""; // We don't have descriptions (well we do, but we use them as the name!) + properties["icon"] = icon; + properties["available"] = (index != PA_INVALID_INDEX); + properties["isAdvanced"] = false; // Nothing is advanced! + } + + // Needed for QMap + inline AudioDevice() {} + + QString pulseName; + uint32_t pulseIndex; + QHash properties; +}; +bool operator!=(const AudioDevice &a, const AudioDevice &b) +{ + return !(a.pulseName == b.pulseName && a.properties == b.properties); +} + +class PulseUserData +{ + public: + inline + PulseUserData() + { + } + + QMap newOutputDevices; + QMap > newOutputDevicePriorities; // prio, device + + QMap newCaptureDevices; + QMap > newCaptureDevicePriorities; // prio, device +}; + +static QMap s_roleCategoryMap; + +static bool s_pulseActive = false; + +static pa_glib_mainloop *s_mainloop = NULL; +static pa_context *s_context = NULL; + + + +static int s_deviceIndexCounter = 0; + +static QMap s_outputDeviceIndexes; +static QMap s_outputDevices; +static QMap > s_outputDevicePriorities; // prio, device +static QMap s_outputStreamIndexMap; + +static QMap s_captureDeviceIndexes; +static QMap s_captureDevices; +static QMap > s_captureDevicePriorities; // prio, device +static QMap s_captureStreamIndexMap; + +static void createGenericDevices() +{ + // OK so we don't have the device manager extension, but we can show a single device and fake it. + int index; + s_outputDeviceIndexes.clear(); + s_outputDevices.clear(); + s_outputDevicePriorities.clear(); + index = s_deviceIndexCounter++; + s_outputDeviceIndexes.insert("sink:default", index); + s_outputDevices.insert(index, AudioDevice("sink:default", QObject::tr("PulseAudio Sound Server").toUtf8(), "audio-backend-pulseaudio", 0)); + for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { + Phonon::Category cat = static_cast(i); + s_outputDevicePriorities[cat].insert(0, index); + } + + s_captureDeviceIndexes.clear(); + s_captureDevices.clear(); + s_captureDevicePriorities.clear(); + index = s_deviceIndexCounter++; + s_captureDeviceIndexes.insert("source:default", index); + s_captureDevices.insert(index, AudioDevice("source:default", QObject::tr("PulseAudio Sound Server").toUtf8(), "audio-backend-pulseaudio", 0)); + for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { + Phonon::Category cat = static_cast(i); + s_captureDevicePriorities[cat].insert(0, index); + } +} + +#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER +static void ext_device_manager_read_cb(pa_context *c, const pa_ext_device_manager_info *info, int eol, void *userdata) { + Q_ASSERT(c); + Q_ASSERT(userdata); + + PulseUserData *u = reinterpret_cast(userdata); + + if (eol < 0) { + logMessage(QString("Failed to initialize device manager extension: %1").arg(pa_strerror(pa_context_errno(c)))); + logMessage("Falling back to single device mode"); + createGenericDevices(); + delete u; + + // If this is our probe phase, exit now + if (s_context != c) + pa_context_disconnect(c); + + return; + } + + if (eol) { + // We're done reading the data, so order it by priority and copy it into the + // static variables where it can then be accessed by those classes that need it. + + QMap::iterator newdev_it; + + // Check for new output devices or things changing about known output devices. + bool output_changed = false; + for (newdev_it = u->newOutputDevices.begin(); newdev_it != u->newOutputDevices.end(); ++newdev_it) { + QString name = newdev_it.key(); + + // The name + index map is always written when a new device is added. + Q_ASSERT(s_outputDeviceIndexes.contains(name)); + + int index = s_outputDeviceIndexes[name]; + if (!s_outputDevices.contains(index)) { + // This is a totally new device + output_changed = true; + logMessage(QString("Brand New Output Device Found.")); + s_outputDevices.insert(index, *newdev_it); + } else if (s_outputDevices[index] != *newdev_it) { + // We have this device already, but is it different? + output_changed = true; + logMessage(QString("Change to Existing Output Device (may be Added/Removed or something else)")); + s_outputDevices.remove(index); + s_outputDevices.insert(index, *newdev_it); + } + } + // Go through the output devices we know about and see if any are no longer mentioned in the list. + QMutableMapIterator output_existing_it(s_outputDeviceIndexes); + while (output_existing_it.hasNext()) { + output_existing_it.next(); + if (!u->newOutputDevices.contains(output_existing_it.key())) { + output_changed = true; + logMessage(QString("Output Device Completely Removed")); + s_outputDevices.remove(output_existing_it.value()); + output_existing_it.remove(); + } + } + + // Check for new capture devices or things changing about known capture devices. + bool capture_changed = false; + for (newdev_it = u->newCaptureDevices.begin(); newdev_it != u->newCaptureDevices.end(); ++newdev_it) { + QString name = newdev_it.key(); + + // The name + index map is always written when a new device is added. + Q_ASSERT(s_captureDeviceIndexes.contains(name)); + + int index = s_captureDeviceIndexes[name]; + if (!s_captureDevices.contains(index)) { + // This is a totally new device + capture_changed = true; + logMessage(QString("Brand New Capture Device Found.")); + s_captureDevices.insert(index, *newdev_it); + } else if (s_captureDevices[index] != *newdev_it) { + // We have this device already, but is it different? + capture_changed = true; + logMessage(QString("Change to Existing Capture Device (may be Added/Removed or something else)")); + s_captureDevices.remove(index); + s_captureDevices.insert(index, *newdev_it); + } + } + // Go through the capture devices we know about and see if any are no longer mentioned in the list. + QMutableMapIterator capture_existing_it(s_captureDeviceIndexes); + while (capture_existing_it.hasNext()) { + capture_existing_it.next(); + if (!u->newCaptureDevices.contains(capture_existing_it.key())) { + capture_changed = true; + logMessage(QString("Capture Device Completely Removed")); + s_captureDevices.remove(capture_existing_it.value()); + capture_existing_it.remove(); + } + } + + // Just copy accross the new priority lists as we know they are valid + if (s_outputDevicePriorities != u->newOutputDevicePriorities) { + output_changed = true; + s_outputDevicePriorities = u->newOutputDevicePriorities; + } + if (s_captureDevicePriorities != u->newCaptureDevicePriorities) { + capture_changed = true; + s_captureDevicePriorities = u->newCaptureDevicePriorities; + } + + if (s_instance) { + // This wont be emitted durring the connection probe phase + // which is intensional + if (output_changed) + s_instance->emitObjectDescriptionChanged(AudioOutputDeviceType); + if (capture_changed) + s_instance->emitObjectDescriptionChanged(AudioCaptureDeviceType); + } + + // We can free the user data as we will not be called again. + delete u; + + // Some debug + logMessage(QString("Output Device Priority List:")); + for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { + Phonon::Category cat = static_cast(i); + if (s_outputDevicePriorities.contains(cat)) { + logMessage(QString(" Phonon Category %1").arg(cat)); + int count = 0; + foreach (int j, s_outputDevicePriorities[cat]) { + QHash &props = s_outputDevices[j].properties; + logMessage(QString(" %1. %2 (Available: %3)").arg(++count).arg(props["name"].toString()).arg(props["available"].toBool())); + } + } + } + logMessage(QString("Capture Device Priority List:")); + for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { + Phonon::Category cat = static_cast(i); + if (s_captureDevicePriorities.contains(cat)) { + logMessage(QString(" Phonon Category %1").arg(cat)); + int count = 0; + foreach (int j, s_captureDevicePriorities[cat]) { + QHash &props = s_captureDevices[j].properties; + logMessage(QString(" %1. %2 (Available: %3)").arg(++count).arg(props["name"].toString()).arg(props["available"].toBool())); + } + } + } + + // If this is our probe phase, exit now as we're finished reading + // our device info and can exit and reconnect + if (s_context != c) + pa_context_disconnect(c); + } + + if (!info) + return; + + Q_ASSERT(info->name); + Q_ASSERT(info->description); + Q_ASSERT(info->icon); + + // QString wrapper + QString name(info->name); + int index; + QMap > *new_prio_map_cats; // prio, device + QMap *new_devices; + + if (name.startsWith("sink:")) { + new_devices = &u->newOutputDevices; + new_prio_map_cats = &u->newOutputDevicePriorities; + + if (s_outputDeviceIndexes.contains(name)) + index = s_outputDeviceIndexes[name]; + else + index = s_outputDeviceIndexes[name] = s_deviceIndexCounter++; + } else if (name.startsWith("source:")) { + new_devices = &u->newCaptureDevices; + new_prio_map_cats = &u->newCaptureDevicePriorities; + + if (s_captureDeviceIndexes.contains(name)) + index = s_captureDeviceIndexes[name]; + else + index = s_captureDeviceIndexes[name] = s_deviceIndexCounter++; + } else { + // This indicates a bug in pulseaudio. + return; + } + + // Add the new device itself. + new_devices->insert(name, AudioDevice(name, info->description, info->icon, info->index)); + + // For each role in the priority, map it to a phonon category and store the order. + for (uint32_t i = 0; i < info->n_role_priorities; ++i) { + pa_ext_device_manager_role_priority_info* role_prio = &info->role_priorities[i]; + Q_ASSERT(role_prio->role); + + if (s_roleCategoryMap.contains(role_prio->role)) { + Phonon::Category cat = s_roleCategoryMap[role_prio->role]; + + (*new_prio_map_cats)[cat].insert(role_prio->priority, index); + } + } +} + +static void ext_device_manager_subscribe_cb(pa_context *c, void *) { + Q_ASSERT(c); + + pa_operation *o; + PulseUserData *u = new PulseUserData; + if (!(o = pa_ext_device_manager_read(c, ext_device_manager_read_cb, u))) { + logMessage(QString("pa_ext_device_manager_read() failed.")); + delete u; + return; + } + pa_operation_unref(o); +} +#endif + +void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata) { + Q_UNUSED(userdata); + Q_ASSERT(c); + + if (eol < 0) { + if (pa_context_errno(c) == PA_ERR_NOENTITY) + return; + + logMessage(QString("Sink input callback failure")); + return; + } + + if (eol > 0) + return; + + Q_ASSERT(i); + + // loop through (*i) and extract phonon->streamindex... + const char *t; + if ((t = pa_proplist_gets(i->proplist, "phonon.streamid"))) { + logMessage(QString("Found PulseAudio stream index %1 for Phonon Output Stream %2").arg(i->index).arg(t)); + s_outputStreamIndexMap[QString(t)] = i->index; + + // Find the sink's phonon index and notify whoever cares... + if (PA_INVALID_INDEX != i->sink) { + bool found = false; + int device; + QMap::iterator it; + for (it = s_outputDevices.begin(); it != s_outputDevices.end(); ++it) { + if ((*it).pulseIndex == i->sink) { + found = true; + device = it.key(); + break; + } + } + if (found) { + // OK so we just emit our signal + logMessage(QString("Letting the rest of phonon know about this")); + s_instance->emitUsingDevice(QString(t), device); + } + } + } +} + +void source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, void *userdata) { + Q_UNUSED(userdata); + Q_ASSERT(c); + + if (eol < 0) { + if (pa_context_errno(c) == PA_ERR_NOENTITY) + return; + + logMessage(QString("Source output callback failure")); + return; + } + + if (eol > 0) + return; + + Q_ASSERT(i); + + // loop through (*i) and extract phonon->streamindex... + const char *t; + if ((t = pa_proplist_gets(i->proplist, "phonon.streamid"))) { + logMessage(QString("Found PulseAudio stream index %1 for Phonon Capture Stream %2").arg(i->index).arg(t)); + s_captureStreamIndexMap[QString(t)] = i->index; + + // Find the source's phonon index and notify whoever cares... + if (PA_INVALID_INDEX != i->source) { + bool found = false; + int device; + QMap::iterator it; + for (it = s_captureDevices.begin(); it != s_captureDevices.end(); ++it) { + if ((*it).pulseIndex == i->source) { + found = true; + device = it.key(); + break; + } + } + if (found) { + // OK so we just emit our signal + logMessage(QString("Letting the rest of phonon know about this")); + s_instance->emitUsingDevice(QString(t), device); + } + } + } +} + +static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, void *userdata) { + Q_UNUSED(userdata); + + switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { + case PA_SUBSCRIPTION_EVENT_SINK_INPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + QString phononid = s_outputStreamIndexMap.key(index); + if (!phononid.isEmpty()) { + if (s_outputStreamIndexMap.contains(phononid)) { + logMessage(QString("Phonon Output Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(phononid)); + s_outputStreamIndexMap[phononid] = PA_INVALID_INDEX; + } else { + logMessage(QString("Removing Phonon Output Stream %1 (it's gone!)").arg(phononid)); + s_outputStreamIndexMap.remove(phononid); + } + } + } else { + pa_operation *o; + if (!(o = pa_context_get_sink_input_info(c, index, sink_input_cb, NULL))) { + logMessage(QString("pa_context_get_sink_input_info() failed")); + return; + } + pa_operation_unref(o); + } + break; + + case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + QString phononid = s_captureStreamIndexMap.key(index); + if (!phononid.isEmpty()) { + if (s_captureStreamIndexMap.contains(phononid)) { + logMessage(QString("Phonon Capture Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(phononid)); + s_captureStreamIndexMap[phononid] = PA_INVALID_INDEX; + } else { + logMessage(QString("Removing Phonon Capture Stream %1 (it's gone!)").arg(phononid)); + s_captureStreamIndexMap.remove(phononid); + } + } + } else { + pa_operation *o; + if (!(o = pa_context_get_source_output_info(c, index, source_output_cb, NULL))) { + logMessage(QString("pa_context_get_sink_input_info() failed")); + return; + } + pa_operation_unref(o); + } + break; + } +} + + +static const char* statename(pa_context_state_t state) +{ + switch (state) + { + case PA_CONTEXT_UNCONNECTED: return "Unconnected"; + case PA_CONTEXT_CONNECTING: return "Connecting"; + case PA_CONTEXT_AUTHORIZING: return "Authorizing"; + case PA_CONTEXT_SETTING_NAME: return "Setting Name"; + case PA_CONTEXT_READY: return "Ready"; + case PA_CONTEXT_FAILED: return "Failed"; + case PA_CONTEXT_TERMINATED: return "Terminated"; + } + + static QString unknown; + unknown = QString("Unknown state: %0").arg(state); + return unknown.toAscii().constData(); +} + +static void context_state_callback(pa_context *c, void *) +{ + Q_ASSERT(c); + + logMessage(QString("context_state_callback %1").arg(statename(pa_context_get_state(c)))); + pa_context_state_t state = pa_context_get_state(c); + if (state == PA_CONTEXT_READY) { + // We've connected to PA, so it is active + s_pulseActive = true; + + // Attempt to load things up + pa_operation *o; + + // 1. Register for the stream changes (except during probe) + if (s_context == c) { + pa_context_set_subscribe_callback(c, subscribe_cb, NULL); + + if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t) + (PA_SUBSCRIPTION_MASK_SINK_INPUT| + PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT), NULL, NULL))) { + logMessage(QString("pa_context_subscribe() failed")); + return; + } + pa_operation_unref(o); + } + +#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER + // 2a. Attempt to initialise Device Manager info (except during probe) + if (s_context == c) { + pa_ext_device_manager_set_subscribe_cb(c, ext_device_manager_subscribe_cb, NULL); + if (!(o = pa_ext_device_manager_subscribe(c, 1, NULL, NULL))) { + logMessage(QString("pa_ext_device_manager_subscribe() failed")); + return; + } + pa_operation_unref(o); + } + + // 3. Attempt to read info from Device Manager + PulseUserData *u = new PulseUserData; + if (!(o = pa_ext_device_manager_read(c, ext_device_manager_read_cb, u))) { + logMessage(QString("pa_ext_device_manager_read() failed. Attempting to continue without device manager support")); + createGenericDevices(); + delete u; + + // If this is our probe phase, exit immediately + if (s_context != c) + pa_context_disconnect(c); + + return; + } + pa_operation_unref(o); + +#else + // If we know do not have Device Manager support, we just create our dummy devices now + createGenericDevices(); + + // If this is our probe phase, exit immediately + if (s_context != c) + pa_context_disconnect(c); +#endif + } else if (!PA_CONTEXT_IS_GOOD(state)) { + /// @todo Deal with reconnection... + //logMessage("Connection to PulseAudio lost"); + + // If this is our probe phase, exit our context immediately + if (s_context != c) + pa_context_disconnect(c); + } +} +#endif // HAVE_PULSEAUDIO + + +PulseSupport* PulseSupport::getInstance() +{ + if (NULL == s_instance) { + s_instance = new PulseSupport(); + } + return s_instance; +} + +void PulseSupport::shutdown() +{ + if (NULL != s_instance) { + delete s_instance; + s_instance = NULL; + } +} + +PulseSupport::PulseSupport() + : QObject(), mEnabled(false) +{ +#ifdef HAVE_PULSEAUDIO + // Initialise our map (is there a better way to do this?) + s_roleCategoryMap["none"] = Phonon::NoCategory; + s_roleCategoryMap["video"] = Phonon::VideoCategory; + s_roleCategoryMap["music"] = Phonon::MusicCategory; + s_roleCategoryMap["game"] = Phonon::GameCategory; + s_roleCategoryMap["event"] = Phonon::NotificationCategory; + s_roleCategoryMap["phone"] = Phonon::CommunicationCategory; + //s_roleCategoryMap["animation"]; // No Mapping + //s_roleCategoryMap["production"]; // No Mapping + s_roleCategoryMap["a11y"] = Phonon::AccessibilityCategory; + + // To allow for easy debugging, give an easy way to disable this pulseaudio check + QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DISABLE"); + if (pulseenv.toInt()) { + logMessage("PulseAudio support disabled: PHONON_PULSEAUDIO_DISABLE is set"); + return; + } + + // We require a glib event loop + if (QLatin1String(QAbstractEventDispatcher::instance()->metaObject()->className()) + != "QGuiEventDispatcherGlib") { + logMessage("Disabling PulseAudio integration for lack of GLib event loop."); + return; + } + + // First of all conenct to PA via simple/blocking means and if that succeeds, + // use a fully async integrated mainloop method to connect and get proper support. + pa_mainloop *p_test_mainloop; + if (!(p_test_mainloop = pa_mainloop_new())) { + logMessage("PulseAudio support disabled: Unable to create mainloop"); + return; + } + + pa_context *p_test_context; + if (!(p_test_context = pa_context_new(pa_mainloop_get_api(p_test_mainloop), "libphonon-probe"))) { + logMessage("PulseAudio support disabled: Unable to create context"); + pa_mainloop_free(p_test_mainloop); + return; + } + + logMessage("Probing for PulseAudio..."); + // (cg) Convert to PA_CONTEXT_NOFLAGS when PulseAudio 0.9.19 is required + if (pa_context_connect(p_test_context, NULL, static_cast(0), NULL) < 0) { + logMessage(QString("PulseAudio support disabled: %1").arg(pa_strerror(pa_context_errno(p_test_context)))); + pa_context_disconnect(p_test_context); + pa_context_unref(p_test_context); + pa_mainloop_free(p_test_mainloop); + return; + } + + pa_context_set_state_callback(p_test_context, &context_state_callback, NULL); + for (;;) { + pa_mainloop_iterate(p_test_mainloop, 1, NULL); + + if (!PA_CONTEXT_IS_GOOD(pa_context_get_state(p_test_context))) { + logMessage("PulseAudio probe complete."); + break; + } + } + pa_context_disconnect(p_test_context); + pa_context_unref(p_test_context); + pa_mainloop_free(p_test_mainloop); + + if (!s_pulseActive) { + logMessage("PulseAudio support is not available."); + return; + } + + // If we're still here, PA is available. + logMessage("PulseAudio support enabled"); + + // Now we connect for real using a proper main loop that we can forget + // all about processing. + s_mainloop = pa_glib_mainloop_new(NULL); + Q_ASSERT(s_mainloop); + pa_mainloop_api *api = pa_glib_mainloop_get_api(s_mainloop); + + s_context = pa_context_new(api, "libphonon"); + // (cg) Convert to PA_CONTEXT_NOFLAGS when PulseAudio 0.9.19 is required + if (pa_context_connect(s_context, NULL, static_cast(0), 0) >= 0) + pa_context_set_state_callback(s_context, &context_state_callback, NULL); +#endif +} + +PulseSupport::~PulseSupport() +{ +#ifdef HAVE_PULSEAUDIO + if (s_context) { + pa_context_disconnect(s_context); + s_context = NULL; + } + + if (s_mainloop) { + pa_glib_mainloop_free(s_mainloop); + s_mainloop = NULL; + } +#endif +} + +bool PulseSupport::isActive() +{ +#ifdef HAVE_PULSEAUDIO + return mEnabled && s_pulseActive; +#else + return false; +#endif +} + +void PulseSupport::enable(bool enabled) +{ + mEnabled = enabled; +} + +QList PulseSupport::objectDescriptionIndexes(ObjectDescriptionType type) const +{ + QList list; + + if (type != AudioOutputDeviceType && type != AudioCaptureDeviceType) + return list; + +#ifdef HAVE_PULSEAUDIO + if (s_pulseActive) { + switch (type) { + + case AudioOutputDeviceType: { + QMap::iterator it; + for (it = s_outputDeviceIndexes.begin(); it != s_outputDeviceIndexes.end(); ++it) { + list.append(*it); + } + break; + } + case AudioCaptureDeviceType: { + QMap::iterator it; + for (it = s_captureDeviceIndexes.begin(); it != s_captureDeviceIndexes.end(); ++it) { + list.append(*it); + } + break; + } + default: + break; + } + } +#endif + + return list; +} + +QHash PulseSupport::objectDescriptionProperties(ObjectDescriptionType type, int index) const +{ + QHash ret; + + if (type != AudioOutputDeviceType && type != AudioCaptureDeviceType) + return ret; + +#ifndef HAVE_PULSEAUDIO + Q_UNUSED(index); +#else + if (s_pulseActive) { + switch (type) { + + case AudioOutputDeviceType: + Q_ASSERT(s_outputDevices.contains(index)); + ret = s_outputDevices[index].properties; + break; + + case AudioCaptureDeviceType: + Q_ASSERT(s_captureDevices.contains(index)); + ret = s_captureDevices[index].properties; + break; + + default: + break; + } + } +#endif + + return ret; +} + +QList PulseSupport::objectIndexesByCategory(ObjectDescriptionType type, Category category) const +{ + QList ret; + + if (type != AudioOutputDeviceType && type != AudioCaptureDeviceType) + return ret; + +#ifndef HAVE_PULSEAUDIO + Q_UNUSED(category); +#else + if (s_pulseActive) { + switch (type) { + + case AudioOutputDeviceType: + if (s_outputDevicePriorities.contains(category)) + ret = s_outputDevicePriorities[category].values(); + break; + + case AudioCaptureDeviceType: + if (s_captureDevicePriorities.contains(category)) + ret = s_captureDevicePriorities[category].values(); + break; + + default: + break; + } + } +#endif + + return ret; +} + +#ifdef HAVE_PULSEAUDIO +static void setDevicePriority(Category category, QStringList list) +{ + QString role = s_roleCategoryMap.key(category); + if (role.isEmpty()) + return; + + logMessage(QString("Reindexing %1: %2").arg(role).arg(list.join(", "))); + + char **devices; + devices = pa_xnew(char *, list.size()+1); + int i = 0; + foreach (QString str, list) { + devices[i++] = pa_xstrdup(str.toUtf8().constData()); + } + devices[list.size()] = NULL; + +#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER + pa_operation *o; + if (!(o = pa_ext_device_manager_reorder_devices_for_role(s_context, role.toUtf8().constData(), (const char**)devices, NULL, NULL))) + logMessage(QString("pa_ext_device_manager_reorder_devices_for_role() failed")); + else + pa_operation_unref(o); +#endif + + for (i = 0; i < list.size(); ++i) + pa_xfree(devices[i]); + pa_xfree(devices); +} +#endif + +void PulseSupport::setOutputDevicePriorityForCategory(Category category, QList order) +{ +#ifndef HAVE_PULSEAUDIO + Q_UNUSED(category); + Q_UNUSED(order); +#else + QStringList list; + QList::iterator it; + + for (it = order.begin(); it != order.end(); ++it) { + if (s_outputDevices.contains(*it)) { + list << s_outputDeviceIndexes.key(*it); + } + } + setDevicePriority(category, list); +#endif +} + +void PulseSupport::setCaptureDevicePriorityForCategory(Category category, QList order) +{ +#ifndef HAVE_PULSEAUDIO + Q_UNUSED(category); + Q_UNUSED(order); +#else + QStringList list; + QList::iterator it; + + for (it = order.begin(); it != order.end(); ++it) { + if (s_captureDevices.contains(*it)) { + list << s_captureDeviceIndexes.key(*it); + } + } + setDevicePriority(category, list); +#endif +} + +void PulseSupport::setStreamPropList(Category category, QString streamUuid) +{ +#ifndef HAVE_PULSEAUDIO + Q_UNUSED(category); + Q_UNUSED(streamUuid); +#else + QString role = s_roleCategoryMap.key(category); + if (role.isEmpty()) + return; + + logMessage(QString("Setting role to %1 for streamindex %2").arg(role).arg(streamUuid)); + setenv("PULSE_PROP_media.role", role.toLatin1().constData(), 1); + setenv("PULSE_PROP_phonon.streamid", streamUuid.toLatin1().constData(), 1); +#endif +} + +void PulseSupport::emitObjectDescriptionChanged(ObjectDescriptionType type) +{ + emit objectDescriptionChanged(type); +} + +void PulseSupport::emitUsingDevice(QString streamUuid, int device) +{ + emit usingDevice(streamUuid, device); +} + +bool PulseSupport::setOutputDevice(QString streamUuid, int device) { +#ifndef HAVE_PULSEAUDIO + Q_UNUSED(streamUuid); + Q_UNUSED(device); + return false; +#else + if (s_outputDevices.size() < 2) + return true; + + if (!s_outputDevices.contains(device)) { + logMessage(QString("Attempting to set Output Device for invalid device id %1.").arg(device)); + return false; + } + const QVariant var = s_outputDevices[device].properties["name"]; + logMessage(QString("Attempting to set Output Device to '%1' for Output Stream %2").arg(var.toString()).arg(streamUuid)); + + // Attempt to look up the pulse stream index. + if (s_outputStreamIndexMap.contains(streamUuid) && s_outputStreamIndexMap[streamUuid] != PA_INVALID_INDEX) { + logMessage(QString("... Found in map. Moving now")); + + uint32_t pulse_device_index = s_outputDevices[device].pulseIndex; + uint32_t pulse_stream_index = s_outputStreamIndexMap[streamUuid]; + + logMessage(QString("Moving Pulse Sink Input %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); + + /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db. + pa_operation* o; + if (!(o = pa_context_move_sink_input_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) { + logMessage(QString("pa_context_move_sink_input_by_index() failed")); + return false; + } + pa_operation_unref(o); + } else { + logMessage(QString("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then")); + } + return true; +#endif +} + +bool PulseSupport::setCaptureDevice(QString streamUuid, int device) { +#ifndef HAVE_PULSEAUDIO + Q_UNUSED(streamUuid); + Q_UNUSED(device); + return false; +#else + if (s_captureDevices.size() < 2) + return true; + + if (!s_captureDevices.contains(device)) { + logMessage(QString("Attempting to set Capture Device for invalid device id %1.").arg(device)); + return false; + } + const QVariant var = s_captureDevices[device].properties["name"]; + logMessage(QString("Attempting to set Capture Device to '%1' for Capture Stream %2").arg(var.toString()).arg(streamUuid)); + + // Attempt to look up the pulse stream index. + if (s_captureStreamIndexMap.contains(streamUuid) && s_captureStreamIndexMap[streamUuid] == PA_INVALID_INDEX) { + logMessage(QString("... Found in map. Moving now")); + + uint32_t pulse_device_index = s_captureDevices[device].pulseIndex; + uint32_t pulse_stream_index = s_captureStreamIndexMap[streamUuid]; + + logMessage(QString("Moving Pulse Source Output %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); + + /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db. + pa_operation* o; + if (!(o = pa_context_move_source_output_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) { + logMessage(QString("pa_context_move_source_output_by_index() failed")); + return false; + } + pa_operation_unref(o); + } else { + logMessage(QString("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then")); + } + return true; +#endif +} + +void PulseSupport::clearStreamCache(QString streamUuid) { +#ifndef HAVE_PULSEAUDIO + Q_UNUSED(streamUuid); + return; +#else + logMessage(QString("Clearing stream cache for stream %1").arg(streamUuid)); + s_outputStreamIndexMap.remove(streamUuid); + s_captureStreamIndexMap.remove(streamUuid); +#endif +} + +} // namespace Phonon + +QT_END_NAMESPACE + +#include "moc_pulsesupport.cpp" + +// vim: sw=4 ts=4 diff --git a/src/3rdparty/phonon/phonon/pulsesupport.h b/src/3rdparty/phonon/phonon/pulsesupport.h new file mode 100644 index 0000000..c38bece --- /dev/null +++ b/src/3rdparty/phonon/phonon/pulsesupport.h @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (C) 2009 Colin Guthrie + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#ifndef PHONON_PULSESUPPORT_H +#define PHONON_PULSESUPPORT_H + +#include "phonon_export.h" +#include "phononnamespace.h" +#include "objectdescription.h" + +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace Phonon +{ + class PHONON_EXPORT PulseSupport : public QObject + { + Q_OBJECT + public: + static PulseSupport* getInstance(); + static void shutdown(); + + bool isActive(); + void enable(bool enabled = true); + + QList objectDescriptionIndexes(ObjectDescriptionType type) const; + QHash objectDescriptionProperties(ObjectDescriptionType type, int index) const; + QList objectIndexesByCategory(ObjectDescriptionType type, Category category) const; + + void setOutputDevicePriorityForCategory(Category category, QList order); + void setCaptureDevicePriorityForCategory(Category category, QList order); + + void setStreamPropList(Category category, QString streamUuid); + void emitObjectDescriptionChanged(ObjectDescriptionType); + void emitUsingDevice(QString streamUuid, int device); + + bool setOutputDevice(QString streamUuid, int device); + bool setCaptureDevice(QString streamUuid, int device); + void clearStreamCache(QString streamUuid); + + signals: + void objectDescriptionChanged(ObjectDescriptionType); + void usingDevice(QString streamUuid, int device); + + private: + PulseSupport(); + ~PulseSupport(); + + bool mEnabled; + }; +} // namespace Phonon + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // PHONON_PULSESUPPORT_H diff --git a/src/3rdparty/phonon/phonon/swiftslider.cpp b/src/3rdparty/phonon/phonon/swiftslider.cpp new file mode 100644 index 0000000..1e274aa --- /dev/null +++ b/src/3rdparty/phonon/phonon/swiftslider.cpp @@ -0,0 +1,103 @@ +/* This file is part of the KDE project + Copyright (C) 2006-2008 Ricardo Villalba + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#include "swiftslider_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#if !defined(QT_NO_PHONON_SEEKSLIDER) && !defined(QT_NO_PHONON_VOLUMESLIDER) + +namespace Phonon +{ + +SwiftSlider::SwiftSlider(Qt::Orientation orientation, QWidget * parent) + : QSlider(orientation, parent) +{ +} + +SwiftSlider::~SwiftSlider() +{ +} + +// Function copied from qslider.cpp +inline int SwiftSlider::pick(const QPoint &pt) const +{ + return orientation() == Qt::Horizontal ? pt.x() : pt.y(); +} + +// Function copied from qslider.cpp and modified to make it compile +int SwiftSlider::pixelPosToRangeValue(int pos) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt); + QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); + QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + int sliderMin, sliderMax, sliderLength; + + if (orientation() == Qt::Horizontal) { + sliderLength = sr.width(); + sliderMin = gr.x(); + sliderMax = gr.right() - sliderLength + 1; + } else { + sliderLength = sr.height(); + sliderMin = gr.y(); + sliderMax = gr.bottom() - sliderLength + 1; + } + return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, + sliderMax - sliderMin, opt.upsideDown); +} + +// Based on code from qslider.cpp +void SwiftSlider::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + QStyleOptionSlider opt; + initStyleOption(&opt); + const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + const QPoint center = sliderRect.center() - sliderRect.topLeft(); + // to take half of the slider off for the setSliderPosition call we use the center - topLeft + + if (!sliderRect.contains(event->pos())) { + event->accept(); + + setSliderPosition(pixelPosToRangeValue(pick(event->pos() - center))); + triggerAction(SliderMove); + setRepeatAction(SliderNoAction); + } else { + QSlider::mousePressEvent(event); + } + } else { + QSlider::mousePressEvent(event); + } +} + +} // namespace Phonon + +#endif //QT_NO_PHONON_VOLUMESLIDER && QT_NO_PHONON_VOLUMESLIDER + +QT_END_NAMESPACE + +#include "moc_swiftslider_p.cpp" diff --git a/src/3rdparty/phonon/phonon/swiftslider_p.h b/src/3rdparty/phonon/phonon/swiftslider_p.h new file mode 100644 index 0000000..b063b47 --- /dev/null +++ b/src/3rdparty/phonon/phonon/swiftslider_p.h @@ -0,0 +1,68 @@ +/* This file is part of the KDE project + Copyright (C) 2006-2008 Ricardo Villalba + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ + +#ifndef SWIFTSLIDER_H +#define SWIFTSLIDER_H + +#include + +QT_BEGIN_NAMESPACE + +#if !defined(QT_NO_PHONON_SEEKSLIDER) && !defined(QT_NO_PHONON_VOLUMESLIDER) + +namespace Phonon +{ + +/** \class SwiftSlider swiftslider_p.h phonon/SwiftSlider + * \short Modified QSlider that allows sudden/quick moves instead of stepped moves ("Click'n'Go" QSlider) + * + * This is an internal class used by SeekSlider and VolumeSlider. + * + * Ricardo Villalba, the original author of MySlider.cpp (from the SMPlayer project) + * gave his permission for the inclusion of this code inside Phonon by + * switching MySlider.cpp to the LGPLv2.1+ license. + * See http://smplayer.svn.sourceforge.net/viewvc/smplayer/smplayer/trunk/src/myslider.cpp?revision=2406&view=markup + * + * The original discussion about a "Click'n'Go QSlider": http://lists.trolltech.com/qt-interest/2006-11/msg00363.html + * + * \ingroup PhononWidgets + */ +class SwiftSlider : public QSlider +{ + Q_OBJECT +public: + SwiftSlider(Qt::Orientation orientation, QWidget * parent); + ~SwiftSlider(); + +private: + void mousePressEvent(QMouseEvent *event); + inline int pick(const QPoint &pt) const; + int pixelPosToRangeValue(int pos) const; +}; + +} // namespace Phonon + +#endif //QT_NO_PHONON_VOLUMESLIDER && QT_NO_PHONON_VOLUMESLIDER + +QT_END_NAMESPACE + +#endif //SWIFTSLIDER_H diff --git a/src/3rdparty/phonon/qt7/mediaobject.mm b/src/3rdparty/phonon/qt7/mediaobject.mm index f8d635a..002c337 100644 --- a/src/3rdparty/phonon/qt7/mediaobject.mm +++ b/src/3rdparty/phonon/qt7/mediaobject.mm @@ -88,7 +88,7 @@ bool MediaObject::setState(Phonon::State state) emit stateChanged(m_state, prevState); if (m_state != state){ // End-application did something - // upon receiving the signal. + // upon receiving the signal. return false; } } @@ -122,7 +122,7 @@ void MediaObject::inspectGraph() // Inspect the graph to check wether there are any // effects or outputs connected. This will have // influence on the audio system and video system that ends up beeing used: - int prevVideoOutputCount = m_videoOutputCount; + int prevVideoOutputCount = m_videoOutputCount; m_audioEffectCount = 0; m_audioOutputCount = 0; m_videoEffectCount = 0; @@ -134,7 +134,7 @@ void MediaObject::inspectGraph() if (m_videoOutputCount != prevVideoOutputCount){ MediaNodeEvent e1(MediaNodeEvent::VideoOutputCountChanged, &m_videoOutputCount); notify(&e1); - } + } } void MediaObject::setupAudioSystem() @@ -167,14 +167,14 @@ void MediaObject::setupAudioSystem() if (newAudioSystem == m_audioSystem) return; - + // Enable selected audio system: - m_audioSystem = newAudioSystem; + m_audioSystem = newAudioSystem; switch (newAudioSystem){ case AS_Silent: m_audioGraph->stop(); m_videoPlayer->enableAudio(false); - m_nextVideoPlayer->enableAudio(false); + m_nextVideoPlayer->enableAudio(false); m_audioPlayer->enableAudio(false); m_nextAudioPlayer->enableAudio(false); break; @@ -260,7 +260,7 @@ void MediaObject::setSource(const MediaSource &source) return; if (!m_videoPlayer->canPlayMedia()) SET_ERROR("Cannot play media.", FATAL_ERROR) - + // The state might have changed from LoadingState // as a response to an error state change. So we // need to check it before stopping: @@ -382,7 +382,7 @@ void MediaObject::play() if (!m_videoPlayer->canPlayMedia()) return; if (!setState(Phonon::PlayingState)) - return; + return; if (m_audioSystem == AS_Graph){ m_audioGraph->start(); m_mediaObjectAudioNode->setMute(true); @@ -446,7 +446,7 @@ void MediaObject::seek(qint64 milliseconds) m_videoPlayer->seek(milliseconds); m_audioPlayer->seek(m_videoPlayer->currentTime()); m_mediaObjectAudioNode->setMute(false); - + // Update time and cancel pending swap: if (m_currentTime < m_videoPlayer->duration()) m_waitNextSwap = false; @@ -557,7 +557,7 @@ bool MediaObject::isSeekable() const qint64 MediaObject::currentTime() const { IMPLEMENTED_SILENT; - const_cast(this)->updateCurrentTime(); + const_cast(this)->updateCurrentTime(); return m_currentTime; } -- cgit v0.12 From 76267b3608836e1cc46171921caf725cfbd2ecf7 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 25 Mar 2010 10:22:53 +0100 Subject: Fix QFontMetrics::height() and QFontMetrics autotest Since the Mac font engine has been fixed to support fractional metrics, we can no longer expect qRound(A + B) to be equal to qRound(A) + qRound(B). The documentation states that height = ascent + descent + 1. To honor this contract, we need to rewrite the implementation of height() to round each metric separately. Same with lineSpacing. The bearingIncludedInBoundingrect() test was wrong. We can guarantee that the italic text is not more narrow than the normal text, but we cannot guarantee that they are never the same width. Reviewed-by: Olivier --- src/gui/text/qfontmetrics.cpp | 4 ++-- tests/auto/qfontmetrics/tst_qfontmetrics.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 13a5704..7f9ae8b 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -328,7 +328,7 @@ int QFontMetrics::height() const { QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); - return qRound(engine->ascent() + engine->descent()) + 1; + return qRound(engine->ascent()) + qRound(engine->descent()) + 1; } /*! @@ -356,7 +356,7 @@ int QFontMetrics::lineSpacing() const { QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); - return qRound(engine->leading() + engine->ascent() + engine->descent()) + 1; + return qRound(engine->leading()) + qRound(engine->ascent()) + qRound(engine->descent()) + 1; } /*! diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index 46f2b15..5d73764 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -259,7 +259,7 @@ void tst_QFontMetrics::bearingIncludedInBoundingRect() font.setItalic(false); QRect brectNormal = QFontMetrics(font).boundingRect("ITALIC"); - QVERIFY(brectItalic.width() > brectNormal.width()); + QVERIFY(brectItalic.width() >= brectNormal.width()); } QTEST_MAIN(tst_QFontMetrics) -- cgit v0.12 From 8f601bf85748ca62344c5dbaef2f3dd941a16466 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 25 Mar 2010 10:32:49 +0100 Subject: Fix QLabel::sizeHint() The QTextControl case of QLabel calculated the bounding rect of the label by taking the size of the control (floating point) and using toSize() to convert this to an integer QSize. While this would work when the font engine always returned integer values, it is not the correct way to calculate a bounding rect, since the bounding rect needs to contain all the pixels of the text, including the ones that are only partially covered, thus its size should never be rounded down. Reviewed-by: Olivier --- src/gui/widgets/qlabel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index b81f04f..bdbd0b0 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -53,6 +53,7 @@ #include #include "qlabel_p.h" #include "private/qstylesheetstyle_p.h" +#include QT_BEGIN_NAMESPACE @@ -661,7 +662,9 @@ QSize QLabelPrivate::sizeForWidth(int w) const } else { control->setTextWidth(-1); } - br = QRect(QPoint(0, 0), control->size().toSize()); + + QSizeF controlSize = control->size(); + br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height()))); // restore state control->setTextWidth(oldTextWidth); -- cgit v0.12 From 114ccb234d875b5680e54fd828195a00267f6ee1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 25 Mar 2010 10:44:39 +0100 Subject: stabilize tst_QTreeView::taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint --- tests/auto/qtreeview/tst_qtreeview.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index da99368..6871982 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -3723,7 +3723,9 @@ public: { QCOMPARE(event->rect(), viewport()->rect()); QTreeView::paintEvent(event); + painted++; } + int painted; }; void tst_QTreeView::taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint() @@ -3736,12 +3738,16 @@ void tst_QTreeView::taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint() view.setUniformRowHeights(true); view.setModel(&model); view.resize(800, 800); + view.painted = 0; view.show(); QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(view.painted > 0); QTest::qWait(100); // This one is needed to make the test fail before the patch. + view.painted = 0; model.setData(model.index(0, 5), QVariant(QSize(100,100)), Qt::SizeHintRole); QTest::qWait(100); + QTRY_VERIFY(view.painted > 0); } QTEST_MAIN(tst_QTreeView) -- cgit v0.12 From e38aef4eee8c6a32bd30632576aee17a3d333c2e Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 11 Mar 2010 13:27:17 +0100 Subject: Doc: Fix links in the ActiveQt framework, and also link to the tools. --- doc/src/frameworks-technologies/activeqt.qdoc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/src/frameworks-technologies/activeqt.qdoc b/doc/src/frameworks-technologies/activeqt.qdoc index 67b9bb3..5e8473f 100644 --- a/doc/src/frameworks-technologies/activeqt.qdoc +++ b/doc/src/frameworks-technologies/activeqt.qdoc @@ -57,6 +57,7 @@ \brief An overview of Qt's ActiveX and COM integration on Windows. \ingroup platform-specific + \ingroup frameworks-technologies \keyword ActiveQt Qt's ActiveX and COM support allows Qt for Windows developers to: @@ -69,19 +70,23 @@ controls. \endlist - The ActiveQt framework consists of two modules: + The ActiveQt framework consists of two frameworks: \list - \o The \l QAxContainer module is a static - library implementing QObject and QWidget subclasses, QAxObject and - QAxWidget, that act as containers for COM objects and ActiveX - controls. - \o The \l QAxServer module is a static library that implements + \o The \l{Using ActiveX controls and COM objects in Qt}{QAxContainer} + module is a static library implementing QObject and QWidget subclasses, + QAxObject and QAxWidget, that act as containers for COM objects and + ActiveX controls. + \o The \l{Building ActiveX servers and controls with Qt}{QAxServer} + module is a static library that implements functionality for in-process and executable COM servers. This module provides the QAxAggregated, QAxBindable and QAxFactory classes. \endlist + A set of \l{Tools for ActiveQt}{tools} is provided to simplify the + developing and building of Qt projects that use ActiveX. + To build the static libraries, change into the \c activeqt directory (usually \c QTDIR/src/activeqt), and run \c qmake and your make tool in both the \c container and the \c control subdirectory. -- cgit v0.12 From 3eed4c454a58b38c895925b74e47a0b1b747df80 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 25 Mar 2010 11:48:44 +0100 Subject: itemChange() is now called when transformation properties change. When changing transformation properties (i.e., setRotation(), setScale(), setTransformOriginPoint()), itemChange() is now called to allow notification and change of the values. The flag ItemSendsGeometryChanges needs to be set to enable this. Autotest included. Task-number: QTBUG-8112 Reviewed-by: alexis --- src/gui/graphicsview/qgraphicsitem.cpp | 127 ++++++++++++++++++++++++- src/gui/graphicsview/qgraphicsitem.h | 8 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 81 +++++++++++++++- 3 files changed, 209 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 948ff28..66b262c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -381,7 +381,9 @@ \value ItemSendsGeometryChanges The item enables itemChange() notifications for ItemPositionChange, ItemPositionHasChanged, - ItemMatrixChange, ItemTransformChange, and ItemTransformHasChanged. For + ItemMatrixChange, ItemTransformChange, ItemTransformHasChanged, + ItemRotationChange, ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged, + ItemTransformOriginPointChange, and ItemTransformOriginPointHasChanged. For performance reasons, these notifications are disabled by default. You must enable this flag to receive notifications for position and transform changes. This flag was introduced in Qt 4.6. @@ -475,6 +477,52 @@ (same as transform()), and QGraphicsItem ignores the return value for this notification (i.e., a read-only notification). + \value ItemRotationChange The item's rotation property changes. This + notification is sent if the ItemSendsGeometryChanges flag is enabled, and + when the item's rotation property changes (i.e., as a result of calling + setRotation()). The value argument is the new rotation (i.e., a double); + to get the old rotation, call rotation(). Do not call setRotation() in + itemChange() as this notification is delivered; instead, you can return + the new rotation from itemChange(). + + \value ItemRotationHasChanged The item's rotation property has changed. + This notification is sent if the ItemSendsGeometryChanges flag is enabled, + and after the item's rotation property has changed. The value argument is + the new rotation (i.e., a double), and QGraphicsItem ignores the return + value for this notification (i.e., a read-only notification). Do not call + setRotation() in itemChange() as this notification is delivered. + + \value ItemScaleChange The item's scale property changes. This notification + is sent if the ItemSendsGeometryChanges flag is enabled, and when the item's + scale property changes (i.e., as a result of calling setScale()). The value + argument is the new scale (i.e., a double); to get the old scale, call + scale(). Do not call setScale() in itemChange() as this notification is + delivered; instead, you can return the new scale from itemChange(). + + \value ItemScaleHasChanged The item's scale property has changed. This + notification is sent if the ItemSendsGeometryChanges flag is enabled, and + after the item's scale property has changed. The value argument is the new + scale (i.e., a double), and QGraphicsItem ignores the return value for this + notification (i.e., a read-only notification). Do not call setScale() in + itemChange() as this notification is delivered. + + \value ItemTransformOriginPointChange The item's transform origin point + property changes. This notification is sent if the ItemSendsGeometryChanges + flag is enabled, and when the item's transform origin point property changes + (i.e., as a result of calling setTransformOriginPoint()). The value argument + is the new origin point (i.e., a QPointF); to get the old origin point, call + transformOriginPoint(). Do not call setTransformOriginPoint() in itemChange() + as this notification is delivered; instead, you can return the new transform + origin point from itemChange(). + + \value ItemTransformOriginPointHasChanged The item's transform origin point + property has changed. This notification is sent if the ItemSendsGeometryChanges + flag is enabled, and after the item's transform origin point property has + changed. The value argument is the new origin point (i.e., a QPointF), and + QGraphicsItem ignores the return value for this notification (i.e., a read-only + notification). Do not call setTransformOriginPoint() in itemChange() as this + notification is delivered. + \value ItemSelectedChange The item's selected state changes. If the item is presently selected, it will become unselected, and vice verca. The value argument is the new selected state (i.e., true or false). Do not call @@ -3722,12 +3770,28 @@ qreal QGraphicsItem::rotation() const void QGraphicsItem::setRotation(qreal angle) { prepareGeometryChange(); + qreal newRotation = angle; + + if (d_ptr->flags & ItemSendsGeometryChanges) { + // Notify the item that the rotation is changing. + const QVariant newRotationVariant(itemChange(ItemRotationChange, angle)); + newRotation = newRotationVariant.toReal(); + } + if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->rotation = angle; + + if (d_ptr->transformData->rotation == newRotation) + return; + + d_ptr->transformData->rotation = newRotation; d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; + // Send post-notification. + if (d_ptr->flags & ItemSendsGeometryChanges) + itemChange(ItemRotationHasChanged, newRotation); + if (d_ptr->isObject) emit static_cast(this)->rotationChanged(); } @@ -3770,12 +3834,28 @@ qreal QGraphicsItem::scale() const void QGraphicsItem::setScale(qreal factor) { prepareGeometryChange(); + qreal newScale = factor; + + if (d_ptr->flags & ItemSendsGeometryChanges) { + // Notify the item that the scale is changing. + const QVariant newScaleVariant(itemChange(ItemScaleChange, factor)); + newScale = newScaleVariant.toReal(); + } + if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->scale = factor; + + if (d_ptr->transformData->scale == newScale) + return; + + d_ptr->transformData->scale = newScale; d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; + // Send post-notification. + if (d_ptr->flags & ItemSendsGeometryChanges) + itemChange(ItemScaleHasChanged, newScale); + if (d_ptr->isObject) emit static_cast(this)->scaleChanged(); } @@ -3877,12 +3957,31 @@ QPointF QGraphicsItem::transformOriginPoint() const void QGraphicsItem::setTransformOriginPoint(const QPointF &origin) { prepareGeometryChange(); + QPointF newOrigin = origin; + + if (d_ptr->flags & ItemSendsGeometryChanges) { + // Notify the item that the origin point is changing. + const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange, + qVariantFromValue(origin))); + newOrigin = newOriginVariant.toPointF(); + } + if (!d_ptr->transformData) d_ptr->transformData = new QGraphicsItemPrivate::TransformData; - d_ptr->transformData->xOrigin = origin.x(); - d_ptr->transformData->yOrigin = origin.y(); + + if (d_ptr->transformData->xOrigin == newOrigin.x() + && d_ptr->transformData->yOrigin == newOrigin.y()) { + return; + } + + d_ptr->transformData->xOrigin = newOrigin.x(); + d_ptr->transformData->yOrigin = newOrigin.y(); d_ptr->transformData->onlyTransform = false; d_ptr->dirtySceneTransform = 1; + + // Send post-notification. + if (d_ptr->flags & ItemSendsGeometryChanges) + itemChange(ItemTransformOriginPointHasChanged, qVariantFromValue(newOrigin)); } /*! @@ -11072,6 +11171,24 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change) case QGraphicsItem::ItemScenePositionHasChanged: str = "ItemScenePositionHasChanged"; break; + case QGraphicsItem::ItemRotationChange: + str = "ItemRotationChange"; + break; + case QGraphicsItem::ItemRotationHasChanged: + str = "ItemRotationHasChanged"; + break; + case QGraphicsItem::ItemScaleChange: + str = "ItemScaleChange"; + break; + case QGraphicsItem::ItemScaleHasChanged: + str = "ItemScaleHasChanged"; + break; + case QGraphicsItem::ItemTransformOriginPointChange: + str = "ItemTransformOriginPointChange"; + break; + case QGraphicsItem::ItemTransformOriginPointHasChanged: + str = "ItemTransformOriginPointHasChanged"; + break; } debug << str; return debug; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 56f94a2..117113f 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -139,7 +139,13 @@ public: ItemZValueHasChanged, ItemOpacityChange, ItemOpacityHasChanged, - ItemScenePositionHasChanged + ItemScenePositionHasChanged, + ItemRotationChange, + ItemRotationHasChanged, + ItemScaleChange, + ItemScaleHasChanged, + ItemTransformOriginPointChange, + ItemTransformOriginPointHasChanged }; enum CacheMode { diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 92a7f2e..b408ba2 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4316,6 +4316,21 @@ protected: break; case QGraphicsItem::ItemScenePositionHasChanged: break; + case QGraphicsItem::ItemRotationChange: + oldValues << rotation(); + break; + case QGraphicsItem::ItemRotationHasChanged: + break; + case QGraphicsItem::ItemScaleChange: + oldValues << scale(); + break; + case QGraphicsItem::ItemScaleHasChanged: + break; + case QGraphicsItem::ItemTransformOriginPointChange: + oldValues << transformOriginPoint(); + break; + case QGraphicsItem::ItemTransformOriginPointHasChanged: + break; } return itemChangeReturnValue.isValid() ? itemChangeReturnValue : value; } @@ -4412,6 +4427,48 @@ void tst_QGraphicsItem::itemChange() QCOMPARE(tester.zValue(), qreal(2.0)); } { + // ItemRotationChange / ItemRotationHasChanged + tester.itemChangeReturnValue = qreal(15.0); + tester.setRotation(10.0); + ++changeCount; // notification sent too + ++changeCount; + QCOMPARE(tester.changes.size(), changeCount); + QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemRotationChange); + QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemRotationHasChanged); + QCOMPARE(tester.values.at(tester.changes.size() - 2), QVariant(qreal(10.0))); + QCOMPARE(tester.values.at(tester.changes.size() - 1), QVariant(qreal(15.0))); + QCOMPARE(tester.oldValues.last(), QVariant(qreal(0.0))); + QCOMPARE(tester.rotation(), qreal(15.0)); + } + { + // ItemScaleChange / ItemScaleHasChanged + tester.itemChangeReturnValue = qreal(2.0); + tester.setScale(1.5); + ++changeCount; // notification sent too + ++changeCount; + QCOMPARE(tester.changes.size(), changeCount); + QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemScaleChange); + QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemScaleHasChanged); + QCOMPARE(tester.values.at(tester.changes.size() - 2), QVariant(qreal(1.5))); + QCOMPARE(tester.values.at(tester.changes.size() - 1), QVariant(qreal(2.0))); + QCOMPARE(tester.oldValues.last(), QVariant(qreal(1.0))); + QCOMPARE(tester.scale(), qreal(2.0)); + } + { + // ItemTransformOriginPointChange / ItemTransformOriginPointHasChanged + tester.itemChangeReturnValue = QPointF(2.0, 2.0); + tester.setTransformOriginPoint(1.0, 1.0); + ++changeCount; // notification sent too + ++changeCount; + QCOMPARE(tester.changes.size(), changeCount); + QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemTransformOriginPointChange); + QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemTransformOriginPointHasChanged); + QCOMPARE(tester.values.at(tester.changes.size() - 2), QVariant(QPointF(1.0, 1.0))); + QCOMPARE(tester.values.at(tester.changes.size() - 1), QVariant(QPointF(2.0, 2.0))); + QCOMPARE(tester.oldValues.last(), QVariant(QPointF(0.0, 0.0))); + QCOMPARE(tester.transformOriginPoint(), QPointF(2.0, 2.0)); + } + { // ItemFlagsChange tester.itemChangeReturnValue = QGraphicsItem::ItemIsSelectable; tester.setFlag(QGraphicsItem::ItemIsSelectable, false); @@ -7385,10 +7442,19 @@ void tst_QGraphicsItem::itemSendsGeometryChanges() QTransform x = QTransform().rotate(45); QPointF pos(10, 10); qreal o(0.5); + qreal r(10.0); + qreal s(1.5); + QPointF origin(1.0, 1.0); item.setTransform(x); item.setPos(pos); + item.setRotation(r); + item.setScale(s); + item.setTransformOriginPoint(origin); QCOMPARE(item.transform(), x); QCOMPARE(item.pos(), pos); + QCOMPARE(item.rotation(), r); + QCOMPARE(item.scale(), s); + QCOMPARE(item.transformOriginPoint(), origin); QCOMPARE(item.changes.size(), 0); item.setOpacity(o); @@ -7402,6 +7468,13 @@ void tst_QGraphicsItem::itemSendsGeometryChanges() QCOMPARE(item.transform(), QTransform()); QCOMPARE(item.pos(), QPointF()); QCOMPARE(item.opacity(), o); + item.setRotation(0.0); + item.setScale(1.0); + item.setTransformOriginPoint(0.0, 0.0); + QCOMPARE(item.changes.size(), 14); // rotation + scale + origin + QCOMPARE(item.rotation(), qreal(0.0)); + QCOMPARE(item.scale(), qreal(1.0)); + QCOMPARE(item.transformOriginPoint(), QPointF(0.0, 0.0)); QCOMPARE(item.changes, QList() << QGraphicsItem::ItemOpacityChange @@ -7411,7 +7484,13 @@ void tst_QGraphicsItem::itemSendsGeometryChanges() << QGraphicsItem::ItemTransformChange << QGraphicsItem::ItemTransformHasChanged << QGraphicsItem::ItemPositionChange - << QGraphicsItem::ItemPositionHasChanged); + << QGraphicsItem::ItemPositionHasChanged + << QGraphicsItem::ItemRotationChange + << QGraphicsItem::ItemRotationHasChanged + << QGraphicsItem::ItemScaleChange + << QGraphicsItem::ItemScaleHasChanged + << QGraphicsItem::ItemTransformOriginPointChange + << QGraphicsItem::ItemTransformOriginPointHasChanged); } // Make sure we update moved items correctly. -- cgit v0.12 From 80cf88a395d61c2dee83d484c91f24437be0c0e0 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Thu, 25 Mar 2010 12:50:48 +0200 Subject: QMessageBox is smaller than native MessageBox Messageboxes are smaller than native ones. This is due to that native ones have a lot of empty space. To fix this, we define a new custom pixel metrics that is the minimum height of one text line messagebox (aka AknPopUp) on the native side. Then we ensure that the QMessageBox is at least of this height. Additionally we do some minor styling for QMessageBox: - the corners graphics are now as rounded as on native side - the font is set to match the native side - the top margin space is doubled for dialogs, which is rather good approximation of native side Task-number: QTBUG-4875 Reviewed-by: Janne Anttila --- src/gui/dialogs/qmessagebox.cpp | 14 ++++++++++++++ src/gui/styles/qs60style.cpp | 35 +++++++++++++++++++++------------- src/gui/styles/qs60style.h | 3 ++- src/gui/styles/qs60style_p.h | 6 +++--- src/gui/styles/qs60style_s60.cpp | 16 ++++++++++------ util/s60pixelmetrics/pixel_metrics.cpp | 11 +++++++++-- util/s60pixelmetrics/pixel_metrics.h | 4 +++- util/s60pixelmetrics/pm_mapperapp.cpp | 9 ++++++--- 8 files changed, 69 insertions(+), 29 deletions(-) diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index bd2df9c..ccc925c 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -65,6 +65,10 @@ #include #include +#ifndef QT_NO_STYLE_S60 +#include +#endif + #ifdef Q_WS_WINCE extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp extern bool qt_wince_is_smartphone();//defined in qguifunctions_wince.cpp @@ -353,6 +357,16 @@ void QMessageBoxPrivate::updateSize() int height = (layout->hasHeightForWidth()) ? layout->totalHeightForWidth(width) : layout->totalMinimumSize().height(); + +#ifndef QT_NO_STYLE_S60 + QS60Style *s60Style = 0; + s60Style = qobject_cast(QApplication::style()); + + //use custom pixel metric to deduce the minimum height of the messagebox + if (s60Style) + height = qMax(height, s60Style->pixelMetric((QStyle::PixelMetric)PM_MessageBoxHeight)); +#endif + q->setFixedSize(width, height); QCoreApplication::removePostedEvents(q, QEvent::LayoutRequest); } diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index af37e6e..2c665fb 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -50,6 +50,7 @@ #include "qcalendarwidget.h" #include "qdial.h" #include "qdialog.h" +#include "qmessagebox.h" #include "qgroupbox.h" #include "qheaderview.h" #include "qlist.h" @@ -91,10 +92,10 @@ static const qreal goldenRatio = 1.618; const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { // *** generated layout data *** -{240,320,1,16,"QVGA Landscape"}, -{320,240,1,16,"QVGA Portrait"}, -{360,640,1,16,"NHD Landscape"}, -{640,360,1,16,"NHD Portrait"}, +{240,320,1,17,"QVGA Landscape"}, +{320,240,1,17,"QVGA Portrait"}, +{360,640,1,17,"NHD Landscape"}, +{640,360,1,17,"NHD Portrait"}, {352,800,1,12,"E90 Landscape"} // *** End of generated data *** }; @@ -103,11 +104,11 @@ const int QS60StylePrivate::m_numberOfLayouts = const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** -{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,0,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, -{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,0,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,0,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,0,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,0,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} +{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,0,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1, 106}, +{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,0,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1, 106}, +{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,0,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1, 135}, +{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,0,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1, 135}, +{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,0,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1, 106} // *** End of generated data *** }; @@ -126,7 +127,7 @@ const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameEleme {SE_ButtonPressed, QS60StyleEnums::SP_QsnFrButtonTbCenterPressed}, {SE_FrameLineEdit, QS60StyleEnums::SP_QsnFrInputCenter}, {SE_ListHighlight, QS60StyleEnums::SP_QsnFrListCenter}, - {SE_OptionsMenu, QS60StyleEnums::SP_QsnFrPopupCenter}, + {SE_PopupBackground, QS60StyleEnums::SP_QsnFrPopupCenter}, {SE_SettingsList, QS60StyleEnums::SP_QsnFrSetOptCenter}, {SE_TableItem, QS60StyleEnums::SP_QsnFrCaleCenter}, {SE_TableHeaderItem, QS60StyleEnums::SP_QsnFrCaleHeadingCenter}, @@ -249,8 +250,8 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter, case SE_ListHighlight: drawFrame(SF_ListHighlight, painter, rect, flags | SF_PointNorth); break; - case SE_OptionsMenu: - drawFrame(SF_OptionsMenu, painter, rect, flags | SF_PointNorth); + case SE_PopupBackground: + drawFrame(SF_PopupBackground, painter, rect, flags | SF_PointNorth); break; case SE_SettingsList: drawFrame(SF_SettingsList, painter, rect, flags | SF_PointNorth); @@ -636,6 +637,8 @@ void QS60StylePrivate::setFont(QWidget *widget) const fontCategory = QS60StyleEnums::FC_Secondary; } else if (qobject_cast(widget)){ fontCategory = QS60StyleEnums::FC_Title; + } else if (qobject_cast(widget)){ + fontCategory = QS60StyleEnums::FC_Primary; } if (fontCategory != QS60StyleEnums::FC_Undefined) { const bool resolveFontSize = widget->testAttribute(Qt::WA_SetFont) @@ -2215,7 +2218,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) && option->palette.window().texture().cacheKey() == QS60StylePrivate::m_themePalette->window().texture().cacheKey()) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_OptionsMenu, painter, option->rect, flags); + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, option->rect, flags); else commonStyleDraws = true; } @@ -2400,6 +2403,12 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const else if (metric == PM_LayoutRightMargin) metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin); } + + if (widget && (metric == PM_LayoutTopMargin)) + if (widget->windowType() == Qt::Dialog) + //double the top layout margin for dialogs, it is very close to real value + //without having to define custom pixel metric + metricValue *= 2; return metricValue; } diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h index af17843..c878538 100644 --- a/src/gui/styles/qs60style.h +++ b/src/gui/styles/qs60style.h @@ -58,7 +58,8 @@ enum { PM_FrameCornerWidth = QStyle::PM_CustomBase + 1, PM_FrameCornerHeight, PM_BoldLineWidth, - PM_ThinLineWidth + PM_ThinLineWidth, + PM_MessageBoxHeight }; class QS60StylePrivate; diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 8bb2f7b..6ce4960 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE const int MAX_NON_CUSTOM_PIXELMETRICS = 92; -const int CUSTOMVALUESCOUNT = 4; +const int CUSTOMVALUESCOUNT = 5; const int MAX_PIXELMETRICS = MAX_NON_CUSTOM_PIXELMETRICS + CUSTOMVALUESCOUNT; @@ -411,7 +411,7 @@ public: SE_TabBarTabWestActive, SE_TabBarTabWestInactive, SE_ListHighlight, - SE_OptionsMenu, + SE_PopupBackground, SE_SettingsList, SE_TableItem, SE_TableHeaderItem, @@ -432,7 +432,7 @@ public: SF_ButtonPressed, SF_FrameLineEdit, SF_ListHighlight, - SF_OptionsMenu, + SF_PopupBackground, SF_SettingsList, SF_TableItem, SF_TableHeaderItem, diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 75ed0c7..1138d20 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -983,16 +983,20 @@ TRect QS60StyleModeSpecifics::innerRectFromElement(QS60StylePrivate::SkinFrameEl switch(frameElement) { case QS60StylePrivate::SF_PanelBackground: // panel should have slightly slimmer border to enable thin line of background graphics between closest component - widthShrink = widthShrink-2; - heightShrink = heightShrink-2; + widthShrink = widthShrink - 2; + heightShrink = heightShrink - 2; break; case QS60StylePrivate::SF_ToolTip: - widthShrink = widthShrink>>1; - heightShrink = heightShrink>>1; + widthShrink = widthShrink >> 1; + heightShrink = heightShrink >> 1; break; case QS60StylePrivate::SF_ListHighlight: - widthShrink = widthShrink-2; - heightShrink = heightShrink-2; + widthShrink = widthShrink - 2; + heightShrink = heightShrink - 2; + break; + case QS60StylePrivate::SF_PopupBackground: + widthShrink = widthShrink + 5; + heightShrink = heightShrink + 5; break; default: break; diff --git a/util/s60pixelmetrics/pixel_metrics.cpp b/util/s60pixelmetrics/pixel_metrics.cpp index beb785e..814e185 100644 --- a/util/s60pixelmetrics/pixel_metrics.cpp +++ b/util/s60pixelmetrics/pixel_metrics.cpp @@ -50,7 +50,7 @@ // so that we can keep dynamic and static values inline. // Please adjust version data if correcting dynamic PM calculations. const TInt KPMMajorVersion = 1; -const TInt KPMMinorVersion = 16; +const TInt KPMMinorVersion = 17; TPixelMetricsVersion PixelMetrics::Version() { @@ -869,7 +869,7 @@ TInt PixelMetrics::PixelMetricValue(QStyle::PixelMetric metric) // The difference of center piece from border tell the frame width. if ( value == QStyle::PM_FocusFrameHMargin) { - //use topleft for horizontal as S60 uses different values for right and left borders + //use topleft for horizontal as S60 uses different values for right and left borders value = listSinglePaneText.TextRect().iTl.iX - highlightRect.Rect().iTl.iX; } else @@ -1003,6 +1003,13 @@ TInt PixelMetrics::PixelMetricValue(QStyle::PixelMetric metric) case QStyle::PM_Custom_ThinLineWidth: value = 1; break; + case QStyle::PM_Custom_MessageBoxHeight: + { + TAknLayoutRect popupRect; + popupRect.LayoutRect(mainPaneRect, AknLayoutScalable_Avkon::popup_window_general(0)); + value = popupRect.Rect().Height(); + } + break; case QStyle::PM_ButtonShiftHorizontal: case QStyle::PM_ButtonShiftVertical: value = 0; diff --git a/util/s60pixelmetrics/pixel_metrics.h b/util/s60pixelmetrics/pixel_metrics.h index 3536c0e..4b0f57e 100644 --- a/util/s60pixelmetrics/pixel_metrics.h +++ b/util/s60pixelmetrics/pixel_metrics.h @@ -185,7 +185,9 @@ NONSHARABLE_CLASS( QStyle ) // Bold line width PM_Custom_BoldLineWidth, // Thin line width - PM_Custom_ThinLineWidth + PM_Custom_ThinLineWidth, + // Height of a popup info messagebox + PM_Custom_MessageBoxHeight }; }; diff --git a/util/s60pixelmetrics/pm_mapperapp.cpp b/util/s60pixelmetrics/pm_mapperapp.cpp index acc6137..a88499d 100644 --- a/util/s60pixelmetrics/pm_mapperapp.cpp +++ b/util/s60pixelmetrics/pm_mapperapp.cpp @@ -155,7 +155,7 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) Exit(); break; case ECmdSwitchOutput: - { + { HBufC* buffer = HBufC::NewLC( 100 ); TPtr bufferPtr = buffer->Des(); TBool last = ETrue; @@ -166,7 +166,7 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) else bufferPtr.Append(_L("screen.")); ShowL( *buffer, last ); - } + } break; case ECmdStatus: { @@ -323,7 +323,7 @@ void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand ) TInt myValue = KErrNotFound; for (;;) { - if (index==QStyle::PM_Custom_ThinLineWidth) + if (index==QStyle::PM_Custom_MessageBoxHeight) { last = ETrue; } @@ -656,6 +656,9 @@ void CPixelMetricsMapperAppUi::ShowSingleValueL(TInt& aPixelMetric, TInt& aValue case QStyle::PM_Custom_BoldLineWidth: bufferPtr.Append(_L("C_BoldLineWidth: ")); break; + case QStyle::PM_Custom_MessageBoxHeight: + bufferPtr.Append(_L("C_MsgBoxHeight: ")); + break; default: bufferPtr.Append(_L("Default: ")); break; -- cgit v0.12 From d7fe2d90fe5a1ac5a29a5bc65eb5657d4d539563 Mon Sep 17 00:00:00 2001 From: mread Date: Thu, 25 Mar 2010 10:58:57 +0000 Subject: Symbian event loop priority drop not used in Symbian^4 The priority drop hack used in the Symbian version of Qt's event dispatcher is not needed from Symbian^4, as the viewsrv panics, which it was designed to prevent, are disabled. This change disables the priority drop code when Qt is compiled in a Symbian^4 environment, using the SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS define as a key. This will improve system and performance predictability, as app priorities will be more stable. It also gives a slight performance boost to app startup in the order of 10ms. Reviewed-by: Jason Barron --- src/corelib/kernel/qeventdispatcher_symbian.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 191be6c..ca44264 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -50,6 +50,13 @@ QT_BEGIN_NAMESPACE +#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS +// when the system UI is Qt based, priority drop is not needed as CPU starved processes will not be killed. +#undef QT_SYMBIAN_PRIORITY_DROP +#else +#define QT_SYMBIAN_PRIORITY_DROP +#endif + #define WAKE_UP_PRIORITY CActive::EPriorityStandard #define TIMER_PRIORITY CActive::EPriorityHigh #define NULLTIMER_PRIORITY CActive::EPriorityLow @@ -697,6 +704,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla bool handledSymbianEvent = false; m_interrupt = false; +#ifdef QT_SYMBIAN_PRIORITY_DROP /* * This QTime variable is used to measure the time it takes to finish * the event loop. If we take too long in the loop, other processes @@ -714,6 +722,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla } timeState = FirstRun; TProcessPriority priority; +#endif while (1) { if (block) { @@ -727,10 +736,12 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla CActiveScheduler::Current()->WaitForAnyRequest(); } +#ifdef QT_SYMBIAN_PRIORITY_DROP if (timeState == SubsequentRun) { time.start(); timeState = TimeStarted; } +#endif TInt error; handledSymbianEvent = CActiveScheduler::RunIfReady(error, KMinTInt); @@ -747,6 +758,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla break; } block = false; +#ifdef QT_SYMBIAN_PRIORITY_DROP if (timeState == TimeStarted && time.elapsed() > 100) { priority = m_processHandle.Priority(); m_processHandle.SetPriority(EPriorityBackground); @@ -759,6 +771,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla } if (timeState == FirstRun) timeState = SubsequentRun; +#endif }; emit awake(); -- cgit v0.12 From ea0b7da7f5c206c436999b35bc2b55fb8863ecfe Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 25 Mar 2010 12:18:42 +0100 Subject: Fix glyph advance on Mac/Carbon Device metrics was turned on for Mac/Carbon to work around a bug in WebKit that required the font engine to report only integer values. This in turn caused positioning of glyphs to be slightly off compared to native applications. The bug has been fixed in WebKit, so now we can turn off the device metrics flag. Since we are now reporting fractional values as well, we need to round the numbers when the ForceIntegerMetrics style strategy flag is set. Task-number: qtbug-5529 Reviewed-by: Trond --- src/gui/text/qfontengine_mac.mm | 53 +++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index fd662e3..3f84544 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -816,6 +817,7 @@ struct QGlyphLayoutInfo int *mappedFonts; QTextEngine::ShaperFlags flags; QFontEngineMacMulti::ShaperItem *shaperItem; + unsigned int styleStrategy; }; static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATSULineRef lineRef, URefCon refCon, @@ -885,6 +887,11 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS QFixed yAdvance = FixedToQFixed(baselineDeltas[glyphIdx]); QFixed xAdvance = FixedToQFixed(layoutData[glyphIdx + 1].realPos - layoutData[glyphIdx].realPos); + if (nfo->styleStrategy & QFont::ForceIntegerMetrics) { + yAdvance = yAdvance.ceil(); + xAdvance = xAdvance.ceil(); + } + if (glyphId != 0xffff || i == 0) { if (i < nfo->glyphs->numGlyphs) { @@ -1061,6 +1068,7 @@ bool QFontEngineMacMulti::stringToCMapInternal(const QChar *str, int len, QGlyph nfo.callbackCalled = false; nfo.flags = flags; nfo.shaperItem = shaperItem; + nfo.styleStrategy = fontDef.styleStrategy; int prevNumGlyphs = *nglyphs; @@ -1090,8 +1098,6 @@ bool QFontEngineMacMulti::stringToCMapInternal(const QChar *str, int len, QGlyph | kATSLineDisableAllJustification ; - layopts |= kATSLineUseDeviceMetrics; - if (fontDef.styleStrategy & QFont::NoAntialias) layopts |= kATSLineNoAntiAliasing; @@ -1395,14 +1401,22 @@ void QFontEngineMac::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla for (int i = 0; i < glyphs->numGlyphs; ++i) { glyphs->advances_x[i] = QFixed::fromReal(metrics[i].deviceAdvance.x); glyphs->advances_y[i] = QFixed::fromReal(metrics[i].deviceAdvance.y); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + glyphs->advances_x[i] = glyphs->advances_x[i].ceil(); + glyphs->advances_y[i] = glyphs->advances_y[i].ceil(); + } } } glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs) { QFixed w; - for (int i = 0; i < glyphs.numGlyphs; ++i) - w += glyphs.effectiveAdvance(i); + for (int i = 0; i < glyphs.numGlyphs; ++i) { + w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? glyphs.effectiveAdvance(i).ceil() + : glyphs.effectiveAdvance(i); + } return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0); } @@ -1427,39 +1441,58 @@ glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph) gm.xoff = QFixed::fromReal(metrics.deviceAdvance.x); gm.yoff = QFixed::fromReal(metrics.deviceAdvance.y); + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + gm.x = gm.x.floor(); + gm.y = gm.y.floor(); + gm.xoff = gm.xoff.ceil(); + gm.yoff = gm.yoff.ceil(); + } + return gm; } QFixed QFontEngineMac::ascent() const { - return m_ascent; + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? m_ascent.ceil() + : m_ascent; } QFixed QFontEngineMac::descent() const { // subtract a pixel to even out the historical +1 in QFontMetrics::height(). // Fix in Qt 5. - return m_descent - 1; + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? m_descent.ceil() - 1 + : m_descent; } QFixed QFontEngineMac::leading() const { - return m_leading; + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? m_leading.ceil() + : m_leading; } qreal QFontEngineMac::maxCharWidth() const { - return m_maxCharWidth; + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? qCeil(m_maxCharWidth) + : m_maxCharWidth; } QFixed QFontEngineMac::xHeight() const { - return m_xHeight; + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? m_xHeight.ceil() + : m_xHeight; } QFixed QFontEngineMac::averageCharWidth() const { - return m_averageCharWidth; + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? m_averageCharWidth.ceil() + : m_averageCharWidth; } static void addGlyphsToPathHelper(ATSUStyle style, glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path) -- cgit v0.12 From 32c6e01bf00bc45363685eb10c51e8b68b4fde89 Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Thu, 25 Mar 2010 14:01:34 +0200 Subject: Fix for submenu placement for QMenus in Symbian. Task-number: QTBUG-5992 Reviewed-By: Sami Merila --- src/gui/styles/qs60style.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 2c665fb..65191a4 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2389,13 +2389,6 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const if (metricValue == KNotFound) metricValue = QCommonStyle::pixelMetric(metric, option, widget); - if (metric == PM_SubMenuOverlap && widget) { - const QMenu *menu = qobject_cast(widget); - if (menu && menu->activeAction() && menu->activeAction()->menu()) { - const int menuWidth = menu->activeAction()->menu()->sizeHint().width(); - metricValue = -menuWidth; - } - } //if layout direction is mirrored, switch left and right border margins if (option && option->direction == Qt::RightToLeft) { if (metric == PM_LayoutLeftMargin) -- cgit v0.12 From a81b5cf5b4e5388f3bda2aa8c4855d9a1b0bba28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Thu, 25 Mar 2010 13:31:16 +0100 Subject: Fixed QPrintPreview text drawing (visible in Assistant). WebKit (which Assistant uses) uses QFont::setPixelSize() to specify the font sizes. Those are treated differently in Qt than fonts specified with setPointSize(). Fonts specified with setPixelSize() should *not* be scaled to compensate for DPI changes between devices, unlike fonts with a pointSize() set. Task-number: QTBUG-9282 Reviewed-by: Eskil --- src/gui/image/qpicture.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 3220a67..45b3ed0 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -651,7 +651,12 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) s >> dbl; QFont fnt(font, painter->device()); - qreal scale = painter->device()->logicalDpiY() / (dbl*qt_defaultDpiY()); + // Fonts that specify a pixel size should not be scaled - QPicture already + // have a matrix set to compensate for the DPI differences between the + // default Qt DPI and the actual target device DPI, and we have to take that + // into consideration in the case where the font has a pixel size set. + + qreal scale = fnt.pointSize() == -1 ? 1 : painter->device()->logicalDpiY() / (dbl*qt_defaultDpiY()); painter->save(); painter->scale(1/scale, 1/scale); @@ -660,7 +665,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int flags = Qt::TextSingleLine | Qt::TextDontClip | Qt::TextForceLeftToRight; - QSizeF size(scale, scale); + QSizeF size(1, 1); if (justificationWidth > 0) { size.setWidth(justificationWidth*scale); flags |= Qt::TextJustificationForced; -- cgit v0.12 From 70f8e3ed2fea750a6a0fd7e08b10330a04eda6a0 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 25 Mar 2010 13:10:30 +0100 Subject: cetest build fix for TCP sync connection Reviewed-by: mauricek --- tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp | 21 +++++++++++++++++++++ tools/qtestlib/wince/cetest/cetcpsyncconnection.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp b/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp index 99219f3..5494194 100644 --- a/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp @@ -198,3 +198,24 @@ bool CeTcpSyncConnection::fileCreationTime(const QString &fileName, FILETIME* de file.remove(); return result; } + +bool CeTcpSyncConnection::resetDevice() +{ + qWarning("CeTcpSyncConnection::resetDevice not implemented"); + return false; +} + +bool CeTcpSyncConnection::toggleDevicePower(int *returnValue) +{ + Q_UNUSED(returnValue); + qWarning("CeTcpSyncConnection::toggleDevicePower not implemented"); + return false; +} + +bool CeTcpSyncConnection::setDeviceAwake(bool activate, int *returnValue) +{ + Q_UNUSED(activate); + Q_UNUSED(returnValue); + qWarning("CeTcpSyncConnection::setDeviceAwake not implemented"); + return false; +} diff --git a/tools/qtestlib/wince/cetest/cetcpsyncconnection.h b/tools/qtestlib/wince/cetest/cetcpsyncconnection.h index 77539cc..e603efc 100644 --- a/tools/qtestlib/wince/cetest/cetcpsyncconnection.h +++ b/tools/qtestlib/wince/cetest/cetcpsyncconnection.h @@ -75,6 +75,9 @@ public: bool createDirectory(const QString&, bool deleteBefore=false); bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL); + bool resetDevice(); + bool toggleDevicePower(int *returnValue = NULL); + bool setDeviceAwake(bool activate, int *returnValue = NULL); private: bool connected; }; -- cgit v0.12 From bd5d323373dbaf9d827126b77895da253128c1e5 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 25 Mar 2010 13:42:52 +0100 Subject: cetest build fix Introducing a new define for building qmake without generators. QT_BUILD_QMAKE_NO_GENERATORS is used for cetest and the qmake COM wrapper of the Visual Studio Add-in. Reviewed-by: mauricek --- qmake/project.cpp | 2 ++ tools/qtestlib/wince/cetest/cetest.pro | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index 9e6db10..01a3843 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1507,6 +1507,7 @@ QMakeProject::read(uchar cmd) void QMakeProject::validateModes() { +#if !defined(QT_BUILD_QMAKE_NO_GENERATORS) if (Option::host_mode == Option::HOST_UNKNOWN_MODE || Option::target_mode == Option::TARG_UNKNOWN_MODE) { Option::HOST_MODE host_mode; @@ -1543,6 +1544,7 @@ void QMakeProject::validateModes() } } } +#endif // !defined(QT_BUILD_QMAKE_NO_GENERATORS) } bool diff --git a/tools/qtestlib/wince/cetest/cetest.pro b/tools/qtestlib/wince/cetest/cetest.pro index 2773fe4..4f0baab 100644 --- a/tools/qtestlib/wince/cetest/cetest.pro +++ b/tools/qtestlib/wince/cetest/cetest.pro @@ -13,7 +13,8 @@ DEFINES += QT_BUILD_QMAKE QT_BOOTSTRAPPED QT_NO_CODECS QT_LITE_UNICODE QT QT_NO_STL QT_NO_COMPRESS QT_NO_DATASTREAM \ QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_NO_THREAD \ QT_NO_SYSTEMLOCALE QT_NO_GEOM_VARIANT \ - QT_NODLL QT_NO_QOBJECT + QT_NODLL QT_NO_QOBJECT \ + QT_BUILD_QMAKE_NO_GENERATORS INCLUDEPATH = \ $$QT_SOURCE_TREE/tools/qtestlib/ce/cetest \ -- cgit v0.12 From 1e6c23469ea78f6ff5a3a546c08ae22a5ba79356 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Mar 2010 14:06:42 +0100 Subject: Fixes a deadlock with streaming in Phonon. Deadlock can occur with certain DirectShow filters when stopping a streamed video. Task-number: QTBUG-8420 Merge-request: 2317 Reviewed-by: Pierre Rossi Reviewed-by: Thierry Bastian --- src/3rdparty/phonon/ds9/iodevicereader.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index 695af59..d706c82 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -107,9 +107,6 @@ namespace Phonon HRESULT read(LONGLONG pos, LONG length, BYTE *buffer, LONG *actual) { Q_ASSERT(!m_mutex.tryLock()); - if (m_mediaGraph->isStopping()) { - return VFW_E_WRONG_STATE; - } if(m_size != 1 && pos + length > m_size) { //it tries to read outside of the boundaries @@ -128,9 +125,6 @@ namespace Phonon int oldSize = m_buffer.size(); while (m_buffer.size() < int(length)) { needData(); - if (m_mediaGraph->isStopping()) { - return VFW_E_WRONG_STATE; - } if (oldSize == m_buffer.size()) { break; //we didn't get any data -- cgit v0.12 From 96ac1964b827ef01ef2edb6411ecb7540ed76ce2 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 25 Mar 2010 14:27:56 +0100 Subject: Prevents a useless repaint with QGraphicsItem cache mode. No repaint is triggered anymore when setting the cache mode to DeviceCoordinateMode when already using that mode. Also added an autotest for checking repaints when setting cache modes. Task-number: QTBUG-9391 Reviewed-by: ahanssen --- src/gui/graphicsview/qgraphicsitem.cpp | 3 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 73 ++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index f110a5c..1b707b0 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1883,7 +1883,8 @@ void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize) d_ptr->cacheMode = mode; bool noVisualChange = (mode == NoCache && lastMode == NoCache) || (mode == NoCache && lastMode == DeviceCoordinateCache) - || (mode == DeviceCoordinateCache && lastMode == NoCache); + || (mode == DeviceCoordinateCache && lastMode == NoCache) + || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache); if (mode == NoCache) { d_ptr->removeExtraItemCache(); } else { diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 75fb337..2b507cb 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -384,6 +384,7 @@ private slots: void tabChangesFocus(); void tabChangesFocus_data(); void cacheMode(); + void cacheMode2(); void updateCachedItemAfterMove(); void deviceTransform_data(); void deviceTransform(); @@ -6926,6 +6927,78 @@ void tst_QGraphicsItem::cacheMode() QCOMPARE(testerChild2->repaints, 6); } +void tst_QGraphicsItem::cacheMode2() +{ + QGraphicsScene scene(0, 0, 100, 100); + QGraphicsView view(&scene); + view.resize(150, 150); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + + // Increase the probability of window activation + // not causing another repaint of test items. + QTest::qWait(50); + + EventTester *tester = new EventTester; + scene.addItem(tester); + QTest::qWait(10); + QTRY_COMPARE(tester->repaints, 1); + + // Switching from NoCache to NoCache (no repaint) + tester->setCacheMode(QGraphicsItem::NoCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 1); + + // Switching from NoCache to DeviceCoordinateCache (no repaint) + tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 1); + + // Switching from DeviceCoordinateCache to DeviceCoordinateCache (no repaint) + tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 1); + + // Switching from DeviceCoordinateCache to NoCache (no repaint) + tester->setCacheMode(QGraphicsItem::NoCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 1); + + // Switching from NoCache to ItemCoordinateCache (repaint) + tester->setCacheMode(QGraphicsItem::ItemCoordinateCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 2); + + // Switching from ItemCoordinateCache to ItemCoordinateCache (no repaint) + tester->setCacheMode(QGraphicsItem::ItemCoordinateCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 2); + + // Switching from ItemCoordinateCache to ItemCoordinateCache with different size (repaint) + tester->setCacheMode(QGraphicsItem::ItemCoordinateCache, QSize(100, 100)); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 3); + + // Switching from ItemCoordinateCache to NoCache (repaint) + tester->setCacheMode(QGraphicsItem::NoCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 4); + + // Switching from DeviceCoordinateCache to ItemCoordinateCache (repaint) + tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 4); + tester->setCacheMode(QGraphicsItem::ItemCoordinateCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 5); + + // Switching from ItemCoordinateCache to DeviceCoordinateCache (repaint) + tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + QTest::qWait(50); + QTRY_COMPARE(tester->repaints, 6); +} + void tst_QGraphicsItem::updateCachedItemAfterMove() { // A simple item that uses ItemCoordinateCache -- cgit v0.12 From 9a11225c71748ccd6ff7e5a3c1f8d8670e699ca8 Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Thu, 25 Mar 2010 14:32:10 +0100 Subject: Correct documentation for ObjectReplacementCharacter and ReplacementCh. Reviewed-by: Marius Storm-Olsen --- src/corelib/tools/qchar.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index 08cb863..3635e7b 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -381,8 +381,12 @@ QT_BEGIN_NAMESPACE \value Null A QChar with this value isNull(). \value Nbsp Non-breaking space. - \value ReplacementCharacter - \value ObjectReplacementCharacter The character shown when a font has no glyph for a certain codepoint. The square character is normally used. + \value ReplacementCharacter The character shown when a font has no glyph + for a certain codepoint. A special question mark character is often + used. Codecs use this codepoint when input data cannot be + represented in Unicode. + \value ObjectReplacementCharacter Used to represent an object such as an + image when such objects cannot be presented. \value ByteOrderMark \value ByteOrderSwapped \value ParagraphSeparator -- cgit v0.12 From 656c02f128c56177c48b3de47f7b1e17dbbfa4d3 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 25 Mar 2010 14:52:53 +0100 Subject: QNAM HTTP: Fix crazy crash when exiting application This fixes a crash in tst_qnetworkreply and in some QtWebKit based browsers. It was related to adding a QPointer on an already deleted QHttpNetworkConnection object. By converting an existing normal pointer to a QPointer we set it a 0-pointer and are safe. https://bugs.webkit.org/show_bug.cgi?id=36290 Reviewed-by: joao Reviewed-by: gabi --- src/network/access/qhttpnetworkconnectionchannel.cpp | 2 +- src/network/access/qhttpnetworkconnectionchannel_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 82bc14f..0804498 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -939,7 +939,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket errorCode = QNetworkReply::UnknownNetworkError; break; } - QPointer that = connection; + QPointer that = connection; QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString()); if (send2Reply) { if (reply) { diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 5032d2b..6ec47c1 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -138,7 +138,7 @@ public: {} void setConnection(QHttpNetworkConnection *c) {connection = c;} - QHttpNetworkConnection *connection; + QPointer connection; void init(); void close(); -- cgit v0.12 From dfbabeca0cb8a9efdb6758c228700eeb5996652c Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 25 Mar 2010 15:52:04 +0100 Subject: Fix warnings and build on mingw --- examples/graphicsview/weatheranchorlayout/main.cpp | 11 +- examples/script/qstetrix/tetrixboard.cpp | 13 +- examples/script/qstetrix/tetrixboard.h | 10 +- src/gui/widgets/qlinecontrol_p.h | 611 +++++---------------- src/multimedia/audio/qaudiooutput_win32_p.cpp | 2 +- src/plugins/imageformats/tiff/qtiffhandler.cpp | 4 +- tools/qdoc3/generator.cpp | 4 +- tools/qdoc3/node.cpp | 6 +- 8 files changed, 164 insertions(+), 497 deletions(-) diff --git a/examples/graphicsview/weatheranchorlayout/main.cpp b/examples/graphicsview/weatheranchorlayout/main.cpp index aa06476..391fdd8 100644 --- a/examples/graphicsview/weatheranchorlayout/main.cpp +++ b/examples/graphicsview/weatheranchorlayout/main.cpp @@ -97,6 +97,8 @@ protected: case Qt::MaximumSize: sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); break; + default: + break; } return sh; } @@ -167,15 +169,6 @@ private: }; -static QGraphicsProxyWidget *createItem(const QString &name = "Unnamed") -{ - QGraphicsProxyWidget *w = new QGraphicsProxyWidget; - w->setWidget(new QPushButton(name)); - w->setData(0, name); - w->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - return w; -} - int main(int argc, char **argv) { Q_INIT_RESOURCE(weatheranchorlayout); diff --git a/examples/script/qstetrix/tetrixboard.cpp b/examples/script/qstetrix/tetrixboard.cpp index 7d44c4c..f35740d 100644 --- a/examples/script/qstetrix/tetrixboard.cpp +++ b/examples/script/qstetrix/tetrixboard.cpp @@ -54,7 +54,12 @@ TetrixBoard::TetrixBoard(QWidget *parent) void TetrixBoard::setNextPieceLabel(QWidget *label) { - nextPieceLabel = qobject_cast(label); + nextPieceLbl = qobject_cast(label); +} + +QLabel *TetrixBoard::nextPieceLabel() const +{ + return nextPieceLbl; } QObject *TetrixBoard::getTimer() @@ -82,16 +87,16 @@ void TetrixBoard::keyPressEvent(QKeyEvent *event) void TetrixBoard::showNextPiece(int width, int height) { - if (!nextPieceLabel) + if (!nextPieceLabel()) return; QPixmap pixmap(width * squareWidth(), height * squareHeight()); QPainter painter(&pixmap); - painter.fillRect(pixmap.rect(), nextPieceLabel->palette().background()); + painter.fillRect(pixmap.rect(), nextPieceLabel()->palette().background()); emit paintNextPieceRequested(&painter); - nextPieceLabel->setPixmap(pixmap); + nextPieceLabel()->setPixmap(pixmap); } void TetrixBoard::drawPauseScreen(QPainter *painter) diff --git a/examples/script/qstetrix/tetrixboard.h b/examples/script/qstetrix/tetrixboard.h index 7a04317..781ec39 100644 --- a/examples/script/qstetrix/tetrixboard.h +++ b/examples/script/qstetrix/tetrixboard.h @@ -45,21 +45,19 @@ #include #include #include - -QT_BEGIN_NAMESPACE -class QLabel; -QT_END_NAMESPACE +#include class TetrixBoard : public QFrame { Q_OBJECT Q_PROPERTY(QObject* timer READ getTimer) - Q_PROPERTY(QWidget* nextPieceLabel WRITE setNextPieceLabel) + Q_PROPERTY(QWidget* nextPieceLabel READ nextPieceLabel WRITE setNextPieceLabel) public: TetrixBoard(QWidget *parent = 0); void setNextPieceLabel(QWidget *label); + QLabel *nextPieceLabel() const; void setBoardWidth(int width); void setBoardHeight(int height); QSize minimumSizeHint() const; @@ -95,7 +93,7 @@ private: int squareHeight() { return contentsRect().height() / BoardHeight; } QTimer *timer; - QPointer nextPieceLabel; + QPointer nextPieceLbl; QImage image; }; diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index dd82581..5da1831 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -94,136 +94,207 @@ public: delete [] m_maskData; } - int nextMaskBlank(int pos); - int prevMaskBlank(int pos); + int nextMaskBlank(int pos) + { + int c = findInMask(pos, true, false); + m_separator |= (c != pos); + return (c != -1 ? c : m_maxLength); + } + + int prevMaskBlank(int pos) + { + int c = findInMask(pos, false, false); + m_separator |= (c != pos); + return (c != -1 ? c : 0); + } + + bool isUndoAvailable() const { return !m_readOnly && m_undoState; } + bool isRedoAvailable() const { return !m_readOnly && m_undoState < (int)m_history.size(); } + void clearUndo() { m_history.clear(); m_modifiedState = m_undoState = 0; } - bool isUndoAvailable() const; - bool isRedoAvailable() const; - void clearUndo(); - bool isModified() const; - void setModified(bool modified); + bool isModified() const { return m_modifiedState != m_undoState; } + void setModified(bool modified) { m_modifiedState = modified ? -1 : m_undoState; } - bool allSelected() const; - bool hasSelectedText() const; + bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); } + bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; } - int width() const; - int height() const; - int ascent() const; - qreal naturalTextWidth() const; + int width() const { return qRound(m_textLayout.lineAt(0).width()) + 1; } + int height() const { return qRound(m_textLayout.lineAt(0).height()) + 1; } + int ascent() const { return m_ascent; } + qreal naturalTextWidth() const { return m_textLayout.lineAt(0).naturalTextWidth(); } void setSelection(int start, int length); - QString selectedText() const; - QString textBeforeSelection() const; - QString textAfterSelection() const; + inline QString selectedText() const { return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); } + QString textBeforeSelection() const { return hasSelectedText() ? m_text.left(m_selstart) : QString(); } + QString textAfterSelection() const { return hasSelectedText() ? m_text.mid(m_selend) : QString(); } - int selectionStart() const; - int selectionEnd() const; - bool inSelection(int x) const; + int selectionStart() const { return hasSelectedText() ? m_selstart : -1; } + int selectionEnd() const { return hasSelectedText() ? m_selend : -1; } + bool inSelection(int x) const + { + if (m_selstart >= m_selend) + return false; + int pos = xToPos(x, QTextLine::CursorOnCharacter); + return pos >= m_selstart && pos < m_selend; + } - void removeSelection(); + void removeSelection() + { + int priorState = m_undoState; + removeSelectedText(); + finishChange(priorState); + } - int start() const; - int end() const; + int start() const { return 0; } + int end() const { return m_text.length(); } #ifndef QT_NO_CLIPBOARD void copy(QClipboard::Mode mode = QClipboard::Clipboard) const; void paste(QClipboard::Mode mode = QClipboard::Clipboard); #endif - int cursor() const; - int preeditCursor() const; + int cursor() const{ return m_cursor; } + int preeditCursor() const { return m_preeditCursor; } + + int cursorWidth() const { return m_cursorWidth; } + void setCursorWidth(int value) { m_cursorWidth = value; } - int cursorWidth() const; - void setCursorWidth(int value); void moveCursor(int pos, bool mark = false); - void cursorForward(bool mark, int steps); - void cursorWordForward(bool mark); - void cursorWordBackward(bool mark); - void home(bool mark); - void end(bool mark); + void cursorForward(bool mark, int steps) + { + int c = m_cursor; + if (steps > 0) { + while (steps--) + c = m_textLayout.nextCursorPosition(c); + } else if (steps < 0) { + while (steps++) + c = m_textLayout.previousCursorPosition(c); + } + moveCursor(c, mark); + } + + void cursorWordForward(bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); } + void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); } + + void home(bool mark) { moveCursor(0, mark); } + void end(bool mark) { moveCursor(text().length(), mark); } int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const; QRect cursorRect() const; - qreal cursorToX(int cursor) const; - qreal cursorToX() const; - - bool isReadOnly() const; - void setReadOnly(bool enable); + qreal cursorToX(int cursor) const { return m_textLayout.lineAt(0).cursorToX(cursor); } + qreal cursorToX() const + { + int cursor = m_cursor; + if (m_preeditCursor != -1) + cursor += m_preeditCursor; + return cursorToX(cursor); + } - QString text() const; - void setText(const QString &txt); + bool isReadOnly() const { return m_readOnly; } + void setReadOnly(bool enable) { m_readOnly = enable; } - QString displayText() const; + QString text() const + { + QString res = m_maskData ? stripString(m_text) : m_text; + return (res.isNull() ? QString::fromLatin1("") : res); + } + void setText(const QString &txt) { internalSetText(txt, -1, false); } + QString displayText() const { return m_textLayout.text(); } void backspace(); void del(); - void deselect(); - void selectAll(); + void deselect() { internalDeselect(); finishChange(); } + void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); } + void insert(const QString &); void clear(); - void undo(); - void redo(); + void undo() { internalUndo(); finishChange(-1, true); } + void redo() { internalRedo(); finishChange(); } void selectWordAtPos(int); - uint echoMode() const; - void setEchoMode(uint mode); + uint echoMode() const { return m_echoMode; } + void setEchoMode(uint mode) + { + m_echoMode = mode; + m_passwordEchoEditing = false; + updateDisplayText(); + } - void setMaxLength(int maxLength); - int maxLength() const; + int maxLength() const { return m_maxLength; } + void setMaxLength(int maxLength) + { + if (m_maskData) + return; + m_maxLength = maxLength; + setText(m_text); + } #ifndef QT_NO_VALIDATOR - const QValidator *validator() const; - void setValidator(const QValidator *); + const QValidator *validator() const { return m_validator; } + void setValidator(const QValidator *v) { m_validator = const_cast(v); } #endif #ifndef QT_NO_COMPLETER - QCompleter *completer() const; - void setCompleter(const QCompleter*); + QCompleter *completer() const { return m_completer; } + /* Note that you must set the widget for the completer seperately */ + void setCompleter(const QCompleter *c) { m_completer = const_cast(c); } void complete(int key); #endif - void setCursorPosition(int pos); - int cursorPosition() const; + int cursorPosition() const { return m_cursor; } + void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); } - bool hasAcceptableInput() const; + bool hasAcceptableInput() const { return hasAcceptableInput(m_text); } bool fixup(); - QString inputMask() const; - void setInputMask(const QString &mask); + QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); } + void setInputMask(const QString &mask) + { + parseInputMask(mask); + if (m_maskData) + moveCursor(nextMaskBlank(0)); + } // input methods #ifndef QT_NO_IM - bool composeMode() const; - void setPreeditArea(int cursor, const QString &text); + bool composeMode() const { return !m_textLayout.preeditAreaText().isEmpty(); } + void setPreeditArea(int cursor, const QString &text) { m_textLayout.setPreeditArea(cursor, text); } #endif - QString preeditAreaText() const; + QString preeditAreaText() const { return m_textLayout.preeditAreaText(); } void updatePasswordEchoEditing(bool editing); - bool passwordEchoEditing() const; + bool passwordEchoEditing() const { return m_passwordEchoEditing; } - QChar passwordCharacter() const; - void setPasswordCharacter(const QChar &character); + QChar passwordCharacter() const { return m_passwordCharacter; } + void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); } - Qt::LayoutDirection layoutDirection() const; - void setLayoutDirection(Qt::LayoutDirection direction); - void setFont(const QFont &font); + Qt::LayoutDirection layoutDirection() const { return m_layoutDirection; } + void setLayoutDirection(Qt::LayoutDirection direction) + { + if (direction != m_layoutDirection) { + m_layoutDirection = direction; + updateDisplayText(); + } + } + + void setFont(const QFont &font) { m_textLayout.setFont(font); updateDisplayText(); } void processInputMethodEvent(QInputMethodEvent *event); void processMouseEvent(QMouseEvent* ev); void processKeyEvent(QKeyEvent* ev); - int cursorBlinkPeriod() const; + int cursorBlinkPeriod() const { return m_blinkPeriod; } void setCursorBlinkPeriod(int msec); - QString cancelText() const; - void setCancelText(const QString &text); + QString cancelText() const { return m_cancelText; } + void setCancelText(const QString &text) { m_cancelText = text; } - const QPalette &palette() const; - void setPalette(const QPalette &); + const QPalette &palette() const { return m_palette; } + void setPalette(const QPalette &p) { m_palette = p; } enum DrawFlags { DrawText = 0x01, @@ -363,406 +434,6 @@ private Q_SLOTS: }; -inline int QLineControl::nextMaskBlank(int pos) -{ - int c = findInMask(pos, true, false); - m_separator |= (c != pos); - return (c != -1 ? c : m_maxLength); -} - -inline int QLineControl::prevMaskBlank(int pos) -{ - int c = findInMask(pos, false, false); - m_separator |= (c != pos); - return (c != -1 ? c : 0); -} - -inline bool QLineControl::isUndoAvailable() const -{ - return !m_readOnly && m_undoState; -} - -inline bool QLineControl::isRedoAvailable() const -{ - return !m_readOnly && m_undoState < (int)m_history.size(); -} - -inline void QLineControl::clearUndo() -{ - m_history.clear(); - m_modifiedState = m_undoState = 0; -} - -inline bool QLineControl::isModified() const -{ - return m_modifiedState != m_undoState; -} - -inline void QLineControl::setModified(bool modified) -{ - m_modifiedState = modified ? -1 : m_undoState; -} - -inline bool QLineControl::allSelected() const -{ - return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); -} - -inline bool QLineControl::hasSelectedText() const -{ - return !m_text.isEmpty() && m_selend > m_selstart; -} - -inline int QLineControl::width() const -{ - return qRound(m_textLayout.lineAt(0).width()) + 1; -} - -inline qreal QLineControl::naturalTextWidth() const -{ - return m_textLayout.lineAt(0).naturalTextWidth(); -} - -inline int QLineControl::height() const -{ - return qRound(m_textLayout.lineAt(0).height()) + 1; -} - -inline int QLineControl::ascent() const -{ - return m_ascent; -} - -inline QString QLineControl::selectedText() const -{ - if (hasSelectedText()) - return m_text.mid(m_selstart, m_selend - m_selstart); - return QString(); -} - -inline QString QLineControl::textBeforeSelection() const -{ - if (hasSelectedText()) - return m_text.left(m_selstart); - return QString(); -} - -inline QString QLineControl::textAfterSelection() const -{ - if (hasSelectedText()) - return m_text.mid(m_selend); - return QString(); -} - -inline int QLineControl::selectionStart() const -{ - return hasSelectedText() ? m_selstart : -1; -} - -inline int QLineControl::selectionEnd() const -{ - return hasSelectedText() ? m_selend : -1; -} - -inline int QLineControl::start() const -{ - return 0; -} - -inline int QLineControl::end() const -{ - return m_text.length(); -} - -inline void QLineControl::removeSelection() -{ - int priorState = m_undoState; - removeSelectedText(); - finishChange(priorState); -} - -inline bool QLineControl::inSelection(int x) const -{ - if (m_selstart >= m_selend) - return false; - int pos = xToPos(x, QTextLine::CursorOnCharacter); - return pos >= m_selstart && pos < m_selend; -} - -inline int QLineControl::cursor() const -{ - return m_cursor; -} - -inline int QLineControl::preeditCursor() const -{ - return m_preeditCursor; -} - -inline int QLineControl::cursorWidth() const -{ - return m_cursorWidth; -} - -inline void QLineControl::setCursorWidth(int value) -{ - m_cursorWidth = value; -} - -inline void QLineControl::cursorForward(bool mark, int steps) -{ - int c = m_cursor; - if (steps > 0) { - while (steps--) - c = m_textLayout.nextCursorPosition(c); - } else if (steps < 0) { - while (steps++) - c = m_textLayout.previousCursorPosition(c); - } - moveCursor(c, mark); -} - -inline void QLineControl::cursorWordForward(bool mark) -{ - moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); -} - -inline void QLineControl::home(bool mark) -{ - moveCursor(0, mark); -} - -inline void QLineControl::end(bool mark) -{ - moveCursor(text().length(), mark); -} - -inline void QLineControl::cursorWordBackward(bool mark) -{ - moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); -} - -inline qreal QLineControl::cursorToX(int cursor) const -{ - return m_textLayout.lineAt(0).cursorToX(cursor); -} - -inline qreal QLineControl::cursorToX() const -{ - int cursor = m_cursor; - if (m_preeditCursor != -1) - cursor += m_preeditCursor; - return cursorToX(cursor); -} - -inline bool QLineControl::isReadOnly() const -{ - return m_readOnly; -} - -inline void QLineControl::setReadOnly(bool enable) -{ - m_readOnly = enable; -} - -inline QString QLineControl::text() const -{ - QString res = m_maskData ? stripString(m_text) : m_text; - return (res.isNull() ? QString::fromLatin1("") : res); -} - -inline void QLineControl::setText(const QString &txt) -{ - internalSetText(txt, -1, false); -} - -inline QString QLineControl::displayText() const -{ - return m_textLayout.text(); -} - -inline void QLineControl::deselect() -{ - internalDeselect(); - finishChange(); -} - -inline void QLineControl::selectAll() -{ - m_selstart = m_selend = m_cursor = 0; - moveCursor(m_text.length(), true); -} - -inline void QLineControl::undo() -{ - internalUndo(); - finishChange(-1, true); -} - -inline void QLineControl::redo() -{ - internalRedo(); - finishChange(); -} - -inline uint QLineControl::echoMode() const -{ - return m_echoMode; -} - -inline void QLineControl::setEchoMode(uint mode) -{ - m_echoMode = mode; - m_passwordEchoEditing = false; - updateDisplayText(); -} - -inline void QLineControl::setMaxLength(int maxLength) -{ - if (m_maskData) - return; - m_maxLength = maxLength; - setText(m_text); -} - -inline int QLineControl::maxLength() const -{ - return m_maxLength; -} - -#ifndef QT_NO_VALIDATOR -inline const QValidator *QLineControl::validator() const -{ - return m_validator; -} - -inline void QLineControl::setValidator(const QValidator *v) -{ - m_validator = const_cast(v); -} -#endif - -#ifndef QT_NO_COMPLETER -inline QCompleter *QLineControl::completer() const -{ - return m_completer; -} - -/* Note that you must set the widget for the completer seperately */ -inline void QLineControl::setCompleter(const QCompleter* c) -{ - m_completer = const_cast(c); -} -#endif - -inline void QLineControl::setCursorPosition(int pos) -{ - if (pos < 0) - pos = 0; - if (pos <= m_text.length()) - moveCursor(pos); -} - -inline int QLineControl::cursorPosition() const -{ - return m_cursor; -} - -inline bool QLineControl::hasAcceptableInput() const -{ - return hasAcceptableInput(m_text); -} - -inline QString QLineControl::inputMask() const -{ - return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); -} - -inline void QLineControl::setInputMask(const QString &mask) -{ - parseInputMask(mask); - if (m_maskData) - moveCursor(nextMaskBlank(0)); -} - -// input methods -#ifndef QT_NO_IM -inline bool QLineControl::composeMode() const -{ - return !m_textLayout.preeditAreaText().isEmpty(); -} - -inline void QLineControl::setPreeditArea(int cursor, const QString &text) -{ - m_textLayout.setPreeditArea(cursor, text); -} -#endif - -inline QString QLineControl::preeditAreaText() const -{ - return m_textLayout.preeditAreaText(); -} - -inline bool QLineControl::passwordEchoEditing() const -{ - return m_passwordEchoEditing; -} - -inline QChar QLineControl::passwordCharacter() const -{ - return m_passwordCharacter; -} - -inline void QLineControl::setPasswordCharacter(const QChar &character) -{ - m_passwordCharacter = character; - updateDisplayText(); -} - -inline Qt::LayoutDirection QLineControl::layoutDirection() const -{ - return m_layoutDirection; -} - -inline void QLineControl::setLayoutDirection(Qt::LayoutDirection direction) -{ - if (direction != m_layoutDirection) { - m_layoutDirection = direction; - updateDisplayText(); - } -} - -inline void QLineControl::setFont(const QFont &font) -{ - m_textLayout.setFont(font); - updateDisplayText(); -} - -inline int QLineControl::cursorBlinkPeriod() const -{ - return m_blinkPeriod; -} - -inline QString QLineControl::cancelText() const -{ - return m_cancelText; -} - -inline void QLineControl::setCancelText(const QString &text) -{ - m_cancelText = text; -} - -inline const QPalette & QLineControl::palette() const -{ - return m_palette; -} - -inline void QLineControl::setPalette(const QPalette &p) -{ - m_palette = p; -} - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp index ab8da53..4bcbd09 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.cpp +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -88,7 +88,7 @@ QAudioOutputPrivate::~QAudioOutputPrivate() DeleteCriticalSection(&waveOutCriticalSection); } -void QT_WIN_CALLBACK QAudioOutputPrivate::waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, +void CALLBACK QAudioOutputPrivate::waveOutProc( HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) { Q_UNUSED(dwParam1) diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index 31e0c92..619aa4e 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -385,8 +385,8 @@ static bool checkGrayscale(const QVector &colorTable) const bool increasing = (colorTable.at(0) == 0xff000000); for (int i = 0; i < 256; ++i) { - if (increasing && colorTable.at(i) != qRgb(i, i, i) - || !increasing && colorTable.at(i) != qRgb(255 - i, 255 - i, 255 - i)) + if ((increasing && colorTable.at(i) != qRgb(i, i, i)) + || (!increasing && colorTable.at(i) != qRgb(255 - i, 255 - i, 255 - i))) return false; } return true; diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 0c6497b..0e90615 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -1194,12 +1194,12 @@ void Generator::appendSortedQmlNames(Text& text, QMap classMap; int index = 0; -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE qDebug() << "Generator::appendSortedQmlNames():" << base->name() << "is inherited by..."; #endif for (int i = 0; i < subs.size(); ++i) { Text t; -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE qDebug() << " " << subs[i]->name(); #endif appendFullName(t, subs[i], base, marker); diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index d60ff73..0d27937 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -1297,7 +1297,7 @@ QmlClassNode::QmlClassNode(InnerNode *parent, */ QmlClassNode::~QmlClassNode() { -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE qDebug() << "Deleting QmlClassNode:" << name(); #endif } @@ -1334,7 +1334,7 @@ QString QmlClassNode::fileBase() const void QmlClassNode::addInheritedBy(const QString& base, Node* sub) { inheritedBy.insert(base,sub); -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE qDebug() << "QmlClassNode::addInheritedBy(): insert" << base << sub->name() << inheritedBy.size(); #endif } @@ -1347,7 +1347,7 @@ void QmlClassNode::subclasses(const QString& base, NodeList& subs) subs.clear(); if (inheritedBy.count(base) > 0) { subs = inheritedBy.values(base); -#ifdef DEBUG_MULTIPLE QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE qDebug() << "QmlClassNode::subclasses():" << inheritedBy.count(base) << base << "subs:" << subs.size() << "total size:" << inheritedBy.size(); #endif -- cgit v0.12 From cc22a14f3d2159a8f760b44e3fe1636a3721ce95 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 25 Mar 2010 16:18:52 +0100 Subject: tst_qnetworkreply: Fix side effect, add another test Fix a test that had a side effect. But actually do the side effect in the last test: Have a QNetworkReply that is parented to the application so it gets destructed after the QNetworkAccessManager. Reviewed-by: gabi --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 261e613..71ee2d0 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -275,6 +275,9 @@ private Q_SLOTS: void ignoreSslErrorsListWithSlot_data(); void ignoreSslErrorsListWithSlot(); #endif + + // NOTE: This test must be last! + void parentingRepliesToTheApp(); }; QT_BEGIN_NAMESPACE @@ -3831,7 +3834,7 @@ void tst_QNetworkReply::httpConnectionCount() for (int i = 0; i < 10; i++) { QNetworkRequest request (QUrl("http://127.0.0.1:" + QString::number(server.serverPort()) + "/" + QString::number(i))); QNetworkReply* reply = manager.get(request); - reply->setParent(this); + reply->setParent(&server); } int pendingConnectionCount = 0; @@ -4105,5 +4108,13 @@ void tst_QNetworkReply::ignoreSslErrorsListWithSlot() #endif // QT_NO_OPENSSL +// NOTE: This test must be last testcase in tst_qnetworkreply! +void tst_QNetworkReply::parentingRepliesToTheApp() +{ + QNetworkRequest request (QUrl("http://" + QtNetworkSettings::serverName())); + manager.get(request)->setParent(this); // parent to this object + manager.get(request)->setParent(qApp); // parent to the app +} + QTEST_MAIN(tst_QNetworkReply) #include "tst_qnetworkreply.moc" -- cgit v0.12 From 43e1cffb16c2eea54392f5c56210b10abb2f044e Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 25 Mar 2010 17:01:45 +0100 Subject: QNAM HTTP: Symbian compile fix --- src/network/access/qhttpnetworkconnectionchannel_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 6ec47c1..4a2f8ad 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -65,6 +65,7 @@ #include #include +#include "qhttpnetworkconnection_p.h" #ifndef QT_NO_HTTP -- cgit v0.12 From b7f48eee301e973fcfae08dfd8997538b6dbe251 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 25 Mar 2010 19:05:18 +0100 Subject: Fix wrong arguments order in a warning in QObject::moveToThread Task-number: QTBUG-8478 --- src/corelib/kernel/qobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 68f34ca..53c5b3b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1479,7 +1479,7 @@ void QObject::moveToThread(QThread *targetThread) } else if (d->threadData != currentData) { qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n" "Cannot move to target thread (%p)\n", - d->threadData->thread, currentData->thread, targetData->thread); + currentData->thread, d->threadData->thread, targetData->thread); #ifdef Q_WS_MAC qWarning("On Mac OS X, you might be loading two sets of Qt binaries into the same process. " -- cgit v0.12 From 075918e796b98155b81871f15bf2eb266a783561 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 25 Mar 2010 21:19:44 +0100 Subject: Fix bad merge --- tools/qdoc3/generator.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index c5b150c..3f955bf 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -322,11 +322,11 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) bool quiet = false; if (node->type() == Node::Function) { -#if 0 +#if 0 const FunctionNode *func = (const FunctionNode *) node; if (func->isOverload() && func->metaness() != FunctionNode::Ctor) generateOverload(node, marker); -#endif +#endif } else if (node->type() == Node::Fake) { const FakeNode *fake = static_cast(node); @@ -347,7 +347,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) if (func->reimplementedFrom() != 0) generateReimplementedFrom(func, marker); } - + if (!generateText(node->doc().body(), node, marker)) if (node->isReimp()) return; @@ -452,7 +452,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) // Now we put this at the top, before the other text. if (func->reimplementedFrom() != 0) generateReimplementedFrom(func, marker); -#endif +#endif } } @@ -544,7 +544,7 @@ void Generator::generateInheritedBy(const ClassNode *classe, example is being formatted. It outputs the list of source files comprising the example, and the list of images used by the example. The images are copied into a subtree of - \c{...doc/html/images/used-in-examples/...} + \c{...doc/html/images/used-in-examples/...} */ void Generator::generateFileList(const FakeNode* fake, CodeMarker* marker, @@ -946,7 +946,7 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker) } ++c; } - if (!exceptions) + if (!exceptions) text << "."; else if (threadSafeness == Node::Reentrant) { if (nonreentrant.isEmpty()) { @@ -1033,7 +1033,7 @@ void Generator::generateOverload(const Node *node, CodeMarker *marker) text << Atom::ParaLeft << "This function overloads "; QString t = node->name() + "()"; - text << Atom::AutoLink << t + text << Atom::AutoLink << t << Atom::ParaRight; generateText(text, node, marker); } @@ -1194,20 +1194,12 @@ void Generator::appendSortedQmlNames(Text& text, QMap classMap; int index = 0; -<<<<<<< HEAD -#ifdef DEBUG_MULTIPLE -======= #ifdef DEBUG_MULTIPLE_QDOCCONF_FILES ->>>>>>> origin/4.7 qDebug() << "Generator::appendSortedQmlNames():" << base->name() << "is inherited by..."; #endif for (int i = 0; i < subs.size(); ++i) { Text t; -<<<<<<< HEAD -#ifdef DEBUG_MULTIPLE -======= #ifdef DEBUG_MULTIPLE_QDOCCONF_FILES ->>>>>>> origin/4.7 qDebug() << " " << subs[i]->name(); #endif appendFullName(t, subs[i], base, marker); -- cgit v0.12 From 7c36400a998b6d4cff34d7cb783f8e228a3e3621 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 26 Mar 2010 08:14:45 +1000 Subject: Fix OpenVG build on non-Symbian platforms. Reviewed-by: trustme --- src/openvg/qpixmapdata_vg.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index d602790..7efec2b 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -45,8 +45,10 @@ #include "qvg_p.h" #include "qvgimagepool_p.h" +#if defined(Q_OS_SYMBIAN) #include #include +#endif #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE #include typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); -- cgit v0.12 From 1e8eb507a7624a1847f3da067f45d1637d47150a Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 26 Mar 2010 08:27:02 +1000 Subject: Fix another off-by-1 error in OpenVG image painting. Off in the vertical direction this time; previously was horizontal. Task-number: QT-2999 Reviewed-by: Jason Barron --- src/openvg/qpaintengine_vg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 4a97a6f..ce6e21b 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -538,7 +538,7 @@ void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) // adds 0.5 to each co-ordinate. QTransform viewport2(1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, - 0.0f, devh, 1.0f); + 0.0f, devh + 1, 1.0f); imageTransform = transform * viewport2; // Calculate the scaling factor to use for turning cosmetic pens -- cgit v0.12 From 7e60531cc1b70c660dd5635b5d105894a49954f2 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Fri, 26 Mar 2010 13:43:10 +1000 Subject: Phonon qt7; Compile fixes after merge. --- src/3rdparty/phonon/qt7/audionode.mm | 15 +++++++++------ src/3rdparty/phonon/qt7/backendinfo.mm | 12 ++++++------ src/3rdparty/phonon/qt7/mediaobjectaudionode.mm | 2 ++ src/3rdparty/phonon/qt7/quicktimeaudioplayer.mm | 2 ++ src/3rdparty/phonon/qt7/quicktimemetadata.mm | 2 ++ 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/3rdparty/phonon/qt7/audionode.mm b/src/3rdparty/phonon/qt7/audionode.mm index cb9e82f..77cd627 100644 --- a/src/3rdparty/phonon/qt7/audionode.mm +++ b/src/3rdparty/phonon/qt7/audionode.mm @@ -68,12 +68,15 @@ void AudioNode::createAndConnectAUNodes() << QString(!FindNextComponent(0, &description) ? "ERROR: COMPONENT NOT FOUND!" : "OK!")) OSStatus err = noErr; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) - err = AUGraphAddNode(m_audioGraph->audioGraphRef(), &description, &m_auNode); - else -#endif - err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode); + + // The proper function to call here is AUGraphAddNode() but the type has + // changed between 10.5 and 10.6. it's still OK to call this function, but + // if we want to use the proper thing we need to move over to + // AudioComponentDescription everywhere, which is very similar to the + // ComponentDescription, but a different size. however, + // AudioComponentDescription only exists on 10.6+. More fun than we need to + // deal with at the moment, so we'll take the "deprecated" warning instead. + err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode); BACKEND_ASSERT2(err != kAUGraphErr_OutputNodeErr, "A MediaObject can only be connected to one audio output device.", FATAL_ERROR) BACKEND_ASSERT2(err == noErr, "Could not create new AUNode.", FATAL_ERROR) diff --git a/src/3rdparty/phonon/qt7/backendinfo.mm b/src/3rdparty/phonon/qt7/backendinfo.mm index e173f05..d84e014 100644 --- a/src/3rdparty/phonon/qt7/backendinfo.mm +++ b/src/3rdparty/phonon/qt7/backendinfo.mm @@ -15,6 +15,12 @@ along with this library. If not, see . */ +#import +#ifdef QUICKTIME_C_API_AVAILABLE + #include + #undef check // avoid name clash; +#endif + #include "backendinfo.h" #include "backendheader.h" @@ -22,12 +28,6 @@ #include #include -#import - -#ifdef QUICKTIME_C_API_AVAILABLE - #include - #undef check // avoid name clash; -#endif QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/qt7/mediaobjectaudionode.mm b/src/3rdparty/phonon/qt7/mediaobjectaudionode.mm index 66d6041..39b0d4e 100644 --- a/src/3rdparty/phonon/qt7/mediaobjectaudionode.mm +++ b/src/3rdparty/phonon/qt7/mediaobjectaudionode.mm @@ -15,6 +15,8 @@ along with this library. If not, see . */ +#import + #include "mediaobjectaudionode.h" #include "quicktimeaudioplayer.h" #include "quicktimevideoplayer.h" diff --git a/src/3rdparty/phonon/qt7/quicktimeaudioplayer.mm b/src/3rdparty/phonon/qt7/quicktimeaudioplayer.mm index 61c97cc..aefec02 100644 --- a/src/3rdparty/phonon/qt7/quicktimeaudioplayer.mm +++ b/src/3rdparty/phonon/qt7/quicktimeaudioplayer.mm @@ -15,6 +15,8 @@ along with this library. If not, see . */ +#import + #include "quicktimeaudioplayer.h" #include "quicktimevideoplayer.h" #include "audiograph.h" diff --git a/src/3rdparty/phonon/qt7/quicktimemetadata.mm b/src/3rdparty/phonon/qt7/quicktimemetadata.mm index 851e707..4ae3e2c 100644 --- a/src/3rdparty/phonon/qt7/quicktimemetadata.mm +++ b/src/3rdparty/phonon/qt7/quicktimemetadata.mm @@ -15,6 +15,8 @@ along with this library. If not, see . */ +#import + #include "quicktimemetadata.h" #include "quicktimevideoplayer.h" -- cgit v0.12 From b66a253318de90e69ce864621b7c323d98c18783 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Fri, 26 Mar 2010 13:43:32 +1000 Subject: Phonon core; compile fixes after merge. --- src/3rdparty/phonon/phonon/audiodataoutput.cpp | 2 -- src/3rdparty/phonon/phonon/audiooutput.cpp | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/3rdparty/phonon/phonon/audiodataoutput.cpp b/src/3rdparty/phonon/phonon/audiodataoutput.cpp index 6c737c2..3a7d3a1 100644 --- a/src/3rdparty/phonon/phonon/audiodataoutput.cpp +++ b/src/3rdparty/phonon/phonon/audiodataoutput.cpp @@ -62,7 +62,5 @@ void AudioDataOutputPrivate::setupBackendObject() } // namespace Phonon -#include "audiodataoutput.moc" - #undef PHONON_CLASSNAME // vim: sw=4 ts=4 tw=80 diff --git a/src/3rdparty/phonon/phonon/audiooutput.cpp b/src/3rdparty/phonon/phonon/audiooutput.cpp index 932a875..e94caad 100644 --- a/src/3rdparty/phonon/phonon/audiooutput.cpp +++ b/src/3rdparty/phonon/phonon/audiooutput.cpp @@ -31,6 +31,7 @@ #include "pulsesupport.h" #include +#include #define PHONON_CLASSNAME AudioOutput #define IFACES2 AudioOutputInterface42 -- cgit v0.12 From c3a7d812d3cf30d23049cfd355c6290a7985f81d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 25 Mar 2010 12:12:01 +0200 Subject: Enable armcc version specific compler options for Symbian VERSION_FLAGS.ARMCC variable is used in symbian.conf to define supported armcc compiler version flags. Values given to this variable must be directly usable as ifdef flags in mmp. QMAKE_CXXFLAGS. variables can now be used to add compiler options to specific compiler versions. Note that options added via QMAKE_CXXFLAGS.ARMCC flag will apply to all versions of armcc compiler. Task-number: QTBUG-8685 Reviewed-by: Iain --- mkspecs/common/symbian/symbian.conf | 5 ++++- qmake/generators/symbian/symmake.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index c39b39d..d66d227 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -26,10 +26,13 @@ QMAKE_CFLAGS_RELEASE = QMAKE_CFLAGS_DEBUG = QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses + +VERSION_FLAGS.ARMCC = ARMCC_4_0 QMAKE_CXX = g++ QMAKE_CXXFLAGS = $$QMAKE_CFLAGS QMAKE_CXXFLAGS.CW = -QMAKE_CXXFLAGS.ARMCC = --visibility_inlines_hidden +QMAKE_CXXFLAGS.ARMCC = --visibility_inlines_hidden +QMAKE_CXXFLAGS.ARMCC_4_0 = --import_all_vtbl QMAKE_CXXFLAGS.GCCE = -fvisibility-inlines-hidden QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 1470a12..e1256d8 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -1246,6 +1246,16 @@ void SymbianMakefileGenerator::writeMmpFileCompilerOptionPart(QTextStream& t) t << MMP_OPTION_CW " " << cw << endl; if (!armcc.isEmpty()) t << MMP_OPTION_ARMCC " " << armcc << endl; + + foreach(QString armccVersion, project->values("VERSION_FLAGS.ARMCC")) { + QStringList currentValues = project->values("QMAKE_CXXFLAGS." + armccVersion); + if (currentValues.size()) { + t << "#if defined(" << armccVersion << ")" << endl; + t << MMP_OPTION_ARMCC " " << currentValues.join(" ") << endl; + t << "#endif" << endl; + } + } + if (!gcce.isEmpty()) t << MMP_OPTION_GCCE " " << gcce << endl; -- cgit v0.12 From aaf0f47930a44f5f36bb825e10a5067eeced6718 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 26 Mar 2010 10:41:35 +0200 Subject: Changed pkg_prerules to not use default_deployment for vendor ID Demos and examples used default_deployment to define vendor ID pkg rule, which is not what default_deployment should be used for. As these are supposed to serve as examples for developers, changed these declarations to use another deployment item. Reviewed-by: TrustMe --- demos/symbianpkgrules.pri | 3 ++- examples/symbianpkgrules.pri | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/demos/symbianpkgrules.pri b/demos/symbianpkgrules.pri index c511836..68a82cd 100644 --- a/demos/symbianpkgrules.pri +++ b/demos/symbianpkgrules.pri @@ -10,6 +10,7 @@ vendorinfo = \ ":\"Nokia, Qt\"" \ " " -default_deployment.pkg_prerules += vendorinfo +demos_deployment.pkg_prerules += vendorinfo +DEPLOYMENT += demos_deployment isEmpty(ICON):ICON = $$QT_SOURCE_TREE/src/s60installs/qt.svg diff --git a/examples/symbianpkgrules.pri b/examples/symbianpkgrules.pri index 35edbfb..a1b6634 100644 --- a/examples/symbianpkgrules.pri +++ b/examples/symbianpkgrules.pri @@ -10,6 +10,7 @@ vendorinfo = \ ":\"Nokia, Qt\"" \ " " -default_deployment.pkg_prerules += vendorinfo +examples_deployment.pkg_prerules += vendorinfo +DEPLOYMENT += examples_deployment isEmpty(ICON):ICON = $$QT_SOURCE_TREE/src/s60installs/qt.svg -- cgit v0.12 From 7b9fd32139d1e381f45a0655dafbfc98dc9aca39 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 26 Mar 2010 09:47:06 +0100 Subject: Fix QItemDelegate::textRectangle The textRectangle should contain all pixels in the text, including those which are only partially covered, so the width and height should never be rounded down. Adding support for fractional font metrics on Mac made this bug visible. Fixes test failure in itemdelegate autotest. Reviewed-by: Olivier --- src/gui/itemviews/qitemdelegate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 7d8e103..25ea4c9 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include @@ -1148,7 +1149,8 @@ QRect QItemDelegate::textRectangle(QPainter * /*painter*/, const QRect &rect, d->textLayout.setTextOption(d->textOption); d->textLayout.setFont(font); d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text)); - const QSize size = d->doTextLayout(rect.width()).toSize(); + QSizeF fpSize = d->doTextLayout(rect.width()); + const QSize size = QSize(qCeil(fpSize.width()), qCeil(fpSize.height())); // ###: textRectangle should take style option as argument const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; return QRect(0, 0, size.width() + 2 * textMargin, size.height()); -- cgit v0.12 From 8d5ae9bca2cbe8c5a7f764b8ba325f79c0bbfe62 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 26 Mar 2010 10:06:50 +0100 Subject: Safeguard the colortable access when converting corrupted indexed8 Fixes: QTBUG-5510 Reviewed-by: Eskil --- src/gui/image/qimage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 94307de..233c58d 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2988,19 +2988,19 @@ static void convert_Indexed8_to_X32(QImageData *dest, const QImageData *src, Qt: colorTable.resize(256); for (int i=0; i<256; ++i) colorTable[i] = qRgb(i, i, i); - } int w = src->width; const uchar *src_data = src->data; uchar *dest_data = dest->data; + int tableSize = colorTable.size() - 1; for (int y = 0; y < src->height; y++) { uint *p = (uint *)dest_data; const uchar *b = src_data; uint *end = p + w; while (p < end) - *p++ = colorTable.at(*b++); + *p++ = colorTable.at(qMin(tableSize, *b++)); src_data += src->bytes_per_line; dest_data += dest->bytes_per_line; -- cgit v0.12 From 348d22c37611066dc7efc9aac820d77bcf3bbbab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 8 Mar 2010 13:38:08 +0100 Subject: Included ARM NEON optimizations from pixman in Qt. On the N900 16 bit text blending is 30 - 50 % faster, and ARGB32PM on RGB16 image blending now runs in 1/10th of the time it used to. We now make ARGB32PM the default pixmap format for alpha pixmaps instead of ARGB8565PM which is unaligned and bad for performance. The relevant numbers: Mostly opaque pixels: ARGB24 on ARGB24 using QPainter..................: 336,813033 ARGB32 on ARGB32 using QPainter.................: 18,419387 RGB16 on ARGB24 using QPainter..................: 167,301014 RGB16 on ARGB32 using QPainter..................: 17,279372 ARGB24 on RGB16 using QPainter..................: 35,100147 ARGB32PM on RGB16 using QPainter................: 15,924256 No opaque pixels: ARGB24 on ARGB24 using QPainter..................: 412,190765 ARGB32 on ARGB32 using QPainter.................: 16,818389 RGB16 on ARGB24 using QPainter..................: 170,957878 RGB16 on ARGB32 using QPainter..................: 16,742984 ARGB24 on RGB16 using QPainter..................: 93,600482 ARGB32PM on RGB16 using QPainter................: 15,999310 So switching to ARGB32PM should give a boost in all areas. Task-number: QTBUG-6684 Reviewed-by: Gunnar Sletta --- doc/src/legal/3rdparty.qdoc | 39 + src/3rdparty/pixman/README | 26 + src/3rdparty/pixman/pixman-arm-neon-asm.S | 1709 +++++++++++++++++++++++++++++ src/3rdparty/pixman/pixman-arm-neon-asm.h | 906 +++++++++++++++ src/gui/image/qpixmap_raster.cpp | 4 + src/gui/painting/painting.pri | 14 +- src/gui/painting/qblendfunctions.cpp | 8 +- src/gui/painting/qdrawhelper.cpp | 4 + src/gui/painting/qdrawhelper_neon.cpp | 144 ++- src/gui/painting/qdrawhelper_neon_p.h | 15 + 10 files changed, 2820 insertions(+), 49 deletions(-) create mode 100644 src/3rdparty/pixman/README create mode 100644 src/3rdparty/pixman/pixman-arm-neon-asm.S create mode 100644 src/3rdparty/pixman/pixman-arm-neon-asm.h diff --git a/doc/src/legal/3rdparty.qdoc b/doc/src/legal/3rdparty.qdoc index d608038..8d0cd2a 100644 --- a/doc/src/legal/3rdparty.qdoc +++ b/doc/src/legal/3rdparty.qdoc @@ -454,4 +454,43 @@ OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. See \c src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp for license details. + + \section1 Pixman (\c pixman) version 0.17.11 + + \e{pixman is a library that provides low-level pixel manipulation + features such as image compositing and trapezoid rasterization.} -- quoted + from \c src/3rdparty/pixman/README + + We are only using the pixman-arm-neon-asm.h and pixman-arm-neon-asm.S + source files which have the following copyright and license header: + + \hr + + Copyright © 2009 Nokia Corporation + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) + + \hr + + See \c src/3rdparty/pixman/pixman-arm-neon-asm.h and + \c src/3rdparty/pixman/pixman-arm-neon-asm.S */ diff --git a/src/3rdparty/pixman/README b/src/3rdparty/pixman/README new file mode 100644 index 0000000..843b069 --- /dev/null +++ b/src/3rdparty/pixman/README @@ -0,0 +1,26 @@ +pixman is a library that provides low-level pixel manipulation +features such as image compositing and trapezoid rasterization. + +Please submit bugs & patches to the libpixman bugzilla: + + https://bugs.freedesktop.org/enter_bug.cgi?product=pixman + +All questions regarding this software should be directed to either the +Xorg mailing list: + + http://lists.freedesktop.org/mailman/listinfo/xorg + +or the cairo mailing list: + + http://lists.freedesktop.org/mailman/listinfo/cairo + +The master development code repository can be found at: + + git://anongit.freedesktop.org/git/pixman + + http://gitweb.freedesktop.org/?p=pixman;a=summary + +For more information on the git code manager, see: + + http://wiki.x.org/wiki/GitPage + diff --git a/src/3rdparty/pixman/pixman-arm-neon-asm.S b/src/3rdparty/pixman/pixman-arm-neon-asm.S new file mode 100644 index 0000000..eb8cc4c --- /dev/null +++ b/src/3rdparty/pixman/pixman-arm-neon-asm.S @@ -0,0 +1,1709 @@ +/* + * Copyright © 2009 Nokia Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) + */ + +/* + * This file contains implementations of NEON optimized pixel processing + * functions. There is no full and detailed tutorial, but some functions + * (those which are exposing some new or interesting features) are + * extensively commented and can be used as examples. + * + * You may want to have a look at the comments for following functions: + * - pixman_composite_over_8888_0565_asm_neon + * - pixman_composite_over_n_8_0565_asm_neon + */ + +/* Prevent the stack from becoming executable for no reason... */ +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + + .text + .fpu neon + .arch armv7a + .altmacro + +#include "pixman-arm-neon-asm.h" + +/* Global configuration options and preferences */ + +/* + * The code can optionally make use of unaligned memory accesses to improve + * performance of handling leading/trailing pixels for each scanline. + * Configuration variable RESPECT_STRICT_ALIGNMENT can be set to 0 for + * example in linux if unaligned memory accesses are not configured to + * generate.exceptions. + */ +.set RESPECT_STRICT_ALIGNMENT, 1 + +/* + * Set default prefetch type. There is a choice between the following options: + * + * PREFETCH_TYPE_NONE (may be useful for the ARM cores where PLD is set to work + * as NOP to workaround some HW bugs or for whatever other reason) + * + * PREFETCH_TYPE_SIMPLE (may be useful for simple single-issue ARM cores where + * advanced prefetch intruduces heavy overhead) + * + * PREFETCH_TYPE_ADVANCED (useful for superscalar cores such as ARM Cortex-A8 + * which can run ARM and NEON instructions simultaneously so that extra ARM + * instructions do not add (many) extra cycles, but improve prefetch efficiency) + * + * Note: some types of function can't support advanced prefetch and fallback + * to simple one (those which handle 24bpp pixels) + */ +.set PREFETCH_TYPE_DEFAULT, PREFETCH_TYPE_ADVANCED + +/* Prefetch distance in pixels for simple prefetch */ +.set PREFETCH_DISTANCE_SIMPLE, 64 + +/* + * Implementation of pixman_composite_over_8888_0565_asm_neon + * + * This function takes a8r8g8b8 source buffer, r5g6b5 destination buffer and + * performs OVER compositing operation. Function fast_composite_over_8888_0565 + * from pixman-fast-path.c does the same in C and can be used as a reference. + * + * First we need to have some NEON assembly code which can do the actual + * operation on the pixels and provide it to the template macro. + * + * Template macro quite conveniently takes care of emitting all the necessary + * code for memory reading and writing (including quite tricky cases of + * handling unaligned leading/trailing pixels), so we only need to deal with + * the data in NEON registers. + * + * NEON registers allocation in general is recommented to be the following: + * d0, d1, d2, d3 - contain loaded source pixel data + * d4, d5, d6, d7 - contain loaded destination pixels (if they are needed) + * d24, d25, d26, d27 - contain loading mask pixel data (if mask is used) + * d28, d29, d30, d31 - place for storing the result (destination pixels) + * + * As can be seen above, four 64-bit NEON registers are used for keeping + * intermediate pixel data and up to 8 pixels can be processed in one step + * for 32bpp formats (16 pixels for 16bpp, 32 pixels for 8bpp). + * + * This particular function uses the following registers allocation: + * d0, d1, d2, d3 - contain loaded source pixel data + * d4, d5 - contain loaded destination pixels (they are needed) + * d28, d29 - place for storing the result (destination pixels) + */ + +/* + * Step one. We need to have some code to do some arithmetics on pixel data. + * This is implemented as a pair of macros: '*_head' and '*_tail'. When used + * back-to-back, they take pixel data from {d0, d1, d2, d3} and {d4, d5}, + * perform all the needed calculations and write the result to {d28, d29}. + * The rationale for having two macros and not just one will be explained + * later. In practice, any single monolitic function which does the work can + * be split into two parts in any arbitrary way without affecting correctness. + * + * There is one special trick here too. Common template macro can optionally + * make our life a bit easier by doing R, G, B, A color components + * deinterleaving for 32bpp pixel formats (and this feature is used in + * 'pixman_composite_over_8888_0565_asm_neon' function). So it means that + * instead of having 8 packed pixels in {d0, d1, d2, d3} registers, we + * actually use d0 register for blue channel (a vector of eight 8-bit + * values), d1 register for green, d2 for red and d3 for alpha. This + * simple conversion can be also done with a few NEON instructions: + * + * Packed to planar conversion: + * vuzp.8 d0, d1 + * vuzp.8 d2, d3 + * vuzp.8 d1, d3 + * vuzp.8 d0, d2 + * + * Planar to packed conversion: + * vzip.8 d0, d2 + * vzip.8 d1, d3 + * vzip.8 d2, d3 + * vzip.8 d0, d1 + * + * But pixel can be loaded directly in planar format using VLD4.8 NEON + * instruction. It is 1 cycle slower than VLD1.32, so this is not always + * desirable, that's why deinterleaving is optional. + * + * But anyway, here is the code: + */ +.macro pixman_composite_over_8888_0565_process_pixblock_head + /* convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format + and put data into d6 - red, d7 - green, d30 - blue */ + vshrn.u16 d6, q2, #8 + vshrn.u16 d7, q2, #3 + vsli.u16 q2, q2, #5 + vsri.u8 d6, d6, #5 + vmvn.8 d3, d3 /* invert source alpha */ + vsri.u8 d7, d7, #6 + vshrn.u16 d30, q2, #2 + /* now do alpha blending, storing results in 8-bit planar format + into d16 - red, d19 - green, d18 - blue */ + vmull.u8 q10, d3, d6 + vmull.u8 q11, d3, d7 + vmull.u8 q12, d3, d30 + vrshr.u16 q13, q10, #8 + vrshr.u16 q3, q11, #8 + vrshr.u16 q15, q12, #8 + vraddhn.u16 d20, q10, q13 + vraddhn.u16 d23, q11, q3 + vraddhn.u16 d22, q12, q15 +.endm + +.macro pixman_composite_over_8888_0565_process_pixblock_tail + /* ... continue alpha blending */ + vqadd.u8 d16, d2, d20 + vqadd.u8 q9, q0, q11 + /* convert the result to r5g6b5 and store it into {d28, d29} */ + vshll.u8 q14, d16, #8 + vshll.u8 q8, d19, #8 + vshll.u8 q9, d18, #8 + vsri.u16 q14, q8, #5 + vsri.u16 q14, q9, #11 +.endm + +/* + * OK, now we got almost everything that we need. Using the above two + * macros, the work can be done right. But now we want to optimize + * it a bit. ARM Cortex-A8 is an in-order core, and benefits really + * a lot from good code scheduling and software pipelining. + * + * Let's construct some code, which will run in the core main loop. + * Some pseudo-code of the main loop will look like this: + * head + * while (...) { + * tail + * head + * } + * tail + * + * It may look a bit weird, but this setup allows to hide instruction + * latencies better and also utilize dual-issue capability more + * efficiently (make pairs of load-store and ALU instructions). + * + * So what we need now is a '*_tail_head' macro, which will be used + * in the core main loop. A trivial straightforward implementation + * of this macro would look like this: + * + * pixman_composite_over_8888_0565_process_pixblock_tail + * vst1.16 {d28, d29}, [DST_W, :128]! + * vld1.16 {d4, d5}, [DST_R, :128]! + * vld4.32 {d0, d1, d2, d3}, [SRC]! + * pixman_composite_over_8888_0565_process_pixblock_head + * cache_preload 8, 8 + * + * Now it also got some VLD/VST instructions. We simply can't move from + * processing one block of pixels to the other one with just arithmetics. + * The previously processed data needs to be written to memory and new + * data needs to be fetched. Fortunately, this main loop does not deal + * with partial leading/trailing pixels and can load/store a full block + * of pixels in a bulk. Additionally, destination buffer is already + * 16 bytes aligned here (which is good for performance). + * + * New things here are DST_R, DST_W, SRC and MASK identifiers. These + * are the aliases for ARM registers which are used as pointers for + * accessing data. We maintain separate pointers for reading and writing + * destination buffer (DST_R and DST_W). + * + * Another new thing is 'cache_preload' macro. It is used for prefetching + * data into CPU L2 cache and improve performance when dealing with large + * images which are far larger than cache size. It uses one argument + * (actually two, but they need to be the same here) - number of pixels + * in a block. Looking into 'pixman-arm-neon-asm.h' can provide some + * details about this macro. Moreover, if good performance is needed + * the code from this macro needs to be copied into '*_tail_head' macro + * and mixed with the rest of code for optimal instructions scheduling. + * We are actually doing it below. + * + * Now after all the explanations, here is the optimized code. + * Different instruction streams (originaling from '*_head', '*_tail' + * and 'cache_preload' macro) use different indentation levels for + * better readability. Actually taking the code from one of these + * indentation levels and ignoring a few VLD/VST instructions would + * result in exactly the code from '*_head', '*_tail' or 'cache_preload' + * macro! + */ + +#if 1 + +.macro pixman_composite_over_8888_0565_process_pixblock_tail_head + vqadd.u8 d16, d2, d20 + vld1.16 {d4, d5}, [DST_R, :128]! + vqadd.u8 q9, q0, q11 + vshrn.u16 d6, q2, #8 + vld4.8 {d0, d1, d2, d3}, [SRC]! + vshrn.u16 d7, q2, #3 + vsli.u16 q2, q2, #5 + vshll.u8 q14, d16, #8 + PF add PF_X, PF_X, #8 + vshll.u8 q8, d19, #8 + PF tst PF_CTL, #0xF + vsri.u8 d6, d6, #5 + PF addne PF_X, PF_X, #8 + vmvn.8 d3, d3 + PF subne PF_CTL, PF_CTL, #1 + vsri.u8 d7, d7, #6 + vshrn.u16 d30, q2, #2 + vmull.u8 q10, d3, d6 + PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] + vmull.u8 q11, d3, d7 + vmull.u8 q12, d3, d30 + PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] + vsri.u16 q14, q8, #5 + PF cmp PF_X, ORIG_W + vshll.u8 q9, d18, #8 + vrshr.u16 q13, q10, #8 + PF subge PF_X, PF_X, ORIG_W + vrshr.u16 q3, q11, #8 + vrshr.u16 q15, q12, #8 + PF subges PF_CTL, PF_CTL, #0x10 + vsri.u16 q14, q9, #11 + PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! + vraddhn.u16 d20, q10, q13 + vraddhn.u16 d23, q11, q3 + PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! + vraddhn.u16 d22, q12, q15 + vst1.16 {d28, d29}, [DST_W, :128]! +.endm + +#else + +/* If we did not care much about the performance, we would just use this... */ +.macro pixman_composite_over_8888_0565_process_pixblock_tail_head + pixman_composite_over_8888_0565_process_pixblock_tail + vst1.16 {d28, d29}, [DST_W, :128]! + vld1.16 {d4, d5}, [DST_R, :128]! + vld4.32 {d0, d1, d2, d3}, [SRC]! + pixman_composite_over_8888_0565_process_pixblock_head + cache_preload 8, 8 +.endm + +#endif + +/* + * And now the final part. We are using 'generate_composite_function' macro + * to put all the stuff together. We are specifying the name of the function + * which we want to get, number of bits per pixel for the source, mask and + * destination (0 if unused, like mask in this case). Next come some bit + * flags: + * FLAG_DST_READWRITE - tells that the destination buffer is both read + * and written, for write-only buffer we would use + * FLAG_DST_WRITEONLY flag instead + * FLAG_DEINTERLEAVE_32BPP - tells that we prefer to work with planar data + * and separate color channels for 32bpp format. + * The next things are: + * - the number of pixels processed per iteration (8 in this case, because + * that's the maximum what can fit into four 64-bit NEON registers). + * - prefetch distance, measured in pixel blocks. In this case it is 5 times + * by 8 pixels. That would be 40 pixels, or up to 160 bytes. Optimal + * prefetch distance can be selected by running some benchmarks. + * + * After that we specify some macros, these are 'default_init', + * 'default_cleanup' here which are empty (but it is possible to have custom + * init/cleanup macros to be able to save/restore some extra NEON registers + * like d8-d15 or do anything else) followed by + * 'pixman_composite_over_8888_0565_process_pixblock_head', + * 'pixman_composite_over_8888_0565_process_pixblock_tail' and + * 'pixman_composite_over_8888_0565_process_pixblock_tail_head' + * which we got implemented above. + * + * The last part is the NEON registers allocation scheme. + */ +generate_composite_function \ + pixman_composite_over_8888_0565_asm_neon, 32, 0, 16, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_over_8888_0565_process_pixblock_head, \ + pixman_composite_over_8888_0565_process_pixblock_tail, \ + pixman_composite_over_8888_0565_process_pixblock_tail_head, \ + 28, /* dst_w_basereg */ \ + 4, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 24 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_over_n_0565_process_pixblock_head + /* convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format + and put data into d6 - red, d7 - green, d30 - blue */ + vshrn.u16 d6, q2, #8 + vshrn.u16 d7, q2, #3 + vsli.u16 q2, q2, #5 + vsri.u8 d6, d6, #5 + vsri.u8 d7, d7, #6 + vshrn.u16 d30, q2, #2 + /* now do alpha blending, storing results in 8-bit planar format + into d16 - red, d19 - green, d18 - blue */ + vmull.u8 q10, d3, d6 + vmull.u8 q11, d3, d7 + vmull.u8 q12, d3, d30 + vrshr.u16 q13, q10, #8 + vrshr.u16 q3, q11, #8 + vrshr.u16 q15, q12, #8 + vraddhn.u16 d20, q10, q13 + vraddhn.u16 d23, q11, q3 + vraddhn.u16 d22, q12, q15 +.endm + +.macro pixman_composite_over_n_0565_process_pixblock_tail + /* ... continue alpha blending */ + vqadd.u8 d16, d2, d20 + vqadd.u8 q9, q0, q11 + /* convert the result to r5g6b5 and store it into {d28, d29} */ + vshll.u8 q14, d16, #8 + vshll.u8 q8, d19, #8 + vshll.u8 q9, d18, #8 + vsri.u16 q14, q8, #5 + vsri.u16 q14, q9, #11 +.endm + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_over_n_0565_process_pixblock_tail_head + pixman_composite_over_n_0565_process_pixblock_tail + vld1.16 {d4, d5}, [DST_R, :128]! + vst1.16 {d28, d29}, [DST_W, :128]! + pixman_composite_over_n_0565_process_pixblock_head +.endm + +.macro pixman_composite_over_n_0565_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vld1.32 {d3[0]}, [DUMMY] + vdup.8 d0, d3[0] + vdup.8 d1, d3[1] + vdup.8 d2, d3[2] + vdup.8 d3, d3[3] + vmvn.8 d3, d3 /* invert source alpha */ +.endm + +generate_composite_function \ + pixman_composite_over_n_0565_asm_neon, 0, 0, 16, \ + FLAG_DST_READWRITE, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_n_0565_init, \ + default_cleanup, \ + pixman_composite_over_n_0565_process_pixblock_head, \ + pixman_composite_over_n_0565_process_pixblock_tail, \ + pixman_composite_over_n_0565_process_pixblock_tail_head, \ + 28, /* dst_w_basereg */ \ + 4, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 24 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_8888_0565_process_pixblock_head + vshll.u8 q8, d1, #8 + vshll.u8 q14, d2, #8 + vshll.u8 q9, d0, #8 +.endm + +.macro pixman_composite_src_8888_0565_process_pixblock_tail + vsri.u16 q14, q8, #5 + vsri.u16 q14, q9, #11 +.endm + +.macro pixman_composite_src_8888_0565_process_pixblock_tail_head + vsri.u16 q14, q8, #5 + PF add PF_X, PF_X, #8 + PF tst PF_CTL, #0xF + vld4.8 {d0, d1, d2, d3}, [SRC]! + PF addne PF_X, PF_X, #8 + PF subne PF_CTL, PF_CTL, #1 + vsri.u16 q14, q9, #11 + PF cmp PF_X, ORIG_W + PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] + vshll.u8 q8, d1, #8 + vst1.16 {d28, d29}, [DST_W, :128]! + PF subge PF_X, PF_X, ORIG_W + PF subges PF_CTL, PF_CTL, #0x10 + vshll.u8 q14, d2, #8 + PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! + vshll.u8 q9, d0, #8 +.endm + +generate_composite_function \ + pixman_composite_src_8888_0565_asm_neon, 32, 0, 16, \ + FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_src_8888_0565_process_pixblock_head, \ + pixman_composite_src_8888_0565_process_pixblock_tail, \ + pixman_composite_src_8888_0565_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_src_0565_8888_process_pixblock_head + vshrn.u16 d30, q0, #8 + vshrn.u16 d29, q0, #3 + vsli.u16 q0, q0, #5 + vmov.u8 d31, #255 + vsri.u8 d30, d30, #5 + vsri.u8 d29, d29, #6 + vshrn.u16 d28, q0, #2 +.endm + +.macro pixman_composite_src_0565_8888_process_pixblock_tail +.endm + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_src_0565_8888_process_pixblock_tail_head + pixman_composite_src_0565_8888_process_pixblock_tail + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! + vld1.16 {d0, d1}, [SRC]! + pixman_composite_src_0565_8888_process_pixblock_head + cache_preload 8, 8 +.endm + +generate_composite_function \ + pixman_composite_src_0565_8888_asm_neon, 16, 0, 32, \ + FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_src_0565_8888_process_pixblock_head, \ + pixman_composite_src_0565_8888_process_pixblock_tail, \ + pixman_composite_src_0565_8888_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_add_8000_8000_process_pixblock_head + vqadd.u8 q14, q0, q2 + vqadd.u8 q15, q1, q3 +.endm + +.macro pixman_composite_add_8000_8000_process_pixblock_tail +.endm + +.macro pixman_composite_add_8000_8000_process_pixblock_tail_head + vld1.8 {d0, d1, d2, d3}, [SRC]! + PF add PF_X, PF_X, #32 + PF tst PF_CTL, #0xF + vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! + PF addne PF_X, PF_X, #32 + PF subne PF_CTL, PF_CTL, #1 + vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! + PF cmp PF_X, ORIG_W + PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] + PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] + PF subge PF_X, PF_X, ORIG_W + PF subges PF_CTL, PF_CTL, #0x10 + vqadd.u8 q14, q0, q2 + PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! + PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! + vqadd.u8 q15, q1, q3 +.endm + +generate_composite_function \ + pixman_composite_add_8000_8000_asm_neon, 8, 0, 8, \ + FLAG_DST_READWRITE, \ + 32, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_add_8000_8000_process_pixblock_head, \ + pixman_composite_add_8000_8000_process_pixblock_tail, \ + pixman_composite_add_8000_8000_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_add_8888_8888_process_pixblock_tail_head + vld1.8 {d0, d1, d2, d3}, [SRC]! + PF add PF_X, PF_X, #8 + PF tst PF_CTL, #0xF + vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! + PF addne PF_X, PF_X, #8 + PF subne PF_CTL, PF_CTL, #1 + vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! + PF cmp PF_X, ORIG_W + PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] + PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] + PF subge PF_X, PF_X, ORIG_W + PF subges PF_CTL, PF_CTL, #0x10 + vqadd.u8 q14, q0, q2 + PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! + PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! + vqadd.u8 q15, q1, q3 +.endm + +generate_composite_function \ + pixman_composite_add_8888_8888_asm_neon, 32, 0, 32, \ + FLAG_DST_READWRITE, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_add_8000_8000_process_pixblock_head, \ + pixman_composite_add_8000_8000_process_pixblock_tail, \ + pixman_composite_add_8888_8888_process_pixblock_tail_head + +generate_composite_function_single_scanline \ + pixman_composite_scanline_add_asm_neon, 32, 0, 32, \ + FLAG_DST_READWRITE, \ + 8, /* number of pixels, processed in a single block */ \ + default_init, \ + default_cleanup, \ + pixman_composite_add_8000_8000_process_pixblock_head, \ + pixman_composite_add_8000_8000_process_pixblock_tail, \ + pixman_composite_add_8888_8888_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_over_8888_8888_process_pixblock_head + vmvn.8 d24, d3 /* get inverted alpha */ + /* do alpha blending */ + vmull.u8 q8, d24, d4 + vmull.u8 q9, d24, d5 + vmull.u8 q10, d24, d6 + vmull.u8 q11, d24, d7 +.endm + +.macro pixman_composite_over_8888_8888_process_pixblock_tail + vrshr.u16 q14, q8, #8 + vrshr.u16 q15, q9, #8 + vrshr.u16 q12, q10, #8 + vrshr.u16 q13, q11, #8 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + vraddhn.u16 d30, q12, q10 + vraddhn.u16 d31, q13, q11 + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 +.endm + +.macro pixman_composite_over_8888_8888_process_pixblock_tail_head + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + vrshr.u16 q14, q8, #8 + PF add PF_X, PF_X, #8 + PF tst PF_CTL, #0xF + vrshr.u16 q15, q9, #8 + vrshr.u16 q12, q10, #8 + vrshr.u16 q13, q11, #8 + PF addne PF_X, PF_X, #8 + PF subne PF_CTL, PF_CTL, #1 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + PF cmp PF_X, ORIG_W + vraddhn.u16 d30, q12, q10 + vraddhn.u16 d31, q13, q11 + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 + vld4.8 {d0, d1, d2, d3}, [SRC]! + PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] + vmvn.8 d22, d3 + PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! + PF subge PF_X, PF_X, ORIG_W + vmull.u8 q8, d22, d4 + PF subges PF_CTL, PF_CTL, #0x10 + vmull.u8 q9, d22, d5 + PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! + vmull.u8 q10, d22, d6 + PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! + vmull.u8 q11, d22, d7 +.endm + +generate_composite_function \ + pixman_composite_over_8888_8888_asm_neon, 32, 0, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_over_8888_8888_process_pixblock_head, \ + pixman_composite_over_8888_8888_process_pixblock_tail, \ + pixman_composite_over_8888_8888_process_pixblock_tail_head + +generate_composite_function_single_scanline \ + pixman_composite_scanline_over_asm_neon, 32, 0, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + default_init, \ + default_cleanup, \ + pixman_composite_over_8888_8888_process_pixblock_head, \ + pixman_composite_over_8888_8888_process_pixblock_tail, \ + pixman_composite_over_8888_8888_process_pixblock_tail_head + +/******************************************************************************/ + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_over_n_8888_process_pixblock_tail_head + pixman_composite_over_8888_8888_process_pixblock_tail + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! + pixman_composite_over_8888_8888_process_pixblock_head +.endm + +.macro pixman_composite_over_n_8888_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vld1.32 {d3[0]}, [DUMMY] + vdup.8 d0, d3[0] + vdup.8 d1, d3[1] + vdup.8 d2, d3[2] + vdup.8 d3, d3[3] +.endm + +generate_composite_function \ + pixman_composite_over_n_8888_asm_neon, 0, 0, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_n_8888_init, \ + default_cleanup, \ + pixman_composite_over_8888_8888_process_pixblock_head, \ + pixman_composite_over_8888_8888_process_pixblock_tail, \ + pixman_composite_over_n_8888_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_over_reverse_n_8888_process_pixblock_tail_head + vrshr.u16 q14, q8, #8 + PF add PF_X, PF_X, #8 + PF tst PF_CTL, #0xF + vrshr.u16 q15, q9, #8 + vrshr.u16 q12, q10, #8 + vrshr.u16 q13, q11, #8 + PF addne PF_X, PF_X, #8 + PF subne PF_CTL, PF_CTL, #1 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + PF cmp PF_X, ORIG_W + vraddhn.u16 d30, q12, q10 + vraddhn.u16 d31, q13, q11 + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 + vld4.8 {d0, d1, d2, d3}, [DST_R, :128]! + vmvn.8 d22, d3 + PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! + PF subge PF_X, PF_X, ORIG_W + vmull.u8 q8, d22, d4 + PF subges PF_CTL, PF_CTL, #0x10 + vmull.u8 q9, d22, d5 + vmull.u8 q10, d22, d6 + PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! + vmull.u8 q11, d22, d7 +.endm + +.macro pixman_composite_over_reverse_n_8888_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vld1.32 {d7[0]}, [DUMMY] + vdup.8 d4, d7[0] + vdup.8 d5, d7[1] + vdup.8 d6, d7[2] + vdup.8 d7, d7[3] +.endm + +generate_composite_function \ + pixman_composite_over_reverse_n_8888_asm_neon, 0, 0, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_reverse_n_8888_init, \ + default_cleanup, \ + pixman_composite_over_8888_8888_process_pixblock_head, \ + pixman_composite_over_8888_8888_process_pixblock_tail, \ + pixman_composite_over_reverse_n_8888_process_pixblock_tail_head, \ + 28, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 4, /* src_basereg */ \ + 24 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_over_n_8_0565_process_pixblock_head + /* in */ + vmull.u8 q0, d24, d8 + vmull.u8 q1, d24, d9 + vmull.u8 q6, d24, d10 + vmull.u8 q7, d24, d11 + vrshr.u16 q10, q0, #8 + vrshr.u16 q11, q1, #8 + vrshr.u16 q12, q6, #8 + vrshr.u16 q13, q7, #8 + vraddhn.u16 d0, q0, q10 + vraddhn.u16 d1, q1, q11 + vraddhn.u16 d2, q6, q12 + vraddhn.u16 d3, q7, q13 + + vshrn.u16 d6, q2, #8 + vshrn.u16 d7, q2, #3 + vsli.u16 q2, q2, #5 + vsri.u8 d6, d6, #5 + vmvn.8 d3, d3 + vsri.u8 d7, d7, #6 + vshrn.u16 d30, q2, #2 + /* now do alpha blending */ + vmull.u8 q10, d3, d6 + vmull.u8 q11, d3, d7 + vmull.u8 q12, d3, d30 + vrshr.u16 q13, q10, #8 + vrshr.u16 q3, q11, #8 + vrshr.u16 q15, q12, #8 + vraddhn.u16 d20, q10, q13 + vraddhn.u16 d23, q11, q3 + vraddhn.u16 d22, q12, q15 +.endm + +.macro pixman_composite_over_n_8_0565_process_pixblock_tail + vqadd.u8 d16, d2, d20 + vqadd.u8 q9, q0, q11 + /* convert to r5g6b5 */ + vshll.u8 q14, d16, #8 + vshll.u8 q8, d19, #8 + vshll.u8 q9, d18, #8 + vsri.u16 q14, q8, #5 + vsri.u16 q14, q9, #11 +.endm + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_over_n_8_0565_process_pixblock_tail_head + pixman_composite_over_n_8_0565_process_pixblock_tail + vst1.16 {d28, d29}, [DST_W, :128]! + vld1.16 {d4, d5}, [DST_R, :128]! + vld1.8 {d24}, [MASK]! + cache_preload 8, 8 + pixman_composite_over_n_8_0565_process_pixblock_head +.endm + +/* + * This function needs a special initialization of solid mask. + * Solid source pixel data is fetched from stack at ARGS_STACK_OFFSET + * offset, split into color components and replicated in d8-d11 + * registers. Additionally, this function needs all the NEON registers, + * so it has to save d8-d15 registers which are callee saved according + * to ABI. These registers are restored from 'cleanup' macro. All the + * other NEON registers are caller saved, so can be clobbered freely + * without introducing any problems. + */ +.macro pixman_composite_over_n_8_0565_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vpush {d8-d15} + vld1.32 {d11[0]}, [DUMMY] + vdup.8 d8, d11[0] + vdup.8 d9, d11[1] + vdup.8 d10, d11[2] + vdup.8 d11, d11[3] +.endm + +.macro pixman_composite_over_n_8_0565_cleanup + vpop {d8-d15} +.endm + +generate_composite_function \ + pixman_composite_over_n_8_0565_asm_neon, 0, 8, 16, \ + FLAG_DST_READWRITE, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_n_8_0565_init, \ + pixman_composite_over_n_8_0565_cleanup, \ + pixman_composite_over_n_8_0565_process_pixblock_head, \ + pixman_composite_over_n_8_0565_process_pixblock_tail, \ + pixman_composite_over_n_8_0565_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_src_0565_0565_process_pixblock_head +.endm + +.macro pixman_composite_src_0565_0565_process_pixblock_tail +.endm + +.macro pixman_composite_src_0565_0565_process_pixblock_tail_head + vst1.16 {d0, d1, d2, d3}, [DST_W, :128]! + vld1.16 {d0, d1, d2, d3}, [SRC]! + cache_preload 16, 16 +.endm + +generate_composite_function \ + pixman_composite_src_0565_0565_asm_neon, 16, 0, 16, \ + FLAG_DST_WRITEONLY, \ + 16, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_src_0565_0565_process_pixblock_head, \ + pixman_composite_src_0565_0565_process_pixblock_tail, \ + pixman_composite_src_0565_0565_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_n_8_process_pixblock_head +.endm + +.macro pixman_composite_src_n_8_process_pixblock_tail +.endm + +.macro pixman_composite_src_n_8_process_pixblock_tail_head + vst1.8 {d0, d1, d2, d3}, [DST_W, :128]! +.endm + +.macro pixman_composite_src_n_8_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vld1.32 {d0[0]}, [DUMMY] + vsli.u64 d0, d0, #8 + vsli.u64 d0, d0, #16 + vsli.u64 d0, d0, #32 + vmov d1, d0 + vmov q1, q0 +.endm + +.macro pixman_composite_src_n_8_cleanup +.endm + +generate_composite_function \ + pixman_composite_src_n_8_asm_neon, 0, 0, 8, \ + FLAG_DST_WRITEONLY, \ + 32, /* number of pixels, processed in a single block */ \ + 0, /* prefetch distance */ \ + pixman_composite_src_n_8_init, \ + pixman_composite_src_n_8_cleanup, \ + pixman_composite_src_n_8_process_pixblock_head, \ + pixman_composite_src_n_8_process_pixblock_tail, \ + pixman_composite_src_n_8_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_n_0565_process_pixblock_head +.endm + +.macro pixman_composite_src_n_0565_process_pixblock_tail +.endm + +.macro pixman_composite_src_n_0565_process_pixblock_tail_head + vst1.16 {d0, d1, d2, d3}, [DST_W, :128]! +.endm + +.macro pixman_composite_src_n_0565_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vld1.32 {d0[0]}, [DUMMY] + vsli.u64 d0, d0, #16 + vsli.u64 d0, d0, #32 + vmov d1, d0 + vmov q1, q0 +.endm + +.macro pixman_composite_src_n_0565_cleanup +.endm + +generate_composite_function \ + pixman_composite_src_n_0565_asm_neon, 0, 0, 16, \ + FLAG_DST_WRITEONLY, \ + 16, /* number of pixels, processed in a single block */ \ + 0, /* prefetch distance */ \ + pixman_composite_src_n_0565_init, \ + pixman_composite_src_n_0565_cleanup, \ + pixman_composite_src_n_0565_process_pixblock_head, \ + pixman_composite_src_n_0565_process_pixblock_tail, \ + pixman_composite_src_n_0565_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_n_8888_process_pixblock_head +.endm + +.macro pixman_composite_src_n_8888_process_pixblock_tail +.endm + +.macro pixman_composite_src_n_8888_process_pixblock_tail_head + vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! +.endm + +.macro pixman_composite_src_n_8888_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vld1.32 {d0[0]}, [DUMMY] + vsli.u64 d0, d0, #32 + vmov d1, d0 + vmov q1, q0 +.endm + +.macro pixman_composite_src_n_8888_cleanup +.endm + +generate_composite_function \ + pixman_composite_src_n_8888_asm_neon, 0, 0, 32, \ + FLAG_DST_WRITEONLY, \ + 8, /* number of pixels, processed in a single block */ \ + 0, /* prefetch distance */ \ + pixman_composite_src_n_8888_init, \ + pixman_composite_src_n_8888_cleanup, \ + pixman_composite_src_n_8888_process_pixblock_head, \ + pixman_composite_src_n_8888_process_pixblock_tail, \ + pixman_composite_src_n_8888_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_8888_8888_process_pixblock_head +.endm + +.macro pixman_composite_src_8888_8888_process_pixblock_tail +.endm + +.macro pixman_composite_src_8888_8888_process_pixblock_tail_head + vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! + vld1.32 {d0, d1, d2, d3}, [SRC]! + cache_preload 8, 8 +.endm + +generate_composite_function \ + pixman_composite_src_8888_8888_asm_neon, 32, 0, 32, \ + FLAG_DST_WRITEONLY, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_src_8888_8888_process_pixblock_head, \ + pixman_composite_src_8888_8888_process_pixblock_tail, \ + pixman_composite_src_8888_8888_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_x888_8888_process_pixblock_head + vorr q0, q0, q2 + vorr q1, q1, q2 +.endm + +.macro pixman_composite_src_x888_8888_process_pixblock_tail +.endm + +.macro pixman_composite_src_x888_8888_process_pixblock_tail_head + vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! + vld1.32 {d0, d1, d2, d3}, [SRC]! + vorr q0, q0, q2 + vorr q1, q1, q2 + cache_preload 8, 8 +.endm + +.macro pixman_composite_src_x888_8888_init + vmov.u8 q2, #0xFF + vshl.u32 q2, q2, #24 +.endm + +generate_composite_function \ + pixman_composite_src_x888_8888_asm_neon, 32, 0, 32, \ + FLAG_DST_WRITEONLY, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + pixman_composite_src_x888_8888_init, \ + default_cleanup, \ + pixman_composite_src_x888_8888_process_pixblock_head, \ + pixman_composite_src_x888_8888_process_pixblock_tail, \ + pixman_composite_src_x888_8888_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_over_n_8_8888_process_pixblock_head + /* expecting deinterleaved source data in {d8, d9, d10, d11} */ + /* d8 - blue, d9 - green, d10 - red, d11 - alpha */ + /* and destination data in {d4, d5, d6, d7} */ + /* mask is in d24 (d25, d26, d27 are unused) */ + + /* in */ + vmull.u8 q0, d24, d8 + vmull.u8 q1, d24, d9 + vmull.u8 q6, d24, d10 + vmull.u8 q7, d24, d11 + vrshr.u16 q10, q0, #8 + vrshr.u16 q11, q1, #8 + vrshr.u16 q12, q6, #8 + vrshr.u16 q13, q7, #8 + vraddhn.u16 d0, q0, q10 + vraddhn.u16 d1, q1, q11 + vraddhn.u16 d2, q6, q12 + vraddhn.u16 d3, q7, q13 + vmvn.8 d24, d3 /* get inverted alpha */ + /* source: d0 - blue, d1 - green, d2 - red, d3 - alpha */ + /* destination: d4 - blue, d5 - green, d6 - red, d7 - alpha */ + /* now do alpha blending */ + vmull.u8 q8, d24, d4 + vmull.u8 q9, d24, d5 + vmull.u8 q10, d24, d6 + vmull.u8 q11, d24, d7 +.endm + +.macro pixman_composite_over_n_8_8888_process_pixblock_tail + vrshr.u16 q14, q8, #8 + vrshr.u16 q15, q9, #8 + vrshr.u16 q12, q10, #8 + vrshr.u16 q13, q11, #8 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + vraddhn.u16 d30, q12, q10 + vraddhn.u16 d31, q13, q11 + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 +.endm + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_over_n_8_8888_process_pixblock_tail_head + pixman_composite_over_n_8_8888_process_pixblock_tail + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + vld1.8 {d24}, [MASK]! + cache_preload 8, 8 + pixman_composite_over_n_8_8888_process_pixblock_head +.endm + +.macro pixman_composite_over_n_8_8888_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vpush {d8-d15} + vld1.32 {d11[0]}, [DUMMY] + vdup.8 d8, d11[0] + vdup.8 d9, d11[1] + vdup.8 d10, d11[2] + vdup.8 d11, d11[3] +.endm + +.macro pixman_composite_over_n_8_8888_cleanup + vpop {d8-d15} +.endm + +generate_composite_function \ + pixman_composite_over_n_8_8888_asm_neon, 0, 8, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_n_8_8888_init, \ + pixman_composite_over_n_8_8888_cleanup, \ + pixman_composite_over_n_8_8888_process_pixblock_head, \ + pixman_composite_over_n_8_8888_process_pixblock_tail, \ + pixman_composite_over_n_8_8888_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_head + /* + * 'combine_mask_ca' replacement + * + * input: solid src (n) in {d8, d9, d10, d11} + * dest in {d4, d5, d6, d7 } + * mask in {d24, d25, d26, d27} + * output: updated src in {d0, d1, d2, d3 } + * updated mask in {d24, d25, d26, d3 } + */ + vmull.u8 q0, d24, d8 + vmull.u8 q1, d25, d9 + vmull.u8 q6, d26, d10 + vmull.u8 q7, d27, d11 + vmull.u8 q9, d11, d25 + vmull.u8 q12, d11, d24 + vmull.u8 q13, d11, d26 + vrshr.u16 q8, q0, #8 + vrshr.u16 q10, q1, #8 + vrshr.u16 q11, q6, #8 + vraddhn.u16 d0, q0, q8 + vraddhn.u16 d1, q1, q10 + vraddhn.u16 d2, q6, q11 + vrshr.u16 q11, q12, #8 + vrshr.u16 q8, q9, #8 + vrshr.u16 q6, q13, #8 + vrshr.u16 q10, q7, #8 + vraddhn.u16 d24, q12, q11 + vraddhn.u16 d25, q9, q8 + vraddhn.u16 d26, q13, q6 + vraddhn.u16 d3, q7, q10 + /* + * 'combine_over_ca' replacement + * + * output: updated dest in {d28, d29, d30, d31} + */ + vmvn.8 d24, d24 + vmvn.8 d25, d25 + vmull.u8 q8, d24, d4 + vmull.u8 q9, d25, d5 + vmvn.8 d26, d26 + vmvn.8 d27, d3 + vmull.u8 q10, d26, d6 + vmull.u8 q11, d27, d7 +.endm + +.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_tail + /* ... continue 'combine_over_ca' replacement */ + vrshr.u16 q14, q8, #8 + vrshr.u16 q15, q9, #8 + vrshr.u16 q6, q10, #8 + vrshr.u16 q7, q11, #8 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + vraddhn.u16 d30, q6, q10 + vraddhn.u16 d31, q7, q11 + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 +.endm + +.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_tail_head + vrshr.u16 q14, q8, #8 + vrshr.u16 q15, q9, #8 + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + vrshr.u16 q6, q10, #8 + vrshr.u16 q7, q11, #8 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + vraddhn.u16 d30, q6, q10 + vraddhn.u16 d31, q7, q11 + vld4.8 {d24, d25, d26, d27}, [MASK]! + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 + cache_preload 8, 8 + pixman_composite_over_n_8888_8888_ca_process_pixblock_head + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! +.endm + +.macro pixman_composite_over_n_8888_8888_ca_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vpush {d8-d15} + vld1.32 {d11[0]}, [DUMMY] + vdup.8 d8, d11[0] + vdup.8 d9, d11[1] + vdup.8 d10, d11[2] + vdup.8 d11, d11[3] +.endm + +.macro pixman_composite_over_n_8888_8888_ca_cleanup + vpop {d8-d15} +.endm + +generate_composite_function \ + pixman_composite_over_n_8888_8888_ca_asm_neon, 0, 32, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_n_8888_8888_ca_init, \ + pixman_composite_over_n_8888_8888_ca_cleanup, \ + pixman_composite_over_n_8888_8888_ca_process_pixblock_head, \ + pixman_composite_over_n_8888_8888_ca_process_pixblock_tail, \ + pixman_composite_over_n_8888_8888_ca_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_add_n_8_8_process_pixblock_head + /* expecting source data in {d8, d9, d10, d11} */ + /* d8 - blue, d9 - green, d10 - red, d11 - alpha */ + /* and destination data in {d4, d5, d6, d7} */ + /* mask is in d24, d25, d26, d27 */ + vmull.u8 q0, d24, d11 + vmull.u8 q1, d25, d11 + vmull.u8 q6, d26, d11 + vmull.u8 q7, d27, d11 + vrshr.u16 q10, q0, #8 + vrshr.u16 q11, q1, #8 + vrshr.u16 q12, q6, #8 + vrshr.u16 q13, q7, #8 + vraddhn.u16 d0, q0, q10 + vraddhn.u16 d1, q1, q11 + vraddhn.u16 d2, q6, q12 + vraddhn.u16 d3, q7, q13 + vqadd.u8 q14, q0, q2 + vqadd.u8 q15, q1, q3 +.endm + +.macro pixman_composite_add_n_8_8_process_pixblock_tail +.endm + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_add_n_8_8_process_pixblock_tail_head + pixman_composite_add_n_8_8_process_pixblock_tail + vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! + vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! + vld1.8 {d24, d25, d26, d27}, [MASK]! + cache_preload 32, 32 + pixman_composite_add_n_8_8_process_pixblock_head +.endm + +.macro pixman_composite_add_n_8_8_init + add DUMMY, sp, #ARGS_STACK_OFFSET + vpush {d8-d15} + vld1.32 {d11[0]}, [DUMMY] + vdup.8 d11, d11[3] +.endm + +.macro pixman_composite_add_n_8_8_cleanup + vpop {d8-d15} +.endm + +generate_composite_function \ + pixman_composite_add_n_8_8_asm_neon, 0, 8, 8, \ + FLAG_DST_READWRITE, \ + 32, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_add_n_8_8_init, \ + pixman_composite_add_n_8_8_cleanup, \ + pixman_composite_add_n_8_8_process_pixblock_head, \ + pixman_composite_add_n_8_8_process_pixblock_tail, \ + pixman_composite_add_n_8_8_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_add_8_8_8_process_pixblock_head + /* expecting source data in {d0, d1, d2, d3} */ + /* destination data in {d4, d5, d6, d7} */ + /* mask in {d24, d25, d26, d27} */ + vmull.u8 q8, d24, d0 + vmull.u8 q9, d25, d1 + vmull.u8 q10, d26, d2 + vmull.u8 q11, d27, d3 + vrshr.u16 q0, q8, #8 + vrshr.u16 q1, q9, #8 + vrshr.u16 q12, q10, #8 + vrshr.u16 q13, q11, #8 + vraddhn.u16 d0, q0, q8 + vraddhn.u16 d1, q1, q9 + vraddhn.u16 d2, q12, q10 + vraddhn.u16 d3, q13, q11 + vqadd.u8 q14, q0, q2 + vqadd.u8 q15, q1, q3 +.endm + +.macro pixman_composite_add_8_8_8_process_pixblock_tail +.endm + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_add_8_8_8_process_pixblock_tail_head + pixman_composite_add_8_8_8_process_pixblock_tail + vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! + vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! + vld1.8 {d24, d25, d26, d27}, [MASK]! + vld1.8 {d0, d1, d2, d3}, [SRC]! + cache_preload 32, 32 + pixman_composite_add_8_8_8_process_pixblock_head +.endm + +.macro pixman_composite_add_8_8_8_init +.endm + +.macro pixman_composite_add_8_8_8_cleanup +.endm + +generate_composite_function \ + pixman_composite_add_8_8_8_asm_neon, 8, 8, 8, \ + FLAG_DST_READWRITE, \ + 32, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_add_8_8_8_init, \ + pixman_composite_add_8_8_8_cleanup, \ + pixman_composite_add_8_8_8_process_pixblock_head, \ + pixman_composite_add_8_8_8_process_pixblock_tail, \ + pixman_composite_add_8_8_8_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_add_8888_8888_8888_process_pixblock_head + /* expecting source data in {d0, d1, d2, d3} */ + /* destination data in {d4, d5, d6, d7} */ + /* mask in {d24, d25, d26, d27} */ + vmull.u8 q8, d27, d0 + vmull.u8 q9, d27, d1 + vmull.u8 q10, d27, d2 + vmull.u8 q11, d27, d3 + vrshr.u16 q0, q8, #8 + vrshr.u16 q1, q9, #8 + vrshr.u16 q12, q10, #8 + vrshr.u16 q13, q11, #8 + vraddhn.u16 d0, q0, q8 + vraddhn.u16 d1, q1, q9 + vraddhn.u16 d2, q12, q10 + vraddhn.u16 d3, q13, q11 + vqadd.u8 q14, q0, q2 + vqadd.u8 q15, q1, q3 +.endm + +.macro pixman_composite_add_8888_8888_8888_process_pixblock_tail +.endm + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_add_8888_8888_8888_process_pixblock_tail_head + pixman_composite_add_8888_8888_8888_process_pixblock_tail + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + vld4.8 {d24, d25, d26, d27}, [MASK]! + vld4.8 {d0, d1, d2, d3}, [SRC]! + cache_preload 8, 8 + pixman_composite_add_8888_8888_8888_process_pixblock_head +.endm + +generate_composite_function \ + pixman_composite_add_8888_8888_8888_asm_neon, 32, 32, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_add_8888_8888_8888_process_pixblock_head, \ + pixman_composite_add_8888_8888_8888_process_pixblock_tail, \ + pixman_composite_add_8888_8888_8888_process_pixblock_tail_head + +generate_composite_function_single_scanline \ + pixman_composite_scanline_add_mask_asm_neon, 32, 32, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + default_init, \ + default_cleanup, \ + pixman_composite_add_8888_8888_8888_process_pixblock_head, \ + pixman_composite_add_8888_8888_8888_process_pixblock_tail, \ + pixman_composite_add_8888_8888_8888_process_pixblock_tail_head + +/******************************************************************************/ + +.macro pixman_composite_over_8888_n_8888_process_pixblock_head + /* expecting source data in {d0, d1, d2, d3} */ + /* destination data in {d4, d5, d6, d7} */ + /* solid mask is in d15 */ + + /* 'in' */ + vmull.u8 q8, d15, d3 + vmull.u8 q6, d15, d2 + vmull.u8 q5, d15, d1 + vmull.u8 q4, d15, d0 + vrshr.u16 q13, q8, #8 + vrshr.u16 q12, q6, #8 + vrshr.u16 q11, q5, #8 + vrshr.u16 q10, q4, #8 + vraddhn.u16 d3, q8, q13 + vraddhn.u16 d2, q6, q12 + vraddhn.u16 d1, q5, q11 + vraddhn.u16 d0, q4, q10 + vmvn.8 d24, d3 /* get inverted alpha */ + /* now do alpha blending */ + vmull.u8 q8, d24, d4 + vmull.u8 q9, d24, d5 + vmull.u8 q10, d24, d6 + vmull.u8 q11, d24, d7 +.endm + +.macro pixman_composite_over_8888_n_8888_process_pixblock_tail + vrshr.u16 q14, q8, #8 + vrshr.u16 q15, q9, #8 + vrshr.u16 q12, q10, #8 + vrshr.u16 q13, q11, #8 + vraddhn.u16 d28, q14, q8 + vraddhn.u16 d29, q15, q9 + vraddhn.u16 d30, q12, q10 + vraddhn.u16 d31, q13, q11 + vqadd.u8 q14, q0, q14 + vqadd.u8 q15, q1, q15 +.endm + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_over_8888_n_8888_process_pixblock_tail_head + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + pixman_composite_over_8888_n_8888_process_pixblock_tail + vld4.8 {d0, d1, d2, d3}, [SRC]! + cache_preload 8, 8 + pixman_composite_over_8888_n_8888_process_pixblock_head + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! +.endm + +.macro pixman_composite_over_8888_n_8888_init + add DUMMY, sp, #48 + vpush {d8-d15} + vld1.32 {d15[0]}, [DUMMY] + vdup.8 d15, d15[3] +.endm + +.macro pixman_composite_over_8888_n_8888_cleanup + vpop {d8-d15} +.endm + +generate_composite_function \ + pixman_composite_over_8888_n_8888_asm_neon, 32, 0, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_8888_n_8888_init, \ + pixman_composite_over_8888_n_8888_cleanup, \ + pixman_composite_over_8888_n_8888_process_pixblock_head, \ + pixman_composite_over_8888_n_8888_process_pixblock_tail, \ + pixman_composite_over_8888_n_8888_process_pixblock_tail_head + +/******************************************************************************/ + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_over_8888_8888_8888_process_pixblock_tail_head + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + pixman_composite_over_8888_n_8888_process_pixblock_tail + vld4.8 {d0, d1, d2, d3}, [SRC]! + cache_preload 8, 8 + vld4.8 {d12, d13, d14, d15}, [MASK]! + pixman_composite_over_8888_n_8888_process_pixblock_head + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! +.endm + +.macro pixman_composite_over_8888_8888_8888_init + vpush {d8-d15} +.endm + +.macro pixman_composite_over_8888_8888_8888_cleanup + vpop {d8-d15} +.endm + +generate_composite_function \ + pixman_composite_over_8888_8888_8888_asm_neon, 32, 32, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_8888_8888_8888_init, \ + pixman_composite_over_8888_8888_8888_cleanup, \ + pixman_composite_over_8888_n_8888_process_pixblock_head, \ + pixman_composite_over_8888_n_8888_process_pixblock_tail, \ + pixman_composite_over_8888_8888_8888_process_pixblock_tail_head \ + 28, /* dst_w_basereg */ \ + 4, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 12 /* mask_basereg */ + +generate_composite_function_single_scanline \ + pixman_composite_scanline_over_mask_asm_neon, 32, 32, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + pixman_composite_over_8888_8888_8888_init, \ + pixman_composite_over_8888_8888_8888_cleanup, \ + pixman_composite_over_8888_n_8888_process_pixblock_head, \ + pixman_composite_over_8888_n_8888_process_pixblock_tail, \ + pixman_composite_over_8888_8888_8888_process_pixblock_tail_head \ + 28, /* dst_w_basereg */ \ + 4, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 12 /* mask_basereg */ + +/******************************************************************************/ + +/* TODO: expand macros and do better instructions scheduling */ +.macro pixman_composite_over_8888_8_8888_process_pixblock_tail_head + vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! + pixman_composite_over_8888_n_8888_process_pixblock_tail + vld4.8 {d0, d1, d2, d3}, [SRC]! + cache_preload 8, 8 + vld1.8 {d15}, [MASK]! + pixman_composite_over_8888_n_8888_process_pixblock_head + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! +.endm + +.macro pixman_composite_over_8888_8_8888_init + vpush {d8-d15} +.endm + +.macro pixman_composite_over_8888_8_8888_cleanup + vpop {d8-d15} +.endm + +generate_composite_function \ + pixman_composite_over_8888_8_8888_asm_neon, 32, 8, 32, \ + FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 5, /* prefetch distance */ \ + pixman_composite_over_8888_8_8888_init, \ + pixman_composite_over_8888_8_8888_cleanup, \ + pixman_composite_over_8888_n_8888_process_pixblock_head, \ + pixman_composite_over_8888_n_8888_process_pixblock_tail, \ + pixman_composite_over_8888_8_8888_process_pixblock_tail_head \ + 28, /* dst_w_basereg */ \ + 4, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 15 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_0888_0888_process_pixblock_head +.endm + +.macro pixman_composite_src_0888_0888_process_pixblock_tail +.endm + +.macro pixman_composite_src_0888_0888_process_pixblock_tail_head + vst3.8 {d0, d1, d2}, [DST_W]! + vld3.8 {d0, d1, d2}, [SRC]! + cache_preload 8, 8 +.endm + +generate_composite_function \ + pixman_composite_src_0888_0888_asm_neon, 24, 0, 24, \ + FLAG_DST_WRITEONLY, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_src_0888_0888_process_pixblock_head, \ + pixman_composite_src_0888_0888_process_pixblock_tail, \ + pixman_composite_src_0888_0888_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_0888_8888_rev_process_pixblock_head + vswp d0, d2 +.endm + +.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail +.endm + +.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail_head + vst4.8 {d0, d1, d2, d3}, [DST_W]! + vld3.8 {d0, d1, d2}, [SRC]! + vswp d0, d2 + cache_preload 8, 8 +.endm + +.macro pixman_composite_src_0888_8888_rev_init + veor d3, d3, d3 +.endm + +generate_composite_function \ + pixman_composite_src_0888_8888_rev_asm_neon, 24, 0, 32, \ + FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + pixman_composite_src_0888_8888_rev_init, \ + default_cleanup, \ + pixman_composite_src_0888_8888_rev_process_pixblock_head, \ + pixman_composite_src_0888_8888_rev_process_pixblock_tail, \ + pixman_composite_src_0888_8888_rev_process_pixblock_tail_head, \ + 0, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_0888_0565_rev_process_pixblock_head + vshll.u8 q8, d1, #8 + vshll.u8 q9, d2, #8 +.endm + +.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail + vshll.u8 q14, d0, #8 + vsri.u16 q14, q8, #5 + vsri.u16 q14, q9, #11 +.endm + +.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail_head + vshll.u8 q14, d0, #8 + vld3.8 {d0, d1, d2}, [SRC]! + vsri.u16 q14, q8, #5 + vsri.u16 q14, q9, #11 + vshll.u8 q8, d1, #8 + vst1.16 {d28, d29}, [DST_W, :128]! + vshll.u8 q9, d2, #8 +.endm + +generate_composite_function \ + pixman_composite_src_0888_0565_rev_asm_neon, 24, 0, 16, \ + FLAG_DST_WRITEONLY, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_src_0888_0565_rev_process_pixblock_head, \ + pixman_composite_src_0888_0565_rev_process_pixblock_tail, \ + pixman_composite_src_0888_0565_rev_process_pixblock_tail_head, \ + 28, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ + +/******************************************************************************/ + +.macro pixman_composite_src_pixbuf_8888_process_pixblock_head + vmull.u8 q8, d3, d0 + vmull.u8 q9, d3, d1 + vmull.u8 q10, d3, d2 +.endm + +.macro pixman_composite_src_pixbuf_8888_process_pixblock_tail + vrshr.u16 q11, q8, #8 + vswp d3, d31 + vrshr.u16 q12, q9, #8 + vrshr.u16 q13, q10, #8 + vraddhn.u16 d30, q11, q8 + vraddhn.u16 d29, q12, q9 + vraddhn.u16 d28, q13, q10 +.endm + +.macro pixman_composite_src_pixbuf_8888_process_pixblock_tail_head + vrshr.u16 q11, q8, #8 + vswp d3, d31 + vrshr.u16 q12, q9, #8 + vrshr.u16 q13, q10, #8 + vld4.8 {d0, d1, d2, d3}, [SRC]! + vraddhn.u16 d30, q11, q8 + PF add PF_X, PF_X, #8 + PF tst PF_CTL, #0xF + PF addne PF_X, PF_X, #8 + PF subne PF_CTL, PF_CTL, #1 + vraddhn.u16 d29, q12, q9 + vraddhn.u16 d28, q13, q10 + vmull.u8 q8, d3, d0 + vmull.u8 q9, d3, d1 + vmull.u8 q10, d3, d2 + vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! + PF cmp PF_X, ORIG_W + PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] + PF subge PF_X, PF_X, ORIG_W + PF subges PF_CTL, PF_CTL, #0x10 + PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! +.endm + +generate_composite_function \ + pixman_composite_src_pixbuf_8888_asm_neon, 32, 0, 32, \ + FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ + 8, /* number of pixels, processed in a single block */ \ + 10, /* prefetch distance */ \ + default_init, \ + default_cleanup, \ + pixman_composite_src_pixbuf_8888_process_pixblock_head, \ + pixman_composite_src_pixbuf_8888_process_pixblock_tail, \ + pixman_composite_src_pixbuf_8888_process_pixblock_tail_head, \ + 28, /* dst_w_basereg */ \ + 0, /* dst_r_basereg */ \ + 0, /* src_basereg */ \ + 0 /* mask_basereg */ diff --git a/src/3rdparty/pixman/pixman-arm-neon-asm.h b/src/3rdparty/pixman/pixman-arm-neon-asm.h new file mode 100644 index 0000000..56c3fae --- /dev/null +++ b/src/3rdparty/pixman/pixman-arm-neon-asm.h @@ -0,0 +1,906 @@ +/* + * Copyright © 2009 Nokia Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) + */ + +/* + * This file contains a macro ('generate_composite_function') which can + * construct 2D image processing functions, based on a common template. + * Any combinations of source, destination and mask images with 8bpp, + * 16bpp, 24bpp, 32bpp color formats are supported. + * + * This macro takes care of: + * - handling of leading and trailing unaligned pixels + * - doing most of the work related to L2 cache preload + * - encourages the use of software pipelining for better instructions + * scheduling + * + * The user of this macro has to provide some configuration parameters + * (bit depths for the images, prefetch distance, etc.) and a set of + * macros, which should implement basic code chunks responsible for + * pixels processing. See 'pixman-arm-neon-asm.S' file for the usage + * examples. + * + * TODO: + * - try overlapped pixel method (from Ian Rickards) when processing + * exactly two blocks of pixels + * - maybe add an option to do reverse scanline processing + */ + +/* + * Bit flags for 'generate_composite_function' macro which are used + * to tune generated functions behavior. + */ +.set FLAG_DST_WRITEONLY, 0 +.set FLAG_DST_READWRITE, 1 +.set FLAG_DEINTERLEAVE_32BPP, 2 + +/* + * Offset in stack where mask and source pointer/stride can be accessed + * from 'init' macro. This is useful for doing special handling for solid mask. + */ +.set ARGS_STACK_OFFSET, 40 + +/* + * Constants for selecting preferable prefetch type. + */ +.set PREFETCH_TYPE_NONE, 0 /* No prefetch at all */ +.set PREFETCH_TYPE_SIMPLE, 1 /* A simple, fixed-distance-ahead prefetch */ +.set PREFETCH_TYPE_ADVANCED, 2 /* Advanced fine-grained prefetch */ + +/* + * Definitions of supplementary pixld/pixst macros (for partial load/store of + * pixel data). + */ + +.macro pixldst1 op, elem_size, reg1, mem_operand, abits +.if abits > 0 + op&.&elem_size {d®1}, [&mem_operand&, :&abits&]! +.else + op&.&elem_size {d®1}, [&mem_operand&]! +.endif +.endm + +.macro pixldst2 op, elem_size, reg1, reg2, mem_operand, abits +.if abits > 0 + op&.&elem_size {d®1, d®2}, [&mem_operand&, :&abits&]! +.else + op&.&elem_size {d®1, d®2}, [&mem_operand&]! +.endif +.endm + +.macro pixldst4 op, elem_size, reg1, reg2, reg3, reg4, mem_operand, abits +.if abits > 0 + op&.&elem_size {d®1, d®2, d®3, d®4}, [&mem_operand&, :&abits&]! +.else + op&.&elem_size {d®1, d®2, d®3, d®4}, [&mem_operand&]! +.endif +.endm + +.macro pixldst0 op, elem_size, reg1, idx, mem_operand, abits + op&.&elem_size {d®1[idx]}, [&mem_operand&]! +.endm + +.macro pixldst3 op, elem_size, reg1, reg2, reg3, mem_operand + op&.&elem_size {d®1, d®2, d®3}, [&mem_operand&]! +.endm + +.macro pixldst30 op, elem_size, reg1, reg2, reg3, idx, mem_operand + op&.&elem_size {d®1[idx], d®2[idx], d®3[idx]}, [&mem_operand&]! +.endm + +.macro pixldst numbytes, op, elem_size, basereg, mem_operand, abits +.if numbytes == 32 + pixldst4 op, elem_size, %(basereg+4), %(basereg+5), \ + %(basereg+6), %(basereg+7), mem_operand, abits +.elseif numbytes == 16 + pixldst2 op, elem_size, %(basereg+2), %(basereg+3), mem_operand, abits +.elseif numbytes == 8 + pixldst1 op, elem_size, %(basereg+1), mem_operand, abits +.elseif numbytes == 4 + .if !RESPECT_STRICT_ALIGNMENT || (elem_size == 32) + pixldst0 op, 32, %(basereg+0), 1, mem_operand, abits + .elseif elem_size == 16 + pixldst0 op, 16, %(basereg+0), 2, mem_operand, abits + pixldst0 op, 16, %(basereg+0), 3, mem_operand, abits + .else + pixldst0 op, 8, %(basereg+0), 4, mem_operand, abits + pixldst0 op, 8, %(basereg+0), 5, mem_operand, abits + pixldst0 op, 8, %(basereg+0), 6, mem_operand, abits + pixldst0 op, 8, %(basereg+0), 7, mem_operand, abits + .endif +.elseif numbytes == 2 + .if !RESPECT_STRICT_ALIGNMENT || (elem_size == 16) + pixldst0 op, 16, %(basereg+0), 1, mem_operand, abits + .else + pixldst0 op, 8, %(basereg+0), 2, mem_operand, abits + pixldst0 op, 8, %(basereg+0), 3, mem_operand, abits + .endif +.elseif numbytes == 1 + pixldst0 op, 8, %(basereg+0), 1, mem_operand, abits +.else + .error "unsupported size: numbytes" +.endif +.endm + +.macro pixld numpix, bpp, basereg, mem_operand, abits=0 +.if bpp > 0 +.if (bpp == 32) && (numpix == 8) && (DEINTERLEAVE_32BPP_ENABLED != 0) + pixldst4 vld4, 8, %(basereg+4), %(basereg+5), \ + %(basereg+6), %(basereg+7), mem_operand, abits +.elseif (bpp == 24) && (numpix == 8) + pixldst3 vld3, 8, %(basereg+3), %(basereg+4), %(basereg+5), mem_operand +.elseif (bpp == 24) && (numpix == 4) + pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 4, mem_operand + pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 5, mem_operand + pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 6, mem_operand + pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 7, mem_operand +.elseif (bpp == 24) && (numpix == 2) + pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 2, mem_operand + pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 3, mem_operand +.elseif (bpp == 24) && (numpix == 1) + pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 1, mem_operand +.else + pixldst %(numpix * bpp / 8), vld1, %(bpp), basereg, mem_operand, abits +.endif +.endif +.endm + +.macro pixst numpix, bpp, basereg, mem_operand, abits=0 +.if bpp > 0 +.if (bpp == 32) && (numpix == 8) && (DEINTERLEAVE_32BPP_ENABLED != 0) + pixldst4 vst4, 8, %(basereg+4), %(basereg+5), \ + %(basereg+6), %(basereg+7), mem_operand, abits +.elseif (bpp == 24) && (numpix == 8) + pixldst3 vst3, 8, %(basereg+3), %(basereg+4), %(basereg+5), mem_operand +.elseif (bpp == 24) && (numpix == 4) + pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 4, mem_operand + pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 5, mem_operand + pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 6, mem_operand + pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 7, mem_operand +.elseif (bpp == 24) && (numpix == 2) + pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 2, mem_operand + pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 3, mem_operand +.elseif (bpp == 24) && (numpix == 1) + pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 1, mem_operand +.else + pixldst %(numpix * bpp / 8), vst1, %(bpp), basereg, mem_operand, abits +.endif +.endif +.endm + +.macro pixld_a numpix, bpp, basereg, mem_operand +.if (bpp * numpix) <= 128 + pixld numpix, bpp, basereg, mem_operand, %(bpp * numpix) +.else + pixld numpix, bpp, basereg, mem_operand, 128 +.endif +.endm + +.macro pixst_a numpix, bpp, basereg, mem_operand +.if (bpp * numpix) <= 128 + pixst numpix, bpp, basereg, mem_operand, %(bpp * numpix) +.else + pixst numpix, bpp, basereg, mem_operand, 128 +.endif +.endm + +.macro vuzp8 reg1, reg2 + vuzp.8 d®1, d®2 +.endm + +.macro vzip8 reg1, reg2 + vzip.8 d®1, d®2 +.endm + +/* deinterleave B, G, R, A channels for eight 32bpp pixels in 4 registers */ +.macro pixdeinterleave bpp, basereg +.if (bpp == 32) && (DEINTERLEAVE_32BPP_ENABLED != 0) + vuzp8 %(basereg+0), %(basereg+1) + vuzp8 %(basereg+2), %(basereg+3) + vuzp8 %(basereg+1), %(basereg+3) + vuzp8 %(basereg+0), %(basereg+2) +.endif +.endm + +/* interleave B, G, R, A channels for eight 32bpp pixels in 4 registers */ +.macro pixinterleave bpp, basereg +.if (bpp == 32) && (DEINTERLEAVE_32BPP_ENABLED != 0) + vzip8 %(basereg+0), %(basereg+2) + vzip8 %(basereg+1), %(basereg+3) + vzip8 %(basereg+2), %(basereg+3) + vzip8 %(basereg+0), %(basereg+1) +.endif +.endm + +/* + * This is a macro for implementing cache preload. The main idea is that + * cache preload logic is mostly independent from the rest of pixels + * processing code. It starts at the top left pixel and moves forward + * across pixels and can jump across scanlines. Prefetch distance is + * handled in an 'incremental' way: it starts from 0 and advances to the + * optimal distance over time. After reaching optimal prefetch distance, + * it is kept constant. There are some checks which prevent prefetching + * unneeded pixel lines below the image (but it still can prefetch a bit + * more data on the right side of the image - not a big issue and may + * be actually helpful when rendering text glyphs). Additional trick is + * the use of LDR instruction for prefetch instead of PLD when moving to + * the next line, the point is that we have a high chance of getting TLB + * miss in this case, and PLD would be useless. + * + * This sounds like it may introduce a noticeable overhead (when working with + * fully cached data). But in reality, due to having a separate pipeline and + * instruction queue for NEON unit in ARM Cortex-A8, normal ARM code can + * execute simultaneously with NEON and be completely shadowed by it. Thus + * we get no performance overhead at all (*). This looks like a very nice + * feature of Cortex-A8, if used wisely. We don't have a hardware prefetcher, + * but still can implement some rather advanced prefetch logic in sofware + * for almost zero cost! + * + * (*) The overhead of the prefetcher is visible when running some trivial + * pixels processing like simple copy. Anyway, having prefetch is a must + * when working with the graphics data. + */ +.macro PF a, x:vararg +.if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_ADVANCED) + a x +.endif +.endm + +.macro cache_preload std_increment, boost_increment +.if (src_bpp_shift >= 0) || (dst_r_bpp != 0) || (mask_bpp_shift >= 0) +.if regs_shortage + PF ldr ORIG_W, [sp] /* If we are short on regs, ORIG_W is kept on stack */ +.endif +.if std_increment != 0 + PF add PF_X, PF_X, #std_increment +.endif + PF tst PF_CTL, #0xF + PF addne PF_X, PF_X, #boost_increment + PF subne PF_CTL, PF_CTL, #1 + PF cmp PF_X, ORIG_W +.if src_bpp_shift >= 0 + PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] +.endif +.if dst_r_bpp != 0 + PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] +.endif +.if mask_bpp_shift >= 0 + PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift] +.endif + PF subge PF_X, PF_X, ORIG_W + PF subges PF_CTL, PF_CTL, #0x10 +.if src_bpp_shift >= 0 + PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! +.endif +.if dst_r_bpp != 0 + PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! +.endif +.if mask_bpp_shift >= 0 + PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]! +.endif +.endif +.endm + +.macro cache_preload_simple +.if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_SIMPLE) +.if src_bpp > 0 + pld [SRC, #(PREFETCH_DISTANCE_SIMPLE * src_bpp / 8)] +.endif +.if dst_r_bpp > 0 + pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE * dst_r_bpp / 8)] +.endif +.if mask_bpp > 0 + pld [MASK, #(PREFETCH_DISTANCE_SIMPLE * mask_bpp / 8)] +.endif +.endif +.endm + +/* + * Macro which is used to process leading pixels until destination + * pointer is properly aligned (at 16 bytes boundary). When destination + * buffer uses 16bpp format, this is unnecessary, or even pointless. + */ +.macro ensure_destination_ptr_alignment process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head +.if dst_w_bpp != 24 + tst DST_R, #0xF + beq 2f + +.irp lowbit, 1, 2, 4, 8, 16 +local skip1 +.if (dst_w_bpp <= (lowbit * 8)) && ((lowbit * 8) < (pixblock_size * dst_w_bpp)) +.if lowbit < 16 /* we don't need more than 16-byte alignment */ + tst DST_R, #lowbit + beq 1f +.endif + pixld (lowbit * 8 / dst_w_bpp), src_bpp, src_basereg, SRC + pixld (lowbit * 8 / dst_w_bpp), mask_bpp, mask_basereg, MASK +.if dst_r_bpp > 0 + pixld_a (lowbit * 8 / dst_r_bpp), dst_r_bpp, dst_r_basereg, DST_R +.else + add DST_R, DST_R, #lowbit +.endif + PF add PF_X, PF_X, #(lowbit * 8 / dst_w_bpp) + sub W, W, #(lowbit * 8 / dst_w_bpp) +1: +.endif +.endr + pixdeinterleave src_bpp, src_basereg + pixdeinterleave mask_bpp, mask_basereg + pixdeinterleave dst_r_bpp, dst_r_basereg + + process_pixblock_head + cache_preload 0, pixblock_size + cache_preload_simple + process_pixblock_tail + + pixinterleave dst_w_bpp, dst_w_basereg +.irp lowbit, 1, 2, 4, 8, 16 +.if (dst_w_bpp <= (lowbit * 8)) && ((lowbit * 8) < (pixblock_size * dst_w_bpp)) +.if lowbit < 16 /* we don't need more than 16-byte alignment */ + tst DST_W, #lowbit + beq 1f +.endif + pixst_a (lowbit * 8 / dst_w_bpp), dst_w_bpp, dst_w_basereg, DST_W +1: +.endif +.endr +.endif +2: +.endm + +/* + * Special code for processing up to (pixblock_size - 1) remaining + * trailing pixels. As SIMD processing performs operation on + * pixblock_size pixels, anything smaller than this has to be loaded + * and stored in a special way. Loading and storing of pixel data is + * performed in such a way that we fill some 'slots' in the NEON + * registers (some slots naturally are unused), then perform compositing + * operation as usual. In the end, the data is taken from these 'slots' + * and saved to memory. + * + * cache_preload_flag - allows to suppress prefetch if + * set to 0 + * dst_aligned_flag - selects whether destination buffer + * is aligned + */ +.macro process_trailing_pixels cache_preload_flag, \ + dst_aligned_flag, \ + process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head + tst W, #(pixblock_size - 1) + beq 2f +.irp chunk_size, 16, 8, 4, 2, 1 +.if pixblock_size > chunk_size + tst W, #chunk_size + beq 1f + pixld chunk_size, src_bpp, src_basereg, SRC + pixld chunk_size, mask_bpp, mask_basereg, MASK +.if dst_aligned_flag != 0 + pixld_a chunk_size, dst_r_bpp, dst_r_basereg, DST_R +.else + pixld chunk_size, dst_r_bpp, dst_r_basereg, DST_R +.endif +.if cache_preload_flag != 0 + PF add PF_X, PF_X, #chunk_size +.endif +1: +.endif +.endr + pixdeinterleave src_bpp, src_basereg + pixdeinterleave mask_bpp, mask_basereg + pixdeinterleave dst_r_bpp, dst_r_basereg + + process_pixblock_head +.if cache_preload_flag != 0 + cache_preload 0, pixblock_size + cache_preload_simple +.endif + process_pixblock_tail + pixinterleave dst_w_bpp, dst_w_basereg +.irp chunk_size, 16, 8, 4, 2, 1 +.if pixblock_size > chunk_size + tst W, #chunk_size + beq 1f +.if dst_aligned_flag != 0 + pixst_a chunk_size, dst_w_bpp, dst_w_basereg, DST_W +.else + pixst chunk_size, dst_w_bpp, dst_w_basereg, DST_W +.endif +1: +.endif +.endr +2: +.endm + +/* + * Macro, which performs all the needed operations to switch to the next + * scanline and start the next loop iteration unless all the scanlines + * are already processed. + */ +.macro advance_to_next_scanline start_of_loop_label +.if regs_shortage + ldrd W, [sp] /* load W and H (width and height) from stack */ +.else + mov W, ORIG_W +.endif + add DST_W, DST_W, DST_STRIDE, lsl #dst_bpp_shift +.if src_bpp != 0 + add SRC, SRC, SRC_STRIDE, lsl #src_bpp_shift +.endif +.if mask_bpp != 0 + add MASK, MASK, MASK_STRIDE, lsl #mask_bpp_shift +.endif +.if (dst_w_bpp != 24) + sub DST_W, DST_W, W, lsl #dst_bpp_shift +.endif +.if (src_bpp != 24) && (src_bpp != 0) + sub SRC, SRC, W, lsl #src_bpp_shift +.endif +.if (mask_bpp != 24) && (mask_bpp != 0) + sub MASK, MASK, W, lsl #mask_bpp_shift +.endif + subs H, H, #1 + mov DST_R, DST_W +.if regs_shortage + str H, [sp, #4] /* save updated height to stack */ +.endif + bge start_of_loop_label +.endm + +/* + * Registers are allocated in the following way by default: + * d0, d1, d2, d3 - reserved for loading source pixel data + * d4, d5, d6, d7 - reserved for loading destination pixel data + * d24, d25, d26, d27 - reserved for loading mask pixel data + * d28, d29, d30, d31 - final destination pixel data for writeback to memory + */ +.macro generate_composite_function fname, \ + src_bpp_, \ + mask_bpp_, \ + dst_w_bpp_, \ + flags, \ + pixblock_size_, \ + prefetch_distance, \ + init, \ + cleanup, \ + process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head, \ + dst_w_basereg_ = 28, \ + dst_r_basereg_ = 4, \ + src_basereg_ = 0, \ + mask_basereg_ = 24 + + .func fname + .global fname + /* For ELF format also set function visibility to hidden */ +#ifdef __ELF__ + .hidden fname + .type fname, %function +#endif +fname: + push {r4-r12, lr} /* save all registers */ + +/* + * Select prefetch type for this function. If prefetch distance is + * set to 0 or one of the color formats is 24bpp, SIMPLE prefetch + * has to be used instead of ADVANCED. + */ + .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_DEFAULT +.if prefetch_distance == 0 + .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE +.elseif (PREFETCH_TYPE_CURRENT > PREFETCH_TYPE_SIMPLE) && \ + ((src_bpp_ == 24) || (mask_bpp_ == 24) || (dst_w_bpp_ == 24)) + .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_SIMPLE +.endif + +/* + * Make some macro arguments globally visible and accessible + * from other macros + */ + .set src_bpp, src_bpp_ + .set mask_bpp, mask_bpp_ + .set dst_w_bpp, dst_w_bpp_ + .set pixblock_size, pixblock_size_ + .set dst_w_basereg, dst_w_basereg_ + .set dst_r_basereg, dst_r_basereg_ + .set src_basereg, src_basereg_ + .set mask_basereg, mask_basereg_ + +/* + * Assign symbolic names to registers + */ + W .req r0 /* width (is updated during processing) */ + H .req r1 /* height (is updated during processing) */ + DST_W .req r2 /* destination buffer pointer for writes */ + DST_STRIDE .req r3 /* destination image stride */ + SRC .req r4 /* source buffer pointer */ + SRC_STRIDE .req r5 /* source image stride */ + DST_R .req r6 /* destination buffer pointer for reads */ + + MASK .req r7 /* mask pointer */ + MASK_STRIDE .req r8 /* mask stride */ + + PF_CTL .req r9 /* combined lines counter and prefetch */ + /* distance increment counter */ + PF_X .req r10 /* pixel index in a scanline for current */ + /* pretetch position */ + PF_SRC .req r11 /* pointer to source scanline start */ + /* for prefetch purposes */ + PF_DST .req r12 /* pointer to destination scanline start */ + /* for prefetch purposes */ + PF_MASK .req r14 /* pointer to mask scanline start */ + /* for prefetch purposes */ +/* + * Check whether we have enough registers for all the local variables. + * If we don't have enough registers, original width and height are + * kept on top of stack (and 'regs_shortage' variable is set to indicate + * this for the rest of code). Even if there are enough registers, the + * allocation scheme may be a bit different depending on whether source + * or mask is not used. + */ +.if (PREFETCH_TYPE_CURRENT < PREFETCH_TYPE_ADVANCED) + ORIG_W .req r10 /* saved original width */ + DUMMY .req r12 /* temporary register */ + .set regs_shortage, 0 +.elseif mask_bpp == 0 + ORIG_W .req r7 /* saved original width */ + DUMMY .req r8 /* temporary register */ + .set regs_shortage, 0 +.elseif src_bpp == 0 + ORIG_W .req r4 /* saved original width */ + DUMMY .req r5 /* temporary register */ + .set regs_shortage, 0 +.else + ORIG_W .req r1 /* saved original width */ + DUMMY .req r1 /* temporary register */ + .set regs_shortage, 1 +.endif + + .set mask_bpp_shift, -1 +.if src_bpp == 32 + .set src_bpp_shift, 2 +.elseif src_bpp == 24 + .set src_bpp_shift, 0 +.elseif src_bpp == 16 + .set src_bpp_shift, 1 +.elseif src_bpp == 8 + .set src_bpp_shift, 0 +.elseif src_bpp == 0 + .set src_bpp_shift, -1 +.else + .error "requested src bpp (src_bpp) is not supported" +.endif +.if mask_bpp == 32 + .set mask_bpp_shift, 2 +.elseif mask_bpp == 24 + .set mask_bpp_shift, 0 +.elseif mask_bpp == 8 + .set mask_bpp_shift, 0 +.elseif mask_bpp == 0 + .set mask_bpp_shift, -1 +.else + .error "requested mask bpp (mask_bpp) is not supported" +.endif +.if dst_w_bpp == 32 + .set dst_bpp_shift, 2 +.elseif dst_w_bpp == 24 + .set dst_bpp_shift, 0 +.elseif dst_w_bpp == 16 + .set dst_bpp_shift, 1 +.elseif dst_w_bpp == 8 + .set dst_bpp_shift, 0 +.else + .error "requested dst bpp (dst_w_bpp) is not supported" +.endif + +.if (((flags) & FLAG_DST_READWRITE) != 0) + .set dst_r_bpp, dst_w_bpp +.else + .set dst_r_bpp, 0 +.endif +.if (((flags) & FLAG_DEINTERLEAVE_32BPP) != 0) + .set DEINTERLEAVE_32BPP_ENABLED, 1 +.else + .set DEINTERLEAVE_32BPP_ENABLED, 0 +.endif + +.if prefetch_distance < 0 || prefetch_distance > 15 + .error "invalid prefetch distance (prefetch_distance)" +.endif + +.if src_bpp > 0 + ldr SRC, [sp, #40] +.endif +.if mask_bpp > 0 + ldr MASK, [sp, #48] +.endif + PF mov PF_X, #0 +.if src_bpp > 0 + ldr SRC_STRIDE, [sp, #44] +.endif +.if mask_bpp > 0 + ldr MASK_STRIDE, [sp, #52] +.endif + mov DST_R, DST_W + +.if src_bpp == 24 + sub SRC_STRIDE, SRC_STRIDE, W + sub SRC_STRIDE, SRC_STRIDE, W, lsl #1 +.endif +.if mask_bpp == 24 + sub MASK_STRIDE, MASK_STRIDE, W + sub MASK_STRIDE, MASK_STRIDE, W, lsl #1 +.endif +.if dst_w_bpp == 24 + sub DST_STRIDE, DST_STRIDE, W + sub DST_STRIDE, DST_STRIDE, W, lsl #1 +.endif + +/* + * Setup advanced prefetcher initial state + */ + PF mov PF_SRC, SRC + PF mov PF_DST, DST_R + PF mov PF_MASK, MASK + /* PF_CTL = prefetch_distance | ((h - 1) << 4) */ + PF mov PF_CTL, H, lsl #4 + PF add PF_CTL, #(prefetch_distance - 0x10) + + init +.if regs_shortage + push {r0, r1} +.endif + subs H, H, #1 +.if regs_shortage + str H, [sp, #4] /* save updated height to stack */ +.else + mov ORIG_W, W +.endif + blt 9f + cmp W, #(pixblock_size * 2) + blt 8f +/* + * This is the start of the pipelined loop, which if optimized for + * long scanlines + */ +0: + ensure_destination_ptr_alignment process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head + + /* Implement "head (tail_head) ... (tail_head) tail" loop pattern */ + pixld_a pixblock_size, dst_r_bpp, \ + (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R + pixld pixblock_size, src_bpp, \ + (src_basereg - pixblock_size * src_bpp / 64), SRC + pixld pixblock_size, mask_bpp, \ + (mask_basereg - pixblock_size * mask_bpp / 64), MASK + PF add PF_X, PF_X, #pixblock_size + process_pixblock_head + cache_preload 0, pixblock_size + cache_preload_simple + subs W, W, #(pixblock_size * 2) + blt 2f +1: + process_pixblock_tail_head + cache_preload_simple + subs W, W, #pixblock_size + bge 1b +2: + process_pixblock_tail + pixst_a pixblock_size, dst_w_bpp, \ + (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W + + /* Process the remaining trailing pixels in the scanline */ + process_trailing_pixels 1, 1, \ + process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head + advance_to_next_scanline 0b + +.if regs_shortage + pop {r0, r1} +.endif + cleanup + pop {r4-r12, pc} /* exit */ +/* + * This is the start of the loop, designed to process images with small width + * (less than pixblock_size * 2 pixels). In this case neither pipelining + * nor prefetch are used. + */ +8: + /* Process exactly pixblock_size pixels if needed */ + tst W, #pixblock_size + beq 1f + pixld pixblock_size, dst_r_bpp, \ + (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R + pixld pixblock_size, src_bpp, \ + (src_basereg - pixblock_size * src_bpp / 64), SRC + pixld pixblock_size, mask_bpp, \ + (mask_basereg - pixblock_size * mask_bpp / 64), MASK + process_pixblock_head + process_pixblock_tail + pixst pixblock_size, dst_w_bpp, \ + (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W +1: + /* Process the remaining trailing pixels in the scanline */ + process_trailing_pixels 0, 0, \ + process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head + advance_to_next_scanline 8b +9: +.if regs_shortage + pop {r0, r1} +.endif + cleanup + pop {r4-r12, pc} /* exit */ + + .unreq SRC + .unreq MASK + .unreq DST_R + .unreq DST_W + .unreq ORIG_W + .unreq W + .unreq H + .unreq SRC_STRIDE + .unreq DST_STRIDE + .unreq MASK_STRIDE + .unreq PF_CTL + .unreq PF_X + .unreq PF_SRC + .unreq PF_DST + .unreq PF_MASK + .unreq DUMMY + .endfunc +.endm + +/* + * A simplified variant of function generation template for a single + * scanline processing (for implementing pixman combine functions) + */ +.macro generate_composite_function_single_scanline fname, \ + src_bpp_, \ + mask_bpp_, \ + dst_w_bpp_, \ + flags, \ + pixblock_size_, \ + init, \ + cleanup, \ + process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head, \ + dst_w_basereg_ = 28, \ + dst_r_basereg_ = 4, \ + src_basereg_ = 0, \ + mask_basereg_ = 24 + + .func fname + .global fname + /* For ELF format also set function visibility to hidden */ +#ifdef __ELF__ + .hidden fname + .type fname, %function +#endif +fname: + .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE +/* + * Make some macro arguments globally visible and accessible + * from other macros + */ + .set src_bpp, src_bpp_ + .set mask_bpp, mask_bpp_ + .set dst_w_bpp, dst_w_bpp_ + .set pixblock_size, pixblock_size_ + .set dst_w_basereg, dst_w_basereg_ + .set dst_r_basereg, dst_r_basereg_ + .set src_basereg, src_basereg_ + .set mask_basereg, mask_basereg_ +/* + * Assign symbolic names to registers + */ + W .req r0 /* width (is updated during processing) */ + DST_W .req r1 /* destination buffer pointer for writes */ + SRC .req r2 /* source buffer pointer */ + DST_R .req ip /* destination buffer pointer for reads */ + MASK .req r3 /* mask pointer */ + +.if (((flags) & FLAG_DST_READWRITE) != 0) + .set dst_r_bpp, dst_w_bpp +.else + .set dst_r_bpp, 0 +.endif +.if (((flags) & FLAG_DEINTERLEAVE_32BPP) != 0) + .set DEINTERLEAVE_32BPP_ENABLED, 1 +.else + .set DEINTERLEAVE_32BPP_ENABLED, 0 +.endif + + init + mov DST_R, DST_W + + cmp W, #pixblock_size + blt 8f + + ensure_destination_ptr_alignment process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head + + subs W, W, #pixblock_size + blt 7f + + /* Implement "head (tail_head) ... (tail_head) tail" loop pattern */ + pixld_a pixblock_size, dst_r_bpp, \ + (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R + pixld pixblock_size, src_bpp, \ + (src_basereg - pixblock_size * src_bpp / 64), SRC + pixld pixblock_size, mask_bpp, \ + (mask_basereg - pixblock_size * mask_bpp / 64), MASK + process_pixblock_head + subs W, W, #pixblock_size + blt 2f +1: + process_pixblock_tail_head + subs W, W, #pixblock_size + bge 1b +2: + process_pixblock_tail + pixst_a pixblock_size, dst_w_bpp, \ + (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W +7: + /* Process the remaining trailing pixels in the scanline (dst aligned) */ + process_trailing_pixels 0, 1, \ + process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head + + cleanup + bx lr /* exit */ +8: + /* Process the remaining trailing pixels in the scanline (dst unaligned) */ + process_trailing_pixels 0, 0, \ + process_pixblock_head, \ + process_pixblock_tail, \ + process_pixblock_tail_head + + cleanup + bx lr /* exit */ + + .unreq SRC + .unreq MASK + .unreq DST_R + .unreq DST_W + .unreq W + .endfunc +.endm + +.macro default_init +.endm + +.macro default_cleanup +.endm diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 0b1c18d..b183d0d 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -182,6 +182,7 @@ void QRasterPixmapData::fromImage(const QImage &sourceImage, QImage::Format opaqueFormat = QNativeImage::systemFormat(); QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; +#ifndef QT_HAVE_NEON switch (opaqueFormat) { case QImage::Format_RGB16: alphaFormat = QImage::Format_ARGB8565_Premultiplied; @@ -189,6 +190,7 @@ void QRasterPixmapData::fromImage(const QImage &sourceImage, default: // We don't care about the others... break; } +#endif if (!sourceImage.hasAlphaChannel() || ((flags & Qt::NoOpaqueDetection) == 0 @@ -238,6 +240,7 @@ void QRasterPixmapData::fill(const QColor &color) if (alpha != 255) { if (!image.hasAlphaChannel()) { QImage::Format toFormat; +#ifndef QT_HAVE_NEON if (image.format() == QImage::Format_RGB16) toFormat = QImage::Format_ARGB8565_Premultiplied; else if (image.format() == QImage::Format_RGB666) @@ -247,6 +250,7 @@ void QRasterPixmapData::fill(const QColor &color) else if (image.format() == QImage::Format_RGB444) toFormat = QImage::Format_ARGB4444_Premultiplied; else +#endif toFormat = QImage::Format_ARGB32_Premultiplied; image = QImage(image.width(), image.height(), toFormat); } diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index a6cc9c7..e61e07c 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -379,11 +379,23 @@ symbian { QMAKE_CXXFLAGS.ARMCC *= -O3 } -neon { +neon:*-g++* { DEFINES += QT_HAVE_NEON HEADERS += painting/qdrawhelper_neon_p.h SOURCES += painting/qdrawhelper_neon.cpp QMAKE_CXXFLAGS *= -mfpu=neon + + PIXMAN_NEON_ASM_FILES = ../3rdparty/pixman/pixman-arm-neon-asm.S + + neon_compiler.commands = $$QMAKE_CXX -c + neon_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} + neon_compiler.dependency_type = TYPE_C + neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} + neon_compiler.input = PIXMAN_NEON_ASM_FILES + neon_compiler.variable_out = OBJECTS + neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN} + silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands + QMAKE_EXTRA_COMPILERS += neon_compiler } contains(QT_CONFIG, zlib) { diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index dc33896..13bb260 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -447,10 +447,10 @@ static void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl, -static void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) +void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) { quint16 *dst = (quint16 *) destPixels; const quint32 *src = (const quint32 *) srcPixels; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 1f75ec7..130270b 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -7961,6 +7961,10 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; + + qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; } #endif diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 77c5202..ef1b85c 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -44,6 +44,7 @@ #ifdef QT_HAVE_NEON #include +#include #include QT_BEGIN_NAMESPACE @@ -87,6 +88,79 @@ static inline uint16x8_t qvsource_over_u16(uint16x8_t src16, uint16x8_t dst16, u return vaddq_u16(src16, qvbyte_mul_u16(dst16, alpha16, half)); } +extern "C" void +pixman_composite_over_8888_0565_asm_neon (int32_t w, + int32_t h, + uint16_t *dst, + int32_t dst_stride, + uint32_t *src, + int32_t src_stride); + +extern "C" void +pixman_composite_over_8888_8888_asm_neon (int32_t w, + int32_t h, + uint32_t *dst, + int32_t dst_stride, + uint32_t *src, + int32_t src_stride); + +extern "C" void +pixman_composite_src_0565_8888_asm_neon (int32_t w, + int32_t h, + uint32_t *dst, + int32_t dst_stride, + uint16_t *src, + int32_t src_stride); + +// qblendfunctions.cpp +void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha); + +void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ + dbpl /= 4; + sbpl /= 2; + + quint32 *dst = (quint32 *) destPixels; + quint16 *src = (quint16 *) srcPixels; + + if (const_alpha != 256) { + quint8 a = (255 * const_alpha) >> 8; + quint8 ia = 255 - a; + + while (h--) { + for (int x=0; x= 0xff000000) { - // all opaque - vst1q_u32((uint32_t *)&dst[x], src32); - } else if (src[x] | src[x+1] | src[x+2] | src[x+3]) { - uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]); - - const uint8x16_t src8 = vreinterpretq_u8_u32(src32); - const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32); - - const uint8x8_t src8_low = vget_low_u8(src8); - const uint8x8_t dst8_low = vget_low_u8(dst8); - - const uint8x8_t src8_high = vget_high_u8(src8); - const uint8x8_t dst8_high = vget_high_u8(dst8); - - const uint16x8_t src16_low = vmovl_u8(src8_low); - const uint16x8_t dst16_low = vmovl_u8(dst8_low); - - const uint16x8_t src16_high = vmovl_u8(src8_high); - const uint16x8_t dst16_high = vmovl_u8(dst8_high); - - const uint16x8_t result16_low = qvsource_over_u16(src16_low, dst16_low, half, full); - const uint16x8_t result16_high = qvsource_over_u16(src16_high, dst16_high, half, full); - - const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); - const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); - - vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); - } - } - for (; x= 0xff000000) - dst[x] = s; - else if (s != 0) - dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); - } - dst = (quint32 *)(((uchar *) dst) + dbpl); - src = (const quint32 *)(((const uchar *) src) + sbpl); - } + pixman_composite_over_8888_8888_asm_neon(w, h, (uint32_t *)destPixels, dbpl / 4, (uint32_t *)srcPixels, sbpl / 4); } else if (const_alpha != 0) { const_alpha = (const_alpha * 255) >> 8; uint16x8_t const_alpha16 = vdupq_n_u16(const_alpha); @@ -254,6 +285,31 @@ void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl, } } +extern "C" void +pixman_composite_over_n_8_0565_asm_neon (int32_t w, + int32_t h, + uint16_t *dst, + int32_t dst_stride, + uint32_t src, + int32_t unused, + uint8_t *mask, + int32_t mask_stride); + + +void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, + int x, int y, quint32 color, + const uchar *bitmap, + int mapWidth, int mapHeight, int mapStride, + const QClipData *) +{ + quint16 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; + const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); + + uchar *mask = const_cast(bitmap); + + pixman_composite_over_n_8_0565_asm_neon(mapWidth, mapHeight, dest, destStride, color, 0, mask, mapStride); +} + QT_END_NAMESPACE #endif // QT_HAVE_NEON diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h index 1994441..6f9604f 100644 --- a/src/gui/painting/qdrawhelper_neon_p.h +++ b/src/gui/painting/qdrawhelper_neon_p.h @@ -69,6 +69,21 @@ void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl, int w, int h, int const_alpha); +void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha); + +void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha); + +void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, + int x, int y, quint32 color, + const uchar *bitmap, + int mapWidth, int mapHeight, int mapStride, + const QClipData *clip); #endif // QT_HAVE_NEON QT_END_NAMESPACE -- cgit v0.12 From 0ad22e6cd1cb353e2e1244c1eb7257cb3af9def4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 24 Mar 2010 19:03:47 +0100 Subject: Optimized scaled/transformed image blending for ARGB32PM and RGB16 on RGB16. Before: :/traces/qmlphoneconcept.trace, iterations: 5, frames: 48, min(ms): 1207, median(ms): 1212, stddev: 0,165153 %, max(fps): 39,768020 After: traces/qmlphoneconcept.trace, iterations: 3, frames: 48, min(ms): 884, median(ms): 886, stddev: 0,383097 %, max(fps): 54,298643 Task-number: QTBUG-6684 Reviewed-by: Gunnar Sletta --- src/gui/painting/painting.pri | 6 +- src/gui/painting/qblendfunctions.cpp | 438 ++-------------------------- src/gui/painting/qblendfunctions_p.h | 497 ++++++++++++++++++++++++++++++++ src/gui/painting/qdrawhelper.cpp | 6 + src/gui/painting/qdrawhelper_neon.cpp | 139 +++++++++ src/gui/painting/qdrawhelper_neon_asm.S | 192 ++++++++++++ src/gui/painting/qdrawhelper_neon_p.h | 31 ++ 7 files changed, 890 insertions(+), 419 deletions(-) create mode 100644 src/gui/painting/qblendfunctions_p.h create mode 100644 src/gui/painting/qdrawhelper_neon_asm.S diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index e61e07c..ed8ee76 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -91,6 +91,8 @@ SOURCES += \ HEADERS += \ painting/qpaintengine_raster_p.h \ + painting/qdrawhelper_p.h \ + painting/qblendfunctions_p.h \ painting/qrasterdefs_p.h \ painting/qgrayraster_p.h @@ -385,13 +387,13 @@ neon:*-g++* { SOURCES += painting/qdrawhelper_neon.cpp QMAKE_CXXFLAGS *= -mfpu=neon - PIXMAN_NEON_ASM_FILES = ../3rdparty/pixman/pixman-arm-neon-asm.S + DRAWHELPER_NEON_ASM_FILES = ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S neon_compiler.commands = $$QMAKE_CXX -c neon_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} neon_compiler.dependency_type = TYPE_C neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} - neon_compiler.input = PIXMAN_NEON_ASM_FILES + neon_compiler.input = DRAWHELPER_NEON_ASM_FILES neon_compiler.variable_out = OBJECTS neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN} silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 13bb260..24908ce 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include -#include "qdrawhelper_p.h" +#include "qblendfunctions_p.h" QT_BEGIN_NAMESPACE @@ -88,6 +88,8 @@ static inline quint16 convert_argb32_to_rgb16(quint32 spix) struct Blend_RGB16_on_RGB16_NoAlpha { inline void write(quint16 *dst, quint16 src) { *dst = src; } + + inline void flush(void *) {} }; struct Blend_RGB16_on_RGB16_ConstAlpha { @@ -100,6 +102,8 @@ struct Blend_RGB16_on_RGB16_ConstAlpha { *dst = BYTE_MUL_RGB16(src, m_alpha) + BYTE_MUL_RGB16(*dst, m_ialpha); } + inline void flush(void *) {} + quint32 m_alpha; quint32 m_ialpha; }; @@ -114,6 +118,8 @@ struct Blend_ARGB24_on_RGB16_SourceAlpha { *dst = s; } } + + inline void flush(void *) {} }; struct Blend_ARGB24_on_RGB16_SourceAndConstAlpha { @@ -132,6 +138,8 @@ struct Blend_ARGB24_on_RGB16_SourceAndConstAlpha { } } + inline void flush(void *) {} + quint32 m_alpha; }; @@ -145,6 +153,8 @@ struct Blend_ARGB32_on_RGB16_SourceAlpha { *dst = s; } } + + inline void flush(void *) {} }; struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha { @@ -163,99 +173,11 @@ struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha { } } + inline void flush(void *) {} + quint32 m_alpha; }; -template -void qt_scale_image_16bit(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &srcRect, - const QRect &clip, - T blender) -{ - qreal sx = targetRect.width() / (qreal) srcRect.width(); - qreal sy = targetRect.height() / (qreal) srcRect.height(); - - int ix = 0x00010000 / sx; - int iy = 0x00010000 / sy; - -// qDebug() << "scale:" << endl -// << " - target" << targetRect << endl -// << " - source" << srcRect << endl -// << " - clip" << clip << endl -// << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy; - - int cx1 = clip.x(); - int cx2 = clip.x() + clip.width(); - int cy1 = clip.top(); - int cy2 = clip.y() + clip.height(); - - int tx1 = qRound(targetRect.left()); - int tx2 = qRound(targetRect.right()); - int ty1 = qRound(targetRect.top()); - int ty2 = qRound(targetRect.bottom()); - - if (tx2 < tx1) - qSwap(tx2, tx1); - - if (ty2 < ty1) - qSwap(ty2, ty1); - - if (tx1 < cx1) - tx1 = cx1; - - if (tx2 >= cx2) - tx2 = cx2; - - if (tx1 >= tx2) - return; - - if (ty1 < cy1) - ty1 = cy1; - - if (ty2 >= cy2) - ty2 = cy2; - - if (ty1 >= ty2) - return; - - int h = ty2 - ty1; - int w = tx2 - tx1; - - - quint32 basex; - quint32 srcy; - - if (sx < 0) { - int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1; - basex = quint32(srcRect.right() * 65536) + dstx; - } else { - int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1; - basex = quint32(srcRect.left() * 65536) + dstx; - } - if (sy < 0) { - int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1; - srcy = quint32(srcRect.bottom() * 65536) + dsty; - } else { - int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1; - srcy = quint32(srcRect.top() * 65536) + dsty; - } - - quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1; - - while (h--) { - const SRC *src = (const SRC *) (srcPixels + (srcy >> 16) * sbpl); - int srcx = basex; - for (int x=0; x> 16]); - srcx += ix; - } - dst = (quint16 *)(((uchar *) dst) + dbpl); - srcy += iy; - } -} - void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, const QRectF &targetRect, @@ -643,6 +565,8 @@ void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl, struct Blend_RGB32_on_RGB32_NoAlpha { inline void write(quint32 *dst, quint32 src) { *dst = src; } + + inline void flush(void *) {} }; struct Blend_RGB32_on_RGB32_ConstAlpha { @@ -655,6 +579,8 @@ struct Blend_RGB32_on_RGB32_ConstAlpha { *dst = BYTE_MUL(src, m_alpha) + BYTE_MUL(*dst, m_ialpha); } + inline void flush(void *) {} + quint32 m_alpha; quint32 m_ialpha; }; @@ -663,6 +589,8 @@ struct Blend_ARGB32_on_ARGB32_SourceAlpha { inline void write(quint32 *dst, quint32 src) { *dst = src + BYTE_MUL(*dst, qAlpha(~src)); } + + inline void flush(void *) {} }; struct Blend_ARGB32_on_ARGB32_SourceAndConstAlpha { @@ -676,98 +604,12 @@ struct Blend_ARGB32_on_ARGB32_SourceAndConstAlpha { *dst = src + BYTE_MUL(*dst, qAlpha(~src)); } + inline void flush(void *) {} + quint32 m_alpha; quint32 m_ialpha; }; -template void qt_scale_image_32bit(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &srcRect, - const QRect &clip, - T blender) -{ - qreal sx = targetRect.width() / (qreal) srcRect.width(); - qreal sy = targetRect.height() / (qreal) srcRect.height(); - - int ix = 0x00010000 / sx; - int iy = 0x00010000 / sy; - -// qDebug() << "scale:" << endl -// << " - target" << targetRect << endl -// << " - source" << srcRect << endl -// << " - clip" << clip << endl -// << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy; - - int cx1 = clip.x(); - int cx2 = clip.x() + clip.width(); - int cy1 = clip.top(); - int cy2 = clip.y() + clip.height(); - - int tx1 = qRound(targetRect.left()); - int tx2 = qRound(targetRect.right()); - int ty1 = qRound(targetRect.top()); - int ty2 = qRound(targetRect.bottom()); - - if (tx2 < tx1) - qSwap(tx2, tx1); - - if (ty2 < ty1) - qSwap(ty2, ty1); - - if (tx1 < cx1) - tx1 = cx1; - - if (tx2 >= cx2) - tx2 = cx2; - - if (tx1 >= tx2) - return; - - if (ty1 < cy1) - ty1 = cy1; - - if (ty2 >= cy2) - ty2 = cy2; - - if (ty1 >= ty2) - return; - - int h = ty2 - ty1; - int w = tx2 - tx1; - - quint32 basex; - quint32 srcy; - - if (sx < 0) { - int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1; - basex = quint32(srcRect.right() * 65536) + dstx; - } else { - int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1; - basex = quint32(srcRect.left() * 65536) + dstx; - } - if (sy < 0) { - int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1; - srcy = quint32(srcRect.bottom() * 65536) + dsty; - } else { - int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1; - srcy = quint32(srcRect.top() * 65536) + dsty; - } - - quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1; - - while (h--) { - const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl); - int srcx = basex; - for (int x=0; x> 16]); - srcx += ix; - } - dst = (quint32 *)(((uchar *) dst) + dbpl); - srcy += iy; - } -} - void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, const QRectF &targetRect, @@ -818,244 +660,6 @@ void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl, } } -struct QTransformImageVertex -{ - qreal x, y, u, v; // destination coordinates (x, y) and source coordinates (u, v) -}; - -template -void qt_transform_image_rasterize(DestT *destPixels, int dbpl, - const SrcT *srcPixels, int sbpl, - const QTransformImageVertex &topLeft, const QTransformImageVertex &bottomLeft, - const QTransformImageVertex &topRight, const QTransformImageVertex &bottomRight, - const QRect &sourceRect, - const QRect &clip, - qreal topY, qreal bottomY, - int dudx, int dvdx, int dudy, int dvdy, int u0, int v0, - Blender blender) -{ - int fromY = qMax(qRound(topY), clip.top()); - int toY = qMin(qRound(bottomY), clip.top() + clip.height()); - if (fromY >= toY) - return; - - qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y); - qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y); - int dx_l = int(leftSlope * 0x10000); - int dx_r = int(rightSlope * 0x10000); - int x_l = int((topLeft.x + (0.5 + fromY - topLeft.y) * leftSlope + 0.5) * 0x10000); - int x_r = int((topRight.x + (0.5 + fromY - topRight.y) * rightSlope + 0.5) * 0x10000); - - int fromX, toX, x1, x2, u, v, i, ii; - DestT *line; - for (int y = fromY; y < toY; ++y) { - line = reinterpret_cast(reinterpret_cast(destPixels) + y * dbpl); - - fromX = qMax(x_l >> 16, clip.left()); - toX = qMin(x_r >> 16, clip.left() + clip.width()); - if (fromX < toX) { - // Because of rounding, we can get source coordinates outside the source image. - // Clamp these coordinates to the source rect to avoid segmentation fault and - // garbage on the screen. - - // Find the first pixel on the current scan line where the source coordinates are within the source rect. - x1 = fromX; - u = x1 * dudx + y * dudy + u0; - v = x1 * dvdx + y * dvdy + v0; - for (; x1 < toX; ++x1) { - int uu = u >> 16; - int vv = v >> 16; - if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() - && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { - break; - } - u += dudx; - v += dvdx; - } - - // Find the last pixel on the current scan line where the source coordinates are within the source rect. - x2 = toX; - u = (x2 - 1) * dudx + y * dudy + u0; - v = (x2 - 1) * dvdx + y * dvdy + v0; - for (; x2 > x1; --x2) { - int uu = u >> 16; - int vv = v >> 16; - if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() - && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { - break; - } - u -= dudx; - v -= dvdx; - } - - // Set up values at the beginning of the scan line. - u = fromX * dudx + y * dudy + u0; - v = fromX * dvdx + y * dvdy + v0; - line += fromX; - - // Beginning of the scan line, with per-pixel checks. - i = x1 - fromX; - while (i) { - int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); - int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); - blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + vv * sbpl)[uu]); - u += dudx; - v += dvdx; - ++line; - --i; - } - - // Middle of the scan line, without checks. - // Manual loop unrolling. - i = x2 - x1; - ii = i >> 3; - while (ii) { - blender.write(&line[0], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; - blender.write(&line[1], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; - blender.write(&line[2], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; - blender.write(&line[3], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; - blender.write(&line[4], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; - blender.write(&line[5], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; - blender.write(&line[6], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; - blender.write(&line[7], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; - line += 8; - --ii; - } - switch (i & 7) { - case 7: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; - case 6: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; - case 5: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; - case 4: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; - case 3: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; - case 2: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; - case 1: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; - } - - // End of the scan line, with per-pixel checks. - i = toX - x2; - while (i) { - int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); - int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); - blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + vv * sbpl)[uu]); - u += dudx; - v += dvdx; - ++line; - --i; - } - } - x_l += dx_l; - x_r += dx_r; - } -} - -template -void qt_transform_image(DestT *destPixels, int dbpl, - const SrcT *srcPixels, int sbpl, - const QRectF &targetRect, - const QRectF &sourceRect, - const QRect &clip, - const QTransform &targetRectTransform, - Blender blender) -{ - enum Corner - { - TopLeft, - TopRight, - BottomRight, - BottomLeft - }; - - // map source rectangle to destination. - QTransformImageVertex v[4]; - v[TopLeft].u = v[BottomLeft].u = sourceRect.left(); - v[TopLeft].v = v[TopRight].v = sourceRect.top(); - v[TopRight].u = v[BottomRight].u = sourceRect.right(); - v[BottomLeft].v = v[BottomRight].v = sourceRect.bottom(); - targetRectTransform.map(targetRect.left(), targetRect.top(), &v[TopLeft].x, &v[TopLeft].y); - targetRectTransform.map(targetRect.right(), targetRect.top(), &v[TopRight].x, &v[TopRight].y); - targetRectTransform.map(targetRect.left(), targetRect.bottom(), &v[BottomLeft].x, &v[BottomLeft].y); - targetRectTransform.map(targetRect.right(), targetRect.bottom(), &v[BottomRight].x, &v[BottomRight].y); - - // find topmost vertex. - int topmost = 0; - for (int i = 1; i < 4; ++i) { - if (v[i].y < v[topmost].y) - topmost = i; - } - // rearrange array such that topmost vertex is at index 0. - switch (topmost) { - case 1: - { - QTransformImageVertex t = v[0]; - for (int i = 0; i < 3; ++i) - v[i] = v[i+1]; - v[3] = t; - } - break; - case 2: - qSwap(v[0], v[2]); - qSwap(v[1], v[3]); - break; - case 3: - { - QTransformImageVertex t = v[3]; - for (int i = 3; i > 0; --i) - v[i] = v[i-1]; - v[0] = t; - } - break; - } - - // if necessary, swap vertex 1 and 3 such that 1 is to the left of 3. - qreal dx1 = v[1].x - v[0].x; - qreal dy1 = v[1].y - v[0].y; - qreal dx2 = v[3].x - v[0].x; - qreal dy2 = v[3].y - v[0].y; - if (dx1 * dy2 - dx2 * dy1 > 0) - qSwap(v[1], v[3]); - - QTransformImageVertex u = {v[1].x - v[0].x, v[1].y - v[0].y, v[1].u - v[0].u, v[1].v - v[0].v}; - QTransformImageVertex w = {v[2].x - v[0].x, v[2].y - v[0].y, v[2].u - v[0].u, v[2].v - v[0].v}; - - qreal det = u.x * w.y - u.y * w.x; - if (det == 0) - return; - - qreal invDet = 1.0 / det; - qreal m11, m12, m21, m22, mdx, mdy; - - m11 = (u.u * w.y - u.y * w.u) * invDet; - m12 = (u.x * w.u - u.u * w.x) * invDet; - m21 = (u.v * w.y - u.y * w.v) * invDet; - m22 = (u.x * w.v - u.v * w.x) * invDet; - mdx = v[0].u - m11 * v[0].x - m12 * v[0].y; - mdy = v[0].v - m21 * v[0].x - m22 * v[0].y; - - int dudx = int(m11 * 0x10000); - int dvdx = int(m21 * 0x10000); - int dudy = int(m12 * 0x10000); - int dvdy = int(m22 * 0x10000); - int u0 = qCeil((0.5 * m11 + 0.5 * m12 + mdx) * 0x10000) - 1; - int v0 = qCeil((0.5 * m21 + 0.5 * m22 + mdy) * 0x10000) - 1; - - int x1 = qFloor(sourceRect.left()); - int y1 = qFloor(sourceRect.top()); - int x2 = qCeil(sourceRect.right()); - int y2 = qCeil(sourceRect.bottom()); - QRect sourceRectI(x1, y1, x2 - x1, y2 - y1); - - // rasterize trapezoids. - if (v[1].y < v[3].y) { - qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); - qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[0], v[3], sourceRectI, clip, v[1].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); - qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[3].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); - } else { - qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); - qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[3], v[2], sourceRectI, clip, v[3].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); - qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[1].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); - } -} - void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, const QRectF &targetRect, diff --git a/src/gui/painting/qblendfunctions_p.h b/src/gui/painting/qblendfunctions_p.h new file mode 100644 index 0000000..ad754b0 --- /dev/null +++ b/src/gui/painting/qblendfunctions_p.h @@ -0,0 +1,497 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLENDFUNCTIONS_P_H +#define QBLENDFUNCTIONS_P_H + +#include +#include "qdrawhelper_p.h" + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +template +void qt_scale_image_16bit(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &srcRect, + const QRect &clip, + T blender) +{ + qreal sx = targetRect.width() / (qreal) srcRect.width(); + qreal sy = targetRect.height() / (qreal) srcRect.height(); + + int ix = 0x00010000 / sx; + int iy = 0x00010000 / sy; + +// qDebug() << "scale:" << endl +// << " - target" << targetRect << endl +// << " - source" << srcRect << endl +// << " - clip" << clip << endl +// << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy; + + int cx1 = clip.x(); + int cx2 = clip.x() + clip.width(); + int cy1 = clip.top(); + int cy2 = clip.y() + clip.height(); + + int tx1 = qRound(targetRect.left()); + int tx2 = qRound(targetRect.right()); + int ty1 = qRound(targetRect.top()); + int ty2 = qRound(targetRect.bottom()); + + if (tx2 < tx1) + qSwap(tx2, tx1); + + if (ty2 < ty1) + qSwap(ty2, ty1); + + if (tx1 < cx1) + tx1 = cx1; + + if (tx2 >= cx2) + tx2 = cx2; + + if (tx1 >= tx2) + return; + + if (ty1 < cy1) + ty1 = cy1; + + if (ty2 >= cy2) + ty2 = cy2; + + if (ty1 >= ty2) + return; + + int h = ty2 - ty1; + int w = tx2 - tx1; + + + quint32 basex; + quint32 srcy; + + if (sx < 0) { + int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1; + basex = quint32(srcRect.right() * 65536) + dstx; + } else { + int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1; + basex = quint32(srcRect.left() * 65536) + dstx; + } + if (sy < 0) { + int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1; + srcy = quint32(srcRect.bottom() * 65536) + dsty; + } else { + int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1; + srcy = quint32(srcRect.top() * 65536) + dsty; + } + + quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1; + + while (h--) { + const SRC *src = (const SRC *) (srcPixels + (srcy >> 16) * sbpl); + int srcx = basex; + int x = 0; + for (; x> 16]); srcx += ix; + blender.write(&dst[x+1], src[srcx >> 16]); srcx += ix; + blender.write(&dst[x+2], src[srcx >> 16]); srcx += ix; + blender.write(&dst[x+3], src[srcx >> 16]); srcx += ix; + blender.write(&dst[x+4], src[srcx >> 16]); srcx += ix; + blender.write(&dst[x+5], src[srcx >> 16]); srcx += ix; + blender.write(&dst[x+6], src[srcx >> 16]); srcx += ix; + blender.write(&dst[x+7], src[srcx >> 16]); srcx += ix; + } + for (; x> 16]); + srcx += ix; + } + blender.flush(&dst[x]); + dst = (quint16 *)(((uchar *) dst) + dbpl); + srcy += iy; + } +} + +template void qt_scale_image_32bit(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &srcRect, + const QRect &clip, + T blender) +{ + qreal sx = targetRect.width() / (qreal) srcRect.width(); + qreal sy = targetRect.height() / (qreal) srcRect.height(); + + int ix = 0x00010000 / sx; + int iy = 0x00010000 / sy; + +// qDebug() << "scale:" << endl +// << " - target" << targetRect << endl +// << " - source" << srcRect << endl +// << " - clip" << clip << endl +// << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy; + + int cx1 = clip.x(); + int cx2 = clip.x() + clip.width(); + int cy1 = clip.top(); + int cy2 = clip.y() + clip.height(); + + int tx1 = qRound(targetRect.left()); + int tx2 = qRound(targetRect.right()); + int ty1 = qRound(targetRect.top()); + int ty2 = qRound(targetRect.bottom()); + + if (tx2 < tx1) + qSwap(tx2, tx1); + + if (ty2 < ty1) + qSwap(ty2, ty1); + + if (tx1 < cx1) + tx1 = cx1; + + if (tx2 >= cx2) + tx2 = cx2; + + if (tx1 >= tx2) + return; + + if (ty1 < cy1) + ty1 = cy1; + + if (ty2 >= cy2) + ty2 = cy2; + + if (ty1 >= ty2) + return; + + int h = ty2 - ty1; + int w = tx2 - tx1; + + quint32 basex; + quint32 srcy; + + if (sx < 0) { + int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1; + basex = quint32(srcRect.right() * 65536) + dstx; + } else { + int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1; + basex = quint32(srcRect.left() * 65536) + dstx; + } + if (sy < 0) { + int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1; + srcy = quint32(srcRect.bottom() * 65536) + dsty; + } else { + int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1; + srcy = quint32(srcRect.top() * 65536) + dsty; + } + + quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1; + + while (h--) { + const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl); + int srcx = basex; + int x = 0; + for (; x> 16]); + srcx += ix; + } + blender.flush(&dst[x]); + dst = (quint32 *)(((uchar *) dst) + dbpl); + srcy += iy; + } +} + +struct QTransformImageVertex +{ + qreal x, y, u, v; // destination coordinates (x, y) and source coordinates (u, v) +}; + +template +void qt_transform_image_rasterize(DestT *destPixels, int dbpl, + const SrcT *srcPixels, int sbpl, + const QTransformImageVertex &topLeft, const QTransformImageVertex &bottomLeft, + const QTransformImageVertex &topRight, const QTransformImageVertex &bottomRight, + const QRect &sourceRect, + const QRect &clip, + qreal topY, qreal bottomY, + int dudx, int dvdx, int dudy, int dvdy, int u0, int v0, + Blender blender) +{ + int fromY = qMax(qRound(topY), clip.top()); + int toY = qMin(qRound(bottomY), clip.top() + clip.height()); + if (fromY >= toY) + return; + + qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y); + qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y); + int dx_l = int(leftSlope * 0x10000); + int dx_r = int(rightSlope * 0x10000); + int x_l = int((topLeft.x + (0.5 + fromY - topLeft.y) * leftSlope + 0.5) * 0x10000); + int x_r = int((topRight.x + (0.5 + fromY - topRight.y) * rightSlope + 0.5) * 0x10000); + + int fromX, toX, x1, x2, u, v, i, ii; + DestT *line; + for (int y = fromY; y < toY; ++y) { + line = reinterpret_cast(reinterpret_cast(destPixels) + y * dbpl); + + fromX = qMax(x_l >> 16, clip.left()); + toX = qMin(x_r >> 16, clip.left() + clip.width()); + if (fromX < toX) { + // Because of rounding, we can get source coordinates outside the source image. + // Clamp these coordinates to the source rect to avoid segmentation fault and + // garbage on the screen. + + // Find the first pixel on the current scan line where the source coordinates are within the source rect. + x1 = fromX; + u = x1 * dudx + y * dudy + u0; + v = x1 * dvdx + y * dvdy + v0; + for (; x1 < toX; ++x1) { + int uu = u >> 16; + int vv = v >> 16; + if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() + && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { + break; + } + u += dudx; + v += dvdx; + } + + // Find the last pixel on the current scan line where the source coordinates are within the source rect. + x2 = toX; + u = (x2 - 1) * dudx + y * dudy + u0; + v = (x2 - 1) * dvdx + y * dvdy + v0; + for (; x2 > x1; --x2) { + int uu = u >> 16; + int vv = v >> 16; + if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() + && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { + break; + } + u -= dudx; + v -= dvdx; + } + + // Set up values at the beginning of the scan line. + u = fromX * dudx + y * dudy + u0; + v = fromX * dvdx + y * dvdy + v0; + line += fromX; + + // Beginning of the scan line, with per-pixel checks. + i = x1 - fromX; + while (i) { + int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); + int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); + blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + vv * sbpl)[uu]); + u += dudx; + v += dvdx; + ++line; + --i; + } + + // Middle of the scan line, without checks. + // Manual loop unrolling. + i = x2 - x1; + ii = i >> 3; + while (ii) { + blender.write(&line[0], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; + blender.write(&line[1], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; + blender.write(&line[2], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; + blender.write(&line[3], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; + blender.write(&line[4], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; + blender.write(&line[5], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; + blender.write(&line[6], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; + blender.write(&line[7], reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; + + line += 8; + + --ii; + } + switch (i & 7) { + case 7: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; + case 6: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; + case 5: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; + case 4: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; + case 3: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; + case 2: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; + case 1: blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line; + } + + // End of the scan line, with per-pixel checks. + i = toX - x2; + while (i) { + int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); + int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); + blender.write(line, reinterpret_cast(reinterpret_cast(srcPixels) + vv * sbpl)[uu]); + u += dudx; + v += dvdx; + ++line; + --i; + } + + blender.flush(line); + } + x_l += dx_l; + x_r += dx_r; + } +} + +template +void qt_transform_image(DestT *destPixels, int dbpl, + const SrcT *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + const QTransform &targetRectTransform, + Blender blender) +{ + enum Corner + { + TopLeft, + TopRight, + BottomRight, + BottomLeft + }; + + // map source rectangle to destination. + QTransformImageVertex v[4]; + v[TopLeft].u = v[BottomLeft].u = sourceRect.left(); + v[TopLeft].v = v[TopRight].v = sourceRect.top(); + v[TopRight].u = v[BottomRight].u = sourceRect.right(); + v[BottomLeft].v = v[BottomRight].v = sourceRect.bottom(); + targetRectTransform.map(targetRect.left(), targetRect.top(), &v[TopLeft].x, &v[TopLeft].y); + targetRectTransform.map(targetRect.right(), targetRect.top(), &v[TopRight].x, &v[TopRight].y); + targetRectTransform.map(targetRect.left(), targetRect.bottom(), &v[BottomLeft].x, &v[BottomLeft].y); + targetRectTransform.map(targetRect.right(), targetRect.bottom(), &v[BottomRight].x, &v[BottomRight].y); + + // find topmost vertex. + int topmost = 0; + for (int i = 1; i < 4; ++i) { + if (v[i].y < v[topmost].y) + topmost = i; + } + // rearrange array such that topmost vertex is at index 0. + switch (topmost) { + case 1: + { + QTransformImageVertex t = v[0]; + for (int i = 0; i < 3; ++i) + v[i] = v[i+1]; + v[3] = t; + } + break; + case 2: + qSwap(v[0], v[2]); + qSwap(v[1], v[3]); + break; + case 3: + { + QTransformImageVertex t = v[3]; + for (int i = 3; i > 0; --i) + v[i] = v[i-1]; + v[0] = t; + } + break; + } + + // if necessary, swap vertex 1 and 3 such that 1 is to the left of 3. + qreal dx1 = v[1].x - v[0].x; + qreal dy1 = v[1].y - v[0].y; + qreal dx2 = v[3].x - v[0].x; + qreal dy2 = v[3].y - v[0].y; + if (dx1 * dy2 - dx2 * dy1 > 0) + qSwap(v[1], v[3]); + + QTransformImageVertex u = {v[1].x - v[0].x, v[1].y - v[0].y, v[1].u - v[0].u, v[1].v - v[0].v}; + QTransformImageVertex w = {v[2].x - v[0].x, v[2].y - v[0].y, v[2].u - v[0].u, v[2].v - v[0].v}; + + qreal det = u.x * w.y - u.y * w.x; + if (det == 0) + return; + + qreal invDet = 1.0 / det; + qreal m11, m12, m21, m22, mdx, mdy; + + m11 = (u.u * w.y - u.y * w.u) * invDet; + m12 = (u.x * w.u - u.u * w.x) * invDet; + m21 = (u.v * w.y - u.y * w.v) * invDet; + m22 = (u.x * w.v - u.v * w.x) * invDet; + mdx = v[0].u - m11 * v[0].x - m12 * v[0].y; + mdy = v[0].v - m21 * v[0].x - m22 * v[0].y; + + int dudx = int(m11 * 0x10000); + int dvdx = int(m21 * 0x10000); + int dudy = int(m12 * 0x10000); + int dvdy = int(m22 * 0x10000); + int u0 = qCeil((0.5 * m11 + 0.5 * m12 + mdx) * 0x10000) - 1; + int v0 = qCeil((0.5 * m21 + 0.5 * m22 + mdy) * 0x10000) - 1; + + int x1 = qFloor(sourceRect.left()); + int y1 = qFloor(sourceRect.top()); + int x2 = qCeil(sourceRect.right()); + int y2 = qCeil(sourceRect.bottom()); + QRect sourceRectI(x1, y1, x2 - x1, y2 - y1); + + // rasterize trapezoids. + if (v[1].y < v[3].y) { + qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); + qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[0], v[3], sourceRectI, clip, v[1].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); + qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[3].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); + } else { + qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); + qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[3], v[2], sourceRectI, clip, v[3].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); + qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[1].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender); + } +} + +QT_END_NAMESPACE + +#endif // QBLENDFUNCTIONS_P_H diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 130270b..dc3b79b 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -7964,6 +7964,12 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; + qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon; + qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon; + + qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon; + qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon; + qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; } #endif diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index ef1b85c..ca1d85f 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -40,6 +40,8 @@ ****************************************************************************/ #include +#include +#include #ifdef QT_HAVE_NEON @@ -310,6 +312,143 @@ void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, pixman_composite_over_n_8_0565_asm_neon(mapWidth, mapHeight, dest, destStride, color, 0, mask, mapStride); } +extern "C" void blend_8_pixels_argb32_on_rgb16_neon(quint16 *dst, const quint32 *src, int const_alpha); +extern "C" void blend_8_pixels_rgb16_on_rgb16_neon(quint16 *dst, const quint16 *src, int const_alpha); + +template +struct Blend_on_RGB16_SourceAndConstAlpha_Neon { + Blend_on_RGB16_SourceAndConstAlpha_Neon(BlendFunc blender, int const_alpha) + : m_index(0) + , m_blender(blender) + , m_const_alpha(const_alpha) + { + } + + inline void write(quint16 *dst, quint32 src) + { + srcBuffer[m_index++] = src; + + if (m_index == 8) { + m_blender(dst - 7, srcBuffer, m_const_alpha); + m_index = 0; + } + } + + inline void flush(quint16 *dst) + { + if (m_index > 0) { + quint16 dstBuffer[8]; + for (int i = 0; i < m_index; ++i) + dstBuffer[i] = dst[i - m_index]; + + m_blender(dstBuffer, srcBuffer, m_const_alpha); + + for (int i = 0; i < m_index; ++i) + dst[i - m_index] = dstBuffer[i]; + + m_index = 0; + } + } + + SRC srcBuffer[8]; + + int m_index; + BlendFunc m_blender; + int m_const_alpha; +}; + +template +Blend_on_RGB16_SourceAndConstAlpha_Neon +Blend_on_RGB16_SourceAndConstAlpha_Neon_create(BlendFunc blender, int const_alpha) +{ + return Blend_on_RGB16_SourceAndConstAlpha_Neon(blender, const_alpha); +} + +void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + int const_alpha) +{ + if (const_alpha == 0) + return; + + qt_scale_image_16bit(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, + Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_argb32_on_rgb16_neon, const_alpha)); +} + +void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + int const_alpha); + +void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + int const_alpha) +{ + if (const_alpha == 0) + return; + + if (const_alpha == 256) { + qt_scale_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, const_alpha); + return; + } + + qt_scale_image_16bit(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, + Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha)); +} + +extern void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + const QTransform &targetRectTransform, + int const_alpha); + +void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + const QTransform &targetRectTransform, + int const_alpha) +{ + if (const_alpha == 0) + return; + + if (const_alpha == 256) { + qt_transform_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, targetRectTransform, const_alpha); + return; + } + + qt_transform_image(reinterpret_cast(destPixels), dbpl, + reinterpret_cast(srcPixels), sbpl, targetRect, sourceRect, clip, targetRectTransform, + Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha)); +} + +void qt_transform_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + const QTransform &targetRectTransform, + int const_alpha) +{ + if (const_alpha == 0) + return; + + qt_transform_image(reinterpret_cast(destPixels), dbpl, + reinterpret_cast(srcPixels), sbpl, targetRect, sourceRect, clip, targetRectTransform, + Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_argb32_on_rgb16_neon, const_alpha)); +} + QT_END_NAMESPACE #endif // QT_HAVE_NEON diff --git a/src/gui/painting/qdrawhelper_neon_asm.S b/src/gui/painting/qdrawhelper_neon_asm.S new file mode 100644 index 0000000..9992817 --- /dev/null +++ b/src/gui/painting/qdrawhelper_neon_asm.S @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* Prevent the stack from becoming executable for no reason... */ +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + +.text +.fpu neon +.arch armv7a +.altmacro + +/* void blend_8_pixels_argb32_on_rgb16_neon(quint16 *dst, const quint32 *src, int const_alpha) */ + + .func blend_8_pixels_argb32_on_rgb16_neon + .global blend_8_pixels_argb32_on_rgb16_neon + /* For ELF format also set function visibility to hidden */ +#ifdef __ELF__ + .hidden blend_8_pixels_argb32_on_rgb16_neon + .type blend_8_pixels_argb32_on_rgb16_neon, %function +#endif +blend_8_pixels_argb32_on_rgb16_neon: + vld4.8 { d0, d1, d2, d3 }, [r1] + vld1.16 { d4, d5 }, [r0] + + cmp r2, #256 + beq .blend_32_inner + + vdup.8 d6, r2 + + /* multiply by const_alpha */ + vmull.u8 q8, d6, d0 + vmull.u8 q9, d6, d1 + vmull.u8 q10, d6, d2 + vmull.u8 q11, d6, d3 + + vshrn.u16 d0, q8, #8 + vshrn.u16 d1, q9, #8 + vshrn.u16 d2, q10, #8 + vshrn.u16 d3, q11, #8 + +.blend_32_inner: + /* convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format + and put data into d6 - red, d7 - green, d30 - blue */ + vshrn.u16 d6, q2, #8 + vshrn.u16 d7, q2, #3 + vsli.u16 q2, q2, #5 + vsri.u8 d6, d6, #5 + vmvn.8 d3, d3 + vsri.u8 d7, d7, #6 + vshrn.u16 d30, q2, #2 + + pld [r0, #128] + + /* now do alpha blending, storing results in 8-bit planar format + into d16 - red, d19 - green, d18 - blue */ + vmull.u8 q10, d3, d6 + vmull.u8 q11, d3, d7 + vmull.u8 q12, d3, d30 + vrshr.u16 q13, q10, #8 + vrshr.u16 q3, q11, #8 + vrshr.u16 q15, q12, #8 + vraddhn.u16 d20, q10, q13 + vraddhn.u16 d23, q11, q3 + vraddhn.u16 d22, q12, q15 + vqadd.u8 d16, d2, d20 + vqadd.u8 q9, q0, q11 + /* convert the result to r5g6b5 and store it into {d28, d29} */ + vshll.u8 q14, d16, #8 + vshll.u8 q8, d19, #8 + vshll.u8 q9, d18, #8 + vsri.u16 q14, q8, #5 + vsri.u16 q14, q9, #11 + + vst1.16 { d28, d29 }, [r0] + + bx lr + + .endfunc + +/* void blend_8_pixels_rgb16_on_rgb16_neon(quint16 *dst, const quint16 *src, int const_alpha) */ + + .func blend_8_pixels_rgb16_on_rgb16_neon + .global blend_8_pixels_rgb16_on_rgb16_neon + /* For ELF format also set function visibility to hidden */ +#ifdef __ELF__ + .hidden blend_8_pixels_rgb16_on_rgb16_neon + .type blend_8_pixels_rgb16_on_rgb16_neon, %function +#endif +blend_8_pixels_rgb16_on_rgb16_neon: + vld1.16 { d0, d1 }, [r0] + vld1.16 { d2, d3 }, [r1] + + rsb r3, r2, #256 + vdup.8 d4, r2 + vdup.8 d5, r3 + + /* convert 8 r5g6b5 pixel data from {d0, d1} to planar 8-bit format + and put data into d6 - red, d7 - green, d30 - blue */ + vshrn.u16 d6, q0, #8 + vshrn.u16 d7, q0, #3 + vsli.u16 q0, q0, #5 + vsri.u8 d6, d6, #5 + vsri.u8 d7, d7, #6 + vshrn.u16 d30, q0, #2 + + /* same from {d2, d3} into {d26, d27, d28} */ + vshrn.u16 d26, q1, #8 + vshrn.u16 d27, q1, #3 + vsli.u16 q1, q1, #5 + vsri.u8 d26, d26, #5 + vsri.u8 d27, d27, #6 + vshrn.u16 d28, q1, #2 + + /* multiply dst by inv const_alpha */ + vmull.u8 q10, d5, d6 + vmull.u8 q11, d5, d7 + vmull.u8 q12, d5, d30 + + vshrn.u16 d6, q10, #8 + vshrn.u16 d7, q11, #8 + vshrn.u16 d30, q12, #8 + + /* multiply src by const_alpha */ + vmull.u8 q10, d4, d26 + vmull.u8 q11, d4, d27 + vmull.u8 q12, d4, d28 + + vshrn.u16 d26, q10, #8 + vshrn.u16 d27, q11, #8 + vshrn.u16 d28, q12, #8 + + /* preload dst + 128 */ + pld [r0, #128] + + /* add components, storing results in 8-bit planar format + into d16 - red, d19 - green, d18 - blue */ + vadd.u8 d16, d26, d6 + vadd.u8 d19, d27, d7 + vadd.u8 d18, d28, d30 + + /* convert the result to r5g6b5 and store it into {d28, d29} */ + vshll.u8 q14, d16, #8 + vshll.u8 q8, d19, #8 + vshll.u8 q9, d18, #8 + vsri.u16 q14, q8, #5 + vsri.u16 q14, q9, #11 + + vst1.16 { d28, d29 }, [r0] + + bx lr + + .endfunc diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h index 6f9604f..6f25243 100644 --- a/src/gui/painting/qdrawhelper_neon_p.h +++ b/src/gui/painting/qdrawhelper_neon_p.h @@ -84,6 +84,37 @@ void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, const uchar *bitmap, int mapWidth, int mapHeight, int mapStride, const QClipData *clip); + +void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + int const_alpha); + +void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + int const_alpha); + +void qt_transform_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + const QTransform &targetRectTransform, + int const_alpha); + +void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + const QTransform &targetRectTransform, + int const_alpha); + #endif // QT_HAVE_NEON QT_END_NAMESPACE -- cgit v0.12 From fa44a37174f51f3d2786fc6e60d8fa5561a4df6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 25 Mar 2010 12:14:40 +0100 Subject: Optimized SourceOver and 16 bit dest fetches, dest stores using NEON. This makes for example linear gradient blending on top of RGB16 156 % faster (from 20.4 fps to 52.3 fps in my benchmark). Task-number: QTBUG-6684 Reviewed-by: Gunnar Sletta --- src/gui/painting/qdrawhelper.cpp | 12 ++-- src/gui/painting/qdrawhelper_neon.cpp | 125 +++++++++++++++++++++++++++++++--- src/gui/painting/qdrawhelper_neon_p.h | 12 ++++ 3 files changed, 134 insertions(+), 15 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index dc3b79b..917b910 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -175,7 +175,7 @@ Q_STATIC_TEMPLATE_FUNCTION uint * QT_FASTCALL destFetch(uint *buffer, QRasterBuf # define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch -static const DestFetchProc destFetchProc[QImage::NImageFormats] = +static DestFetchProc destFetchProc[QImage::NImageFormats] = { 0, // Format_Invalid destFetchMono, // Format_Mono, @@ -323,7 +323,7 @@ Q_STATIC_TEMPLATE_FUNCTION void QT_FASTCALL destStore(QRasterBuffer *rasterBuffe # define SPANFUNC_POINTER_DESTSTORE(DEST) destStore -static const DestStoreProc destStoreProc[QImage::NImageFormats] = +static DestStoreProc destStoreProc[QImage::NImageFormats] = { 0, // Format_Invalid destStoreMono, // Format_Mono, @@ -2827,7 +2827,7 @@ static void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, } } -static const CompositionFunctionSolid functionForModeSolid_C[] = { +static CompositionFunctionSolid functionForModeSolid_C[] = { comp_func_solid_SourceOver, comp_func_solid_DestinationOver, comp_func_solid_Clear, @@ -2865,7 +2865,7 @@ static const CompositionFunctionSolid functionForModeSolid_C[] = { static const CompositionFunctionSolid *functionForModeSolid = functionForModeSolid_C; -static const CompositionFunction functionForMode_C[] = { +static CompositionFunction functionForMode_C[] = { comp_func_SourceOver, comp_func_DestinationOver, comp_func_Clear, @@ -7971,6 +7971,10 @@ void qInitDrawhelperAsm() qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon; qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; + + functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon; + destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon; + destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon; } #endif diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index ca1d85f..946e100 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -114,6 +114,21 @@ pixman_composite_src_0565_8888_asm_neon (int32_t w, uint16_t *src, int32_t src_stride); +extern "C" void +pixman_composite_over_n_8_0565_asm_neon (int32_t w, + int32_t h, + uint16_t *dst, + int32_t dst_stride, + uint32_t src, + int32_t unused, + uint8_t *mask, + int32_t mask_stride); + +extern "C" void +pixman_composite_scanline_over_asm_neon (int32_t w, + const uint32_t *dst, + const uint32_t *src); + // qblendfunctions.cpp void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, @@ -163,6 +178,15 @@ void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, pixman_composite_over_8888_0565_asm_neon(w, h, dst, dbpl / 2, src, sbpl / 4); } +void qt_blend_argb32_on_argb32_scanline_neon(uint *dest, const uint *src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + pixman_composite_scanline_over_asm_neon(length, dest, src); + } else { + qt_blend_argb32_on_argb32_neon((uchar *)dest, 4 * length, (uchar *)src, 4 * length, length, 1, (const_alpha * 256) / 255); + } +} + void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, @@ -287,17 +311,6 @@ void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl, } } -extern "C" void -pixman_composite_over_n_8_0565_asm_neon (int32_t w, - int32_t h, - uint16_t *dst, - int32_t dst_stride, - uint32_t src, - int32_t unused, - uint8_t *mask, - int32_t mask_stride); - - void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, int x, int y, quint32 color, const uchar *bitmap, @@ -449,6 +462,96 @@ void qt_transform_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, Blend_on_RGB16_SourceAndConstAlpha_Neon_create(blend_8_pixels_argb32_on_rgb16_neon, const_alpha)); } +static inline void convert_8_pixels_rgb16_to_argb32(quint32 *dst, const quint16 *src) +{ + asm volatile ( + "vld1.16 { d0, d1 }, [%[SRC]]\n\t" + + /* convert 8 r5g6b5 pixel data from {d0, d1} to planar 8-bit format + and put data into d4 - red, d3 - green, d2 - blue */ + "vshrn.u16 d4, q0, #8\n\t" + "vshrn.u16 d3, q0, #3\n\t" + "vsli.u16 q0, q0, #5\n\t" + "vsri.u8 d4, d4, #5\n\t" + "vsri.u8 d3, d3, #6\n\t" + "vshrn.u16 d2, q0, #2\n\t" + + /* fill d5 - alpha with 0xff */ + "mov r2, #255\n\t" + "vdup.8 d5, r2\n\t" + + "vst4.8 { d2, d3, d4, d5 }, [%[DST]]" + : : [DST]"r" (dst), [SRC]"r" (src) + : "memory", "r2", "d0", "d1", "d2", "d3", "d4", "d5" + ); +} + +uint * QT_FASTCALL qt_destFetchRGB16_neon(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) +{ + const ushort *data = (const ushort *)rasterBuffer->scanLine(y) + x; + + int i = 0; + for (; i < length - 7; i += 8) + convert_8_pixels_rgb16_to_argb32(&buffer[i], &data[i]); + + if (i < length) { + quint16 srcBuffer[8]; + quint32 dstBuffer[8]; + + int tail = length - i; + for (int j = 0; j < tail; ++j) + srcBuffer[j] = data[i + j]; + + convert_8_pixels_rgb16_to_argb32(dstBuffer, srcBuffer); + + for (int j = 0; j < tail; ++j) + buffer[i + j] = dstBuffer[j]; + } + + return buffer; +} + +static inline void convert_8_pixels_argb32_to_rgb16(quint16 *dst, const quint32 *src) +{ + asm volatile ( + "vld4.8 { d0, d1, d2, d3 }, [%[SRC]]\n\t" + + /* convert to r5g6b5 and store it into {d28, d29} */ + "vshll.u8 q14, d2, #8\n\t" + "vshll.u8 q8, d1, #8\n\t" + "vshll.u8 q9, d0, #8\n\t" + "vsri.u16 q14, q8, #5\n\t" + "vsri.u16 q14, q9, #11\n\t" + + "vst1.16 { d28, d29 }, [%[DST]]" + : : [DST]"r" (dst), [SRC]"r" (src) + : "memory", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d28", "d29" + ); +} + +void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) +{ + quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x; + + int i = 0; + for (; i < length - 7; i += 8) + convert_8_pixels_argb32_to_rgb16(&data[i], &buffer[i]); + + if (i < length) { + quint32 srcBuffer[8]; + quint16 dstBuffer[8]; + + int tail = length - i; + for (int j = 0; j < tail; ++j) + srcBuffer[j] = buffer[i + j]; + + convert_8_pixels_argb32_to_rgb16(dstBuffer, srcBuffer); + + for (int j = 0; j < tail; ++j) + data[i + j] = dstBuffer[j]; + } +} + QT_END_NAMESPACE #endif // QT_HAVE_NEON diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h index 6f25243..d6a4509 100644 --- a/src/gui/painting/qdrawhelper_neon_p.h +++ b/src/gui/painting/qdrawhelper_neon_p.h @@ -74,6 +74,11 @@ void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, int w, int h, int const_alpha); +void qt_blend_argb32_on_argb32_scanline_neon(uint *dest, + const uint *src, + int length, + uint const_alpha); + void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, @@ -115,6 +120,13 @@ void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, const QTransform &targetRectTransform, int const_alpha); +uint * QT_FASTCALL qt_destFetchRGB16_neon(uint *buffer, + QRasterBuffer *rasterBuffer, + int x, int y, int length); + +void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, + int x, int y, const uint *buffer, int length); + #endif // QT_HAVE_NEON QT_END_NAMESPACE -- cgit v0.12 From 5e2b330aaa0ef964d45f9cb60ea258b33d6e7c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 25 Mar 2010 15:47:18 +0100 Subject: Optimized ARGB32PM on RGB16 blending with opacity using NEON. Use the blend_8_pixels_argb32_on_rgb16_neon function that was introduced in an earlier commit. Before: traces/qmlsamegame.trace, iterations: 3, frames: 15, min(ms): 63, median(ms): 64, stddev: 1,275776 %, max(fps): 238,095238 After: traces/qmlsamegame.trace, iterations: 3, frames: 15, min(ms): 57, median(ms): 58, stddev: 0,817464 %, max(fps): 263,157895 Task-number: QTBUG-6684 Reviewed-by: Gunnar Sletta --- src/gui/painting/qdrawhelper_neon.cpp | 37 ++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 946e100..ee5f24a 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -162,19 +162,47 @@ void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, pixman_composite_src_0565_8888_asm_neon(w, h, dst, dbpl, src, sbpl); } +extern "C" void blend_8_pixels_argb32_on_rgb16_neon(quint16 *dst, const quint32 *src, int const_alpha); + void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, int const_alpha) { + quint16 *dst = (quint16 *) destPixels; + quint32 *src = (quint32 *) srcPixels; + if (const_alpha != 256) { - qt_blend_argb32_on_rgb16_const_alpha(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + for (int y=0; y -- cgit v0.12 From 41e9adb44137c8839d0d7e131802de198b0e7168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 18 Mar 2010 14:38:50 +0100 Subject: Paintbuffer single frame profiling. Added new --instrumentframe=X argument which gives a detailed run-down of how many milliseconds each paint command of that frame takes. Reviewed-by: Gunnar Sletta --- src/gui/painting/qpaintbuffer.cpp | 303 ++++++++++++++++++++++++++++++++++++-- src/gui/painting/qpaintbuffer_p.h | 8 +- src/gui/painting/qtransform.cpp | 15 +- tools/qttracereplay/main.cpp | 99 +++++++++++-- 4 files changed, 400 insertions(+), 25 deletions(-) diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index 39b76c8..ca2077f 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -269,24 +269,304 @@ void QPaintBuffer::draw(QPainter *painter, int frame) const printf("\n"); #endif - if (painter && !painter->isActive()) - return; + processCommands(painter, frameStartIndex(frame), frameEndIndex(frame)); + +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBuffer::draw() -------------------------------- DONE!"; +#endif +} + +int QPaintBuffer::frameStartIndex(int frame) const +{ + return (frame == 0) ? 0 : d_ptr->frames.at(frame - 1); +} + +int QPaintBuffer::frameEndIndex(int frame) const +{ + return (frame == d_ptr->frames.size()) ? d_ptr->commands.size() : d_ptr->frames.at(frame); +} + +int QPaintBuffer::processCommands(QPainter *painter, int begin, int end) const +{ + if (!painter || !painter->isActive()) + return 0; QPaintEngineEx *xengine = painter->paintEngine()->isExtended() ? (QPaintEngineEx *) painter->paintEngine() : 0; if (xengine) { QPaintEngineExReplayer player; - player.draw(*this, painter, frame); + player.processCommands(*this, painter, begin, end); } else { QPainterReplayer player; - player.draw(*this, painter, frame); + player.processCommands(*this, painter, begin, end); } -#ifdef QPAINTBUFFER_DEBUG_DRAW - qDebug() << "QPaintBuffer::draw() -------------------------------- DONE!"; -#endif + int depth = 0; + for (int i = begin; i < end; ++i) { + const QPaintBufferCommand &cmd = d_ptr->commands.at(i); + if (cmd.id == QPaintBufferPrivate::Cmd_Save) + ++depth; + else if (cmd.id == QPaintBufferPrivate::Cmd_Restore) + --depth; + } + return depth; } +QString QPaintBuffer::commandDescription(int command) const +{ + QString desc; + QDebug debug(&desc); + + const QPaintBufferCommand &cmd = d_ptr->commands.at(command); + + switch (cmd.id) { + case QPaintBufferPrivate::Cmd_Save: { + debug << "Cmd_Save"; + break; } + + case QPaintBufferPrivate::Cmd_Restore: { + debug << "Cmd_Restore"; + break; } + + case QPaintBufferPrivate::Cmd_SetBrush: { + QBrush brush = qVariantValue(d_ptr->variants.at(cmd.offset)); + debug << "Cmd_SetBrush: " << brush; + break; } + + case QPaintBufferPrivate::Cmd_SetBrushOrigin: { + debug << "Cmd_SetBrushOrigin: " << d_ptr->variants.at(cmd.offset).toPointF(); + break; } + + case QPaintBufferPrivate::Cmd_SetCompositionMode: { + QPainter::CompositionMode mode = (QPainter::CompositionMode) cmd.extra; + debug << "ExCmd_SetCompositionMode, mode: " << mode; + break; } + + case QPaintBufferPrivate::Cmd_SetOpacity: { + debug << "ExCmd_SetOpacity: " << d_ptr->variants.at(cmd.offset).toDouble(); + break; } + + case QPaintBufferPrivate::Cmd_DrawVectorPath: { + debug << "ExCmd_DrawVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2; + break; } + + case QPaintBufferPrivate::Cmd_StrokeVectorPath: { + QPen pen = qVariantValue(d_ptr->variants.at(cmd.extra)); + debug << "ExCmd_StrokeVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2 << pen; + break; } + + case QPaintBufferPrivate::Cmd_FillVectorPath: { + QBrush brush = qVariantValue(d_ptr->variants.at(cmd.extra)); + debug << "ExCmd_FillVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2 << brush; + break; } + + case QPaintBufferPrivate::Cmd_FillRectBrush: { + QBrush brush = qVariantValue(d_ptr->variants.at(cmd.extra)); + QRectF *rect = (QRectF *)(d_ptr->floats.constData() + cmd.offset); + debug << "ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush; + break; } + + case QPaintBufferPrivate::Cmd_FillRectColor: { + QColor color = qVariantValue(d_ptr->variants.at(cmd.extra)); + QRectF *rect = (QRectF *)(d_ptr->floats.constData() + cmd.offset); + debug << "ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color; + break; } + + case QPaintBufferPrivate::Cmd_DrawPolygonF: { + debug << "ExCmd_DrawPolygonF, offset: " << cmd.offset << " size: " << cmd.size + << " mode: " << cmd.extra + << d_ptr->floats.at(cmd.offset) + << d_ptr->floats.at(cmd.offset+1); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolygonI: { + debug << "ExCmd_DrawPolygonI, offset: " << cmd.offset << " size: " << cmd.size + << " mode: " << cmd.extra + << d_ptr->ints.at(cmd.offset) + << d_ptr->ints.at(cmd.offset+1); + break; } + + case QPaintBufferPrivate::Cmd_DrawEllipseF: { + debug << "ExCmd_DrawEllipseF, offset: " << cmd.offset; + break; } + + case QPaintBufferPrivate::Cmd_DrawLineF: { + debug << "ExCmd_DrawLineF, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawLineI: { + debug << "ExCmd_DrawLineI, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawPointsF: { + debug << "ExCmd_DrawPointsF, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawPointsI: { + debug << "ExCmd_DrawPointsI, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawPolylineF: { + debug << "ExCmd_DrawPolylineF, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawPolylineI: { + debug << "ExCmd_DrawPolylineI, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawRectF: { + debug << "ExCmd_DrawRectF, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawRectI: { + debug << "ExCmd_DrawRectI, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_SetClipEnabled: { + bool clipEnabled = d_ptr->variants.at(cmd.offset).toBool(); + debug << "ExCmd_SetClipEnabled:" << clipEnabled; + break; } + + case QPaintBufferPrivate::Cmd_ClipVectorPath: { + QVectorPathCmd path(d_ptr, cmd); + debug << "ExCmd_ClipVectorPath:" << path().elementCount(); + break; } + + case QPaintBufferPrivate::Cmd_ClipRect: { + QRect rect(QPoint(d_ptr->ints.at(cmd.offset), d_ptr->ints.at(cmd.offset + 1)), + QPoint(d_ptr->ints.at(cmd.offset + 2), d_ptr->ints.at(cmd.offset + 3))); + debug << "ExCmd_ClipRect:" << rect << cmd.extra; + break; } + + case QPaintBufferPrivate::Cmd_ClipRegion: { + QRegion region(d_ptr->variants.at(cmd.offset).value()); + debug << "ExCmd_ClipRegion:" << region.boundingRect() << cmd.extra; + break; } + + case QPaintBufferPrivate::Cmd_SetPen: { + QPen pen = qVariantValue(d_ptr->variants.at(cmd.offset)); + debug << "Cmd_SetPen: " << pen; + break; } + + case QPaintBufferPrivate::Cmd_SetTransform: { + QTransform xform = qVariantValue(d_ptr->variants.at(cmd.offset)); + debug << "Cmd_SetTransform, offset: " << cmd.offset << xform; + break; } + + case QPaintBufferPrivate::Cmd_SetRenderHints: { + debug << "Cmd_SetRenderHints, hints: " << cmd.extra; + break; } + + case QPaintBufferPrivate::Cmd_SetBackgroundMode: { + debug << "Cmd_SetBackgroundMode: " << cmd.extra; + break; } + + case QPaintBufferPrivate::Cmd_DrawConvexPolygonF: { + debug << "Cmd_DrawConvexPolygonF, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawConvexPolygonI: { + debug << "Cmd_DrawConvexPolygonI, offset: " << cmd.offset << " size: " << cmd.size; + break; } + + case QPaintBufferPrivate::Cmd_DrawEllipseI: { + debug << "Cmd_DrawEllipseI, offset: " << cmd.offset; + break; } + + case QPaintBufferPrivate::Cmd_DrawPixmapRect: { + QPixmap pm(d_ptr->variants.at(cmd.offset).value()); + QRectF r(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1), + d_ptr->floats.at(cmd.extra+2), d_ptr->floats.at(cmd.extra+3)); + + QRectF sr(d_ptr->floats.at(cmd.extra+4), d_ptr->floats.at(cmd.extra+5), + d_ptr->floats.at(cmd.extra+6), d_ptr->floats.at(cmd.extra+7)); + debug << "Cmd_DrawPixmapRect:" << r << sr << pm.size(); + break; } + + case QPaintBufferPrivate::Cmd_DrawPixmapPos: { + QPixmap pm(d_ptr->variants.at(cmd.offset).value()); + QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); + debug << "Cmd_DrawPixmapPos:" << pos << pm.size(); + break; } + + case QPaintBufferPrivate::Cmd_DrawTiledPixmap: { + QPixmap pm(d_ptr->variants.at(cmd.offset).value()); + QRectF r(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1), + d_ptr->floats.at(cmd.extra+2), d_ptr->floats.at(cmd.extra+3)); + + QPointF offset(d_ptr->floats.at(cmd.extra+4), d_ptr->floats.at(cmd.extra+5)); + debug << "Cmd_DrawTiledPixmap:" << r << offset << pm.size(); + break; } + + case QPaintBufferPrivate::Cmd_DrawImageRect: { + QImage image(d_ptr->variants.at(cmd.offset).value()); + QRectF r(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1), + d_ptr->floats.at(cmd.extra+2), d_ptr->floats.at(cmd.extra+3)); + QRectF sr(d_ptr->floats.at(cmd.extra+4), d_ptr->floats.at(cmd.extra+5), + d_ptr->floats.at(cmd.extra+6), d_ptr->floats.at(cmd.extra+7)); + debug << "Cmd_DrawImageRect:" << r << sr << image.size(); + break; } + + case QPaintBufferPrivate::Cmd_DrawImagePos: { + QImage image(d_ptr->variants.at(cmd.offset).value()); + QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); + debug << "Cmd_DrawImagePos:" << pos << image.size(); + break; } + + case QPaintBufferPrivate::Cmd_DrawText: { + QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); + QList variants(d_ptr->variants.at(cmd.offset).value >()); + + QFont font(variants.at(0).value()); + QString text(variants.at(1).value()); + + debug << "Cmd_DrawText:" << pos << text << font.family(); + break; } + + case QPaintBufferPrivate::Cmd_DrawTextItem: { + QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); + QTextItemIntCopy *tiCopy = reinterpret_cast(qVariantValue(d_ptr->variants.at(cmd.offset))); + QTextItemInt &ti = (*tiCopy)(); + QString text(ti.text()); + + QFont font(ti.font()); + font.setUnderline(false); + font.setStrikeOut(false); + font.setOverline(false); + + const QTextItemInt &si = static_cast(ti); + qreal justificationWidth = 0; + if (si.justified) + justificationWidth = si.width.toReal(); + + debug << "Cmd_DrawTextItem:" << pos << " " << text; + break; } + case QPaintBufferPrivate::Cmd_SystemStateChanged: { + QRegion systemClip(d_ptr->variants.at(cmd.offset).value()); + + debug << "Cmd_SystemStateChanged:" << systemClip; + break; } + case QPaintBufferPrivate::Cmd_Translate: { + QPointF delta(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); + debug << "Cmd_Translate:" << delta; + break; } + case QPaintBufferPrivate::Cmd_DrawStaticText: { + QPointF delta(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); + QVariantList variants(d_ptr->variants.at(cmd.offset).value()); + + QStaticText text(variants.at(0).value()); + debug << "Cmd_DrawStaticText:" << text.text(); + break; } + } + + return desc; +} QRectF QPaintBuffer::boundingRect() const { @@ -1110,15 +1390,12 @@ void QPainterReplayer::setupTransform(QPainter *_painter) painter->setTransform(m_world_matrix); } -void QPainterReplayer::draw(const QPaintBuffer &buffer, QPainter *_painter, int frame) +void QPainterReplayer::processCommands(const QPaintBuffer &buffer, QPainter *p, int begin, int end) { d = buffer.d_ptr; - setupTransform(_painter); - - int frameStart = (frame == 0) ? 0 : d->frames.at(frame-1); - int frameEnd = (frame == d->frames.size()) ? d->commands.size() : d->frames.at(frame); + painter = p; - for (int cmdIndex=frameStart; cmdIndexcommands.at(cmdIndex); process(cmd); } diff --git a/src/gui/painting/qpaintbuffer_p.h b/src/gui/painting/qpaintbuffer_p.h index 0fde290..4576947 100644 --- a/src/gui/painting/qpaintbuffer_p.h +++ b/src/gui/painting/qpaintbuffer_p.h @@ -78,6 +78,12 @@ public: int numFrames() const; void draw(QPainter *painter, int frame = 0) const; + + int frameStartIndex(int frame) const; + int frameEndIndex(int frame) const; + int processCommands(QPainter *painter, int begin, int end) const; + QString commandDescription(int command) const; + void setBoundingRect(const QRectF &rect); QRectF boundingRect() const; @@ -317,7 +323,7 @@ public: void setupTransform(QPainter *painter); virtual void process(const QPaintBufferCommand &cmd); - void draw(const QPaintBuffer &buffer, QPainter *painter, int frame); + void processCommands(const QPaintBuffer &buffer, QPainter *painter, int begin, int end); protected: QPaintBufferPrivate *d; diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 4f42a58..988d678 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1037,8 +1037,18 @@ QDataStream & operator>>(QDataStream &s, QTransform &t) #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QTransform &m) { - dbg.nospace() << "QTransform(" - << "11=" << m.m11() + static const char *typeStr[] = + { + "TxNone", + "TxTranslate", + "TxScale", + "TxRotate", + "TxShear", + "TxProject" + }; + + dbg.nospace() << "QTransform(type=" << typeStr[m.type()] << ',' + << " 11=" << m.m11() << " 12=" << m.m12() << " 13=" << m.m13() << " 21=" << m.m21() @@ -1048,6 +1058,7 @@ QDebug operator<<(QDebug dbg, const QTransform &m) << " 32=" << m.m32() << " 33=" << m.m33() << ')'; + return dbg.space(); } #endif diff --git a/tools/qttracereplay/main.cpp b/tools/qttracereplay/main.cpp index be7906b..101d512 100644 --- a/tools/qttracereplay/main.cpp +++ b/tools/qttracereplay/main.cpp @@ -49,7 +49,7 @@ class ReplayWidget : public QWidget { Q_OBJECT public: - ReplayWidget(const QString &filename, int from, int to, bool single); + ReplayWidget(const QString &filename, int from, int to, bool single, int frame); void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); @@ -66,27 +66,96 @@ public: QTime timer; QList visibleUpdates; - QList iterationTimes; + + QVector iterationTimes; QString filename; int from; int to; bool single; + + int frame; + int currentCommand; }; void ReplayWidget::updateRect() { - if (!visibleUpdates.isEmpty()) + if (frame >= 0 && !updates.isEmpty()) + update(updates.at(frame)); + else if (!visibleUpdates.isEmpty()) update(updates.at(visibleUpdates.at(currentFrame))); } +const int singleFrameRepeatsPerCommand = 100; +const int singleFrameIterations = 4; + void ReplayWidget::paintEvent(QPaintEvent *) { QPainter p(this); + QTimer::singleShot(0, this, SLOT(updateRect())); + // p.setClipRegion(frames.at(currentFrame).updateRegion); + if (frame >= 0) { + int start = buffer.frameStartIndex(frame); + int end = buffer.frameEndIndex(frame); + + iterationTimes.resize(end - start); + + int saveRestoreStackDepth = buffer.processCommands(&p, start, start + currentCommand); + + for (int i = 0; i < saveRestoreStackDepth; ++i) + p.restore(); + + const int repeats = currentIteration >= 3 ? singleFrameRepeatsPerCommand : 1; + + ++currentFrame; + if (currentFrame == repeats) { + currentFrame = 0; + if (currentIteration >= 3) { + iterationTimes[currentCommand - 1] = qMin(iterationTimes[currentCommand - 1], uint(timer.elapsed())); + timer.restart(); + } + + if (currentIteration >= singleFrameIterations + 3) { + printf(" # | ms | description\n"); + printf("------+---------+------------------------------------------------------------\n"); + + qSort(iterationTimes); + + int sum = 0; + for (int i = 0; i < iterationTimes.size(); ++i) { + int delta = iterationTimes.at(i); + if (i > 0) + delta -= iterationTimes.at(i-1); + sum += delta; + qreal deltaF = delta / qreal(repeats); + printf("%.5d | %.5f | %s\n", i, deltaF, qPrintable(buffer.commandDescription(start + i))); + } + printf("Total | %.5f | Total frame time\n", sum / qreal(repeats)); + deleteLater(); + return; + } + + if (start + currentCommand >= end) { + currentCommand = 1; + ++currentIteration; + if (currentIteration == 3) { + timer.start(); + iterationTimes.fill(uint(-1)); + } + if (currentIteration >= 3 && currentIteration < singleFrameIterations + 3) + printf("Profiling iteration %d of %d\n", currentIteration - 2, singleFrameIterations); + } else { + ++currentCommand; + } + } + + return; + } + buffer.draw(&p, visibleUpdates.at(currentFrame)); ++currentFrame; @@ -138,11 +207,9 @@ void ReplayWidget::paintEvent(QPaintEvent *) } } } - - QTimer::singleShot(0, this, SLOT(updateRect())); } -void ReplayWidget::resizeEvent(QResizeEvent *event) +void ReplayWidget::resizeEvent(QResizeEvent *) { visibleUpdates.clear(); @@ -162,13 +229,15 @@ void ReplayWidget::resizeEvent(QResizeEvent *event) } -ReplayWidget::ReplayWidget(const QString &filename_, int from_, int to_, bool single_) +ReplayWidget::ReplayWidget(const QString &filename_, int from_, int to_, bool single_, int frame_) : currentFrame(0) , currentIteration(0) , filename(filename_) , from(from_) , to(to_) , single(single_) + , frame(frame_) + , currentCommand(1) { setWindowTitle(filename); QFile file(filename); @@ -216,7 +285,8 @@ int main(int argc, char **argv) printf("Usage:\n > %s [OPTIONS] [traceFile]\n", argv[0]); printf("OPTIONS\n" " --range=from-to to specify a frame range.\n" - " --singlerun to do only one run (without statistics)\n"); + " --singlerun to do only one run (without statistics)\n" + " --instrumentframe=frame to instrument a single frame\n"); return 1; } @@ -228,6 +298,8 @@ int main(int argc, char **argv) bool single = false; + int frame = -1; + int from = 0; int to = -1; for (int i = 1; i < app.arguments().size() - 1; ++i) { @@ -253,13 +325,22 @@ int main(int argc, char **argv) } } else if (arg == QLatin1String("--singlerun")) { single = true; + } else if (arg.startsWith(QLatin1String("--instrumentframe="))) { + QString rest = arg.mid(18); + bool ok = false; + int frameCandidate = rest.toInt(&ok); + if (ok) { + frame = frameCandidate; + } else { + printf("ERROR: malformed syntax in argument %s\n", qPrintable(arg)); + } } else { printf("Unrecognized argument: %s\n", qPrintable(arg)); return 1; } } - ReplayWidget *widget = new ReplayWidget(app.arguments().last(), from, to, single); + ReplayWidget *widget = new ReplayWidget(app.arguments().last(), from, to, single, frame); if (!widget->updates.isEmpty()) { widget->show(); -- cgit v0.12 From 47472906fd00e0eff820870330d481c4229ee285 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 26 Mar 2010 10:43:40 +0100 Subject: Synchronize rich text and plain text code paths in QStaticText Drawing a string as plain text and rich text should have identical results unless special formatting information is added in the html. This means we should not have any implicit margin on the QTextDocument used to paint the text, and we should make up for the fact that the drawStaticText() call currently takes the position of the baseline and QTextDocument::drawContents() takes the top-left corner. Reviewed-by: Gunnar --- src/gui/text/qstatictext.cpp | 6 +++-- tests/auto/qstatictext/tst_qstatictext.cpp | 36 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 1fabf12..d685cd9 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -553,12 +553,14 @@ void QStaticTextPrivate::paintText(const QPointF &pos, QPainter *p) } else { QTextDocument document; document.setDefaultFont(font); + document.setDocumentMargin(0.0); document.setHtml(text); - QRectF rect = maximumSize.isValid() ? QRectF(pos, maximumSize) : QRectF(); + QPointF adjustedPos = pos - QPointF(0, QFontMetricsF(font).ascent()); + QRectF rect = maximumSize.isValid() ? QRectF(adjustedPos, maximumSize) : QRectF(); document.adjustSize(); p->save(); - p->translate(pos); + p->translate(adjustedPos); document.drawContents(p, rect); p->restore(); actualSize = document.size(); diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index 16832ad..a038878 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -79,6 +79,8 @@ private slots: void projectedPainter(); void rotatedScaledAndTranslatedPainter(); void transformationChanged(); + + void plainTextVsRichText(); }; void tst_QStaticText::init() @@ -482,5 +484,39 @@ void tst_QStaticText::transformationChanged() QCOMPARE(imageDrawStaticText, imageDrawText); } +void tst_QStaticText::plainTextVsRichText() +{ + QPixmap imagePlainText(1000, 1000); + imagePlainText.fill(Qt::white); + { + QPainter p(&imagePlainText); + + QStaticText staticText; + staticText.setText("FOObar"); + staticText.setTextFormat(Qt::PlainText); + + p.drawStaticText(10, 10, staticText); + } + + QPixmap imageRichText(1000, 1000); + imageRichText.fill(Qt::white); + { + QPainter p(&imageRichText); + + QStaticText staticText; + staticText.setText("FOObar"); + staticText.setTextFormat(Qt::RichText); + + p.drawStaticText(10, 10, staticText); + } + +#if defined(DEBUG_SAVE_IMAGE) + imagePlainText.save("plainTextVsRichText_imagePlainText.png"); + imageRichText.save("plainTextVsRichText_imageRichText.png"); +#endif + + QCOMPARE(imagePlainText, imageRichText); +} + QTEST_MAIN(tst_QStaticText) #include "tst_qstatictext.moc" -- cgit v0.12 From df0e6759e8ebc1053f951d3a5398a41156e91913 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 25 Mar 2010 20:05:35 +0100 Subject: QMetaObject::normalizeType: fix uses of const and template. 'const' was not removed from templated class This even fixes compilation errors if using const return templated types We can change the normalized signature in Qt 4.7 as it has already changed and we have code to check that if moc revision < 5 it will renormalize all the symbols cf commit b881d8fb99972f1bd04ab4c84843cc8d43ddbeed Task-number: QTBUG-7421 Reviewed-by: Brad Reviewed-by: Kent Hansen --- src/corelib/kernel/qmetaobject_p.h | 4 +++- tests/auto/moc/tst_moc.cpp | 11 +++++++++++ tests/auto/qmetaobject/tst_qmetaobject.cpp | 6 ++++++ tests/auto/qobject/tst_qobject.cpp | 20 ++++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index a176149..1f4bd2f 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -196,7 +196,7 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc if (*(e-1) == '&') { // treat const reference as value t += 6; --e; - } else if (is_ident_char(*(e-1))) { // treat const value as value + } else if (is_ident_char(*(e-1)) || *(e-1) == '>') { // treat const value as value t += 6; } } @@ -294,6 +294,8 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc if (adjustConst && t != e && *t == '&') { // treat const ref as value ++t; + } else if (adjustConst && !star) { + // treat const as value } else if (!star) { // move const to the front (but not if const comes after a *) result.prepend("const "); diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 30c2721..8890a15 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -1302,6 +1302,17 @@ void tst_Moc::QTBUG5590_dummyProperty() QCOMPARE(o.value2(), 82); } +class QTBUG7421_ReturnConstTemplate: public QObject +{ Q_OBJECT +public slots: + const QList returnConstTemplate1() { return QList(); } + QList const returnConstTemplate2() { return QList(); } + const int returnConstInt() { return 0; } + const QString returnConstString(const QString s) { return s; } + QString const returnConstString2( QString const s) { return s; } +}; + + QTEST_APPLESS_MAIN(tst_Moc) #include "tst_moc.moc" diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index bb4a0d2..e81607e 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -706,6 +706,12 @@ void tst_QMetaObject::normalizedSignature_data() QTest::newRow("const6") << "void foo(QList)" << "void foo(QList)"; QTest::newRow("const7") << "void foo(QList)" << "void foo(QList)"; QTest::newRow("const8") << "void foo(QList)" << "void foo(QList)"; + QTest::newRow("const9") << "void foo(const Foo)" << "void foo(Foo)"; + QTest::newRow("const10") << "void foo(Fooconst)" << "void foo(Foo)"; + QTest::newRow("const11") << "void foo(Foo *const)" << "void foo(Foo*const)"; + QTest::newRow("const12") << "void foo(Fooconst*const *const)" << "void foo(Foo*const*const)"; + QTest::newRow("const13") << "void foo(const Foo&)" << "void foo(Foo)"; + QTest::newRow("const14") << "void foo(Fooconst&)" << "void foo(Foo)"; } void tst_QMetaObject::normalizedSignature() diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 8da3484..08b7c19 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -2088,6 +2088,9 @@ signals: void typePointerConstRefSignal(Class * const &); + void constTemplateSignal1( Template ); + void constTemplateSignal2( Template< const int >); + public slots: void uintPointerSlot(uint *) { } void ulongPointerSlot(ulong *) { } @@ -2124,6 +2127,10 @@ public slots: void typeConstRefSlot(Template const &) {} void typePointerConstRefSlot(Class * const &) {} + + void constTemplateSlot1(Template const) {} + void constTemplateSlot2(const Template ) {} + void constTemplateSlot3(const Template< const int >) {} }; #include "oldnormalizeobject.h" @@ -2526,6 +2533,19 @@ void tst_QObject::normalize() QVERIFY(object.connect(&object, SIGNAL(typePointerConstRefSignal(Class*)), SLOT(typePointerConstRefSlot(Class*)))); + + QVERIFY( connect(&object, SIGNAL(constTemplateSignal1(Template )), + &object , SLOT(constTemplateSlot1 (Template ) ) )); + QVERIFY( connect(&object, SIGNAL(constTemplateSignal1(Template )), + &object , SLOT(constTemplateSlot2 (Template ) ) )); + QVERIFY( connect(&object, SIGNAL(constTemplateSignal2(Template )), + &object , SLOT(constTemplateSlot3(Template ) ) )); + + //type does not match + QTest::ignoreMessage(QtWarningMsg, "QObject::connect: Incompatible sender/receiver arguments\n" + " NormalizeObject::constTemplateSignal1(Template) --> NormalizeObject::constTemplateSlot3(Template)"); + QVERIFY(!connect(&object, SIGNAL(constTemplateSignal1(Template )), + &object , SLOT(constTemplateSlot3(Template ) ) )); } class SiblingDeleter : public QObject -- cgit v0.12 From ff870dbf9106f2bbb2cf64f5aa35fc5917e5f4f2 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 26 Mar 2010 11:26:42 +0100 Subject: QMetaObject::normalizeType: Fix parsing of type which contains "const" in names Regression since b881d8fb99972f1bd04ab4c84843cc8d43ddbeed Task-number: QTBUG-9354 Reviewed-by: Kent Hansen --- src/corelib/kernel/qmetaobject_p.h | 3 ++- tests/auto/moc/tst_moc.cpp | 9 +++++++++ tests/auto/qmetaobject/tst_qmetaobject.cpp | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index 1f4bd2f..b538787 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -287,7 +287,8 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc } // cv qualifers can appear after the type as well - if (t != e && (e - t >= 5 && strncmp("const", t, 5) == 0)) { + if (!is_ident_char(c) && t != e && (e - t >= 5 && strncmp("const", t, 5) == 0) + && (e - t == 5 || !is_ident_char(t[5]))) { t += 5; while (t != e && is_space(*t)) ++t; diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 8890a15..a56d842 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -1312,6 +1312,15 @@ public slots: QString const returnConstString2( QString const s) { return s; } }; +class QTBUG9354_constInName: public QObject +{ Q_OBJECT +public slots: + void slotChooseScientificConst0(struct science_constant const &) {}; + void foo(struct science_const const &) {}; + void foo(struct constconst const &) {}; + void foo(struct constconst *) {}; + void foo(struct const_ *) {}; +}; QTEST_APPLESS_MAIN(tst_Moc) #include "tst_moc.moc" diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index e81607e..c0b1303 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -740,6 +740,14 @@ void tst_QMetaObject::normalizedType_data() QTest::newRow("template7") << "QList >" << "QList >"; QTest::newRow("value1") << "const QString &" << "QString"; QTest::newRow("value2") << "QString const &" << "QString"; + QTest::newRow("constInName1") << "constconst" << "constconst"; + QTest::newRow("constInName2") << "constconst*" << "constconst*"; + QTest::newRow("constInName3") << "const constconst&" << "constconst"; + QTest::newRow("constInName4") << "constconst const*const" << "constconst*const"; + QTest::newRow("class") << "const class foo&" << "foo"; + QTest::newRow("struct") << "const struct foo*" << "const foo*"; + QTest::newRow("struct2") << "struct foo const*" << "const foo*"; + QTest::newRow("enum") << "enum foo" << "foo"; } void tst_QMetaObject::normalizedType() -- cgit v0.12 From fa40e6fd8b719e2edfdbde94ac70431c68e92449 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 26 Mar 2010 10:54:34 +0100 Subject: Stabilize tst_QTreeView::taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint Non expected paint events and screen size on pulse_qws/linux-x86-g++ seem to be the reason the auto-test fails. Reviewed-by: jeremy --- tests/auto/qtreeview/tst_qtreeview.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index 6871982..2de189d 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -3721,11 +3721,13 @@ class TreeViewQTBUG_9216 : public QTreeView public: void paintEvent(QPaintEvent *event) { - QCOMPARE(event->rect(), viewport()->rect()); + if (doCompare) + QCOMPARE(event->rect(), viewport()->rect()); QTreeView::paintEvent(event); painted++; } int painted; + bool doCompare; }; void tst_QTreeView::taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint() @@ -3737,15 +3739,16 @@ void tst_QTreeView::taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint() TreeViewQTBUG_9216 view; view.setUniformRowHeights(true); view.setModel(&model); - view.resize(800, 800); view.painted = 0; + view.doCompare = false; view.show(); QTest::qWaitForWindowShown(&view); QTRY_VERIFY(view.painted > 0); QTest::qWait(100); // This one is needed to make the test fail before the patch. view.painted = 0; - model.setData(model.index(0, 5), QVariant(QSize(100,100)), Qt::SizeHintRole); + view.doCompare = true; + model.setData(model.index(0, 0), QVariant(QSize(50, 50)), Qt::SizeHintRole); QTest::qWait(100); QTRY_VERIFY(view.painted > 0); } -- cgit v0.12 From ea0f3f7db1d62b2ee94addbeb991061bc2811745 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 26 Mar 2010 14:09:47 +0200 Subject: QS60Style cannot draw transparency to UI element border areas Due to incorrect initialization of CFbsBitmap, graphic frames (9-part, or 3-part ones) are drawn with white non-transparent rect below them. Initialization corrected. Task-number: QT-3185 Reviewed-by: Janne Anttila --- src/gui/styles/qs60style_s60.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 1138d20..97cf919 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -859,11 +859,9 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr User::LeaveIfError(bitmapDev->CreateContext(bitmapGc)); CleanupStack::PushL(bitmapGc); -#ifndef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE frame->LockHeap(); memset(frame->DataAddress(), 0, frame->SizeInPixels().iWidth * frame->SizeInPixels().iHeight * 4); // 4: argb bytes frame->UnlockHeap(); -#endif const TRect outerRect(TPoint(0, 0), targetSize); const TRect innerRect = innerRectFromElement(frameElement, outerRect); -- cgit v0.12 From 75bb84ac0e6f17446d87a34ae8a644abff6009af Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 22 Mar 2010 10:48:39 +0100 Subject: Implement Texture-From-Pixmap using EGLImage extensions on X11/EGL There's lots of EGLImage extensions, split between EGL and client rendering APIs like OpenGL ES & OpenVG. To implement texture-from- pixmap using EGLImage, both EGL extensions and OpenGL ES extensions are needed. This patch resolves the EGL extension function pointers after the display is initialized in QEgl::display(). These are then exported from QtGui so they can be used in QtOpenGL. The OpenGL ES extension function pointers are resolved using the usual qglextensions.cpp mechanism. Using EGLImage seems to remove a fixed ~10 millisecond overhead per pixmap bind when compared to using EGLSurface. Exact results per bind for 100 QPixmaps are: 8x8 Pixmap: 12 -> 1.71 msecs (EGLSurface -> EGLImage) 64x64 Pixmap: 11.6 -> 1.83 msecs (EGLSurface -> EGLImage) 128x128 Pixmap: 12.8 -> 2.74 msecs (EGLSurface -> EGLImage) 256x256 Pixmap: 16 -> 6.20 msecs (EGLSurface -> EGLImage) Reviewed-By: Trond --- src/gui/egl/qegl.cpp | 9 +++ src/gui/egl/qegl_p.h | 24 ++++++- src/opengl/qgl_egl_p.h | 1 + src/opengl/qgl_x11egl.cpp | 146 ++++++++++++++++++++++++++++++++----------- src/opengl/qglextensions.cpp | 11 ++++ src/opengl/qglextensions_p.h | 36 +++++++++++ 6 files changed, 190 insertions(+), 37 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index b870523..507fab3 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -528,6 +528,9 @@ QEglProperties QEglContext::configProperties() const return QEglProperties(config()); } +_eglCreateImageKHR eglCreateImageKHR = 0; +_eglDestroyImageKHR eglDestroyImageKHR = 0; + EGLDisplay QEgl::display() { static EGLDisplay dpy = EGL_NO_DISPLAY; @@ -549,6 +552,12 @@ EGLDisplay QEgl::display() qWarning() << "QEgl::display(): Cannot initialize EGL display:" << QEgl::errorString(); return EGL_NO_DISPLAY; } + + // Resolve the egl extension function pointers: + if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_base")) { + eglCreateImageKHR = (_eglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); + eglDestroyImageKHR = (_eglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); + } } return dpy; diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index 7dad9fe..b570329 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -100,13 +100,34 @@ typedef NativeDisplayType EGLNativeDisplayType; QT_END_INCLUDE_NAMESPACE #include - #include QT_BEGIN_NAMESPACE #define QEGL_NO_CONFIG ((EGLConfig)-1) +#ifndef EGLAPIENTRY +#define EGLAPIENTRY +#endif + +#if !defined(EGL_KHR_image) || !defined(EGL_KHR_image_base) + +typedef void *EGLImageKHR; +#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 + +typedef EGLImageKHR (EGLAPIENTRY *_eglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); +typedef EGLBoolean (EGLAPIENTRY *_eglDestroyImageKHR)(EGLDisplay, EGLImageKHR); + +// Defined in qegl.cpp: +extern Q_GUI_EXPORT _eglCreateImageKHR eglCreateImageKHR; +extern Q_GUI_EXPORT _eglDestroyImageKHR eglDestroyImageKHR; + +#endif // !defined(EGL_KHR_image) || !defined(EGL_KHR_image_base) + +#if !defined(EGL_KHR_image) || !defined(EGL_KHR_image_pixmap) +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 +#endif class QEglProperties; @@ -132,7 +153,6 @@ namespace QEgl { }; Q_DECLARE_FLAGS(ConfigOptions, ConfigOption); - // Most of the time we use the same config for things like widgets & pixmaps, so rather than // go through the eglChooseConfig loop every time, we use defaultConfig, which will return // the config for a particular device/api/option combo. This function assumes that once a diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h index 43793cd..85d7f32 100644 --- a/src/opengl/qgl_egl_p.h +++ b/src/opengl/qgl_egl_p.h @@ -53,6 +53,7 @@ // We mean it. // +#include #include #include diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 0954e69..6980281 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -367,6 +367,30 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons static bool checkedForTFP = false; static bool haveTFP = false; + static bool checkedForEglImageTFP = false; + static bool haveEglImageTFP = false; + + + if (!checkedForEglImageTFP) { + checkedForEglImageTFP = true; + + // We need to be able to create an EGLImage from a native pixmap, which was split + // into a seperate EGL extension, EGL_KHR_image_pixmap. It is possible to have + // eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must + // check we have the EGLImage from pixmap functionality. + if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) { + Q_ASSERT(eglCreateImageKHR); + Q_ASSERT(eglDestroyImageKHR); + + // Being able to create an EGLImage from a native pixmap is also pretty useless + // without the ability to bind that EGLImage as a texture, which is provided by + // the GL_OES_EGL_image extension, which we try to resolve here: + haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q); + + if (haveEglImageTFP) + qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!"); + } + } if (!checkedForTFP) { // Check for texture_from_pixmap egl extension @@ -379,61 +403,113 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons } } - if (!haveTFP) + if (!haveTFP && !haveEglImageTFP) return 0; - QX11PixmapData *pixmapData = static_cast(pd); + + QX11PixmapData *pixmapData = static_cast(pd); bool hasAlpha = pixmapData->hasAlphaChannel(); + bool pixmapHasValidSurface = false; + bool textureIsBound = false; + GLuint textureId; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); - // Check to see if the surface is still valid - if (pixmapData->gl_surface && - hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) + if (haveTFP && pixmapData->gl_surface && + hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) { - // Surface is invalid! - destroyGlSurfaceForPixmap(pixmapData); + pixmapHasValidSurface = true; } - if (pixmapData->gl_surface == 0) { - EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, - QEgl::OpenGL, - hasAlpha ? QEgl::Translucent : QEgl::NoOptions); + // If we already have a valid EGL surface for the pixmap, we should use it + if (pixmapHasValidSurface) { + EGLBoolean success; + success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); + if (success == EGL_FALSE) { + qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); + eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); + pixmapData->gl_surface = (void*)EGL_NO_SURFACE; + } else + textureIsBound = true; + } - QPixmap tmpPixmap(pixmapData); //### - pixmapData->gl_surface = (void*)QEgl::createSurface(&tmpPixmap, config); - if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) { - haveTFP = false; - return 0; - } + // If the pixmap doesn't already have a valid surface, try binding it via EGLImage + // first, as going through EGLImage should be faster and better supported: + if (!textureIsBound && haveEglImageTFP) { + Q_ASSERT(eglCreateImageKHR); + + EGLImageKHR eglImage; + QPixmap tmpPixmap(pd); + + EGLint attribs[] = { + EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, + EGL_NONE + }; + eglImage = eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer)QEgl::nativePixmap(&tmpPixmap), attribs); + + QGLContext* ctx = q; + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage); + + GLint err = glGetError(); + if (err == GL_NO_ERROR) + textureIsBound = true; + + // Once the egl image is bound, the texture becomes a new sibling image and we can safely + // destroy the EGLImage we created for the pixmap: + if (eglImage != EGL_NO_IMAGE_KHR) + eglDestroyImageKHR(QEgl::display(), eglImage); } - Q_ASSERT(pixmapData->gl_surface); + if (!textureIsBound && haveTFP) { + // Check to see if the surface is still valid + if (pixmapData->gl_surface && + hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) + { + // Surface is invalid! + destroyGlSurfaceForPixmap(pixmapData); + } - GLuint textureId; - glGenTextures(1, &textureId); - glBindTexture(GL_TEXTURE_2D, textureId); + if (pixmapData->gl_surface == 0) { + EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, + QEgl::OpenGL, + hasAlpha ? QEgl::Translucent : QEgl::NoOptions); - // bind the egl pixmap surface to a texture - EGLBoolean success; - success = eglBindTexImage(eglContext->display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); - if (success == EGL_FALSE) { - qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); - eglDestroySurface(eglContext->display(), (EGLSurface)pixmapData->gl_surface); - pixmapData->gl_surface = (void*)EGL_NO_SURFACE; - haveTFP = false; - return 0; + QPixmap tmpPixmap(pixmapData); //### + pixmapData->gl_surface = (void*)QEgl::createSurface(&tmpPixmap, config); + if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) + return false; + } + + EGLBoolean success; + success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); + if (success == EGL_FALSE) { + qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); + eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); + pixmapData->gl_surface = (void*)EGL_NO_SURFACE; + haveTFP = false; // If TFP isn't working, disable it's use + } else + textureIsBound = true; } - QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); - pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture; + QGLTexture *texture = 0; - // We assume the cost of bound pixmaps is zero - QGLTextureCache::instance()->insert(q, key, texture, 0); + if (textureIsBound) { + texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); + pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture; + + // We assume the cost of bound pixmaps is zero + QGLTextureCache::instance()->insert(q, key, texture, 0); + + glBindTexture(GL_TEXTURE_2D, textureId); + } else + glDeleteTextures(1, &textureId); - glBindTexture(GL_TEXTURE_2D, textureId); return texture; } + void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd) { Q_ASSERT(pmd->classId() == QPixmapData::X11Class); diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp index 02d5501..ef3c4cd 100644 --- a/src/opengl/qglextensions.cpp +++ b/src/opengl/qglextensions.cpp @@ -222,6 +222,17 @@ bool qt_resolve_buffer_extensions(QGLContext *ctx) #endif } +#ifndef QT_NO_EGL +bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx) +{ + if (glEGLImageTargetTexture2DOES || glEGLImageTargetRenderbufferStorageOES) + return true; + glEGLImageTargetTexture2DOES = (_glEGLImageTargetTexture2DOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetTexture2DOES")); + glEGLImageTargetRenderbufferStorageOES = (_glEGLImageTargetRenderbufferStorageOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetRenderbufferStorageOES")); + return glEGLImageTargetTexture2DOES && glEGLImageTargetRenderbufferStorageOES; +} +#endif + bool qt_resolve_glsl_extensions(QGLContext *ctx) { // Geometry shaders are optional... diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index f6926f3..7597b33 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -68,6 +68,11 @@ # define APIENTRYP * #endif +#ifndef QT_NO_EGL +// Needed for EGLImageKHR definition: +#include +#endif + #include #ifndef GL_ARB_vertex_buffer_object @@ -210,6 +215,14 @@ typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum atta typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +#ifndef QT_NO_EGL +// OES_EGL_image +// Note: We define these to take EGLImage whereas spec says they take a new GLeglImageOES +// type, which the EGL image should be cast to. +typedef void (APIENTRY *_glEGLImageTargetTexture2DOES) (GLenum, EGLImageKHR); +typedef void (APIENTRY *_glEGLImageTargetRenderbufferStorageOES) (GLenum, EGLImageKHR); +#endif + QT_BEGIN_NAMESPACE struct QGLExtensionFuncs @@ -327,6 +340,12 @@ struct QGLExtensionFuncs // Texture compression qt_glCompressedTexImage2DARB = 0; #endif + +#ifndef QT_NO_EGL + // OES_EGL_image + qt_glEGLImageTargetTexture2DOES = 0; + qt_glEGLImageTargetRenderbufferStorageOES = 0; +#endif } @@ -447,6 +466,13 @@ struct QGLExtensionFuncs // Texture compression _glCompressedTexImage2DARB qt_glCompressedTexImage2DARB; #endif + +#ifndef QT_NO_EGL + // OES_EGL_image + _glEGLImageTargetTexture2DOES qt_glEGLImageTargetTexture2DOES; + _glEGLImageTargetRenderbufferStorageOES qt_glEGLImageTargetRenderbufferStorageOES; +#endif + }; @@ -839,6 +865,12 @@ struct QGLExtensionFuncs #define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB #endif +#ifndef QT_NO_EGL +// OES_EGL_image +#define glEGLImageTargetTexture2DOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetTexture2DOES +#define glEGLImageTargetRenderbufferStorageOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetRenderbufferStorageOES +#endif + extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx); bool qt_resolve_buffer_extensions(QGLContext *ctx); @@ -849,6 +881,10 @@ bool qt_resolve_frag_program_extensions(QGLContext *ctx); bool qt_resolve_glsl_extensions(QGLContext *ctx); +#ifndef QT_NO_EGL +bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx); +#endif + QT_END_NAMESPACE #endif // QGL_EXTENSIONS_P_H -- cgit v0.12 From 7488aa544bdfccc0131427669266a93c44501c42 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 22 Mar 2010 14:21:23 +0100 Subject: Avoid having to create temporary QPixmaps when binding to texture Reviewed-By: TrustMe --- src/opengl/qgl.cpp | 2 +- src/opengl/qgl_p.h | 2 +- src/opengl/qgl_x11.cpp | 6 +++--- src/opengl/qgl_x11egl.cpp | 13 +++++-------- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 7aba25a..e56b149 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2444,7 +2444,7 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType && xinfo && xinfo->screen() == pixmap.x11Info().screen()) { - texture = bindTextureFromNativePixmap(pd, key, options); + texture = bindTextureFromNativePixmap(const_cast(&pixmap), key, options); if (texture) { texture->options |= QGLContext::MemoryManagedBindOption; texture->boundPixmap = pd; diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 45f8f30..1169533 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -361,7 +361,7 @@ public: quint32 gpm; int screen; QHash boundPixmaps; - QGLTexture *bindTextureFromNativePixmap(QPixmapData*, const qint64 key, + QGLTexture *bindTextureFromNativePixmap(QPixmap*, const qint64 key, QGLContext::BindOptions options); static void destroyGlSurfaceForPixmap(QPixmapData*); static void unbindPixmapFromTexture(QPixmapData*); diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 4fa1467..e1a202f 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -1671,7 +1671,7 @@ static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice) #endif //defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) -QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData *pmd, const qint64 key, +QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, QGLContext::BindOptions options) { #if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX) @@ -1679,12 +1679,12 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData *pmd, con #else Q_Q(QGLContext); - Q_ASSERT(pmd->classId() == QPixmapData::X11Class); + QX11PixmapData *pixmapData = static_cast(pixmap->data_ptr().data()); + Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); if (!qt_resolveTextureFromPixmap(paintDevice)) return 0; - QX11PixmapData *pixmapData = static_cast(pmd); const QX11Info &x11Info = pixmapData->xinfo; // Store the configs (Can be static because configs aren't dependent on current context) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 6980281..af0100b 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -354,7 +354,7 @@ void QGLWidgetPrivate::recreateEglSurface(bool force) } -QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, const qint64 key, +QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, QGLContext::BindOptions options) { Q_Q(QGLContext); @@ -363,7 +363,6 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons if (!(options & QGLContext::CanFlipNativePixmapBindOption)) return 0; - Q_ASSERT(pd->classId() == QPixmapData::X11Class); static bool checkedForTFP = false; static bool haveTFP = false; @@ -407,8 +406,8 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons return 0; - - QX11PixmapData *pixmapData = static_cast(pd); + QX11PixmapData *pixmapData = static_cast(pixmap->data_ptr().data()); + Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); bool hasAlpha = pixmapData->hasAlphaChannel(); bool pixmapHasValidSurface = false; bool textureIsBound = false; @@ -440,14 +439,13 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons Q_ASSERT(eglCreateImageKHR); EGLImageKHR eglImage; - QPixmap tmpPixmap(pd); EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; eglImage = eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, - (EGLClientBuffer)QEgl::nativePixmap(&tmpPixmap), attribs); + (EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs); QGLContext* ctx = q; glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage); @@ -476,8 +474,7 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons QEgl::OpenGL, hasAlpha ? QEgl::Translucent : QEgl::NoOptions); - QPixmap tmpPixmap(pixmapData); //### - pixmapData->gl_surface = (void*)QEgl::createSurface(&tmpPixmap, config); + pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config); if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) return false; } -- cgit v0.12 From f8b0da8c12fcdcb9a820b208c27313cea10d8798 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 26 Mar 2010 13:37:25 +0100 Subject: Remove EGLImage create/destroy resolving from VG pixmap data eglCreateImageKHR and eglDestroyImageKHR are now defined in qegl.cpp and resolved when the display is opened with QEgl::display(). Reviewed-By: Jason Barron --- src/openvg/qpixmapdata_vg.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index e66d80b..7550446 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -42,6 +42,7 @@ #include "qpixmapdata_vg_p.h" #include "qpaintengine_vg_p.h" #include +#include #include "qvg_p.h" #include "qvgimagepool_p.h" @@ -49,8 +50,6 @@ #include #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE #include -typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); -typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE @@ -486,8 +485,6 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) return; } - pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); - pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { @@ -607,8 +604,6 @@ void* QVGPixmapData::toNativeType(NativeType type) return 0; } - pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); - pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { -- cgit v0.12 From 0d5c68c7e4f31300ac6736203cea4f67e8b825b5 Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Fri, 26 Mar 2010 14:53:30 +0200 Subject: QInputContextFactory::languages implementation for Symbian. Task-number: QTBUG-6851 Reviewed-by: Sami Merila --- src/gui/inputmethod/inputmethod.pri | 2 +- src/gui/inputmethod/qinputcontextfactory.cpp | 47 +++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/gui/inputmethod/inputmethod.pri b/src/gui/inputmethod/inputmethod.pri index 6d9f748..02e3e57 100644 --- a/src/gui/inputmethod/inputmethod.pri +++ b/src/gui/inputmethod/inputmethod.pri @@ -26,6 +26,6 @@ mac:!embedded { symbian:contains(QT_CONFIG, s60) { HEADERS += inputmethod/qcoefepinputcontext_p.h SOURCES += inputmethod/qcoefepinputcontext_s60.cpp - LIBS += -lfepbase + LIBS += -lfepbase -lakninputlanguage } diff --git a/src/gui/inputmethod/qinputcontextfactory.cpp b/src/gui/inputmethod/qinputcontextfactory.cpp index 501a36e..d47e343 100644 --- a/src/gui/inputmethod/qinputcontextfactory.cpp +++ b/src/gui/inputmethod/qinputcontextfactory.cpp @@ -73,6 +73,7 @@ #endif #ifdef Q_WS_S60 #include "qcoefepinputcontext_p.h" +#include "akninputlanguageinfo.h" #endif #include "private/qfactoryloader_p.h" @@ -198,6 +199,42 @@ QStringList QInputContextFactory::keys() return result; } +#if defined(Q_WS_S60) +/*! + \internal + + This function contains pure Symbian exception handling code for + getting S60 language list. + Returned object ownership is transfered to caller. +*/ +static CAknInputLanguageList* s60LangListL() +{ + CAknInputLanguageInfo *langInfo = AknInputLanguageInfoFactory::CreateInputLanguageInfoL(); + CleanupStack::PushL(langInfo); + // In rare phone there is more than 7 languages installed -> use 7 as an array granularity + CAknInputLanguageList *langList = new (ELeave) CAknInputLanguageList(7); + CleanupStack::PushL(langList); + langInfo->AppendAvailableLanguagesL(langList); + CleanupStack::Pop(langList); + CleanupStack::PopAndDestroy(langInfo); + return langList; +} + +/*! + \internal + + This function utility function return S60 language list. + Returned object ownership is transfered to caller. +*/ +static CAknInputLanguageList* s60LangList() +{ + CAknInputLanguageList *langList = NULL; + TRAP_IGNORE(langList = s60LangListL()); + q_check_ptr(langList); + return langList; +} +#endif + /*! Returns the languages supported by the QInputContext object specified by \a key. @@ -229,7 +266,15 @@ QStringList QInputContextFactory::languages( const QString &key ) #endif #if defined(Q_WS_S60) if (key == QLatin1String("coefep")) - return QStringList(QString()); + { + CAknInputLanguageList *langList = s60LangList(); + int count = langList->Count(); + for (int i = 0; i < count; ++i) + { + result.append(QString(qt_symbianLocaleName(langList->At(i)->LanguageCode()))); + } + delete langList; + } #endif #if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) Q_UNUSED(key); -- cgit v0.12 From c7d39e1335775979d43833d0b7f6c32cef898424 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 26 Mar 2010 14:09:26 +0100 Subject: uic3: -extract: Write XPM-images correctly. Add magic header '/* XPM */' and turn off wrapping of lines that broke image readers. Add a command line option to activate line-wrapping in case someone exclusively wants to use the extracted images for embedding in code. Also do line-wrapping in case images are embedded into the ui-file. Note: The current versions of MSVC do not seem to have a limitation of line lengths any more. Task-number: QTBUG-9207 Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppextractimages.cpp | 2 +- src/tools/uic/cpp/cppwriteicondata.cpp | 12 ++++++++---- src/tools/uic/cpp/cppwriteicondata.h | 3 ++- src/tools/uic/option.h | 2 ++ src/tools/uic3/converter.cpp | 1 + src/tools/uic3/form.cpp | 1 + src/tools/uic3/main.cpp | 3 +++ src/tools/uic3/ui3reader.h | 3 ++- tests/auto/uic/baseline/config_fromuic3.ui.h | 1 + tests/auto/uic/baseline/paletteeditoradvancedbase.ui.h | 1 + 10 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/tools/uic/cpp/cppextractimages.cpp b/src/tools/uic/cpp/cppextractimages.cpp index d452168..52c1b9d 100644 --- a/src/tools/uic/cpp/cppextractimages.cpp +++ b/src/tools/uic/cpp/cppextractimages.cpp @@ -134,7 +134,7 @@ void ExtractImages::acceptImage(DomImage *image) QTextStream *imageOut = new QTextStream(&f); imageOut->setCodec(QTextCodec::codecForName("UTF-8")); - CPP::WriteIconData::writeImage(*imageOut, QString(), image); + CPP::WriteIconData::writeImage(*imageOut, QString(), m_option.limitXPM_LineLength, image); delete imageOut; } else { CPP::WriteIconData::writeImage(f, image); diff --git a/src/tools/uic/cpp/cppwriteicondata.cpp b/src/tools/uic/cpp/cppwriteicondata.cpp index 81ef56b..7e4b5c8 100644 --- a/src/tools/uic/cpp/cppwriteicondata.cpp +++ b/src/tools/uic/cpp/cppwriteicondata.cpp @@ -114,10 +114,12 @@ void WriteIconData::acceptImages(DomImages *images) void WriteIconData::acceptImage(DomImage *image) { - writeImage(output, option.indent, image); + // Limit line length when writing code. + writeImage(output, option.indent, true, image); } -void WriteIconData::writeImage(QTextStream &output, const QString &indent, DomImage *image) +void WriteIconData::writeImage(QTextStream &output, const QString &indent, + bool limitXPM_LineLength, const DomImage *image) { QString img = image->attributeName() + QLatin1String("_data"); QString data = image->elementData()->text(); @@ -133,7 +135,8 @@ void WriteIconData::writeImage(QTextStream &output, const QString &indent, DomIm int a = 0; int column = 0; bool inQuote = false; - output << indent << "static const char* const " << img << "[] = { \n"; + output << indent << "/* XPM */\n" + << indent << "static const char* const " << img << "[] = { \n"; while (baunzip[a] != '\"') a++; for (; a < (int) length; a++) { @@ -144,7 +147,8 @@ void WriteIconData::writeImage(QTextStream &output, const QString &indent, DomIm inQuote = !inQuote; } - if (column++ >= 511 && inQuote) { + column++; + if (limitXPM_LineLength && column >= 512 && inQuote) { output << "\"\n\""; // be nice with MSVC & Co. column = 1; } diff --git a/src/tools/uic/cpp/cppwriteicondata.h b/src/tools/uic/cpp/cppwriteicondata.h index 40d56bc..42cfab0 100644 --- a/src/tools/uic/cpp/cppwriteicondata.h +++ b/src/tools/uic/cpp/cppwriteicondata.h @@ -64,7 +64,8 @@ public: void acceptImages(DomImages *images); void acceptImage(DomImage *image); - static void writeImage(QTextStream &output, const QString &indent, DomImage *image); + static void writeImage(QTextStream &output, const QString &indent, + bool limitXPM_LineLength, const DomImage *image); static void writeImage(QIODevice &output, DomImage *image); private: diff --git a/src/tools/uic/option.h b/src/tools/uic/option.h index f1198a0..8556728 100644 --- a/src/tools/uic/option.h +++ b/src/tools/uic/option.h @@ -61,6 +61,7 @@ struct Option unsigned int autoConnection : 1; unsigned int dependencies : 1; unsigned int extractImages : 1; + unsigned int limitXPM_LineLength : 1; unsigned int implicitIncludes: 1; Generator generator; @@ -85,6 +86,7 @@ struct Option autoConnection(1), dependencies(0), extractImages(0), + limitXPM_LineLength(0), implicitIncludes(1), generator(CppGenerator), prefix(QLatin1String("Ui_")) diff --git a/src/tools/uic3/converter.cpp b/src/tools/uic3/converter.cpp index e1b4b38..2ee939d 100644 --- a/src/tools/uic3/converter.cpp +++ b/src/tools/uic3/converter.cpp @@ -518,6 +518,7 @@ DomUI *Ui3Reader::generateUi4(const QDomElement &widget) if (m_extractImages) { Option opt; opt.extractImages = m_extractImages; + opt.limitXPM_LineLength = (m_options & LimitXPM_LineLength) ? 1 : 0; opt.qrcOutputFile = m_qrcOutputFile; CPP::ExtractImages(opt).acceptUI(ui); diff --git a/src/tools/uic3/form.cpp b/src/tools/uic3/form.cpp index df1314f..9df644a 100644 --- a/src/tools/uic3/form.cpp +++ b/src/tools/uic3/form.cpp @@ -256,6 +256,7 @@ void Ui3Reader::createFormDecl(const QDomElement &e) d.option().headerProtection = false; d.option().copyrightHeader = false; d.option().extractImages = m_extractImages; + d.option().limitXPM_LineLength = (m_options & LimitXPM_LineLength) ? 1 : 0; d.option().qrcOutputFile = m_qrcOutputFile; d.option().implicitIncludes = (m_options & ImplicitIncludes) ? 1 : 0; if (trmacro.size()) diff --git a/src/tools/uic3/main.cpp b/src/tools/uic3/main.cpp index 1ebb76a..d7657b1 100644 --- a/src/tools/uic3/main.cpp +++ b/src/tools/uic3/main.cpp @@ -149,6 +149,8 @@ int runUic3(int argc, char * argv[]) readerOptions &= ~Ui3Reader::CustomWidgetForwardDeclarations; } else if (opt == "layout-names") { readerOptions |= Ui3Reader::PreserveLayoutNames; + } else if (opt == "limit-xpm-linelength") { + readerOptions |= Ui3Reader::LimitXPM_LineLength; } else if (opt == "nounload") { // skip } else if (opt == "convert") { @@ -251,6 +253,7 @@ int runUic3(int argc, char * argv[]) "Options:\n" "\t-o file Write output to file rather than stdout\n" "\t-extract qrcFile Create resource file and extract embedded images into \"image\" dir\n" + "\t-limit-xpm-linelength Limit the line length of XPM files for -extract.\n" "\t-pch file Add #include \"file\" as the first statement in implementation\n" "\t-nofwd Omit forward declarations of custom classes\n" "\t-layout-names Preserve layout names of Qt Designer 3\n" diff --git a/src/tools/uic3/ui3reader.h b/src/tools/uic3/ui3reader.h index 144ef05..abe323e 100644 --- a/src/tools/uic3/ui3reader.h +++ b/src/tools/uic3/ui3reader.h @@ -68,7 +68,8 @@ typedef QList > ColorGroup; class Ui3Reader { public: - enum Options { CustomWidgetForwardDeclarations = 0x1, ImplicitIncludes = 0x2, PreserveLayoutNames = 0x4 }; + enum Options { CustomWidgetForwardDeclarations = 0x1, ImplicitIncludes = 0x2, + PreserveLayoutNames = 0x4, LimitXPM_LineLength = 0x8 }; explicit Ui3Reader(QTextStream &stream, unsigned options); ~Ui3Reader(); diff --git a/tests/auto/uic/baseline/config_fromuic3.ui.h b/tests/auto/uic/baseline/config_fromuic3.ui.h index c77b303..7e0189e 100644 --- a/tests/auto/uic/baseline/config_fromuic3.ui.h +++ b/tests/auto/uic/baseline/config_fromuic3.ui.h @@ -670,6 +670,7 @@ protected: }; static QPixmap qt_get_icon(IconID id) { + /* XPM */ static const char* const image0_data[] = { "22 22 2 1", ". c None", diff --git a/tests/auto/uic/baseline/paletteeditoradvancedbase.ui.h b/tests/auto/uic/baseline/paletteeditoradvancedbase.ui.h index 50cc4c8..40485ac 100644 --- a/tests/auto/uic/baseline/paletteeditoradvancedbase.ui.h +++ b/tests/auto/uic/baseline/paletteeditoradvancedbase.ui.h @@ -439,6 +439,7 @@ protected: }; static QPixmap qt_get_icon(IconID id) { + /* XPM */ static const char* const image0_data[] = { "22 22 2 1", ". c None", -- cgit v0.12 From fc6cbc103be7eb77d692fb2975397c656b6a939b Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Fri, 26 Mar 2010 14:39:23 +0100 Subject: Fix compile error on Symbian 9.1, caused in network/access. RVCT has trouble when QPointer is instantiated on classes with inlined constructors/functions. Compile fix for 43e1cffb16c2eea54392f5c56210b10abb2f044e, cc22a14f3d2159a8f760b44e3fe1636a3721ce95 and 656c02f128c56177c48b3de47f7b1e17dbbfa4d3 Reviewed-by: Peter Hartmann Reviewed-by: Prasanth --- .../access/qhttpnetworkconnectionchannel.cpp | 30 ++++++++++++++++++++++ .../access/qhttpnetworkconnectionchannel_p.h | 17 +++--------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 0804498..bc7684a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -58,6 +58,28 @@ QT_BEGIN_NAMESPACE // TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp +QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel() + : socket(0) + , state(IdleState) + , reply(0) + , written(0) + , bytesTotal(0) + , resendCurrent(false) + , lastStatus(0) + , pendingEncrypt(false) + , reconnectAttempts(2) + , authMehtod(QAuthenticatorPrivate::None) + , proxyAuthMehtod(QAuthenticatorPrivate::None) +#ifndef QT_NO_OPENSSL + , ignoreAllSslErrors(false) +#endif + , pipeliningSupported(PipeliningSupportUnknown) + , connection(0) +{ + // Inlining this function in the header leads to compiler error on + // release-armv5, on at least timebox 9.2 and 10.1. +} + void QHttpNetworkConnectionChannel::init() { #ifndef QT_NO_OPENSSL @@ -994,8 +1016,16 @@ void QHttpNetworkConnectionChannel::_q_encryptedBytesWritten(qint64 bytes) sendRequest(); // otherwise we do nothing } + #endif +void QHttpNetworkConnectionChannel::setConnection(QHttpNetworkConnection *c) +{ + // Inlining this function in the header leads to compiler error on + // release-armv5, on at least timebox 9.2 and 10.1. + connection = c; +} + QT_END_NAMESPACE #include "moc_qhttpnetworkconnectionchannel_p.cpp" diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 4a2f8ad..51cb5e8 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -81,7 +81,6 @@ QT_BEGIN_NAMESPACE class QHttpNetworkRequest; class QHttpNetworkReply; class QByteArray; -class QHttpNetworkConnection; #ifndef HttpMessagePair typedef QPair HttpMessagePair; @@ -128,17 +127,9 @@ public: QList alreadyPipelinedRequests; - QHttpNetworkConnectionChannel() : socket(0), state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), - lastStatus(0), pendingEncrypt(false), reconnectAttempts(2), - authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) -#ifndef QT_NO_OPENSSL - , ignoreAllSslErrors(false) -#endif - , pipeliningSupported(PipeliningSupportUnknown) - , connection(0) - {} - - void setConnection(QHttpNetworkConnection *c) {connection = c;} + QHttpNetworkConnectionChannel(); + + void setConnection(QHttpNetworkConnection *c); QPointer connection; void init(); @@ -188,8 +179,6 @@ public: #endif }; - - QT_END_NAMESPACE #endif // QT_NO_HTTP -- cgit v0.12 From 5de7a8578cf5ac563d8b17b2e1eadde06e469d8e Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Thu, 18 Mar 2010 23:00:09 +0900 Subject: Fix compile error with QT_NO_TEXTHTMLPARSER in QtGui Merge-request: 528 Reviewed-by: Zeno Albisser --- src/gui/text/qstatictext.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 1fabf12..798ae37 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -553,8 +553,11 @@ void QStaticTextPrivate::paintText(const QPointF &pos, QPainter *p) } else { QTextDocument document; document.setDefaultFont(font); +#ifndef QT_NO_TEXTHTMLPARSER document.setHtml(text); - +#else + document.setPlainText(text); +#endif QRectF rect = maximumSize.isValid() ? QRectF(pos, maximumSize) : QRectF(); document.adjustSize(); p->save(); -- cgit v0.12 From 6829ee30f02f162bbb399000c853c8d680f8f8de Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Fri, 26 Mar 2010 14:55:27 +0100 Subject: Compile on Maemo 5 qmake for Maemo 5 needs to be bootstrapped with an older gcc, which doesn't like foreach() in templates. Use a traditional for loop to iterate over the container instead. --- qmake/generators/symbian/symbian_makefile.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qmake/generators/symbian/symbian_makefile.h b/qmake/generators/symbian/symbian_makefile.h index f9d3c24..289f9ae 100644 --- a/qmake/generators/symbian/symbian_makefile.h +++ b/qmake/generators/symbian/symbian_makefile.h @@ -71,8 +71,9 @@ public: if (targetType == TypeExe) { generatePkg = true; } else { - foreach(QString item, this->project->values("DEPLOYMENT")) { - if (!this->project->values(item + ".sources").isEmpty()) { + const QStringList deployments = this->project->values("DEPLOYMENT"); + for (int i = 0; i < deployments.count(); ++i) { + if (!this->project->values(deployments.at(i) + ".sources").isEmpty()) { generatePkg = true; break; } -- cgit v0.12 From ed8b490ff07afbca5f23aa19d995c017e2823114 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 26 Mar 2010 15:04:24 +0100 Subject: cetest: remove source file duplicates from cetest.pro epocroot.cpp and registry.cpp are already in qmake_include.pri --- tools/qtestlib/wince/cetest/cetest.pro | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/qtestlib/wince/cetest/cetest.pro b/tools/qtestlib/wince/cetest/cetest.pro index 4f0baab..43ed18e 100644 --- a/tools/qtestlib/wince/cetest/cetest.pro +++ b/tools/qtestlib/wince/cetest/cetest.pro @@ -37,8 +37,6 @@ HEADERS += \ SOURCES += \ remoteconnection.cpp \ deployment.cpp \ - symbian/epocroot.cpp \ - windows/registry.cpp \ main.cpp LIBS += ole32.lib advapi32.lib -- cgit v0.12 From 454400ff604bcc3cd720ca0487ab6fd4b77d764c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 26 Mar 2010 16:11:18 +0100 Subject: Round instead of ceil font metrics when ForceIntegerMetrics is enabled This matches how both the simple and complex paths in WebKit handle float to integer conversion, and looks much better. Reviewed-by: Eskil --- src/gui/text/qfontengine_mac.mm | 48 ++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 3f84544..0bfdbc0 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -306,8 +306,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y); if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - outAdvances_x[idx] = outAdvances_x[idx].ceil(); - outAdvances_y[idx] = outAdvances_y[idx].ceil(); + outAdvances_x[idx] = outAdvances_x[idx].round(); + outAdvances_y[idx] = outAdvances_y[idx].round(); } } CGSize lastGlyphAdvance; @@ -316,7 +316,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; outAdvances_x[rtl ? 0 : (glyphCount - 1)] = (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(lastGlyphAdvance.width).ceil() + ? QFixed::fromReal(lastGlyphAdvance.width).round() : QFixed::fromReal(lastGlyphAdvance.width); } outGlyphs += glyphCount; @@ -389,7 +389,7 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) QFixed w; for (int i = 0; i < glyphs.numGlyphs; ++i) { w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? glyphs.effectiveAdvance(i).ceil() + ? glyphs.effectiveAdvance(i).round() : glyphs.effectiveAdvance(i); } return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0); @@ -409,8 +409,8 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) ret.yoff = QFixed::fromReal(advances[0].height); if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - ret.xoff = ret.xoff.ceil(); - ret.yoff = ret.yoff.ceil(); + ret.xoff = ret.xoff.round(); + ret.yoff = ret.yoff.round(); } return ret; @@ -419,14 +419,14 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) QFixed QCoreTextFontEngine::ascent() const { return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetAscent(ctfont)).ceil() + ? QFixed::fromReal(CTFontGetAscent(ctfont)).round() : QFixed::fromReal(CTFontGetAscent(ctfont)); } QFixed QCoreTextFontEngine::descent() const { QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont)); if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - d = d.ceil(); + d = d.round(); // subtract a pixel to even out the historical +1 in QFontMetrics::height(). // Fix in Qt 5. @@ -435,20 +435,20 @@ QFixed QCoreTextFontEngine::descent() const QFixed QCoreTextFontEngine::leading() const { return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetLeading(ctfont)).ceil() + ? QFixed::fromReal(CTFontGetLeading(ctfont)).round() : QFixed::fromReal(CTFontGetLeading(ctfont)); } QFixed QCoreTextFontEngine::xHeight() const { return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetXHeight(ctfont)).ceil() + ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round() : QFixed::fromReal(CTFontGetXHeight(ctfont)); } QFixed QCoreTextFontEngine::averageCharWidth() const { // ### Need to implement properly and get the information from the OS/2 Table. return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFontEngine::averageCharWidth().ceil() + ? QFontEngine::averageCharWidth().round() : QFontEngine::averageCharWidth(); } @@ -888,8 +888,8 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS QFixed xAdvance = FixedToQFixed(layoutData[glyphIdx + 1].realPos - layoutData[glyphIdx].realPos); if (nfo->styleStrategy & QFont::ForceIntegerMetrics) { - yAdvance = yAdvance.ceil(); - xAdvance = xAdvance.ceil(); + yAdvance = yAdvance.round(); + xAdvance = xAdvance.round(); } if (glyphId != 0xffff || i == 0) { @@ -1403,8 +1403,8 @@ void QFontEngineMac::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla glyphs->advances_y[i] = QFixed::fromReal(metrics[i].deviceAdvance.y); if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - glyphs->advances_x[i] = glyphs->advances_x[i].ceil(); - glyphs->advances_y[i] = glyphs->advances_y[i].ceil(); + glyphs->advances_x[i] = glyphs->advances_x[i].round(); + glyphs->advances_y[i] = glyphs->advances_y[i].round(); } } } @@ -1414,7 +1414,7 @@ glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs) QFixed w; for (int i = 0; i < glyphs.numGlyphs; ++i) { w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? glyphs.effectiveAdvance(i).ceil() + ? glyphs.effectiveAdvance(i).round() : glyphs.effectiveAdvance(i); } return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0); @@ -1444,8 +1444,8 @@ glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph) if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { gm.x = gm.x.floor(); gm.y = gm.y.floor(); - gm.xoff = gm.xoff.ceil(); - gm.yoff = gm.yoff.ceil(); + gm.xoff = gm.xoff.round(); + gm.yoff = gm.yoff.round(); } return gm; @@ -1454,7 +1454,7 @@ glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph) QFixed QFontEngineMac::ascent() const { return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? m_ascent.ceil() + ? m_ascent.round() : m_ascent; } @@ -1463,35 +1463,35 @@ QFixed QFontEngineMac::descent() const // subtract a pixel to even out the historical +1 in QFontMetrics::height(). // Fix in Qt 5. return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? m_descent.ceil() - 1 + ? m_descent.round() - 1 : m_descent; } QFixed QFontEngineMac::leading() const { return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? m_leading.ceil() + ? m_leading.round() : m_leading; } qreal QFontEngineMac::maxCharWidth() const { return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? qCeil(m_maxCharWidth) + ? qRound(m_maxCharWidth) : m_maxCharWidth; } QFixed QFontEngineMac::xHeight() const { return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? m_xHeight.ceil() + ? m_xHeight.round() : m_xHeight; } QFixed QFontEngineMac::averageCharWidth() const { return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? m_averageCharWidth.ceil() + ? m_averageCharWidth.round() : m_averageCharWidth; } -- cgit v0.12 From 61b488a965eebc52104243dce21eaeb203cfecae Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 26 Mar 2010 13:59:26 +0100 Subject: QtScript: Make sure the old identifier table is restored Use a shim to take care of that. --- src/script/api/qscriptengine.cpp | 2 +- src/script/api/qscriptengine_p.h | 1 - src/script/api/qscriptstring.cpp | 6 +++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index b322523..a393ead 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -915,7 +915,7 @@ QScriptEnginePrivate::QScriptEnginePrivate() QScriptEnginePrivate::~QScriptEnginePrivate() { - JSC::setCurrentIdentifierTable(globalData->identifierTable); + QScript::APIShim shim(this); //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events QHash::const_iterator it; diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 70ab7c9..5c2007f 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -798,7 +798,6 @@ inline void QScriptEnginePrivate::unregisterScriptString(QScriptStringPrivate *v registeredScriptStrings = value->next; value->prev = 0; value->next = 0; - JSC::setCurrentIdentifierTable(globalData->identifierTable); } inline QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame) diff --git a/src/script/api/qscriptstring.cpp b/src/script/api/qscriptstring.cpp index 7978b61..d0b0ffd 100644 --- a/src/script/api/qscriptstring.cpp +++ b/src/script/api/qscriptstring.cpp @@ -92,8 +92,12 @@ QScriptString::~QScriptString() d->ref.ref(); // avoid deletion break; case QScriptStringPrivate::HeapAllocated: - if (d->engine && (d->ref == 1)) + if (d->engine && (d->ref == 1)) { + // Make sure the identifier is removed from the correct engine. + QScript::APIShim(d->engine); + d->identifier = JSC::Identifier(); d->engine->unregisterScriptString(d); + } break; } } -- cgit v0.12 From 7a11acd536d84ad22ef98a0fdbdb4322a55efafb Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 26 Mar 2010 14:00:02 +0100 Subject: QtScript: Add yet more missing API shims - for QScriptEngine and QScriptContext; we don't control what the JSC functions are doing, so it's better to have shims than not to have them (which can cause something to blow up), even if they might not be strictly necessary as of this writing. - for QScriptDeclarativeClass; otherwise the identifiers might be created/destroyed in the wrong engine. - for QScriptValueIterator destructor; otherwise the identifiers might be destroyed in the wrong engine. This is an attempt to fix a crash in Bauhaus, but it might still be crashing (i.e. still some shims missing, somewhere) ;( --- src/script/api/qscriptcontext.cpp | 14 ++++++++++++++ src/script/api/qscriptengine.cpp | 28 +++++++++++++++++++++++++++ src/script/api/qscriptvalueiterator.cpp | 6 ++++++ src/script/bridge/qscriptdeclarativeclass.cpp | 21 ++++++++++++++++---- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp index b1732ee..639af80 100644 --- a/src/script/api/qscriptcontext.cpp +++ b/src/script/api/qscriptcontext.cpp @@ -161,6 +161,7 @@ QScriptContext::QScriptContext() QScriptValue QScriptContext::throwValue(const QScriptValue &value) { JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::JSValue jscValue = QScript::scriptEngineFromExec(frame)->scriptValueToJSCValue(value); frame->setException(jscValue); return value; @@ -183,6 +184,7 @@ QScriptValue QScriptContext::throwValue(const QScriptValue &value) QScriptValue QScriptContext::throwError(Error error, const QString &text) { JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::ErrorType jscError = JSC::GeneralError; switch (error) { case UnknownError: @@ -218,6 +220,7 @@ QScriptValue QScriptContext::throwError(Error error, const QString &text) QScriptValue QScriptContext::throwError(const QString &text) { JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::JSObject *result = JSC::throwError(frame, JSC::GeneralError, text); return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); } @@ -265,6 +268,7 @@ QScriptValue QScriptContext::argument(int index) const QScriptValue QScriptContext::callee() const { const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->callee()); } @@ -286,6 +290,7 @@ QScriptValue QScriptContext::callee() const QScriptValue QScriptContext::argumentsObject() const { JSC::CallFrame *frame = const_cast(QScriptEnginePrivate::frameForContext(this)); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); if (frame == frame->lexicalGlobalObject()->globalExec()) { // context doesn't have arguments. return an empty object @@ -322,6 +327,7 @@ QScriptValue QScriptContext::argumentsObject() const bool QScriptContext::isCalledAsConstructor() const { JSC::CallFrame *frame = const_cast(QScriptEnginePrivate::frameForContext(this)); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); //For native functions, look up flags. uint flags = QScriptEnginePrivate::contextFlags(frame); @@ -355,6 +361,7 @@ bool QScriptContext::isCalledAsConstructor() const QScriptContext *QScriptContext::parentContext() const { const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::CallFrame *callerFrame = frame->callerFrame()->removeHostCallFrameFlag(); return QScriptEnginePrivate::contextForFrame(callerFrame); } @@ -412,6 +419,7 @@ void QScriptContext::setReturnValue(const QScriptValue &result) QScriptValue QScriptContext::activationObject() const { JSC::CallFrame *frame = const_cast(QScriptEnginePrivate::frameForContext(this)); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::JSObject *result = 0; uint flags = QScriptEnginePrivate::contextFlags(frame); @@ -477,6 +485,7 @@ void QScriptContext::setActivationObject(const QScriptValue &activation) } JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + QScript::APIShim shim(engine); JSC::JSObject *object = JSC::asObject(engine->scriptValueToJSCValue(activation)); if (object == engine->originalGlobalObjectProxy) object = engine->originalGlobalObject(); @@ -521,6 +530,7 @@ QScriptValue QScriptContext::thisObject() const { JSC::CallFrame *frame = const_cast(QScriptEnginePrivate::frameForContext(this)); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + QScript::APIShim shim(engine); JSC::JSValue result = engine->thisForContext(frame); if (!result || result.isNull()) result = frame->globalThisValue(); @@ -536,6 +546,7 @@ QScriptValue QScriptContext::thisObject() const void QScriptContext::setThisObject(const QScriptValue &thisObject) { JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); if (!thisObject.isObject()) return; if (thisObject.engine() != engine()) { @@ -662,6 +673,7 @@ QScriptValueList QScriptContext::scopeChain() const activationObject(); //ensure the creation of the normal scope for native context const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + QScript::APIShim shim(engine); QScriptValueList result; JSC::ScopeChainNode *node = frame->scopeChain(); JSC::ScopeChainIterator it(node); @@ -700,6 +712,7 @@ void QScriptContext::pushScope(const QScriptValue &object) } JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + QScript::APIShim shim(engine); JSC::JSObject *jscObject = JSC::asObject(engine->scriptValueToJSCValue(object)); if (jscObject == engine->originalGlobalObjectProxy) jscObject = engine->originalGlobalObject(); @@ -733,6 +746,7 @@ QScriptValue QScriptContext::popScope() JSC::ScopeChainNode *scope = frame->scopeChain(); Q_ASSERT(scope != 0); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + QScript::APIShim shim(engine); QScriptValue result = engine->scriptValueFromJSCValue(scope->object); if (!scope->next) { // We cannot have a null scope chain, so just zap the object pointer. diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index a393ead..3e5249a 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1899,6 +1899,7 @@ QScriptEngine::~QScriptEngine() QScriptValue QScriptEngine::globalObject() const { Q_D(const QScriptEngine); + QScript::APIShim shim(const_cast(d)); JSC::JSObject *result = d->globalObject(); return const_cast(d)->scriptValueFromJSCValue(result); } @@ -1920,6 +1921,7 @@ void QScriptEngine::setGlobalObject(const QScriptValue &object) Q_D(QScriptEngine); if (!object.isObject()) return; + QScript::APIShim shim(d); JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object)); d->setGlobalObject(jscObject); } @@ -1976,6 +1978,7 @@ QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::ExecState* exec = d->currentFrame; JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun); QScriptValue result = d->scriptValueFromJSCValue(function); @@ -1999,6 +2002,7 @@ extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); QScriptValue QScriptEngine::newRegExp(const QRegExp ®exp) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, regexp)); } @@ -2017,6 +2021,7 @@ QScriptValue QScriptEngine::newRegExp(const QRegExp ®exp) QScriptValue QScriptEngine::newVariant(const QVariant &value) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return d->scriptValueFromJSCValue(d->newVariant(value)); } @@ -2050,6 +2055,7 @@ QScriptValue QScriptEngine::newVariant(const QScriptValue &object, const QVariant &value) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::JSValue jsObject = d->scriptValueToJSCValue(object); return d->scriptValueFromJSCValue(d->newVariant(jsObject, value)); } @@ -2081,6 +2087,7 @@ QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership const QObjectWrapOptions &options) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::JSValue jscQObject = d->newQObject(object, ownership, options); return d->scriptValueFromJSCValue(jscQObject); } @@ -2117,8 +2124,10 @@ QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject, ValueOwnership ownership, const QObjectWrapOptions &options) { + Q_D(QScriptEngine); if (!scriptObject.isObject()) return newQObject(qtObject, ownership, options); + QScript::APIShim shim(d); JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue); if (!jscObject->inherits(&QScriptObject::info)) { qWarning("QScriptEngine::newQObject(): changing class of non-QScriptObject not supported"); @@ -2149,6 +2158,7 @@ QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject, QScriptValue QScriptEngine::newObject() { Q_D(QScriptEngine); + QScript::APIShim shim(d); return d->scriptValueFromJSCValue(d->newObject()); } @@ -2170,6 +2180,7 @@ QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass, const QScriptValue &data) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::ExecState* exec = d->currentFrame; QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure); result->setDelegate(new QScript::ClassObjectDelegate(scriptClass)); @@ -2237,6 +2248,7 @@ QScriptValue QScriptEngine::newActivationObject() QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::ExecState* exec = d->currentFrame; JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun); QScriptValue result = d->scriptValueFromJSCValue(function); @@ -2254,6 +2266,7 @@ QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, in QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::ExecState* exec = d->currentFrame; JSC::JSValue function = new (exec)QScript::FunctionWithArgWrapper(exec, /*length=*/0, JSC::Identifier(exec, ""), fun, arg); QScriptValue result = d->scriptValueFromJSCValue(function); @@ -2272,6 +2285,7 @@ QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature QScriptValue QScriptEngine::newArray(uint length) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return d->scriptValueFromJSCValue(d->newArray(d->currentFrame, length)); } @@ -2285,6 +2299,7 @@ QScriptValue QScriptEngine::newArray(uint length) QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, pattern, flags)); } @@ -2296,6 +2311,7 @@ QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &fla QScriptValue QScriptEngine::newDate(qsreal value) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value)); } @@ -2307,6 +2323,7 @@ QScriptValue QScriptEngine::newDate(qsreal value) QScriptValue QScriptEngine::newDate(const QDateTime &value) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value)); } @@ -2330,6 +2347,7 @@ QScriptValue QScriptEngine::newQMetaObject( const QMetaObject *metaObject, const QScriptValue &ctor) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::JSValue jscCtor = d->scriptValueToJSCValue(ctor); JSC::JSValue jscQMetaObject = d->newQMetaObject(metaObject, jscCtor); return d->scriptValueFromJSCValue(jscQMetaObject); @@ -2582,6 +2600,7 @@ QScriptContext *QScriptEngine::currentContext() const QScriptContext *QScriptEngine::pushContext() { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, d->currentFrame->globalData().dynamicGlobalObject, JSC::ArgList(), /*callee = */0); @@ -2673,6 +2692,7 @@ void QScriptEngine::popContext() if (agent()) agent()->contextPop(); Q_D(QScriptEngine); + QScript::APIShim shim(d); if (d->currentFrame->returnPC() != 0 || d->currentFrame->codeBlock() != 0 || !currentContext()->parentContext()) { qWarning("QScriptEngine::popContext() doesn't match with pushContext()"); @@ -2868,6 +2888,7 @@ void QScriptEngine::setDefaultPrototype(int metaTypeId, const QScriptValue &prot QScriptValue QScriptEngine::create(int type, const void *ptr) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return d->scriptValueFromJSCValue(d->create(d->currentFrame, type, ptr)); } @@ -3277,6 +3298,7 @@ bool QScriptEnginePrivate::hasDemarshalFunction(int type) const bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return QScriptEnginePrivate::convertValue(d->currentFrame, d->scriptValueToJSCValue(value), type, ptr); } @@ -3309,6 +3331,7 @@ void QScriptEngine::registerCustomType(int type, MarshalFunction mf, const QScriptValue &prototype) { Q_D(QScriptEngine); + QScript::APIShim shim(d); QScriptTypeInfo *info = d->m_typeInfos.value(type); if (!info) { info = new QScriptTypeInfo(); @@ -3341,6 +3364,7 @@ void QScriptEngine::registerCustomType(int type, MarshalFunction mf, void QScriptEngine::installTranslatorFunctions(const QScriptValue &object) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::ExecState* exec = d->currentFrame; JSC::JSValue jscObject = d->scriptValueToJSCValue(object); JSC::JSGlobalObject *glob = d->originalGlobalObject(); @@ -3374,6 +3398,7 @@ QScriptValue QScriptEngine::importExtension(const QString &extension) Q_UNUSED(extension); #else Q_D(QScriptEngine); + QScript::APIShim shim(d); if (d->importedExtensions.contains(extension)) return undefinedValue(); // already imported @@ -4014,6 +4039,7 @@ bool qScriptConnect(QObject *sender, const char *signal, if (receiver.isObject() && (receiver.engine() != function.engine())) return false; QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine()); + QScript::APIShim shim(engine); JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver); JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function); return engine->scriptConnect(sender, signal, jscReceiver, jscFunction, @@ -4040,6 +4066,7 @@ bool qScriptDisconnect(QObject *sender, const char *signal, if (receiver.isObject() && (receiver.engine() != function.engine())) return false; QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine()); + QScript::APIShim shim(engine); JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver); JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function); return engine->scriptDisconnect(sender, signal, jscReceiver, jscFunction); @@ -4145,6 +4172,7 @@ QScriptString QScriptEngine::toStringHandle(const QString &str) QScriptValue QScriptEngine::toObject(const QScriptValue &value) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::JSValue jscValue = d->scriptValueToJSCValue(value); if (!jscValue || jscValue.isUndefined() || jscValue.isNull()) return QScriptValue(); diff --git a/src/script/api/qscriptvalueiterator.cpp b/src/script/api/qscriptvalueiterator.cpp index 7fd7093..c58c046 100644 --- a/src/script/api/qscriptvalueiterator.cpp +++ b/src/script/api/qscriptvalueiterator.cpp @@ -139,6 +139,12 @@ QScriptValueIterator::QScriptValueIterator(const QScriptValue &object) */ QScriptValueIterator::~QScriptValueIterator() { + Q_D(QScriptValueIterator); + if (d && d->engine()) { + // Make sure identifiers are removed from the correct engine. + QScript::APIShim shim(d->engine()); + d->propertyNames.clear(); + } } /*! diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index acfb2a4..c72eb94 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -148,9 +148,12 @@ QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier() QScriptDeclarativeClass::PersistentIdentifier::~PersistentIdentifier() { - if (engine) - JSC::setCurrentIdentifierTable(engine->globalData->identifierTable); - ((JSC::Identifier &)d).JSC::Identifier::~Identifier(); + if (engine) { + QScript::APIShim shim(engine); + ((JSC::Identifier &)d).JSC::Identifier::~Identifier(); + } else { + ((JSC::Identifier &)d).JSC::Identifier::~Identifier(); + } } QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier(const PersistentIdentifier &other) @@ -184,7 +187,8 @@ QScriptValue QScriptDeclarativeClass::newObject(QScriptEngine *engine, Q_ASSERT(engine); Q_ASSERT(scriptClass); - QScriptEnginePrivate *p = static_cast(QObjectPrivate::get(engine)); + QScriptEnginePrivate *p = static_cast(QObjectPrivate::get(engine)); + QScript::APIShim shim(p); JSC::ExecState* exec = p->currentFrame; QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure); @@ -201,6 +205,7 @@ QScriptDeclarativeClass::newObjectValue(QScriptEngine *engine, Q_ASSERT(scriptClass); QScriptEnginePrivate *p = static_cast(QObjectPrivate::get(engine)); + QScript::APIShim shim(p); JSC::ExecState* exec = p->currentFrame; QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure); @@ -231,6 +236,7 @@ QScriptValue QScriptDeclarativeClass::function(const QScriptValue &v, const Iden if (!d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::ExecState *exec = d->engine->currentFrame; JSC::JSObject *object = d->jscValue.getObject(); JSC::PropertySlot slot(const_cast(object)); @@ -254,6 +260,7 @@ QScriptValue QScriptDeclarativeClass::property(const QScriptValue &v, const Iden if (!d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::ExecState *exec = d->engine->currentFrame; JSC::JSObject *object = d->jscValue.getObject(); JSC::PropertySlot slot(const_cast(object)); @@ -277,6 +284,7 @@ QScriptDeclarativeClass::functionValue(const QScriptValue &v, const Identifier & if (!d->isObject()) return Value(); + QScript::APIShim shim(d->engine); JSC::ExecState *exec = d->engine->currentFrame; JSC::JSObject *object = d->jscValue.getObject(); JSC::PropertySlot slot(const_cast(object)); @@ -301,6 +309,7 @@ QScriptDeclarativeClass::propertyValue(const QScriptValue &v, const Identifier & if (!d->isObject()) return Value(); + QScript::APIShim shim(d->engine); JSC::ExecState *exec = d->engine->currentFrame; JSC::JSObject *object = d->jscValue.getObject(); JSC::PropertySlot slot(const_cast(object)); @@ -326,6 +335,7 @@ QScriptValue QScriptDeclarativeClass::scopeChainValue(QScriptContext *context, i context->activationObject(); //ensure the creation of the normal scope for native context const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(context); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + QScript::APIShim shim(engine); JSC::ScopeChainNode *node = frame->scopeChain(); JSC::ScopeChainIterator it(node); @@ -386,6 +396,7 @@ QScriptContext * QScriptDeclarativeClass::pushCleanContext(QScriptEngine *engine return 0; QScriptEnginePrivate *d = QScriptEnginePrivate::get(engine); + QScript::APIShim shim(d); JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, d->currentFrame->globalData().dynamicGlobalObject, @@ -421,6 +432,7 @@ QScriptDeclarativeClass::createPersistentIdentifier(const QString &str) { QScriptEnginePrivate *p = static_cast(QObjectPrivate::get(d_ptr->engine)); + QScript::APIShim shim(p); JSC::ExecState* exec = p->currentFrame; PersistentIdentifier rv(p); @@ -434,6 +446,7 @@ QScriptDeclarativeClass::createPersistentIdentifier(const Identifier &id) { QScriptEnginePrivate *p = static_cast(QObjectPrivate::get(d_ptr->engine)); + QScript::APIShim shim(p); JSC::ExecState* exec = p->currentFrame; PersistentIdentifier rv(p); -- cgit v0.12 From f681d8e2ebf774f69f92359d33ff80dd13c1bf87 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 26 Mar 2010 15:05:07 +0100 Subject: Unskip test that used to crash After updating JavaScriptCore for 4.7 it no longer crashes. --- tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp index a3dfd6c..5f9a578 100644 --- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp +++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp @@ -255,10 +255,6 @@ tst_Suite::tst_Suite() addTestExclusion("string-case", "V8-specific behavior? (Doesn't pass on SpiderMonkey either)"); -#ifdef Q_CC_MINGW - addTestExclusion("date$", "QTBUG-7698: Date.prototype.setMonth() crashes on win32-g++"); -#endif - #ifdef Q_OS_WINCE addTestExclusion("deep-recursion", "Demands too much memory on WinCE"); addTestExclusion("nested-repetition-count-overflow", "Demands too much memory on WinCE"); -- cgit v0.12 From a8af0e05b30cc4ec26f58378cd5a4e11b20cf9bd Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Fri, 26 Mar 2010 08:23:58 -0700 Subject: Fix linking error The #include "moc_qgraphicswidget.cpp" is superfluous and caused these link errors: .obj/debug-shared-emb-x86_64/moc_qgraphicswidget.o:(.data.rel.ro+0x0): multiple definition of `QGraphicsWidget::staticMetaObject' .obj/debug-shared-emb-x86_64/qgraphicswidget.o:(.data.rel.ro+0x0): first defined here .obj/debug-shared-emb-x86_64/moc_qgraphicswidget.o: In function `QGraphicsWidget::metaObject() const': Presumably this only happens when you have a stale moc file sitting around but it's a bug none-the-less. Reviewed-by: TrustMe --- src/gui/graphicsview/qgraphicswidget.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index a091347..131ee87 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -342,7 +342,7 @@ void QGraphicsWidget::resize(const QSizeF &size) A side effect of calling this function is that the widget will receive a move event and a resize event. Also, if the widget has a layout assigned, the layout will activate. - + \sa geometry(), resize() */ void QGraphicsWidget::setGeometry(const QRectF &rect) @@ -574,7 +574,7 @@ void QGraphicsWidget::getWindowFrameMargins(qreal *left, qreal *top, qreal *righ void QGraphicsWidget::unsetWindowFrameMargins() { Q_D(QGraphicsWidget); - if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup && + if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup && (d->windowFlags & Qt::WindowType_Mask) != Qt::ToolTip && !(d->windowFlags & Qt::FramelessWindowHint)) { QStyleOptionTitleBar bar; d->initStyleOptionTitleBar(&bar); @@ -1151,7 +1151,7 @@ bool QGraphicsWidget::sceneEvent(QEvent *event) Returns true if \a event has been recognized and processed; otherwise, returns false. - + \sa event() */ bool QGraphicsWidget::windowFrameEvent(QEvent *event) @@ -1208,7 +1208,7 @@ Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) const QRectF r = windowFrameRect(); if (!r.contains(pos)) return Qt::NoSection; - + const qreal left = r.left(); const qreal top = r.top(); const qreal right = r.right(); @@ -2335,6 +2335,4 @@ void QGraphicsWidget::dumpFocusChain() QT_END_NAMESPACE -#include "moc_qgraphicswidget.cpp" - #endif //QT_NO_GRAPHICSVIEW -- cgit v0.12 From a44026a3885e1505b9206a4d9a47ea21aa6d6787 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 26 Mar 2010 16:32:55 +0100 Subject: Fix build on Windows On unix platforms, QT_NO_EGL is defined by configure. However, this is not defined by windows's configure.exe so add it in opengl.pro. Reviewed-By: Brad --- src/opengl/opengl.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index ff42a49..9473343 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -116,6 +116,7 @@ mac { LIBS_PRIVATE += -framework AppKit -framework Carbon } win32:!wince*: { + DEFINES += QT_NO_EGL SOURCES += qgl_win.cpp \ qglpixelbuffer_win.cpp } -- cgit v0.12 From e9538ced914739129681362dea03ebc323602126 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 26 Mar 2010 16:27:04 +0100 Subject: Reverts using composition mode when using DeviceCoordinateMode cache. Going back to always blitting the newly painted areas to the cache (and not blending it like before). To avoid painting artifacts when the item is rotated and when it uses DeviceCoordinateMode cache mode, the entire cache is always repainted in that case. Task-number: QTBUG-7863 Reviewed-by: trustme --- src/gui/graphicsview/qgraphicsscene.cpp | 13 ++++++------- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 18 +++++++++++------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 6934abc..6581727 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4285,12 +4285,7 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion & if (!subPix.isNull()) { // Blit the subpixmap into the main pixmap. pixmapPainter.begin(pix); - if (item->cacheMode() == QGraphicsItem::DeviceCoordinateCache - && itemToPixmap.type() > QTransform::TxTranslate) { - pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceAtop); - } else { - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); - } + pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); pixmapPainter.setClipRegion(pixmapExposed); pixmapPainter.drawPixmap(br.topLeft(), subPix); pixmapPainter.end(); @@ -4456,6 +4451,8 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte } // Create or reuse offscreen pixmap, possibly scroll/blit from the old one. + // If the world transform is rotated we always recreate the cache to avoid + // wrong blending. bool pixModified = false; QGraphicsItemCache::DeviceData *deviceData = &itemCache->deviceData[widget]; bool invertable = true; @@ -4463,7 +4460,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte if (invertable) diff *= painter->worldTransform(); deviceData->lastTransform = painter->worldTransform(); - if (!invertable || diff.type() > QTransform::TxTranslate) { + if (!invertable + || diff.type() > QTransform::TxTranslate + || painter->worldTransform().type() > QTransform::TxScale) { pixModified = true; itemCache->allExposed = true; itemCache->exposed.clear(); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 2b507cb..6725159 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -6825,6 +6825,9 @@ void tst_QGraphicsItem::cacheMode() QTRY_COMPARE(tester->repaints, 4); QCOMPARE(testerChild->repaints, 4); QCOMPARE(testerChild2->repaints, 3); + tester->resetTransform(); + testerChild->resetTransform(); + testerChild2->resetTransform(); // Explicit update causes a repaint. tester->update(0, 0, 5, 5); @@ -6898,23 +6901,24 @@ void tst_QGraphicsItem::cacheMode() // because the parent is rotated with a perspective. testerChild->setPos(1, 1); QTest::qWait(25); - QTRY_COMPARE(tester->repaints, 10); + QTRY_COMPARE(tester->repaints, 11); QCOMPARE(testerChild->repaints, 10); QCOMPARE(testerChild2->repaints, 5); + tester->resetTransform(); // Make a huge item tester->setGeometry(QRectF(-4000, -4000, 8000, 8000)); QTest::qWait(25); - QTRY_COMPARE(tester->repaints, 11); - QCOMPARE(testerChild->repaints, 10); + QTRY_COMPARE(tester->repaints, 12); + QCOMPARE(testerChild->repaints, 11); QCOMPARE(testerChild2->repaints, 5); // Move the large item - will cause a repaint as the // cache is clipped. tester->setPos(5, 0); QTest::qWait(25); - QTRY_COMPARE(tester->repaints, 12); - QCOMPARE(testerChild->repaints, 10); + QTRY_COMPARE(tester->repaints, 13); + QCOMPARE(testerChild->repaints, 11); QCOMPARE(testerChild2->repaints, 5); // Hiding and showing should invalidate the cache @@ -6922,8 +6926,8 @@ void tst_QGraphicsItem::cacheMode() QTest::qWait(25); tester->show(); QTest::qWait(25); - QTRY_COMPARE(tester->repaints, 13); - QCOMPARE(testerChild->repaints, 11); + QTRY_COMPARE(tester->repaints, 14); + QCOMPARE(testerChild->repaints, 12); QCOMPARE(testerChild2->repaints, 6); } -- cgit v0.12 From 345e299c512094b50868c9ee71cbba83db593444 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 26 Mar 2010 16:42:04 +0100 Subject: improve mingw 64 bit support --- src/network/ssl/qsslsocket_openssl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 4010710..050fb1b 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -146,7 +146,7 @@ static void locking_function(int mode, int lockNumber, const char *, int) } static unsigned long id_function() { - return (unsigned long)QThread::currentThreadId(); + return (quintptr)QThread::currentThreadId(); } } // extern "C" -- cgit v0.12 From 392aaba04d8eda52ec7f6c36c31bcd23b0458140 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Mar 2010 16:44:41 +0100 Subject: Remove QGuard. This class is no longer in use by QtDeclarative. Task-number: QT-3031 Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/kernel.pri | 1 - src/corelib/kernel/qguard_p.h | 157 ----------------------------------------- src/corelib/kernel/qobject.cpp | 9 --- src/corelib/kernel/qobject_p.h | 31 +------- 4 files changed, 1 insertion(+), 197 deletions(-) delete mode 100644 src/corelib/kernel/qguard_p.h diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index d0dad49..1851e04 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -33,7 +33,6 @@ HEADERS += \ kernel/qsystemsemaphore.h \ kernel/qsystemsemaphore_p.h \ kernel/qfunctions_p.h \ - kernel/qguard_p.h \ kernel/qmath.h SOURCES += \ diff --git a/src/corelib/kernel/qguard_p.h b/src/corelib/kernel/qguard_p.h deleted file mode 100644 index 0f7fd94..0000000 --- a/src/corelib/kernel/qguard_p.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGUARD_P_H -#define QGUARD_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include "QtCore/qglobal.h" - -QT_BEGIN_NAMESPACE - -class QObject; -template -class QGuard -{ - QObject *o; - QGuard *next; - QGuard **prev; - friend void q_guard_addGuard(QGuard *); - friend void q_guard_removeGuard(QGuard *); - friend class QObjectPrivate; -public: - inline QGuard(); - inline QGuard(T *); - inline QGuard(const QGuard &); - inline virtual ~QGuard(); - - inline QGuard &operator=(const QGuard &o); - inline QGuard &operator=(T *); - - inline bool isNull() const - { return !o; } - - inline T* operator->() const - { return static_cast(const_cast(o)); } - inline T& operator*() const - { return *static_cast(const_cast(o)); } - inline operator T*() const - { return static_cast(const_cast(o)); } - inline T* data() const - { return static_cast(const_cast(o)); } - -protected: - virtual void objectDestroyed(T *) {} -}; - -QT_END_NAMESPACE - -#include "private/qobject_p.h" - -QT_BEGIN_NAMESPACE - -inline void q_guard_addGuard(QGuard *); -inline void q_guard_removeGuard(QGuard *); - -template -QGuard::QGuard() -: o(0), next(0), prev(0) -{ -} - -template -QGuard::QGuard(T *g) -: o(g), next(0), prev(0) -{ - if (o) q_guard_addGuard(reinterpret_cast *>(this)); -} - -template -QGuard::QGuard(const QGuard &g) -: o(g.o), next(0), prev(0) -{ - if (o) q_guard_addGuard(reinterpret_cast *>(this)); -} - -template -QGuard::~QGuard() -{ - if (prev) q_guard_removeGuard(reinterpret_cast *>(this)); - o = 0; -} - -template -QGuard &QGuard::operator=(const QGuard &g) -{ - if (g.o != o) { - if (prev) - q_guard_removeGuard(reinterpret_cast *>(this)); - o = g.o; - if (o) q_guard_addGuard(reinterpret_cast *>(this)); - } - return *this; -} - -template -inline QGuard &QGuard::operator=(T *g) -{ - if (g != o) { - if (prev) - q_guard_removeGuard(reinterpret_cast *>(this)); - o = g; - if (o) q_guard_addGuard(reinterpret_cast *>(this)); - } - return *this; -} - -QT_END_NAMESPACE - -#endif // QGUARD_P_H diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 68f34ca..dbc6be2 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -496,15 +496,6 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o) void QObjectPrivate::clearGuards(QObject *object) { QObjectPrivate *priv = QObjectPrivate::get(object); - QGuard *guard = priv->extraData ? priv->extraData->objectGuards : 0; - while (guard) { - QGuard *g = guard; - guard = guard->next; - g->o = 0; - g->prev = 0; - g->next = 0; - g->objectDestroyed(object); - } if (!priv->hasGuards) return; diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 20e3da1..3b59abb 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -60,7 +60,6 @@ #include "QtCore/qvector.h" #include "QtCore/qreadwritelock.h" #include "QtCore/qvariant.h" -#include "private/qguard_p.h" QT_BEGIN_NAMESPACE @@ -100,13 +99,12 @@ class Q_CORE_EXPORT QObjectPrivate : public QObjectData public: struct ExtraData { - ExtraData() : objectGuards(0) {} + ExtraData() {} #ifndef QT_NO_USERDATA QVector userData; #endif QList propertyNames; QList propertyValues; - QGuard *objectGuards; //linked list handle of QGuards }; struct Connection @@ -224,33 +222,6 @@ inline bool QObjectPrivate::isSignalConnected(uint signal_index) const } -inline void q_guard_addGuard(QGuard *g) -{ - QObjectPrivate *p = QObjectPrivate::get(g->o); - if (p->wasDeleted) { - qWarning("QGuard: cannot add guard to deleted object"); - g->o = 0; - return; - } - - if (!p->extraData) - p->extraData = new QObjectPrivate::ExtraData; - - g->next = p->extraData->objectGuards; - p->extraData->objectGuards = g; - g->prev = &p->extraData->objectGuards; - if (g->next) - g->next->prev = &g->next; -} - -inline void q_guard_removeGuard(QGuard *g) -{ - if (g->next) g->next->prev = g->prev; - *g->prev = g->next; - g->next = 0; - g->prev = 0; -} - Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE); -- cgit v0.12 From 0e7a43dba248030c673be5deab8ca70d14c0798f Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 26 Mar 2010 16:57:48 +0100 Subject: Define QT_NO_EGL in configure.exe This is the "proper" fix for the windows build failure introduced by 75bb84ac. a44026a3 should be reverted once configure.exe is rebuilt to incorperate this fix. Reviewed-By: Marius Storm-Olsen --- tools/configure/configureapp.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 0b14cba..dfd1196 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3041,6 +3041,10 @@ void Configure::generateConfigfiles() if(dictionary["S60"] == "no") qconfigList += "QT_NO_S60"; if(dictionary["NATIVE_GESTURES"] == "no") qconfigList += "QT_NO_NATIVE_GESTURES"; + if(dictionary["OPENGL_ES_CM"] == "no" && + dictionary["OPENGL_ES_2"] == "no" && + dictionary["OPENVG"] == "no") qconfigList += "QT_NO_EGL"; + if(dictionary["OPENGL_ES_CM"] == "yes" || dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES"; -- cgit v0.12 From 96d6bff54942be11458801edc5c59e2cf646253c Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Fri, 26 Mar 2010 11:08:12 -0700 Subject: QDirectFBPixmap can handle NoOpaqueDetection. We don't need to do the conversion using QImage when NoOpaqueDetection is specified. Reviewed-by: muthu --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 4219f6f..f2fd699 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -307,7 +307,7 @@ void QDirectFBPixmapData::fromImage(const QImage &img, imageFormat = screen->pixelFormat(); } QImage image; - if (flags != Qt::AutoColor) { + if ((flags & ~Qt::NoOpaqueDetection) != Qt::AutoColor) { image = img.convertToFormat(imageFormat, flags); flags = Qt::AutoColor; } else if (img.format() == QImage::Format_RGB32) { -- cgit v0.12 From ec401f7a4c682b3ccdbc64edb4aa9881830b45cf Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Fri, 26 Mar 2010 11:17:39 -0700 Subject: Refactor QDirectFBPixmap::fromImage slightly Clean up the function a little and make sure I don't call QImage::hasAlphaChannel twice for opaque images. Reviewed-by: muthu --- .../gfxdrivers/directfb/qdirectfbpixmap.cpp | 23 +++++++++------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index f2fd699..80366d1 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -290,27 +290,22 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti void QDirectFBPixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags) { - if (img.depth() == 1 || img.format() == QImage::Format_RGB32) { - fromImage(img.convertToFormat(screen->alphaPixmapFormat()), flags); - return; - } - - if (img.hasAlphaChannel() + if (img.depth() == 1) { + alpha = true; #ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION - && (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img)) -#endif - ) { + } else if (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img)) { alpha = true; - imageFormat = screen->alphaPixmapFormat(); - } else { - alpha = false; - imageFormat = screen->pixelFormat(); +#else + } else if (img.hasAlphaChannel()) { + alpha = true; +#endif } + imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat(); QImage image; if ((flags & ~Qt::NoOpaqueDetection) != Qt::AutoColor) { image = img.convertToFormat(imageFormat, flags); flags = Qt::AutoColor; - } else if (img.format() == QImage::Format_RGB32) { + } else if (img.format() == QImage::Format_RGB32 || img.depth() == 1) { image = img.convertToFormat(imageFormat, flags); } else { image = img; -- cgit v0.12 From 8db35fe685d115f136bb2ec0305300dd082b278b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 26 Mar 2010 22:36:34 +0100 Subject: Fix a bug in greek shaping causing infinite loops Update harfbuzz to 33b9cde6a08293d26047734e046c6677a2959adb Reviewed-By: TrustMe AutoTest: qtextscriptengine Task-number: QTBUG-391 --- src/3rdparty/harfbuzz/src/harfbuzz-greek.c | 27 +++++++++------ src/3rdparty/harfbuzz/tests/shaping/main.cpp | 40 ++++++++++++++++++++-- .../qtextscriptengine/tst_qtextscriptengine.cpp | 36 +++++++++++++++++++ 3 files changed, 90 insertions(+), 13 deletions(-) diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-greek.c b/src/3rdparty/harfbuzz/src/harfbuzz-greek.c index 59f3077..2e9b858 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-greek.c +++ b/src/3rdparty/harfbuzz/src/harfbuzz-greek.c @@ -77,10 +77,12 @@ static HB_UChar16 compose_0x300(HB_UChar16 base) return 0x1fdd; return 0; } - const hb_greek_decomposition *d = decompose_0x300; - while (d->base && d->base != base) - ++d; - return d->composed; + { + const hb_greek_decomposition *d = decompose_0x300; + while (d->base && d->base != base) + ++d; + return d->composed; + } } static const hb_greek_decomposition decompose_0x301[] = { @@ -115,10 +117,12 @@ static HB_UChar16 compose_0x301(HB_UChar16 base) if (base == 0x1ffe) return 0x1fde; } - const hb_greek_decomposition *d = decompose_0x301; - while (d->base && d->base != base) - ++d; - return d->composed; + { + const hb_greek_decomposition *d = decompose_0x301; + while (d->base && d->base != base) + ++d; + return d->composed; + } } static const hb_greek_decomposition decompose_0x304[] = { @@ -351,8 +355,7 @@ static HB_UChar16 compose_0x345(HB_UChar16 base) */ HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item) { - assert(shaper_item->item.script == HB_Script_Greek); - + const int availableGlyphs = shaper_item->num_glyphs; const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos; unsigned short *logClusters = shaper_item->log_clusters; HB_GlyphAttributes *attributes = shaper_item->attributes; @@ -363,6 +366,9 @@ HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item) hb_uint32 i; HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length); + + assert(shaper_item->item.script == HB_Script_Greek); + *shapedChars = *uc; logClusters[0] = 0; @@ -430,7 +436,6 @@ HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item) #ifndef NO_OPENTYPE if (HB_SelectScript(shaper_item, greek_features)) { - const int availableGlyphs = shaper_item->num_glyphs; HB_OpenTypeShape(shaper_item, /*properties*/0); return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE); } diff --git a/src/3rdparty/harfbuzz/tests/shaping/main.cpp b/src/3rdparty/harfbuzz/tests/shaping/main.cpp index b48b0a9..320e8ee 100644 --- a/src/3rdparty/harfbuzz/tests/shaping/main.cpp +++ b/src/3rdparty/harfbuzz/tests/shaping/main.cpp @@ -272,7 +272,6 @@ Shaper::Shaper(FT_Face face, HB_Script script, const QString &str) } -#if defined(Q_WS_X11) static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch) { QString uc = QString().append(ch); @@ -318,7 +317,6 @@ static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch) qDebug(" decomposed glyph result = %s", str.toLatin1().constData()); return false; } -#endif struct ShapeTable { unsigned short unicode[16]; @@ -382,6 +380,44 @@ void tst_QScriptEngine::greek() continue; QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) ); } + FT_Done_Face(face); + } else { + QSKIP("couln't find DejaVu Sans", SkipAll); + } + + + face = loadFace("SBL_grk.ttf"); + if (face) { + for (int uc = 0x1f00; uc <= 0x1fff; ++uc) { + QString str; + str.append(uc); + if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) { + //qDebug() << "skipping" << hex << uc; + continue; + } + if (uc == 0x1fc1 || uc == 0x1fed) + continue; + QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) ); + + } + + const ShapeTable shape_table [] = { + { { 0x3b1, 0x300, 0x313, 0x0 }, + { 0xb8, 0x3d3, 0x3c7, 0x0 } }, + { { 0x3b1, 0x313, 0x300, 0x0 }, + { 0xd4, 0x0 } }, + + { {0}, {0} } + }; + + + const ShapeTable *s = shape_table; + while (s->unicode[0]) { + QVERIFY( shaping(face, s, HB_Script_Greek) ); + ++s; + } + + FT_Done_Face(face); } else { QSKIP("couln't find DejaVu Sans", SkipAll); } diff --git a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp index 841f5b9..018c036 100644 --- a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp @@ -1068,6 +1068,42 @@ void tst_QTextScriptEngine::greek() QSKIP("couln't find DejaVu Sans", SkipAll); } } + + { + if (QFontDatabase().families(QFontDatabase::Any).contains("SBL Greek")) { + QFont f("SBL Greek"); + for (int uc = 0x1f00; uc <= 0x1fff; ++uc) { + QString str; + str.append(uc); + if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) { + //qDebug() << "skipping" << hex << uc; + continue; + } + if (uc == 0x1fc1 || uc == 0x1fed) + continue; + QVERIFY( decomposedShaping(f, QChar(uc) ) ); + + } + + const ShapeTable shape_table [] = { + { { 0x3b1, 0x300, 0x313, 0x0 }, + { 0xb8, 0x3d3, 0x3c7, 0x0 } }, + { { 0x3b1, 0x313, 0x300, 0x0 }, + { 0xd4, 0x0 } }, + + { {0}, {0} } + }; + + + const ShapeTable *s = shape_table; + while (s->unicode[0]) { + QVERIFY( shaping(f, s) ); + ++s; + } + } else { + QSKIP("couln't find SBL_grk", SkipAll); + } + } #else QSKIP("X11 specific test", SkipAll); #endif -- cgit v0.12 From e69e397cee5ac1ce1bd6a1bca559e5607bb4258a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 27 Mar 2010 08:33:48 +0100 Subject: Autotests: oops, remove last traces of QGuard --- .../tst_qdeclarativeproperty.cpp | 137 ++++---- tests/auto/qguard/qguard.pro | 2 - tests/auto/qguard/tst_qguard.cpp | 350 --------------------- 3 files changed, 68 insertions(+), 421 deletions(-) delete mode 100644 tests/auto/qguard/qguard.pro delete mode 100644 tests/auto/qguard/tst_qguard.cpp diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp index 56166f2..7d51bb6 100644 --- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp +++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -138,9 +137,9 @@ void tst_qdeclarativeproperty::qmlmetaproperty() { QDeclarativeProperty prop; - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -169,10 +168,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), -1); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -234,9 +233,9 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object() { QDeclarativeProperty prop(&object); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -265,10 +264,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), -1); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -279,10 +278,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object() { QDeclarativeProperty prop(&dobject); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); - binding->setTarget(prop); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + binding.data()->setTarget(prop); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -312,11 +311,11 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object() QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); QTest::ignoreMessage(QtWarningMsg, ":-1: Unable to assign null to int"); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding != 0); - QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding); + QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding.data()); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -333,9 +332,9 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() { QDeclarativeProperty prop(&object, QString("defaultProperty")); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -364,10 +363,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), -1); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -378,10 +377,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() { QDeclarativeProperty prop(&dobject, QString("defaultProperty")); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); - binding->setTarget(prop); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + binding.data()->setTarget(prop); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -411,11 +410,11 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); QTest::ignoreMessage(QtWarningMsg, ":-1: Unable to assign null to int"); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding != 0); - QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding); + QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding.data()); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -426,10 +425,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() { QDeclarativeProperty prop(&dobject, QString("onClicked")); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); - binding->setTarget(prop); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + binding.data()->setTarget(prop); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -458,12 +457,12 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression != 0); - QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression); + QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression.data()); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()")); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -473,10 +472,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() { QDeclarativeProperty prop(&dobject, QString("onPropertyWithNotifyChanged")); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); - binding->setTarget(prop); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + binding.data()->setTarget(prop); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -505,12 +504,12 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression != 0); - QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression); + QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression.data()); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()")); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -526,9 +525,9 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_context() { QDeclarativeProperty prop(&object, engine.rootContext()); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -557,10 +556,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_context() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), -1); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -571,10 +570,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_context() { QDeclarativeProperty prop(&dobject, engine.rootContext()); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); - binding->setTarget(prop); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + binding.data()->setTarget(prop); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -604,11 +603,11 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_context() QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); QTest::ignoreMessage(QtWarningMsg, ":-1: Unable to assign null to int"); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding != 0); - QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding); + QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding.data()); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -625,9 +624,9 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() { QDeclarativeProperty prop(&object, QString("defaultProperty"), engine.rootContext()); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -656,10 +655,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), -1); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -670,10 +669,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() { QDeclarativeProperty prop(&dobject, QString("defaultProperty"), engine.rootContext()); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); - binding->setTarget(prop); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + binding.data()->setTarget(prop); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -703,11 +702,11 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); QTest::ignoreMessage(QtWarningMsg, ":-1: Unable to assign null to int"); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding != 0); - QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding); + QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding.data()); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression == 0); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -718,10 +717,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() { QDeclarativeProperty prop(&dobject, QString("onClicked"), engine.rootContext()); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); - binding->setTarget(prop); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + binding.data()->setTarget(prop); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -750,12 +749,12 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression != 0); - QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression); + QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression.data()); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()")); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -765,10 +764,10 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() { QDeclarativeProperty prop(&dobject, QString("onPropertyWithNotifyChanged"), engine.rootContext()); - QGuard binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); - binding->setTarget(prop); + QWeakPointer binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext())); + binding.data()->setTarget(prop); QVERIFY(binding != 0); - QGuard expression(new QDeclarativeExpression()); + QWeakPointer expression(new QDeclarativeExpression()); QVERIFY(expression != 0); QObject *obj = new QObject; @@ -797,12 +796,12 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0); + QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0); QVERIFY(binding == 0); QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0); + QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0); QVERIFY(expression != 0); - QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression); + QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression.data()); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()")); QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1); diff --git a/tests/auto/qguard/qguard.pro b/tests/auto/qguard/qguard.pro deleted file mode 100644 index f249dde..0000000 --- a/tests/auto/qguard/qguard.pro +++ /dev/null @@ -1,2 +0,0 @@ -load(qttest_p4) -SOURCES += tst_qguard.cpp diff --git a/tests/auto/qguard/tst_qguard.cpp b/tests/auto/qguard/tst_qguard.cpp deleted file mode 100644 index 465ad0e..0000000 --- a/tests/auto/qguard/tst_qguard.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// NOTE: This is identical to the QPointer autotest - -#include - -#include -#include -#include -#include - -class tst_QGuard : public QObject -{ - Q_OBJECT -public: - tst_QGuard(); - ~tst_QGuard(); - - inline tst_QGuard *me() const - { return const_cast(this); } - -public slots: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); -private slots: - void constructors(); - void destructor(); - void assignment_operators(); - void equality_operators(); - void isNull(); - void dereference_operators(); - void disconnect(); - void castDuringDestruction(); - void data() const; - void dataSignature() const; -}; - -tst_QGuard::tst_QGuard() -{ } - -tst_QGuard::~tst_QGuard() -{ } - -void tst_QGuard::initTestCase() -{ } - -void tst_QGuard::cleanupTestCase() -{ } - -void tst_QGuard::init() -{ } - -void tst_QGuard::cleanup() -{ } - -void tst_QGuard::constructors() -{ - QGuard p1; - QGuard p2(this); - QGuard p3(p2); - QCOMPARE(p1, QGuard(0)); - QCOMPARE(p2, QGuard(this)); - QCOMPARE(p3, QGuard(this)); -} - -void tst_QGuard::destructor() -{ - QObject *object = new QObject; - QGuard p = object; - QCOMPARE(p, QGuard(object)); - delete object; - QCOMPARE(p, QGuard(0)); -} - -void tst_QGuard::assignment_operators() -{ - QGuard p1; - QGuard p2; - - p1 = this; - p2 = p1; - - QCOMPARE(p1, QGuard(this)); - QCOMPARE(p2, QGuard(this)); - QCOMPARE(p1, QGuard(p2)); - - p1 = 0; - p2 = p1; - QCOMPARE(p1, QGuard(0)); - QCOMPARE(p2, QGuard(0)); - QCOMPARE(p1, QGuard(p2)); - - QObject *object = new QObject; - - p1 = object; - p2 = p1; - QCOMPARE(p1, QGuard(object)); - QCOMPARE(p2, QGuard(object)); - QCOMPARE(p1, QGuard(p2)); - - delete object; - QCOMPARE(p1, QGuard(0)); - QCOMPARE(p2, QGuard(0)); - QCOMPARE(p1, QGuard(p2)); -} - -void tst_QGuard::equality_operators() -{ - QGuard p1; - QGuard p2; - - QVERIFY(p1 == p2); - - QObject *object = 0; - QWidget *widget = 0; - - p1 = object; - QVERIFY(p1 == p2); - QVERIFY(p1 == object); - p2 = object; - QVERIFY(p2 == p1); - QVERIFY(p2 == object); - - p1 = this; - QVERIFY(p1 != p2); - p2 = p1; - QVERIFY(p1 == p2); - - // compare to zero - p1 = 0; - QVERIFY(p1 == 0); - QVERIFY(0 == p1); - QVERIFY(p2 != 0); - QVERIFY(0 != p2); - QVERIFY(p1 == object); - QVERIFY(object == p1); - QVERIFY(p2 != object); - QVERIFY(object != p2); - QVERIFY(p1 == widget); - QVERIFY(widget == p1); - QVERIFY(p2 != widget); - QVERIFY(widget != p2); -} - -void tst_QGuard::isNull() -{ - QGuard p1; - QVERIFY(p1.isNull()); - p1 = this; - QVERIFY(!p1.isNull()); - p1 = 0; - QVERIFY(p1.isNull()); -} - -void tst_QGuard::dereference_operators() -{ - QGuard p1 = this; - - QObject *object = p1->me(); - QVERIFY(object == this); - - QObject &ref = *p1; - QVERIFY(&ref == this); - - object = static_cast(p1); - QVERIFY(object == this); -} - -void tst_QGuard::disconnect() -{ - QGuard p1 = new QObject; - QVERIFY(!p1.isNull()); - p1->disconnect(); - QVERIFY(!p1.isNull()); - delete static_cast(p1); - QVERIFY(p1.isNull()); -} - -class ChildObject : public QObject -{ - QGuard guardedPointer; - -public: - ChildObject(QObject *parent) - : QObject(parent), guardedPointer(parent) - { } - ~ChildObject(); -}; - -ChildObject::~ChildObject() -{ - QCOMPARE(static_cast(guardedPointer), static_cast(0)); - QCOMPARE(qobject_cast(guardedPointer), static_cast(0)); -} - -class ChildWidget : public QWidget -{ - QGuard guardedPointer; - -public: - ChildWidget(QWidget *parent) - : QWidget(parent), guardedPointer(parent) - { } - ~ChildWidget(); -}; - -ChildWidget::~ChildWidget() -{ - QCOMPARE(static_cast(guardedPointer), static_cast(0)); - QCOMPARE(qobject_cast(guardedPointer), static_cast(0)); -} - -class DerivedChild; - -class DerivedParent : public QObject -{ - Q_OBJECT - - DerivedChild *derivedChild; - -public: - DerivedParent(); - ~DerivedParent(); -}; - -class DerivedChild : public QObject -{ - Q_OBJECT - - DerivedParent *parentPointer; - QGuard guardedParentPointer; - -public: - DerivedChild(DerivedParent *parent) - : QObject(parent), parentPointer(parent), guardedParentPointer(parent) - { } - ~DerivedChild(); -}; - -DerivedParent::DerivedParent() - : QObject() -{ - derivedChild = new DerivedChild(this); -} - -DerivedParent::~DerivedParent() -{ - delete derivedChild; -} - -DerivedChild::~DerivedChild() -{ - QCOMPARE(static_cast(guardedParentPointer), parentPointer); - QCOMPARE(qobject_cast(guardedParentPointer), parentPointer); -} - -void tst_QGuard::castDuringDestruction() -{ - { - QObject *parentObject = new QObject(); - (void) new ChildObject(parentObject); - delete parentObject; - } - - { - QWidget *parentWidget = new QWidget(); - (void) new ChildWidget(parentWidget); - delete parentWidget; - } - - { - delete new DerivedParent(); - } -} - -void tst_QGuard::data() const -{ - /* Check value of a default constructed object. */ - { - QGuard p; - QCOMPARE(p.data(), static_cast(0)); - } - - /* Check value of a default constructed object. */ - { - QObject *const object = new QObject(); - QGuard p(object); - QCOMPARE(p.data(), object); - } -} - -void tst_QGuard::dataSignature() const -{ - /* data() should be const. */ - { - const QGuard p; - p.data(); - } - - /* The return type should be T. */ - { - const QGuard p; - /* If the types differs, the QCOMPARE will fail to instansiate. */ - QCOMPARE(p.data(), static_cast(0)); - } -} - -QTEST_MAIN(tst_QGuard) -#include "tst_qguard.moc" -- cgit v0.12 From caada5afef099b0ba7ecedb8a08ef0ecc7b5802d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 27 Mar 2010 18:30:37 +0100 Subject: Autotest: oops, fix oops: remove qguard from auto.pro --- tests/auto/gui.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro index 10a760c..a8fd2b4 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -78,7 +78,6 @@ SUBDIRS=\ qgraphicswidget \ qgridlayout \ qgroupbox \ - qguard \ qguivariant \ qheaderview \ qhelpcontentmodel \ -- cgit v0.12 From dcb055cde3a8d31e52a2d2143f14ca8662859541 Mon Sep 17 00:00:00 2001 From: John Brooks Date: Sat, 27 Mar 2010 11:35:27 -0600 Subject: Trivial fix to JavaScriptCore to fix building with MSVC 2010 Reviewed-By: Thiago Macieira --- .../javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h | 4 ++-- src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h index 35fb7e4..2ecf0d3 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h @@ -143,14 +143,14 @@ namespace JSC { if (!specificValue) { TransitionTable::iterator find = table()->find(key); if (find == table()->end()) - table()->add(key, Transition(structure, 0)); + table()->add(key, Transition(structure, (Structure*)0)); else find->second.first = structure; } else { // If we're adding a transition to a specific value, then there cannot be // an existing transition ASSERT(!table()->contains(key)); - table()->add(key, Transition(0, structure)); + table()->add(key, Transition((Structure*)0, structure)); } } diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h index 0fa7b73..f39560a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h @@ -143,14 +143,14 @@ namespace JSC { if (!specificValue) { TransitionTable::iterator find = table()->find(key); if (find == table()->end()) - table()->add(key, Transition(structure, 0)); + table()->add(key, Transition(structure, (Structure*)0)); else find->second.first = structure; } else { // If we're adding a transition to a specific value, then there cannot be // an existing transition ASSERT(!table()->contains(key)); - table()->add(key, Transition(0, structure)); + table()->add(key, Transition((Structure*)0, structure)); } } -- cgit v0.12 From d2a394ea9d433070ea0e8817b27debd9cfc8e7cd Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Mon, 29 Mar 2010 10:35:18 +1000 Subject: QuickTime media backend: Render CIImage based video frames directly with OpenGL paint engine. This makes video rendering with QGraphicsVideoItem much faster on 64 bits systems. Reviewed-by: Justin McPherson --- src/multimedia/base/base.pri | 8 +- src/multimedia/base/qpaintervideosurface.cpp | 31 +-- src/multimedia/base/qpaintervideosurface_mac.mm | 274 +++++++++++++++++++++ src/multimedia/base/qpaintervideosurface_mac_p.h | 100 ++++++++ src/multimedia/base/qpaintervideosurface_p.h | 22 +- src/plugins/mediaservices/qt7/qt7.pro | 2 + .../mediaservices/qt7/qt7ciimagevideobuffer.h | 90 +++++++ .../mediaservices/qt7/qt7ciimagevideobuffer.mm | 104 ++++++++ src/plugins/mediaservices/qt7/qt7movierenderer.mm | 13 +- .../mediaservices/qt7/qt7movieviewrenderer.h | 1 + .../mediaservices/qt7/qt7movieviewrenderer.mm | 81 +++--- 11 files changed, 660 insertions(+), 66 deletions(-) create mode 100644 src/multimedia/base/qpaintervideosurface_mac.mm create mode 100644 src/multimedia/base/qpaintervideosurface_mac_p.h create mode 100644 src/plugins/mediaservices/qt7/qt7ciimagevideobuffer.h create mode 100644 src/plugins/mediaservices/qt7/qt7ciimagevideobuffer.mm diff --git a/src/multimedia/base/base.pri b/src/multimedia/base/base.pri index 5aebbf0..49eca49 100644 --- a/src/multimedia/base/base.pri +++ b/src/multimedia/base/base.pri @@ -60,4 +60,10 @@ SOURCES += \ $$PWD/qpaintervideosurface.cpp \ $$PWD/qmediatimerange.cpp - +mac { + HEADERS += $$PWD/qpaintervideosurface_mac_p.h + OBJECTIVE_SOURCES += $$PWD/qpaintervideosurface_mac.mm + + LIBS += -framework AppKit -framework QuartzCore -framework QTKit + +} diff --git a/src/multimedia/base/qpaintervideosurface.cpp b/src/multimedia/base/qpaintervideosurface.cpp index 695dc73..b8028d8f 100644 --- a/src/multimedia/base/qpaintervideosurface.cpp +++ b/src/multimedia/base/qpaintervideosurface.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qpaintervideosurface_p.h" +#include "qpaintervideosurface_mac_p.h" #include @@ -56,28 +57,6 @@ QT_BEGIN_NAMESPACE -class QVideoSurfacePainter -{ -public: - virtual ~QVideoSurfacePainter(); - - virtual QList supportedPixelFormats( - QAbstractVideoBuffer::HandleType handleType) const = 0; - - virtual bool isFormatSupported( - const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const = 0; - - virtual QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) = 0; - virtual void stop() = 0; - - virtual QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame) = 0; - - virtual QAbstractVideoSurface::Error paint( - const QRectF &target, QPainter *painter, const QRectF &source) = 0; - - virtual void updateColors(int brightness, int contrast, int hue, int saturation) = 0; -}; - QVideoSurfacePainter::~QVideoSurfacePainter() { } @@ -1544,6 +1523,14 @@ void QPainterVideoSurface::createPainter() { Q_ASSERT(!m_painter); +#ifdef Q_WS_MAC + if (m_glContext) + m_glContext->makeCurrent(); + + m_painter = new QVideoSurfaceCoreGraphicsPainter(m_glContext != 0); + return; +#endif + #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) switch (m_shaderType) { #ifndef QT_OPENGL_ES diff --git a/src/multimedia/base/qpaintervideosurface_mac.mm b/src/multimedia/base/qpaintervideosurface_mac.mm new file mode 100644 index 0000000..899b98f --- /dev/null +++ b/src/multimedia/base/qpaintervideosurface_mac.mm @@ -0,0 +1,274 @@ +/**************************************************************************** +** +** 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 QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpaintervideosurface_mac_p.h" + +#include + +#include + +#include +#include +#include + +#include + +#include + + +QT_BEGIN_NAMESPACE + +extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); //qpaintdevice_mac.cpp + +QVideoSurfaceCoreGraphicsPainter::QVideoSurfaceCoreGraphicsPainter(bool glSupported) + : ciContext(0) + , m_imageFormat(QImage::Format_Invalid) + , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom) +{ + //qDebug() << "QVideoSurfaceCoreGraphicsPainter, GL supported:" << glSupported; + ciContext = 0; + m_imagePixelFormats + << QVideoFrame::Format_RGB32; + + m_supportedHandles + << QAbstractVideoBuffer::NoHandle + << QAbstractVideoBuffer::CoreImageHandle; + + if (glSupported) + m_supportedHandles << QAbstractVideoBuffer::GLTextureHandle; +} + +QVideoSurfaceCoreGraphicsPainter::~QVideoSurfaceCoreGraphicsPainter() +{ + [(CIContext*)ciContext release]; +} + +QList QVideoSurfaceCoreGraphicsPainter::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + return m_supportedHandles.contains(handleType) + ? m_imagePixelFormats + : QList(); +} + +bool QVideoSurfaceCoreGraphicsPainter::isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *) const +{ + return m_supportedHandles.contains(format.handleType()) + && m_imagePixelFormats.contains(format.pixelFormat()) + && !format.frameSize().isEmpty(); +} + +QAbstractVideoSurface::Error QVideoSurfaceCoreGraphicsPainter::start(const QVideoSurfaceFormat &format) +{ + m_frame = QVideoFrame(); + m_imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + m_imageSize = format.frameSize(); + m_scanLineDirection = format.scanLineDirection(); + + return m_supportedHandles.contains(format.handleType()) + && m_imageFormat != QImage::Format_Invalid + && !m_imageSize.isEmpty() + ? QAbstractVideoSurface::NoError + : QAbstractVideoSurface::UnsupportedFormatError; +} + +void QVideoSurfaceCoreGraphicsPainter::stop() +{ + m_frame = QVideoFrame(); +} + +QAbstractVideoSurface::Error QVideoSurfaceCoreGraphicsPainter::setCurrentFrame(const QVideoFrame &frame) +{ + m_frame = frame; + + return QAbstractVideoSurface::NoError; +} + +QAbstractVideoSurface::Error QVideoSurfaceCoreGraphicsPainter::paint( + const QRectF &target, QPainter *painter, const QRectF &source) +{ + if (m_frame.handleType() == QAbstractVideoBuffer::CoreImageHandle) { + if (painter->paintEngine()->type() == QPaintEngine::CoreGraphics ) { + + CIImage *img = (CIImage*)(m_frame.handle().value()); + + if (img) { + CGContextRef cgContext = qt_mac_cg_context(painter->device()); + + if (cgContext) { + painter->beginNativePainting(); + + CGRect sRect = CGRectMake(source.x(), source.y(), source.width(), source.height()); + CGRect dRect = CGRectMake(target.x(), target.y(), target.width(), target.height()); + + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img]; + + if (m_scanLineDirection == QVideoSurfaceFormat::TopToBottom) { + CGContextSaveGState( cgContext ); + CGContextTranslateCTM(cgContext, 0, dRect.origin.y + CGRectGetMaxY(dRect)); + CGContextScaleCTM(cgContext, 1, -1); + + CGContextDrawImage(cgContext, dRect, [bitmap CGImage]); + + CGContextRestoreGState(cgContext); + } else { + CGContextDrawImage(cgContext, dRect, [bitmap CGImage]); + } + + [bitmap release]; + + painter->endNativePainting(); + + return QAbstractVideoSurface::NoError; + } + } + } else if (painter->paintEngine()->type() == QPaintEngine::OpenGL2 || + painter->paintEngine()->type() == QPaintEngine::OpenGL) { + CIImage *img = (CIImage*)(m_frame.handle().value()); + + if (img) { + CGLContextObj cglContext = CGLGetCurrentContext(); + + if (cglContext) { + + if (!ciContext) { + CGLContextObj cglContext = CGLGetCurrentContext(); + NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat]; + CGLPixelFormatObj cglPixelFormat = static_cast([nsglPixelFormat CGLPixelFormatObj]); + + ciContext = [CIContext contextWithCGLContext:cglContext + pixelFormat:cglPixelFormat + options:nil]; + + [(CIContext*)ciContext retain]; + } + + CGRect sRect = CGRectMake(source.x(), source.y(), source.width(), source.height()); + CGRect dRect = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom ? + CGRectMake(target.x(), target.y()+target.height(), target.width(), -target.height()) : + CGRectMake(target.x(), target.y(), target.width(), target.height()); + + + painter->beginNativePainting(); + + [(CIContext*)ciContext drawImage:img inRect:dRect fromRect:sRect]; + + painter->endNativePainting(); + + return QAbstractVideoSurface::NoError; + } + } + } + } + + if (m_frame.handleType() == QAbstractVideoBuffer::GLTextureHandle && + (painter->paintEngine()->type() == QPaintEngine::OpenGL2 || + painter->paintEngine()->type() == QPaintEngine::OpenGL)) { + + painter->beginNativePainting(); + GLuint texture = m_frame.handle().toUInt(); + + glDisable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + const float txLeft = source.left() / m_frame.width(); + const float txRight = source.right() / m_frame.width(); + const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom + ? source.top() / m_frame.height() + : source.bottom() / m_frame.height(); + const float txBottom = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom + ? source.bottom() / m_frame.height() + : source.top() / m_frame.height(); + + glBegin(GL_QUADS); + QRectF rect = target; + glTexCoord2f(txLeft, txBottom); + glVertex2f(rect.topLeft().x(), rect.topLeft().y()); + glTexCoord2f(txRight, txBottom); + glVertex2f(rect.topRight().x() + 1, rect.topRight().y()); + glTexCoord2f(txRight, txTop); + glVertex2f(rect.bottomRight().x() + 1, rect.bottomRight().y() + 1); + glTexCoord2f(txLeft, txTop); + glVertex2f(rect.bottomLeft().x(), rect.bottomLeft().y() + 1); + glEnd(); + painter->endNativePainting(); + + return QAbstractVideoSurface::NoError; + } + + //fallback case, software rendering + if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) { + QImage image( + m_frame.bits(), + m_imageSize.width(), + m_imageSize.height(), + m_frame.bytesPerLine(), + m_imageFormat); + + if (m_scanLineDirection == QVideoSurfaceFormat::BottomToTop) { + const QTransform oldTransform = painter->transform(); + + painter->scale(1, -1); + painter->translate(0, -target.bottom()); + painter->drawImage( + QRectF(target.x(), 0, target.width(), target.height()), image, source); + painter->setTransform(oldTransform); + } else { + painter->drawImage(target, image, source); + } + + m_frame.unmap(); + } else { + painter->fillRect(target, Qt::black); + } + return QAbstractVideoSurface::NoError; +} + +void QVideoSurfaceCoreGraphicsPainter::updateColors(int, int, int, int) +{ +} + +QT_END_NAMESPACE diff --git a/src/multimedia/base/qpaintervideosurface_mac_p.h b/src/multimedia/base/qpaintervideosurface_mac_p.h new file mode 100644 index 0000000..64442ed --- /dev/null +++ b/src/multimedia/base/qpaintervideosurface_mac_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** 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 QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPAINTERVIDEOSURFACE_MAC_P_H +#define QPAINTERVIDEOSURFACE_MAC_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qpaintervideosurface_p.h" +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QVideoSurfaceCoreGraphicsPainter : public QVideoSurfacePainter +{ +public: + QVideoSurfaceCoreGraphicsPainter(bool glSupported); + ~QVideoSurfaceCoreGraphicsPainter(); + + QList supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const; + + bool isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const; + + QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format); + void stop(); + + QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame); + + QAbstractVideoSurface::Error paint( + const QRectF &target, QPainter *painter, const QRectF &source); + + void updateColors(int brightness, int contrast, int hue, int saturation); + +private: + void* ciContext; + QList m_imagePixelFormats; + QVideoFrame m_frame; + QSize m_imageSize; + QImage::Format m_imageFormat; + QVector m_supportedHandles; + QVideoSurfaceFormat::Direction m_scanLineDirection; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qpaintervideosurface_p.h b/src/multimedia/base/qpaintervideosurface_p.h index d4b6740..caba3ba 100644 --- a/src/multimedia/base/qpaintervideosurface_p.h +++ b/src/multimedia/base/qpaintervideosurface_p.h @@ -67,8 +67,28 @@ QT_BEGIN_NAMESPACE class QGLContext; +class QVideoSurfacePainter +{ +public: + virtual ~QVideoSurfacePainter(); + + virtual QList supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const = 0; + + virtual bool isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const = 0; + + virtual QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) = 0; + virtual void stop() = 0; + + virtual QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame) = 0; + + virtual QAbstractVideoSurface::Error paint( + const QRectF &target, QPainter *painter, const QRectF &source) = 0; + + virtual void updateColors(int brightness, int contrast, int hue, int saturation) = 0; +}; -class QVideoSurfacePainter; class Q_MULTIMEDIA_EXPORT QPainterVideoSurface : public QAbstractVideoSurface { Q_OBJECT diff --git a/src/plugins/mediaservices/qt7/qt7.pro b/src/plugins/mediaservices/qt7/qt7.pro index 6624d13..8791d73 100644 --- a/src/plugins/mediaservices/qt7/qt7.pro +++ b/src/plugins/mediaservices/qt7/qt7.pro @@ -25,6 +25,7 @@ HEADERS += \ qt7movieviewrenderer.h \ qt7serviceplugin.h \ qt7movierenderer.h \ + qt7ciimagevideobuffer.h \ qcvdisplaylink.h OBJECTIVE_SOURCES += \ @@ -35,6 +36,7 @@ OBJECTIVE_SOURCES += \ qt7movieviewrenderer.mm \ qt7movierenderer.mm \ qt7videooutputcontrol.mm \ + qt7ciimagevideobuffer.mm \ qcvdisplaylink.mm include(mediaplayer/mediaplayer.pri) diff --git a/src/plugins/mediaservices/qt7/qt7ciimagevideobuffer.h b/src/plugins/mediaservices/qt7/qt7ciimagevideobuffer.h new file mode 100644 index 0000000..669724f --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7ciimagevideobuffer.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7CIIMAGEVIDEOBUFFER_H +#define QT7CIIMAGEVIDEOBUFFER_H + +#include "qt7backend.h" +#import + +#include +#include + + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QT7CIImageVideoBuffer : public QAbstractVideoBuffer +{ +public: + QT7CIImageVideoBuffer(CIImage *image); + + virtual ~QT7CIImageVideoBuffer(); + + MapMode mapMode() const; + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine); + void unmap(); + QVariant handle() const; + +private: + CIImage *m_image; + NSBitmapImageRep *m_buffer; + MapMode m_mode; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/qt7ciimagevideobuffer.mm b/src/plugins/mediaservices/qt7/qt7ciimagevideobuffer.mm new file mode 100644 index 0000000..3778b58 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7ciimagevideobuffer.mm @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qt7ciimagevideobuffer.h" + +QT7CIImageVideoBuffer::QT7CIImageVideoBuffer(CIImage *image) + : QAbstractVideoBuffer(CoreImageHandle) + , m_image(image) + , m_buffer(0) + , m_mode(NotMapped) +{ + [m_image retain]; +} + +QT7CIImageVideoBuffer::~QT7CIImageVideoBuffer() +{ + [m_image release]; + [m_buffer release]; +} + +QAbstractVideoBuffer::MapMode QT7CIImageVideoBuffer::mapMode() const +{ + return m_mode; +} + +uchar *QT7CIImageVideoBuffer::map(QAbstractVideoBuffer::MapMode mode, int *numBytes, int *bytesPerLine) +{ + if (mode == NotMapped || m_mode != NotMapped || !m_image) + return 0; + + if (!m_buffer) { + //swap R and B channels + CIFilter *colorSwapFilter = [CIFilter filterWithName: @"CIColorMatrix" keysAndValues: + @"inputImage", m_image, + @"inputRVector", [CIVector vectorWithX: 0 Y: 0 Z: 1 W: 0], + @"inputGVector", [CIVector vectorWithX: 0 Y: 1 Z: 0 W: 0], + @"inputBVector", [CIVector vectorWithX: 1 Y: 0 Z: 0 W: 0], + @"inputAVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 1], + @"inputBiasVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 0], + nil]; + CIImage *img = [colorSwapFilter valueForKey: @"outputImage"]; + + m_buffer = [[NSBitmapImageRep alloc] initWithCIImage:img]; + } + + if (numBytes) + *numBytes = [m_buffer bytesPerPlane]; + + if (bytesPerLine) + *bytesPerLine = [m_buffer bytesPerRow]; + + m_mode = mode; + + return [m_buffer bitmapData]; +} + +void QT7CIImageVideoBuffer::unmap() +{ + m_mode = NotMapped; +} + +QVariant QT7CIImageVideoBuffer::handle() const +{ + return QVariant::fromValue(m_image); +} + diff --git a/src/plugins/mediaservices/qt7/qt7movierenderer.mm b/src/plugins/mediaservices/qt7/qt7movierenderer.mm index 1c1f5e4..a6d9d8d 100644 --- a/src/plugins/mediaservices/qt7/qt7movierenderer.mm +++ b/src/plugins/mediaservices/qt7/qt7movierenderer.mm @@ -46,6 +46,7 @@ #include "qt7playercontrol.h" #include "qt7movierenderer.h" #include "qt7playersession.h" +#include "qt7ciimagevideobuffer.h" #include "qcvdisplaylink.h" #include #include @@ -64,7 +65,7 @@ class CVGLTextureVideoBuffer : public QAbstractVideoBuffer { public: CVGLTextureVideoBuffer(CVOpenGLTextureRef buffer) - : QAbstractVideoBuffer(NoHandle) + : QAbstractVideoBuffer(GLTextureHandle) , m_buffer(buffer) , m_mode(NotMapped) { @@ -82,11 +83,6 @@ public: return QVariant(int(id)); } - HandleType handleType() const - { - return GLTextureHandle; - } - MapMode mapMode() const { return m_mode; } uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) @@ -447,15 +443,14 @@ void QT7MovieRenderer::updateVideoFrame(const CVTimeStamp &ts) OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, &imageBuffer); if (status == noErr && imageBuffer) { - //qDebug() << "render video frame"; QAbstractVideoBuffer *buffer = 0; if (m_usingGLContext) { - buffer = new CVGLTextureVideoBuffer((CVOpenGLTextureRef)imageBuffer); + buffer = new QT7CIImageVideoBuffer([CIImage imageWithCVImageBuffer:imageBuffer]); CVOpenGLTextureRelease((CVOpenGLTextureRef)imageBuffer); - //qDebug() << "render GL video frame" << buffer->handle(); } else { buffer = new CVPixelBufferVideoBuffer((CVPixelBufferRef)imageBuffer); + //buffer = new QT7CIImageVideoBuffer( [CIImage imageWithCVImageBuffer:imageBuffer] ); CVPixelBufferRelease((CVPixelBufferRef)imageBuffer); } diff --git a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h index 336006c..0126360 100644 --- a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h +++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h @@ -87,6 +87,7 @@ private: QSize m_nativeSize; QAbstractVideoSurface *m_surface; QVideoFrame m_currentFrame; + bool m_pendingRenderEvent; QMutex m_mutex; }; diff --git a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm index 5047853..5f11479 100644 --- a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm +++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm @@ -46,6 +46,7 @@ #include "qt7playercontrol.h" #include "qt7movieviewrenderer.h" #include "qt7playersession.h" +#include "qt7ciimagevideobuffer.h" #include #include #include @@ -113,6 +114,7 @@ QT_END_NAMESPACE - (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer; - (void) setRenderer:(QT7MovieViewRenderer *)renderer; - (void) setDrawRect:(const QRect &)rect; +- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img; @end @implementation HiddenQTMovieView @@ -163,33 +165,37 @@ QT_END_NAMESPACE // before the image will be drawn. Q_UNUSED(view); if (m_renderer) { - NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img]; CGRect bounds = [img extent]; int w = bounds.size.width; int h = bounds.size.height; - // Swap red and blue (same as QImage::rgbSwapped, but without copy) - uchar *data = [bitmap bitmapData]; - //qDebug() << data << w << h; - int bytesPerLine = [bitmap bytesPerRow]; - for (int i=0; i> 16) & 0xff) | (*p & 0xff00ff00); - p++; - } - } + QVideoFrame frame; - QVideoFrame frame( new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 ); + QAbstractVideoSurface *surface = m_renderer->surface(); + if (!surface || !surface->isActive()) + return img; - //static int i=0; - //i++; - //QImage img([bitmap bitmapData], w, h, QImage::Format_RGB32); - //img.save(QString("img%1.jpg").arg(i)); - - [bitmap release]; + if (surface->surfaceFormat().handleType() == QAbstractVideoBuffer::CoreImageHandle) { + //surface supports rendering of opengl based CIImage + frame = QVideoFrame(new QT7CIImageVideoBuffer(img), QSize(w,h), QVideoFrame::Format_RGB32 ); + } else { + //Swap R and B colors + CIFilter *colorSwapFilter = [CIFilter filterWithName: @"CIColorMatrix" keysAndValues: + @"inputImage", img, + @"inputRVector", [CIVector vectorWithX: 0 Y: 0 Z: 1 W: 0], + @"inputGVector", [CIVector vectorWithX: 0 Y: 1 Z: 0 W: 0], + @"inputBVector", [CIVector vectorWithX: 1 Y: 0 Z: 0 W: 0], + @"inputAVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 1], + @"inputBiasVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 0], + nil]; + CIImage *img = [colorSwapFilter valueForKey: @"outputImage"]; + NSBitmapImageRep *bitmap =[[NSBitmapImageRep alloc] initWithCIImage:img]; + //requesting the bitmap data is slow, + //but it's better to do it here to avoid blocking the main thread for a long. + [bitmap bitmapData]; + frame = QVideoFrame(new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 ); + [bitmap release]; + } if (m_renderer) m_renderer->renderFrame(frame); @@ -230,7 +236,8 @@ QT7MovieViewRenderer::QT7MovieViewRenderer(QObject *parent) :QT7VideoRendererControl(parent), m_movie(0), m_movieView(0), - m_surface(0) + m_surface(0), + m_pendingRenderEvent(false) { } @@ -267,11 +274,15 @@ void QT7MovieViewRenderer::setupVideoOutput() } [movieView setMovie:(QTMovie*)m_movie]; - //[movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)]; + [movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)]; } if (m_surface && !m_nativeSize.isEmpty()) { - QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32); + bool coreImageFrameSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::CoreImageHandle).isEmpty() && + !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty(); + + QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32, + coreImageFrameSupported ? QAbstractVideoBuffer::CoreImageHandle : QAbstractVideoBuffer::NoHandle); if (m_surface->isActive() && m_surface->surfaceFormat() != format) { // qDebug() << "Surface format was changed, stop the surface."; @@ -279,10 +290,11 @@ void QT7MovieViewRenderer::setupVideoOutput() } if (!m_surface->isActive()) { -// qDebug() << "Starting the surface with format" << format; - m_surface->start(format); -// if (!m_surface->start(format)) -// qDebug() << "failed to start video surface" << m_surface->error(); + //qDebug() << "Starting the surface with format" << format; + if (!m_surface->start(format)) { + qWarning() << "Failed to start video surface" << m_surface->error(); + qWarning() << "Surface format:" << format; + } } } } @@ -330,18 +342,21 @@ void QT7MovieViewRenderer::setSurface(QAbstractVideoSurface *surface) void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame) { - { - QMutexLocker locker(&m_mutex); - m_currentFrame = frame; - } - qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); + QMutexLocker locker(&m_mutex); + m_currentFrame = frame; + + if (!m_pendingRenderEvent) + qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); + + m_pendingRenderEvent = true; } bool QT7MovieViewRenderer::event(QEvent *event) { if (event->type() == QEvent::User) { QMutexLocker locker(&m_mutex); + m_pendingRenderEvent = false; if (m_surface->isActive()) m_surface->present(m_currentFrame); } -- cgit v0.12 From 04d3b7ada83042c587a9ba199395b639c5f83623 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Mon, 29 Mar 2010 11:08:21 +1000 Subject: Remove references to evr based renderer from .pro. --- src/plugins/phonon/ds9/ds9.pro | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/plugins/phonon/ds9/ds9.pro b/src/plugins/phonon/ds9/ds9.pro index 301808e..de7efbe 100644 --- a/src/plugins/phonon/ds9/ds9.pro +++ b/src/plugins/phonon/ds9/ds9.pro @@ -7,7 +7,7 @@ LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 TARGET = phonon_ds9 DEFINES += PHONON_MAKE_QT_ONLY_BACKEND -PHONON_DS9_DIR = $$QT_SOURCE_TREE/src/3rdparty/phonon/ds9 +PHONON_DS9_DI = $$QT_SOURCE_TREE/src/3rdparty/phonon/ds9 # Input HEADERS += \ @@ -51,15 +51,6 @@ SOURCES += \ $$PHONON_DS9_DIR/qaudiocdreader.cpp \ $$PHONON_DS9_DIR/qmeminputpin.cpp -#the EVR renderer (only available on desktop) -!wince*:SOURCES += $$PHONON_DS9_DIR/videorenderer_evr.cpp \ - $$PHONON_DS9_DIR/videorenderer_vmr9.cpp -!wince*:HEADERS += $$PHONON_DS9_DIR/qevr9.h \ - $$PHONON_DS9_DIR/videorenderer_evr.h \ - $$PHONON_DS9_DIR/videorenderer_vmr9.h -wince*:SOURCES += $$PHONON_DS9_DIR/videorenderer_default.cpp -wince*:HEADERS += $$PHONON_DS9_DIR/videorenderer_default.h - target.path = $$[QT_INSTALL_PLUGINS]/phonon_backend INSTALLS += target -- cgit v0.12 From c90402f06dbd84a372209fc643f0e3463c41e48a Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Mon, 29 Mar 2010 13:21:32 +1000 Subject: QuickTime backend: disable video outputs in stopped state. To keep backend behaviour consistent with other platforms. Also dropped QT7VideoOutput::setEnabled(), currentry the video output is disabled with passing null movie, this allows to ensure the movie is not retained more than necessary. Reviewed-by: Justin McPherson --- .../qt7/mediaplayer/qt7playersession.mm | 31 +++++++++++++--------- src/plugins/mediaservices/qt7/qt7movierenderer.h | 1 - src/plugins/mediaservices/qt7/qt7movierenderer.mm | 4 --- .../mediaservices/qt7/qt7movievideowidget.h | 1 - .../mediaservices/qt7/qt7movievideowidget.mm | 4 --- src/plugins/mediaservices/qt7/qt7movieviewoutput.h | 1 - .../mediaservices/qt7/qt7movieviewoutput.mm | 4 --- .../mediaservices/qt7/qt7movieviewrenderer.h | 1 - .../mediaservices/qt7/qt7movieviewrenderer.mm | 4 --- .../mediaservices/qt7/qt7videooutputcontrol.h | 1 - 10 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm index d83c0e3..f35a9fa 100644 --- a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm @@ -193,17 +193,13 @@ void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output) if (m_videoOutput == output) return; - if (m_videoOutput) { - m_videoOutput->setEnabled(false); + if (m_videoOutput) m_videoOutput->setMovie(0); - } m_videoOutput = output; - if (m_videoOutput) { - m_videoOutput->setEnabled(m_QTMovie != 0); + if (m_videoOutput && m_state != QMediaPlayer::StoppedState) m_videoOutput->setMovie(m_QTMovie); - } } @@ -297,6 +293,9 @@ void QT7PlayerSession::setPosition(qint64 pos) void QT7PlayerSession::play() { + if (m_videoOutput) + m_videoOutput->setMovie(m_QTMovie); + float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue]; [(QTMovie*)m_QTMovie setRate:preferredRate*m_rate]; @@ -306,6 +305,9 @@ void QT7PlayerSession::play() void QT7PlayerSession::pause() { + if (m_videoOutput) + m_videoOutput->setMovie(m_QTMovie); + m_state = QMediaPlayer::PausedState; [(QTMovie*)m_QTMovie setRate:0]; @@ -320,6 +322,9 @@ void QT7PlayerSession::stop() [(QTMovie*)m_QTMovie setRate:0]; setPosition(0); + if (m_videoOutput) + m_videoOutput->setMovie(0); + if (m_state == QMediaPlayer::StoppedState) emit stateChanged(m_state); } @@ -361,10 +366,8 @@ void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) if (m_QTMovie) { [(QTMovieObserver*)m_movieObserver setMovie:nil]; - if (m_videoOutput) { - m_videoOutput->setEnabled(false); + if (m_videoOutput) m_videoOutput->setMovie(0); - } [(QTMovie*)m_QTMovie release]; m_QTMovie = 0; @@ -425,10 +428,9 @@ void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) } else { [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie]; - if (m_videoOutput) { + if (m_videoOutput && m_state != QMediaPlayer::StoppedState) m_videoOutput->setMovie(m_QTMovie); - m_videoOutput->setEnabled(true); - } + processLoadStateChange(); [(QTMovie*)m_QTMovie setMuted:m_muted]; @@ -457,6 +459,8 @@ bool QT7PlayerSession::isVideoAvailable() const void QT7PlayerSession::processEOS() { m_mediaStatus = QMediaPlayer::EndOfMedia; + if (m_videoOutput) + m_videoOutput->setMovie(0); emit stateChanged(m_state = QMediaPlayer::StoppedState); emit mediaStatusChanged(m_mediaStatus); } @@ -493,6 +497,9 @@ void QT7PlayerSession::processLoadStateChange() if (state == kMovieLoadStateError) { newStatus = QMediaPlayer::InvalidMedia; + if (m_videoOutput) + m_videoOutput->setMovie(0); + emit error(QMediaPlayer::FormatError, tr("Failed to load media")); emit stateChanged(m_state = QMediaPlayer::StoppedState); } diff --git a/src/plugins/mediaservices/qt7/qt7movierenderer.h b/src/plugins/mediaservices/qt7/qt7movierenderer.h index a547329..c2dd177 100644 --- a/src/plugins/mediaservices/qt7/qt7movierenderer.h +++ b/src/plugins/mediaservices/qt7/qt7movierenderer.h @@ -74,7 +74,6 @@ public: QT7MovieRenderer(QObject *parent = 0); virtual ~QT7MovieRenderer(); - void setEnabled(bool); void setMovie(void *movie); void updateNaturalSize(const QSize &newSize); diff --git a/src/plugins/mediaservices/qt7/qt7movierenderer.mm b/src/plugins/mediaservices/qt7/qt7movierenderer.mm index a6d9d8d..95f5d4c 100644 --- a/src/plugins/mediaservices/qt7/qt7movierenderer.mm +++ b/src/plugins/mediaservices/qt7/qt7movierenderer.mm @@ -368,10 +368,6 @@ void QT7MovieRenderer::setupVideoOutput() } -void QT7MovieRenderer::setEnabled(bool) -{ -} - void QT7MovieRenderer::setMovie(void *movie) { // qDebug() << "QT7MovieRenderer::setMovie" << movie; diff --git a/src/plugins/mediaservices/qt7/qt7movievideowidget.h b/src/plugins/mediaservices/qt7/qt7movievideowidget.h index 7908efd..831a18d 100644 --- a/src/plugins/mediaservices/qt7/qt7movievideowidget.h +++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.h @@ -72,7 +72,6 @@ public: QT7MovieVideoWidget(QObject *parent = 0); virtual ~QT7MovieVideoWidget(); - void setEnabled(bool); void setMovie(void *movie); void updateNaturalSize(const QSize &newSize); diff --git a/src/plugins/mediaservices/qt7/qt7movievideowidget.mm b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm index 197c26e..c58d0a0 100644 --- a/src/plugins/mediaservices/qt7/qt7movievideowidget.mm +++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm @@ -279,10 +279,6 @@ void QT7MovieVideoWidget::setupVideoOutput() m_displayLink->start(); } -void QT7MovieVideoWidget::setEnabled(bool) -{ -} - void QT7MovieVideoWidget::setMovie(void *movie) { if (m_movie == movie) diff --git a/src/plugins/mediaservices/qt7/qt7movieviewoutput.h b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h index 49049ad..0fee41c 100644 --- a/src/plugins/mediaservices/qt7/qt7movieviewoutput.h +++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h @@ -63,7 +63,6 @@ public: QT7MovieViewOutput(QObject *parent = 0); ~QT7MovieViewOutput(); - void setEnabled(bool); void setMovie(void *movie); void updateNaturalSize(const QSize &newSize); diff --git a/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm index 8e4dd9b..20f1a02 100644 --- a/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm +++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm @@ -194,10 +194,6 @@ void QT7MovieViewOutput::setupVideoOutput() setDisplayRect(m_displayRect); } -void QT7MovieViewOutput::setEnabled(bool) -{ -} - void QT7MovieViewOutput::setMovie(void *movie) { if (m_movie != movie) { diff --git a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h index 0126360..0b515ae 100644 --- a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h +++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h @@ -67,7 +67,6 @@ public: QT7MovieViewRenderer(QObject *parent = 0); ~QT7MovieViewRenderer(); - void setEnabled(bool); void setMovie(void *movie); void updateNaturalSize(const QSize &newSize); diff --git a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm index 5f11479..33a6970 100644 --- a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm +++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm @@ -299,10 +299,6 @@ void QT7MovieViewRenderer::setupVideoOutput() } } -void QT7MovieViewRenderer::setEnabled(bool) -{ -} - void QT7MovieViewRenderer::setMovie(void *movie) { if (movie == m_movie) diff --git a/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h index 2c60919..3c74cb8 100644 --- a/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h +++ b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h @@ -67,7 +67,6 @@ class QT7PlayerService; class QT7VideoOutput { public: virtual ~QT7VideoOutput() {} - virtual void setEnabled(bool enabled) = 0; virtual void setMovie(void *movie) = 0; virtual void updateNaturalSize(const QSize &newSize) = 0; }; -- cgit v0.12 From 6a90b60d5c794470334e961d724b2f26a082cad7 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Mon, 29 Mar 2010 13:27:15 +1000 Subject: QuickTime media backend: ensure quicktime notification are received in the player session thread. Reviewed-by: Justin McPherson --- src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm index f35a9fa..65c9f7d 100644 --- a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm @@ -128,25 +128,25 @@ - (void) processEOS:(NSNotification *)notification { Q_UNUSED(notification); - m_session->processEOS(); + QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection); } - (void) processLoadStateChange:(NSNotification *)notification { Q_UNUSED(notification); - m_session->processLoadStateChange(); + QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection); } - (void) processVolumeChange:(NSNotification *)notification { Q_UNUSED(notification); - m_session->processVolumeChange(); + QMetaObject::invokeMethod(m_session, "processVolumeChange", Qt::AutoConnection); } - (void) processNaturalSizeChange :(NSNotification *)notification { Q_UNUSED(notification); - m_session->processNaturalSizeChange(); + QMetaObject::invokeMethod(m_session, "processNaturalSizeChange", Qt::AutoConnection); } @end -- cgit v0.12 From 131c96bb02fd584af04cd765aec46d9198ebeca8 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Mon, 29 Mar 2010 14:21:11 +1000 Subject: Change availabilty of camera related code. Reviewed-by: Dmytro Poplavskiy --- src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.cpp | 9 ++++++++- .../gstreamer/qgstreamervideoinputdevicecontrol.cpp | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.cpp b/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.cpp index 589d2b5..98068ac 100644 --- a/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.cpp +++ b/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.cpp @@ -52,9 +52,9 @@ #ifdef QMEDIA_GSTREAMER_CAPTURE #include "qgstreamercaptureservice.h" #endif - #include +#ifdef QMEDIA_GSTREAMER_CAPTURE #include #include #include @@ -66,6 +66,7 @@ #include #include #include +#endif QT_BEGIN_NAMESPACE @@ -109,18 +110,21 @@ void QGstreamerServicePlugin::release(QMediaService *service) QList QGstreamerServicePlugin::devices(const QByteArray &service) const { +#ifdef QMEDIA_GSTREAMER_CAPTURE if (service == Q_MEDIASERVICE_CAMERA) { if (m_cameraDevices.isEmpty()) updateDevices(); return m_cameraDevices; } +#endif return QList(); } QString QGstreamerServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) { +#ifdef QMEDIA_GSTREAMER_CAPTURE if (service == Q_MEDIASERVICE_CAMERA) { if (m_cameraDevices.isEmpty()) updateDevices(); @@ -129,12 +133,14 @@ QString QGstreamerServicePlugin::deviceDescription(const QByteArray &service, co if (m_cameraDevices[i] == device) return m_cameraDescriptions[i]; } +#endif return QString(); } void QGstreamerServicePlugin::updateDevices() const { +#ifdef QMEDIA_GSTREAMER_CAPTURE m_cameraDevices.clear(); m_cameraDescriptions.clear(); @@ -178,6 +184,7 @@ void QGstreamerServicePlugin::updateDevices() const } ::close(fd); } +#endif } Q_EXPORT_PLUGIN2(gstengine, QGstreamerServicePlugin); diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.cpp b/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.cpp index 406cefe11..4ecf10b 100644 --- a/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.cpp +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.cpp @@ -117,6 +117,7 @@ void QGstreamerVideoInputDeviceControl::update() m_names.clear(); m_descriptions.clear(); +#ifdef QMEDIA_GSTREAMER_CAPTURE QDir devDir("/dev"); devDir.setFilter(QDir::System); @@ -157,6 +158,7 @@ void QGstreamerVideoInputDeviceControl::update() } ::close(fd); } +#endif } QT_END_NAMESPACE -- cgit v0.12 From 56c18942a13da36d79707ebc814d486dc0dbbc67 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Mon, 29 Mar 2010 14:36:04 +1000 Subject: Fix strange typo? in Phonon/ds9.pro. Reviewed-by: Andrew den Exter --- src/plugins/phonon/ds9/ds9.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/phonon/ds9/ds9.pro b/src/plugins/phonon/ds9/ds9.pro index de7efbe..e77c50d 100644 --- a/src/plugins/phonon/ds9/ds9.pro +++ b/src/plugins/phonon/ds9/ds9.pro @@ -7,7 +7,7 @@ LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 TARGET = phonon_ds9 DEFINES += PHONON_MAKE_QT_ONLY_BACKEND -PHONON_DS9_DI = $$QT_SOURCE_TREE/src/3rdparty/phonon/ds9 +PHONON_DS9_DIR = $$QT_SOURCE_TREE/src/3rdparty/phonon/ds9 # Input HEADERS += \ -- cgit v0.12 From 51a444a789ff5f3ba72d3f817f4cdf427d2ff91d Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 29 Mar 2010 08:01:09 +0200 Subject: Use QSKIP rather than commenting a failure. Reviewed-by:TrustMe --- tests/auto/qfiledialog/tst_qfiledialog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index f246750..9adb4fc 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -547,6 +547,9 @@ void tst_QFiledialog::completer() // ### FIXME: This will fail on Symbian on some tests and some environments until the file engine and QFileSystemModel // are fixed to properly capitalize paths, so that some folders are not duplicated in QFileSystemModel. +#if defined(Q_OS_SYMBIAN) + QSKIP("This will fail on Symbian on some tests and some environments until the file engine and QFileSystemModel are fixed to properly capitalize paths") +#endif QTRY_COMPARE(cModel->rowCount(), expected); } QT_CATCH(...) { qDeleteAll(files); -- cgit v0.12 From 0c2f6d17b3eecf88feb3e7720f9654601d75033a Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Mon, 29 Mar 2010 16:05:53 +1000 Subject: Update PulseAudio config.test. Originally by Thiago Macieira Reviewed-by: Justin McPherson --- config.tests/unix/pulseaudio/pulseaudio.cpp | 58 +++++++++++++++++++++++++ config.tests/unix/pulseaudio/pulseaudio.pro | 7 ++- config.tests/unix/pulseaudio/pulseaudiotest.cpp | 49 --------------------- configure | 33 ++++++++++---- src/multimedia/effects/effects.pri | 3 +- 5 files changed, 87 insertions(+), 63 deletions(-) create mode 100644 config.tests/unix/pulseaudio/pulseaudio.cpp delete mode 100644 config.tests/unix/pulseaudio/pulseaudiotest.cpp diff --git a/config.tests/unix/pulseaudio/pulseaudio.cpp b/config.tests/unix/pulseaudio/pulseaudio.cpp new file mode 100644 index 0000000..ba5405b --- /dev/null +++ b/config.tests/unix/pulseaudio/pulseaudio.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#if !defined(PA_API_VERSION) || PA_API_VERSION-0 != 12 +# error "Incompatible PulseAudio API version" +#endif +#if !PA_CHECK_VERSION(0,9,0) +# error "PulseAudio version too old" +#endif + +int main(int, char **) +{ + const char *headers = pa_get_headers_version(); + const char *library = pa_get_library_version(); + pa_glib_mainloop_new(0); + return (headers - library) * 0; +} diff --git a/config.tests/unix/pulseaudio/pulseaudio.pro b/config.tests/unix/pulseaudio/pulseaudio.pro index 698a35f..d75b16f 100644 --- a/config.tests/unix/pulseaudio/pulseaudio.pro +++ b/config.tests/unix/pulseaudio/pulseaudio.pro @@ -1,4 +1,3 @@ -SOURCES = pulseaudiotest.cpp -LIBS+=-lpulse -CONFIG -= qt dylib -mac:CONFIG -= app_bundle +SOURCES = pulseaudio.cpp +CONFIG -= qt +LIBS += diff --git a/config.tests/unix/pulseaudio/pulseaudiotest.cpp b/config.tests/unix/pulseaudio/pulseaudiotest.cpp deleted file mode 100644 index eed88da..0000000 --- a/config.tests/unix/pulseaudio/pulseaudiotest.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation 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 - -int main(int ,char **) -{ - pa_threaded_mainloop *mainloop = pa_threaded_mainloop_new(); - return 0; -} - diff --git a/configure b/configure index 3c38763..4ffc457 100755 --- a/configure +++ b/configure @@ -5213,6 +5213,29 @@ if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QWS" = "yes" ]; then elif [ "$CFG_GLIB" = "no" ]; then CFG_ICD=no fi + + # Auto-detect PulseAudio support + if [ "$CFG_PULSEAUDIO" != "no" ]; then + if [ -n "$PKG_CONFIG" ]; then + QT_CFLAGS_PULSEAUDIO=`$PKG_CONFIG --cflags libpulse '>=' 0.9.10 libpulse-mainloop-glib 2>/dev/null` + QT_LIBS_PULSEAUDIO=`$PKG_CONFIG --libs libpulse '>=' 0.9.10 libpulse-mainloop-glib 2>/dev/null` + fi + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/pulseaudio "PulseAudio" $L_FLAGS $I_FLAGS $l_FLAGS $QT_CFLAGS_PULSEAUDIO $QT_LIBS_PULSEAUDIO $X11TESTS_FLAGS; then + CFG_PULSEAUDIO=yes + QMakeVar set QT_CFLAGS_PULSEAUDIO "$QT_CFLAGS_PULSEAUDIO" + QMakeVar set QT_LIBS_PULSEAUDIO "$QT_LIBS_PULSEAUDIO" + else + if [ "$CFG_PULSEAUDIO" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + echo "PulseAudio support cannot be enabled due to functionality tests!" + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 + else + CFG_PULSEAUDIO=no + fi + fi + fi fi # X11/QWS # x11 @@ -6036,14 +6059,6 @@ if [ "$CFG_ALSA" = "auto" ]; then fi fi -if [ "$CFG_PULSEAUDIO" = "auto" ]; then - if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/pulseaudio "pulseaudio" $L_FLAGS $I_FLAGS $l_FLAGS; then - CFG_PULSEAUDIO=yes - else - CFG_PULSEAUDIO=no - fi -fi - if [ "$CFG_JAVASCRIPTCORE_JIT" = "yes" ] || [ "$CFG_JAVASCRIPTCORE_JIT" = "auto" ]; then if [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]; then "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/javascriptcore-jit "javascriptcore-jit" $L_FLAGS $I_FLAGS $l_FLAGS @@ -7700,6 +7715,7 @@ echo "CUPS support ........... $CFG_CUPS" echo "Iconv support .......... $CFG_ICONV" echo "Glib support ........... $CFG_GLIB" echo "GStreamer support ...... $CFG_GSTREAMER" +echo "PulseAudio support ..... $CFG_PULSEAUDIO" echo "Large File support ..... $CFG_LARGEFILE" echo "GIF support ............ $CFG_GIF" if [ "$CFG_TIFF" = "no" ]; then @@ -7807,7 +7823,6 @@ elif [ "$CFG_OPENSSL" = "linked" ]; then fi echo "OpenSSL support ........ $CFG_OPENSSL $OPENSSL_LINKAGE" echo "Alsa support ........... $CFG_ALSA" -echo "Pulse Audio support .... $CFG_PULSEAUDIO" if [ "$PLATFORM_MAC" = "yes" ]; then echo "CoreWlan support ....... $CFG_COREWLAN" fi diff --git a/src/multimedia/effects/effects.pri b/src/multimedia/effects/effects.pri index be2b696..6307255 100644 --- a/src/multimedia/effects/effects.pri +++ b/src/multimedia/effects/effects.pri @@ -5,7 +5,8 @@ unix:!mac { DEFINES += QT_MULTIMEDIA_PULSEAUDIO HEADERS += $$PWD/qsoundeffect_pulse_p.h SOURCES += $$PWD/qsoundeffect_pulse_p.cpp - LIBS += -lpulse + QMAKE_CXXFLAGS += $$QT_CFLAGS_PULSEAUDIO + LIBS += $$QT_LIBS_PULSEAUDIO } else { DEFINES += QT_MULTIMEDIA_QMEDIAPLAYER HEADERS += $$PWD/qsoundeffect_qmedia_p.h -- cgit v0.12 From d8419cf58ffea2b9cab4986389472c991e2a2f63 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 29 Mar 2010 08:18:09 +0200 Subject: Protect EGLImage function definitions in #ifdef This should fix the build on Symbian. Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 507fab3..3417781 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -528,8 +528,10 @@ QEglProperties QEglContext::configProperties() const return QEglProperties(config()); } +#if !defined(EGL_KHR_image) || !defined(EGL_KHR_image_base) _eglCreateImageKHR eglCreateImageKHR = 0; _eglDestroyImageKHR eglDestroyImageKHR = 0; +#endif EGLDisplay QEgl::display() { -- cgit v0.12 From 60039ad6f100c10c4e95a0caeeb46e3038272319 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Mon, 29 Mar 2010 16:21:03 +1000 Subject: QuickTime video widget: use widget palette for video background color. Reviewed-by: Justin McPherson --- src/plugins/mediaservices/qt7/qt7movievideowidget.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/mediaservices/qt7/qt7movievideowidget.mm b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm index c58d0a0..648d6b4 100644 --- a/src/plugins/mediaservices/qt7/qt7movievideowidget.mm +++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm @@ -73,7 +73,8 @@ public: void initializeGL() { - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + QColor bgColor = palette().color(QPalette::Background); + glClearColor(bgColor.redF(), bgColor.greenF(), bgColor.blueF(), bgColor.alphaF()); } void resizeGL(int w, int h) -- cgit v0.12 From 0056c0a654a930fe082787ec7e8579a6e74d9ad5 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 29 Mar 2010 08:35:39 +0200 Subject: Change ORs to ANDs when checking EGLImage extension defines We should only define the EGLImage functions if both EGL_KHR_image _and_ EGL_KHR_image_base are undefined. Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 2 +- src/gui/egl/qegl_p.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 3417781..9a552cf 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -528,7 +528,7 @@ QEglProperties QEglContext::configProperties() const return QEglProperties(config()); } -#if !defined(EGL_KHR_image) || !defined(EGL_KHR_image_base) +#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) _eglCreateImageKHR eglCreateImageKHR = 0; _eglDestroyImageKHR eglDestroyImageKHR = 0; #endif diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index b570329..c659796 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -110,7 +110,7 @@ QT_BEGIN_NAMESPACE #define EGLAPIENTRY #endif -#if !defined(EGL_KHR_image) || !defined(EGL_KHR_image_base) +#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) typedef void *EGLImageKHR; #define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) @@ -123,9 +123,9 @@ typedef EGLBoolean (EGLAPIENTRY *_eglDestroyImageKHR)(EGLDisplay, EGLImageKHR); extern Q_GUI_EXPORT _eglCreateImageKHR eglCreateImageKHR; extern Q_GUI_EXPORT _eglDestroyImageKHR eglDestroyImageKHR; -#endif // !defined(EGL_KHR_image) || !defined(EGL_KHR_image_base) +#endif // !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) -#if !defined(EGL_KHR_image) || !defined(EGL_KHR_image_pixmap) +#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_pixmap) #define EGL_NATIVE_PIXMAP_KHR 0x30B0 #endif -- cgit v0.12 From ef4d44f7513bc69a33e3c0328d9f4ed856f6da57 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Mon, 29 Mar 2010 17:13:15 +1000 Subject: Fix compile. Add videorenderer_vmr9.h/cpp back into ds9.pro Reviewed-by: Justin McPherson --- src/plugins/phonon/ds9/ds9.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/phonon/ds9/ds9.pro b/src/plugins/phonon/ds9/ds9.pro index e77c50d..f40c561 100644 --- a/src/plugins/phonon/ds9/ds9.pro +++ b/src/plugins/phonon/ds9/ds9.pro @@ -22,6 +22,7 @@ HEADERS += \ $$PHONON_DS9_DIR/mediaobject.h \ $$PHONON_DS9_DIR/videowidget.h \ $$PHONON_DS9_DIR/videorenderer_soft.h \ + $$PHONON_DS9_DIR/videorenderer_vmr9.h \ $$PHONON_DS9_DIR/volumeeffect.h \ $$PHONON_DS9_DIR/qbasefilter.h \ $$PHONON_DS9_DIR/qpin.h \ @@ -44,6 +45,7 @@ SOURCES += \ $$PHONON_DS9_DIR/mediaobject.cpp \ $$PHONON_DS9_DIR/videowidget.cpp \ $$PHONON_DS9_DIR/videorenderer_soft.cpp \ + $$PHONON_DS9_DIR/videorenderer_vmr9.cpp \ $$PHONON_DS9_DIR/volumeeffect.cpp \ $$PHONON_DS9_DIR/qbasefilter.cpp \ $$PHONON_DS9_DIR/qpin.cpp \ -- cgit v0.12 From 780f0cf58d93babd4bbfb5d3d00156a96fc7dacb Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 29 Mar 2010 17:26:33 +1000 Subject: Export QGLContextResource for use with Qt/3D --- src/opengl/qgl_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 80217c0..191131e 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -578,7 +578,7 @@ inline GLenum qt_gl_preferredTextureTarget() } // One resource per group of shared contexts. -class Q_AUTOTEST_EXPORT QGLContextResource +class Q_OPENGL_EXPORT QGLContextResource { public: typedef void (*FreeFunc)(void *); -- cgit v0.12 From 83232d804cade8efee70b0cd992d21d7ca73f399 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Mon, 29 Mar 2010 12:51:50 +0300 Subject: QS60Style: very tall QSpinBox's buttons hide lineEdit If the spinbox is very tall considering its width (ratio 2:1), the spinbuttons can easily hide the lineEdit when they are scaled up. For example QSize(200, 100) QSpinBox does not have any lineEdit at all, since spinbuttons are scaled up to be 100*100 squares and deployed side-by-side. As a fix, once spinbuttons occupy half of the total width of spinbox, they stop growing. For very tall spinboxes, spinbuttons are deployed one top of the other, to make the lineEdit bigger. Task-number: QTBUG-9321 Reviewed-by: Alessandro Portale --- src/gui/styles/qs60style.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 65191a4..000696c 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2626,14 +2626,22 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0; const int buttonMargin = spinbox->frame ? 2 : 0; const int buttonContentWidth = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin; + // Spinbox buttons should be no larger than one fourth of total width. + // Thus, side-by-side buttons would take half of the total width. + const int maxSize = qMax(spinbox->rect.width() / 4, buttonContentWidth); QSize buttonSize; - buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); + buttonSize.setHeight(qMin(maxSize, qMax(8, spinbox->rect.height() - frameThickness))); //width should at least be equal to height buttonSize.setWidth(qMax(buttonSize.height(), buttonContentWidth)); buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); - const int y = frameThickness + spinbox->rect.y(); - const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2 * buttonSize.width(); + // Normally spinbuttons should be side-by-side, but if spinbox grows very big + // and spinbuttons reach their maximum size, they can be deployed one top of the other. + const bool sideBySide = (buttonSize.height() * 2 < spinbox->rect.height()) ? false : true; + const int y = frameThickness + spinbox->rect.y() + + (spinbox->rect.height() - (sideBySide ? 1 : 2) * buttonSize.height()) / 2; + const int x = spinbox->rect.x() + + spinbox->rect.width() - frameThickness - (sideBySide ? 2 : 1) * buttonSize.width(); switch (scontrol) { case SC_SpinBoxUp: @@ -2644,7 +2652,9 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple case SC_SpinBoxDown: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x + buttonSize.width(), y, buttonSize.width(), buttonSize.height()); + ret = QRect(x + (sideBySide ? buttonSize.width() : 0), + y + (sideBySide ? 0 : buttonSize.height()), + buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxEditField: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) @@ -2787,11 +2797,10 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con break; case SE_LineEditContents: { // in S60 the input text box doesn't start from line Edit's TL, but - // a bit indented. - QRect lineEditRect = opt->rect; - const int adjustment = opt->rect.height() >> 2; - lineEditRect.adjust(adjustment, 0, 0, 0); - ret = lineEditRect; + // a bit indented (8 pixels). + const int KLineEditDefaultIndention = 8; + ret = visualRect( + opt->direction, opt->rect, opt->rect.adjusted(KLineEditDefaultIndention, 0, 0, 0)); } break; case SE_TabBarTearIndicator: -- cgit v0.12 From 62b082833d904688e44e1bac4849bfa54bf5fe82 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 29 Mar 2010 12:21:40 +0200 Subject: Don't try to resolve EGLImage function pointers if they are defined We assume the presence of EGL_KHR_image or EGL_KHR_image_base means that the eglCreateImageKHR/eglDestroyImageKHR methods are exported by the EGL library and thus do not need to be resolved. Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 9a552cf..f36904d 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -556,10 +556,12 @@ EGLDisplay QEgl::display() } // Resolve the egl extension function pointers: +#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_base")) { eglCreateImageKHR = (_eglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); eglDestroyImageKHR = (_eglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); } +#endif } return dpy; -- cgit v0.12 From a078587d6a0a3fc514d5395984b0c6e2efa76e9d Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Sun, 28 Mar 2010 21:22:11 +0200 Subject: Fixed a typo in the QDoubleValidotor doc. Reviewed-by: trustme --- src/gui/widgets/qvalidator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qvalidator.cpp b/src/gui/widgets/qvalidator.cpp index 0b5cc5a..b75db45 100644 --- a/src/gui/widgets/qvalidator.cpp +++ b/src/gui/widgets/qvalidator.cpp @@ -523,7 +523,7 @@ public: In addition, QDoubleValidator is always guaranteed to accept a number formatted according to the "C" locale. QDoubleValidator will not accept - numbers with thousand-seperators. + numbers with thousand-separators. \sa QIntValidator, QRegExpValidator, {Line Edits Example} */ -- cgit v0.12 From 96e55b0693b7917dd56cedf95b3205cd20c7b651 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 29 Mar 2010 13:13:05 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( bd724fb2f716336a8a4b54cd2edc96851a5a26a4 ) Changes in WebKit/qt since the last update: ++ b/WebKit/qt/ChangeLog 2010-03-22 Jakub Wieczorek Reviewed by Simon Hausmann. [Qt] Don't construct a QLineEdit every time when painting a text field https://bugs.webkit.org/show_bug.cgi?id=36373 Add a simple benchmark covering this area. * tests/benchmarks/painting/tst_painting.cpp: (tst_Painting::textAreas): 2010-03-22 Yi Shen Reviewed by Simon Hausmann. https://bugs.webkit.org/show_bug.cgi?id=35933 [Qt] [Symbian] Can not backward select (highlight) text using virtual keyboard Make sure the selection start index is smaller than the selection end index. * Api/qwebpage.cpp: (QWebPagePrivate::inputMethodEvent): * tests/qwebpage/tst_qwebpage.cpp: (tst_QWebPage::inputMethods): 2010-03-25 Yael Aharon Reviewed by Kenneth Rohde Christiansen. [Qt] QtLauncher crashes on Mac OS and Linux when exiting with QGraphicsView mode enabled https://bugs.webkit.org/show_bug.cgi?id=35251 Followed the way QWebView registers for the signal QWebPage::destroyed(), to prevent QGraphicsWebView from referencing QWebPage after it was deleted. * Api/qgraphicswebview.cpp: (QGraphicsWebViewPrivate::_q_pageDestroyed): (QGraphicsWebView::setPage): * Api/qgraphicswebview.h: 2010-03-23 David Leong Reviewed by Laszlo Gombos. Build fix for Symbian Def file. * symbian/eabi/QtWebKitu.def: 2010-03-18 Joe Ligman Reviewed by Simon Hausmann. [Qt] New API scrollRecursively has several problems. https://bugs.webkit.org/show_bug.cgi?id=35873 Remove scrollRecursively from the Qt 4.7 API Update the internal API to accept a hit test position for nested scrolling * Api/qwebframe.cpp: (webframe_scrollOverflow): (qtwebkit_webframe_scrollRecursively): * Api/qwebframe.h: * Api/qwebframe_p.h: * tests/qwebframe/tst_qwebframe.cpp: 2009-12-18 Joe Ligman Reviewed by Kenneth Rohde Christiansen. [Qt] Add new API to QWebFrame to scrollRecursively starting with any css overflow then checking current frame and then ancestors https://bugs.webkit.org/show_bug.cgi?id=32668 * Api/qwebframe.cpp: (QWebFramePrivate::scrollOverflow): (QWebFrame::scrollRecursively): * Api/qwebframe.h: * Api/qwebframe_p.h: * tests/qwebframe/qwebframe.qrc: * tests/qwebframe/testiframe.html: Added. * tests/qwebframe/testiframe2.html: Added. * tests/qwebframe/tst_qwebframe.cpp: --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 181 +++++++++++++++++++++ src/3rdparty/webkit/WebCore/config.h | 2 + src/3rdparty/webkit/WebCore/css/CSSParser.cpp | 8 +- src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp | 3 +- src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h | 20 ++- .../webkit/WebCore/dom/XMLTokenizerLibxml2.cpp | 59 +++---- .../webkit/WebCore/html/HTMLFormElement.cpp | 2 + .../webkit/WebCore/html/HTMLImageElement.cpp | 24 +++ .../webkit/WebCore/html/HTMLImageElement.h | 7 +- .../webkit/WebCore/html/HTMLInputElement.cpp | 7 +- src/3rdparty/webkit/WebCore/html/HTMLParser.cpp | 3 +- src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp | 8 +- .../webkit/WebCore/platform/qt/RenderThemeQt.cpp | 10 +- .../webkit/WebCore/platform/qt/RenderThemeQt.h | 4 + .../webkit/WebCore/rendering/RenderText.cpp | 11 +- .../webkit/WebKit/qt/Api/qgraphicswebview.cpp | 9 + .../webkit/WebKit/qt/Api/qgraphicswebview.h | 1 + src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp | 36 ++-- src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 4 +- src/3rdparty/webkit/WebKit/qt/ChangeLog | 84 ++++++++++ .../webkit/WebKit/qt/symbian/eabi/QtWebKitu.def | 4 +- .../qt/tests/benchmarks/painting/tst_painting.cpp | 27 +++ .../WebKit/qt/tests/qwebframe/tst_qwebframe.cpp | 67 -------- .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 20 +++ 25 files changed, 468 insertions(+), 135 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 9dac2f8..414ba17 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - aa40cdb9595eb15a68e7be03322f973aa613a8f9 + bd724fb2f716336a8a4b54cd2edc96851a5a26a4 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 0a444bc..10aa0f2 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,184 @@ +2010-03-22 Jakub Wieczorek + + Reviewed by Simon Hausmann. + + [Qt] Don't construct a QLineEdit every time when painting a text field + https://bugs.webkit.org/show_bug.cgi?id=36373 + + Instead, keep one instance per RenderTheme around. + + * platform/qt/RenderThemeQt.cpp: + (WebCore::findFrameLineWidth): + +2010-03-26 Janne Koskinen + + Reviewed by Laszlo Gombos. + + Don't undefine SKIP_STATIC_CONSTRUCTORS_ON_GCC for Symbian HW targets. + https://bugs.webkit.org/show_bug.cgi?id=34081 + + Defining StringImpl instances as globals will cause a crash on process exit as + StringImpl::Remove expects TLS which was already deleted at time of exiting main and ends up + constructing one exiting thread. + + * config.h: + +2010-02-02 Alexey Proskuryakov + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=34076 + Crash in mangleme in WebCore::Element::getAttribute + + Test: fast/forms/misplaced-img-form-registration.html + + * html/HTMLFormElement.cpp: + (WebCore::HTMLFormElement::registerImgElement): Assert that the same image isn't added + to vector again. + (WebCore::HTMLFormElement::removeImgElement): Similarly, assert that we're removing something + that's actually registered. + + * html/HTMLImageElement.cpp: (WebCore::HTMLImageElement::~HTMLImageElement): If parser fails + to insert the image element, then there will be no removed from tree notification either, + need to unregister right away. + +2010-01-25 Alexey Proskuryakov + + Rubber-stamped by Geoffrey Garen. + + https://bugs.webkit.org/show_bug.cgi?id=34076 + An image remains accessible via form.property syntax after being removed from document. + + Fix crashing regression tests (tables/mozilla/bugs/bug4527.html et al.) + + * html/HTMLImageElement.cpp: (WebCore::HTMLImageElement::insertedIntoTree): Remove incorrect + assertions added in the previous patch - it's mot true that m_for is always a parent; table + parsing can reparent the image element, but m_form still needs to be set. + +2010-01-25 Alexey Proskuryakov + + Reviewed by Geoffrey Garen. + + https://bugs.webkit.org/show_bug.cgi?id=34076 + An image remains accessible via form.property syntax after being removed from document. + + Tests: fast/forms/removed-image-as-property.html + fast/forms/reparented-image-as-property.html + + * html/HTMLImageElement.cpp: + (WebCore::HTMLImageElement::~HTMLImageElement): This is called during GC - not a good time + to make observable changes to DOM. + (WebCore::HTMLImageElement::insertedIntoTree): This is the right place to do any work that + depends on connectedness to some ancestor. We still allow for m_form to be set via constructor, + which happens during parsing. + (WebCore::HTMLImageElement::removedFromTree): Ditto. + + * html/HTMLImageElement.h: Added removedFromTree/insertedIntoTree, moved removedFromDocument + and insertedIntoDocument to private section, as they shouldn't be called directly. + +2009-12-08 Brady Eidson + + Reviewed by Darin Adler. + + Navigating to a cached page can result in accessing a destroyed HTMLInputElement. + and https://webkit.org/b/32293 + + Test: fast/loader/input-element-page-cache-crash.html + + * html/HTMLInputElement.cpp: + (WebCore::HTMLInputElement::parseMappedAttribute): Make sure to unregister for the activation + callback after the new m_autocomplete setting has been stored so the unregistration actually + takes place. + +2009-12-13 Dan Bernstein + + Reviewed by Simon Fraser. + + Crash at HTMLParser::popOneBlockCommon() after + handling misnested residual style tags + + Test: fast/parser/residual-style-close-ref-clone.html + + * html/HTMLParser.cpp: + (WebCore::HTMLParser::handleResidualStyleCloseTagAcrossBlocks): Gave the + block stack a strong reference to the cloned residual style element. + +2009-12-23 Dan Bernstein + + Reviewed by Darin Adler. + + First line of text cannot be selected + https://bugs.webkit.org/show_bug.cgi?id=32749 + + Test: fast/text/remove-zero-length-run.html + + * rendering/RenderText.cpp: + (WebCore::RenderText::positionLineBox): Changed code that assumed that if a box was being + removed, it was the only box in the RenderText. Instead, correctly preserve the list of + text boxes. + (WebCore::RenderText::checkConsistency): Updated for earlier rename. + +2009-12-10 Oliver Hunt + + Reviewed by Alexey Proskuryakov. + + Crash in XMLTokenizer::popCurrentNode if window.close() is called during parsing + https://bugs.webkit.org/show_bug.cgi?id=31576 + + Add a RefCounted wrapper object around xmlParserCtxtPtr so we can + maintain it's lifetime more effectively. + + Test: fast/parser/xhtml-close-while-parsing.xhtml + + * dom/XMLTokenizer.cpp: + (WebCore::XMLTokenizer::popCurrentNode): + * dom/XMLTokenizer.h: + (WebCore::XMLParserContext::context): + (WebCore::XMLParserContext::XMLParserContext): + (WebCore::XMLTokenizer::context): + * dom/XMLTokenizerLibxml2.cpp: + (WebCore::XMLParserContext::createStringParser): + (WebCore::XMLParserContext::createMemoryParser): + (WebCore::XMLParserContext::~XMLParserContext): + (WebCore::XMLTokenizer::~XMLTokenizer): + (WebCore::XMLTokenizer::doWrite): + (WebCore::XMLTokenizer::initializeParserContext): + (WebCore::XMLTokenizer::doEnd): + (WebCore::XMLTokenizer::lineNumber): + (WebCore::XMLTokenizer::columnNumber): + (WebCore::XMLTokenizer::stopParsing): + (WebCore::parseXMLDocumentFragment): + (WebCore::parseAttributes): + +2009-11-09 Anders Carlsson + + Reviewed by Darin Adler and Dan Bernstein. + + + https://bugs.webkit.org/show_bug.cgi?id=31277 + + When an object tag's style changes (for example when child nodes are added/removed), + reuse its Frame (if it has one) instead of creating multiple Frames. + + Test: fast/dom/HTMLObjectElement/children-changed.html + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::requestObject): + +2009-12-05 Adam Langley + + Reviewed by Adam Barth. + + Check that a CSS format() argument is of a valid type. + + https://bugs.webkit.org/show_bug.cgi?id=31815 + http://code.google.com/p/chromium/issues/detail?id=28582 + + Test: fast/css/url-format-non-string.html + + * css/CSSParser.cpp: + (WebCore::CSSParser::parseFontFaceSrc): + 2010-03-19 Miikka Heikkinen Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/config.h b/src/3rdparty/webkit/WebCore/config.h index 62a7f60a..003acbe 100644 --- a/src/3rdparty/webkit/WebCore/config.h +++ b/src/3rdparty/webkit/WebCore/config.h @@ -144,7 +144,9 @@ #if PLATFORM(SYMBIAN) #undef WIN32 #undef _WIN32 +#if COMPILER(WINSCW) #undef SKIP_STATIC_CONSTRUCTORS_ON_GCC +#endif #define USE_SYSTEM_MALLOC 1 #define U_HAVE_INT8_T 0 #define U_HAVE_INT16_T 0 diff --git a/src/3rdparty/webkit/WebCore/css/CSSParser.cpp b/src/3rdparty/webkit/WebCore/css/CSSParser.cpp index 6024a5b..7750a80 100644 --- a/src/3rdparty/webkit/WebCore/css/CSSParser.cpp +++ b/src/3rdparty/webkit/WebCore/css/CSSParser.cpp @@ -3328,6 +3328,12 @@ bool CSSParser::parseFontWeight(bool important) return false; } +static bool isValidFormatFunction(CSSParserValue* val) +{ + CSSParserValueList* args = val->function->args; + return equalIgnoringCase(val->function->name, "format(") && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT); +} + bool CSSParser::parseFontFaceSrc() { RefPtr values(CSSValueList::createCommaSeparated()); @@ -3355,7 +3361,7 @@ bool CSSParser::parseFontFaceSrc() CSSParserValue* a = args->current(); uriValue.clear(); parsedValue = CSSFontFaceSrcValue::createLocal(a->string); - } else if (equalIgnoringCase(val->function->name, "format(") && allowFormat && uriValue) { + } else if (allowFormat && uriValue && isValidFormatFunction(val)) { expectComma = true; allowFormat = false; uriValue->setFormat(args->current()->string); diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp index 30d39e0..56f8ff4 100644 --- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp +++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.cpp @@ -91,7 +91,8 @@ void XMLTokenizer::pushCurrentNode(Node* n) void XMLTokenizer::popCurrentNode() { - ASSERT(m_currentNode); + if (!m_currentNode) + return; ASSERT(m_currentNodeStack.size()); if (m_currentNode != m_doc) diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h index a83e73a..3bd15c8 100644 --- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h +++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h @@ -52,6 +52,23 @@ namespace WebCore { class PendingCallbacks; class ScriptElement; +#if !USE(QXMLSTREAM) + class XMLParserContext : public RefCounted { + public: + static PassRefPtr createMemoryParser(xmlSAXHandlerPtr, void*, const char*); + static PassRefPtr createStringParser(xmlSAXHandlerPtr, void*); + ~XMLParserContext(); + xmlParserCtxtPtr context() const { return m_context; } + + private: + XMLParserContext(xmlParserCtxtPtr context) + : m_context(context) + { + } + xmlParserCtxtPtr m_context; + }; +#endif + class XMLTokenizer : public Tokenizer, public CachedResourceClient { public: XMLTokenizer(Document*, FrameView* = 0); @@ -146,7 +163,8 @@ public: QXmlStreamReader m_stream; bool m_wroteText; #else - xmlParserCtxtPtr m_context; + xmlParserCtxtPtr context() const { return m_context ? m_context->context() : 0; }; + RefPtr m_context; OwnPtr m_pendingCallbacks; Vector m_bufferedText; #endif diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp index 9aa0961..42c8b9b 100644 --- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp +++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizerLibxml2.cpp @@ -465,7 +465,7 @@ static void errorFunc(void*, const char*, ...) static bool didInit = false; -static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* userData) +PassRefPtr XMLParserContext::createStringParser(xmlSAXHandlerPtr handlers, void* userData) { if (!didInit) { xmlInitParser(); @@ -482,12 +482,12 @@ static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* user const unsigned char BOMHighByte = *reinterpret_cast(&BOM); xmlSwitchEncoding(parser, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE); - return parser; + return adoptRef(new XMLParserContext(parser)); } // Chunk should be encoded in UTF-8 -static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk) +PassRefPtr XMLParserContext::createMemoryParser(xmlSAXHandlerPtr handlers, void* userData, const char* chunk) { if (!didInit) { xmlInitParser(); @@ -518,8 +518,8 @@ static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* user parser->str_xmlns = xmlDictLookup(parser->dict, BAD_CAST "xmlns", 5); parser->str_xml_ns = xmlDictLookup(parser->dict, XML_XML_NAMESPACE, 36); parser->_private = userData; - - return parser; + + return adoptRef(new XMLParserContext(parser)); } // -------------------------------- @@ -609,6 +609,13 @@ XMLTokenizer::XMLTokenizer(DocumentFragment* fragment, Element* parentElement) m_defaultNamespaceURI = parentElement->namespaceURI(); } +XMLParserContext::~XMLParserContext() +{ + if (m_context->myDoc) + xmlFreeDoc(m_context->myDoc); + xmlFreeParserCtxt(m_context); +} + XMLTokenizer::~XMLTokenizer() { clearCurrentNodeStack(); @@ -616,15 +623,16 @@ XMLTokenizer::~XMLTokenizer() m_doc->deref(); if (m_pendingScript) m_pendingScript->removeClient(this); - if (m_context) - xmlFreeParserCtxt(m_context); } void XMLTokenizer::doWrite(const String& parseString) { if (!m_context) initializeParserContext(); - + + // Protect the libxml context from deletion during a callback + RefPtr context = m_context; + // libXML throws an error if you try to switch the encoding for an empty string. if (parseString.length()) { // Hack around libxml2's lack of encoding overide support by manually @@ -633,15 +641,15 @@ void XMLTokenizer::doWrite(const String& parseString) // and switch encodings, causing the parse to fail. const UChar BOM = 0xFEFF; const unsigned char BOMHighByte = *reinterpret_cast(&BOM); - xmlSwitchEncoding(m_context, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE); + xmlSwitchEncoding(context->context(), BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE); XMLTokenizerScope scope(m_doc->docLoader()); - xmlParseChunk(m_context, reinterpret_cast(parseString.characters()), sizeof(UChar) * parseString.length(), 0); + xmlParseChunk(context->context(), reinterpret_cast(parseString.characters()), sizeof(UChar) * parseString.length(), 0); } if (m_doc->decoder() && m_doc->decoder()->sawError()) { // If the decoder saw an error, report it as fatal (stops parsing) - handleError(fatal, "Encoding error", lineNumber(), columnNumber()); + handleError(fatal, "Encoding error", context->context()->input->line, context->context()->input->col); } return; @@ -1277,9 +1285,9 @@ void XMLTokenizer::initializeParserContext(const char* chunk) XMLTokenizerScope scope(m_doc->docLoader()); if (m_parsingFragment) - m_context = createMemoryParser(&sax, this, chunk); + m_context = XMLParserContext::createMemoryParser(&sax, this, chunk); else - m_context = createStringParser(&sax, this); + m_context = XMLParserContext::createStringParser(&sax, this); } void XMLTokenizer::doEnd() @@ -1300,12 +1308,9 @@ void XMLTokenizer::doEnd() // Tell libxml we're done. { XMLTokenizerScope scope(m_doc->docLoader()); - xmlParseChunk(m_context, 0, 0, 1); + xmlParseChunk(context(), 0, 0, 1); } - if (m_context->myDoc) - xmlFreeDoc(m_context->myDoc); - xmlFreeParserCtxt(m_context); m_context = 0; } } @@ -1334,18 +1339,19 @@ void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const Strin int XMLTokenizer::lineNumber() const { - return m_context ? m_context->input->line : 1; + return context() ? context()->input->line : 1; } int XMLTokenizer::columnNumber() const { - return m_context ? m_context->input->col : 1; + return context() ? context()->input->col : 1; } void XMLTokenizer::stopParsing() { Tokenizer::stopParsing(); - xmlStopParser(m_context); + if (context()) + xmlStopParser(context()); } void XMLTokenizer::resumeParsing() @@ -1384,17 +1390,17 @@ bool parseXMLDocumentFragment(const String& chunk, DocumentFragment* fragment, E CString chunkAsUtf8 = chunk.utf8(); tokenizer.initializeParserContext(chunkAsUtf8.data()); - xmlParseContent(tokenizer.m_context); + xmlParseContent(tokenizer.context()); tokenizer.endDocument(); // Check if all the chunk has been processed. - long bytesProcessed = xmlByteConsumed(tokenizer.m_context); + long bytesProcessed = xmlByteConsumed(tokenizer.context()); if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) != chunkAsUtf8.length()) return false; // No error if the chunk is well formed or it is not but we have no error. - return tokenizer.m_context->wellFormed || xmlCtxtGetLastError(tokenizer.m_context) == 0; + return tokenizer.context()->wellFormed || xmlCtxtGetLastError(tokenizer.context()) == 0; } // -------------------------------- @@ -1437,12 +1443,9 @@ HashMap parseAttributes(const String& string, bool& attrsOK) memset(&sax, 0, sizeof(sax)); sax.startElementNs = attributesStartElementNsHandler; sax.initialized = XML_SAX2_MAGIC; - xmlParserCtxtPtr parser = createStringParser(&sax, &state); + RefPtr parser = XMLParserContext::createStringParser(&sax, &state); String parseString = ""; - xmlParseChunk(parser, reinterpret_cast(parseString.characters()), parseString.length() * sizeof(UChar), 1); - if (parser->myDoc) - xmlFreeDoc(parser->myDoc); - xmlFreeParserCtxt(parser); + xmlParseChunk(parser->context(), reinterpret_cast(parseString.characters()), parseString.length() * sizeof(UChar), 1); attrsOK = state.gotAttributes; return state.attributes; } diff --git a/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp index ace0f2f..a74ff83 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLFormElement.cpp @@ -515,11 +515,13 @@ bool HTMLFormElement::isURLAttribute(Attribute* attr) const void HTMLFormElement::registerImgElement(HTMLImageElement* e) { + ASSERT(imgElements.find(e) == notFound); imgElements.append(e); } void HTMLFormElement::removeImgElement(HTMLImageElement* e) { + ASSERT(imgElements.find(e) != notFound); removeFromVector(imgElements, e); } diff --git a/src/3rdparty/webkit/WebCore/html/HTMLImageElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLImageElement.cpp index d353073..3db6811 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLImageElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLImageElement.cpp @@ -209,6 +209,30 @@ void HTMLImageElement::removedFromDocument() HTMLElement::removedFromDocument(); } +void HTMLImageElement::insertedIntoTree(bool deep) +{ + if (!m_form) { + // m_form can be non-null if it was set in constructor. + for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { + if (ancestor->hasTagName(formTag)) { + m_form = static_cast(ancestor); + m_form->registerImgElement(this); + break; + } + } + } + + HTMLElement::insertedIntoTree(deep); +} + +void HTMLImageElement::removedFromTree(bool deep) +{ + if (m_form) + m_form->removeImgElement(this); + m_form = 0; + HTMLElement::removedFromTree(deep); +} + int HTMLImageElement::width(bool ignorePendingStylesheets) const { if (!renderer()) { diff --git a/src/3rdparty/webkit/WebCore/html/HTMLImageElement.h b/src/3rdparty/webkit/WebCore/html/HTMLImageElement.h index f58574d..14e5fa3 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLImageElement.h +++ b/src/3rdparty/webkit/WebCore/html/HTMLImageElement.h @@ -45,8 +45,6 @@ public: virtual void attach(); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - virtual void insertedIntoDocument(); - virtual void removedFromDocument(); virtual bool canStartSelection() const { return false; } @@ -105,6 +103,11 @@ public: virtual void addSubresourceAttributeURLs(ListHashSet&) const; private: + virtual void insertedIntoDocument(); + virtual void removedFromDocument(); + virtual void insertedIntoTree(bool deep); + virtual void removedFromTree(bool deep); + HTMLImageLoader m_imageLoader; String usemap; bool ismap; diff --git a/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp index f25c908..652bc40 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLInputElement.cpp @@ -701,12 +701,15 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr) m_autocomplete = Off; registerForActivationCallbackIfNeeded(); } else { - if (m_autocomplete == Off) - unregisterForActivationCallbackIfNeeded(); + bool needsToUnregister = m_autocomplete == Off; + if (attr->isEmpty()) m_autocomplete = Uninitialized; else m_autocomplete = On; + + if (needsToUnregister) + unregisterForActivationCallbackIfNeeded(); } } else if (attr->name() == typeAttr) { setInputType(attr->value()); diff --git a/src/3rdparty/webkit/WebCore/html/HTMLParser.cpp b/src/3rdparty/webkit/WebCore/html/HTMLParser.cpp index 1cb47ae..99c66de 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLParser.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLParser.cpp @@ -1275,7 +1275,8 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem) prevMaxElem->next = elem; ASSERT(newNodePtr); prevMaxElem->node = newNodePtr; - prevMaxElem->didRefNode = false; + newNodePtr->ref(); + prevMaxElem->didRefNode = true; } else delete elem; } diff --git a/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp b/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp index a85dcf5..7d857d4 100644 --- a/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp +++ b/src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp @@ -1260,9 +1260,11 @@ bool FrameLoader::requestObject(RenderPart* renderer, const String& url, const A ASSERT(renderer->node()->hasTagName(objectTag) || renderer->node()->hasTagName(embedTag)); HTMLPlugInElement* element = static_cast(renderer->node()); - - // FIXME: OK to always make a new frame? When does the old frame get removed? - return loadSubframe(element, completedURL, frameName, m_outgoingReferrer); + + // If the plug-in element already contains a subframe, requestFrame will re-use it. Otherwise, + // it will create a new frame and set it as the RenderPart's widget, causing what was previously + // in the widget to be torn down. + return requestFrame(element, completedURL, frameName); } bool FrameLoader::shouldUsePlugin(const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback) diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp index 37a6408..298d840 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp @@ -126,6 +126,7 @@ PassRefPtr RenderTheme::themeForPage(Page* page) RenderThemeQt::RenderThemeQt(Page* page) : RenderTheme() , m_page(page) + , m_lineEdit(0) { QPushButton button; button.setAttribute(Qt::WA_MacSmallSize); @@ -142,6 +143,7 @@ RenderThemeQt::RenderThemeQt(Page* page) RenderThemeQt::~RenderThemeQt() { delete m_fallbackStyle; + delete m_lineEdit; } // for some widget painting, we need to fallback to Windows style @@ -207,11 +209,13 @@ bool RenderThemeQt::supportsControlTints() const return true; } -static int findFrameLineWidth(QStyle* style) +int RenderThemeQt::findFrameLineWidth(QStyle* style) const { - QLineEdit lineEdit; + if (!m_lineEdit) + m_lineEdit = new QLineEdit(); + QStyleOptionFrameV2 opt; - return style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, &lineEdit); + return style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, m_lineEdit); } static QRect inflateButtonRect(const QRect& originalRect, QStyle* style) diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h index 13fb42f..64921b1 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h +++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h @@ -27,6 +27,7 @@ #include QT_BEGIN_NAMESPACE +class QLineEdit; class QPainter; class QWidget; QT_END_NAMESPACE @@ -140,6 +141,8 @@ private: void setButtonPadding(RenderStyle*) const; void setPopupPadding(RenderStyle*) const; + int findFrameLineWidth(QStyle* style) const; + QStyle* fallbackStyle() const; Page* m_page; @@ -150,6 +153,7 @@ private: QString m_buttonFontFamily; QStyle* m_fallbackStyle; + mutable QLineEdit* m_lineEdit; }; class StylePainter { diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp index 40c3d75..88a05e5 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderText.cpp @@ -1047,8 +1047,15 @@ void RenderText::positionLineBox(InlineBox* box) if (!s->len()) { // We want the box to be destroyed. s->remove(); + if (m_firstTextBox == s) + m_firstTextBox = s->nextTextBox(); + else + s->prevTextBox()->setNextLineBox(s->nextTextBox()); + if (m_lastTextBox == s) + m_lastTextBox = s->prevTextBox(); + else + s->nextTextBox()->setPreviousLineBox(s->prevTextBox()); s->destroy(renderArena()); - m_firstTextBox = m_lastTextBox = 0; return; } @@ -1349,7 +1356,7 @@ void RenderText::checkConsistency() const #ifdef CHECK_CONSISTENCY const InlineTextBox* prev = 0; for (const InlineTextBox* child = m_firstTextBox; child != 0; child = child->nextTextBox()) { - ASSERT(child->object() == this); + ASSERT(child->renderer() == this); ASSERT(child->prevTextBox() == prev); prev = child; } diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp index a80c5d3..490ada1 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp @@ -65,6 +65,7 @@ public: void _q_doLoadFinished(bool success); void _q_updateMicroFocus(); + void _q_pageDestroyed(); QGraphicsWebView* q; QWebPage* page; @@ -97,6 +98,12 @@ void QGraphicsWebViewPrivate::_q_updateMicroFocus() #endif } +void QGraphicsWebViewPrivate::_q_pageDestroyed() +{ + page = 0; + q->setPage(0); +} + void QGraphicsWebViewPrivate::scroll(int dx, int dy, const QRect& rectToScroll) { q->scroll(qreal(dx), qreal(dy), QRectF(rectToScroll)); @@ -454,6 +461,8 @@ void QGraphicsWebView::setPage(QWebPage* page) this, SIGNAL(linkClicked(QUrl))); connect(d->page, SIGNAL(microFocusChanged()), this, SLOT(_q_updateMicroFocus())); + connect(d->page, SIGNAL(destroyed()), + this, SLOT(_q_pageDestroyed())); } /*! diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h index f983ae4..1b02f35 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.h @@ -135,6 +135,7 @@ protected: private: Q_PRIVATE_SLOT(d, void _q_doLoadFinished(bool success)) Q_PRIVATE_SLOT(d, void _q_updateMicroFocus()) + Q_PRIVATE_SLOT(d, void _q_pageDestroyed()) QGraphicsWebViewPrivate* const d; friend class QGraphicsWebViewPrivate; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp index e4c2afc..710e11b 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp @@ -324,15 +324,12 @@ void QWebFramePrivate::renderPrivate(QPainter *painter, QWebFrame::RenderLayer l } } -static bool webframe_scrollOverflow(WebCore::Frame* frame, int dx, int dy) +static bool webframe_scrollOverflow(WebCore::Frame* frame, int dx, int dy, const QPoint& pos) { if (!frame || !frame->document() || !frame->eventHandler()) return false; - Node* node = frame->document()->focusedNode(); - if (!node) - node = frame->document()->elementFromPoint(frame->eventHandler()->currentMousePosition().x(), - frame->eventHandler()->currentMousePosition().y()); + Node* node = frame->document()->elementFromPoint(pos.x(), pos.y()); if (!node) return false; @@ -363,6 +360,10 @@ static bool webframe_scrollOverflow(WebCore::Frame* frame, int dx, int dy) return (scrolledHorizontal || scrolledVertical); } + + + + /*! \class QWebFrame \since 4.4 @@ -1047,27 +1048,24 @@ void QWebFrame::scroll(int dx, int dy) } /*! - \since 4.7 \internal Scrolls nested frames starting at this frame, \a dx pixels to the right and \a dy pixels downward. Both \a dx and \a dy may be negative. First attempts - to scroll elements with CSS overflow followed by this frame. If this + to scroll elements with CSS overflow at position pos, followed by this frame. If this frame doesn't scroll, attempts to scroll the parent - - \sa QWebFrame::scroll */ -bool QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy) +void QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy, const QPoint& pos) { Frame* frame = QWebFramePrivate::core(qFrame); - bool scrolledHorizontal = false; - bool scrolledVertical = false; - bool scrolledOverflow = webframe_scrollOverflow(frame, dx, dy); - - if (!scrolledOverflow) { - if (!frame || !frame->view()) - return false; + if (!frame || !frame->view()) + return; + + if (!webframe_scrollOverflow(frame, dx, dy, pos)) { do { + bool scrolledHorizontal = false; + bool scrolledVertical = false; + IntSize scrollOffset = frame->view()->scrollOffset(); IntPoint maxScrollOffset = frame->view()->maximumScrollPosition(); @@ -1083,12 +1081,12 @@ bool QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int d if (scrolledHorizontal || scrolledVertical) { frame->view()->scrollBy(IntSize(dx, dy)); - return true; + return; } + frame = frame->tree()->parent(); } while (frame && frame->view()); } - return (scrolledHorizontal || scrolledVertical || scrolledOverflow); } /*! diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index a289ec0..97a4e4e 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -1248,8 +1248,8 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) #if QT_VERSION >= 0x040600 case QInputMethodEvent::Selection: { if (renderTextControl) { - renderTextControl->setSelectionStart(a.start); - renderTextControl->setSelectionEnd(a.start + a.length); + renderTextControl->setSelectionStart(qMin(a.start, (a.start + a.length))); + renderTextControl->setSelectionEnd(qMax(a.start, (a.start + a.length))); } break; } diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index a5441cd..64726c2 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,87 @@ +2010-03-22 Jakub Wieczorek + + Reviewed by Simon Hausmann. + + [Qt] Don't construct a QLineEdit every time when painting a text field + https://bugs.webkit.org/show_bug.cgi?id=36373 + + Add a simple benchmark covering this area. + + * tests/benchmarks/painting/tst_painting.cpp: + (tst_Painting::textAreas): + +2010-03-22 Yi Shen + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=35933 + [Qt] [Symbian] Can not backward select (highlight) text using virtual keyboard + Make sure the selection start index is smaller than the selection end index. + + * Api/qwebpage.cpp: + (QWebPagePrivate::inputMethodEvent): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods): + +2010-03-25 Yael Aharon + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QtLauncher crashes on Mac OS and Linux when exiting with QGraphicsView mode enabled + https://bugs.webkit.org/show_bug.cgi?id=35251 + + Followed the way QWebView registers for the signal QWebPage::destroyed(), to prevent + QGraphicsWebView from referencing QWebPage after it was deleted. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::_q_pageDestroyed): + (QGraphicsWebView::setPage): + * Api/qgraphicswebview.h: + +2010-03-23 David Leong + + Reviewed by Laszlo Gombos. + + Build fix for Symbian Def file. + + * symbian/eabi/QtWebKitu.def: + +2010-03-18 Joe Ligman + + Reviewed by Simon Hausmann. + + [Qt] New API scrollRecursively has several problems. + https://bugs.webkit.org/show_bug.cgi?id=35873 + + Remove scrollRecursively from the Qt 4.7 API + Update the internal API to accept a hit test position + for nested scrolling + + * Api/qwebframe.cpp: + (webframe_scrollOverflow): + (qtwebkit_webframe_scrollRecursively): + * Api/qwebframe.h: + * Api/qwebframe_p.h: + * tests/qwebframe/tst_qwebframe.cpp: + +2009-12-18 Joe Ligman + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add new API to QWebFrame to scrollRecursively starting with any css overflow + then checking current frame and then ancestors + https://bugs.webkit.org/show_bug.cgi?id=32668 + + * Api/qwebframe.cpp: + (QWebFramePrivate::scrollOverflow): + (QWebFrame::scrollRecursively): + * Api/qwebframe.h: + * Api/qwebframe_p.h: + * tests/qwebframe/qwebframe.qrc: + * tests/qwebframe/testiframe.html: Added. + * tests/qwebframe/testiframe2.html: Added. + * tests/qwebframe/tst_qwebframe.cpp: + 2010-03-21 Kristian Amlie Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def b/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def index 5dd2e20..cfa8f7f 100644 --- a/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def +++ b/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def @@ -693,5 +693,5 @@ EXPORTS _Z23qt_networkAccessAllowedb @ 692 NONAME _Z25qt_resumeActiveDOMObjectsP9QWebFrame @ 693 NONAME _Z26qt_suspendActiveDOMObjectsP9QWebFrame @ 694 NONAME - _Z35qtwebkit_webframe_scrollRecursivelyP9QWebFrameii @ 695 NONAME - + _Z35qtwebkit_webframe_scrollRecursivelyP9QWebFrameii @ 695 NONAME ABSENT + _Z35qtwebkit_webframe_scrollRecursivelyP9QWebFrameiiRK6QPoint @ 715 NONAME diff --git a/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.cpp b/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.cpp index f4531fd..fc5b8e3 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/benchmarks/painting/tst_painting.cpp @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -59,6 +60,7 @@ public Q_SLOTS: private Q_SLOTS: void paint_data(); void paint(); + void textAreas(); private: QWebView* m_view; @@ -105,5 +107,30 @@ void tst_Painting::paint() } } +void tst_Painting::textAreas() +{ + m_view->load(QUrl("data:text/html;")); + ::waitForSignal(m_view, SIGNAL(loadFinished(bool))); + + QWebElement bodyElement = m_page->mainFrame()->findFirstElement("body"); + + int count = 100; + while (count--) { + QString markup(""); + bodyElement.appendInside(markup); + } + + /* force a layout */ + QWebFrame* mainFrame = m_page->mainFrame(); + mainFrame->toPlainText(); + + QPixmap pixmap(mainFrame->contentsSize()); + QBENCHMARK { + QPainter painter(&pixmap); + mainFrame->render(&painter, QRect(QPoint(0, 0), mainFrame->contentsSize())); + painter.end(); + } +} + QTEST_MAIN(tst_Painting) #include "tst_painting.moc" diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp index 609f8b4..8cc7953 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp @@ -606,7 +606,6 @@ private slots: void scrollPosition(); void evaluateWillCauseRepaint(); void qObjectWrapperWithSameIdentity(); - void scrollRecursively(); private: QString evalJS(const QString&s) { @@ -2825,71 +2824,5 @@ void tst_QWebFrame::qObjectWrapperWithSameIdentity() QCOMPARE(mainFrame->toPlainText(), QString("test2")); } -bool QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy); - -void tst_QWebFrame::scrollRecursively() -{ - // The test content is - // a nested frame set - // The main frame scrolls - // and has two children - // an iframe and a div overflow - // both scroll - QWebView webView; - QWebPage* webPage = webView.page(); - QSignalSpy loadSpy(webPage, SIGNAL(loadFinished(bool))); - QUrl url = QUrl("qrc:///testiframe.html"); - webPage->mainFrame()->load(url); - QTRY_COMPARE(loadSpy.count(), 1); - - QList children = webPage->mainFrame()->childFrames(); - QVERIFY(children.count() == 1); - - // 1st test - // call scrollRecursively over mainframe - // verify scrolled - // verify scroll postion changed - QPoint scrollPosition(webPage->mainFrame()->scrollPosition()); - QVERIFY(qtwebkit_webframe_scrollRecursively(webPage->mainFrame(), 10, 10)); - QVERIFY(scrollPosition != webPage->mainFrame()->scrollPosition()); - - // 2nd test - // call scrollRecursively over child iframe - // verify scrolled - // verify child scroll position changed - // verify parent's scroll position did not change - scrollPosition = webPage->mainFrame()->scrollPosition(); - QPoint childScrollPosition = children.at(0)->scrollPosition(); - QVERIFY(qtwebkit_webframe_scrollRecursively(children.at(0), 10, 10)); - QVERIFY(scrollPosition == webPage->mainFrame()->scrollPosition()); - QVERIFY(childScrollPosition != children.at(0)->scrollPosition()); - - // 3rd test - // call scrollRecursively over div overflow - // verify scrolled == true - // verify parent and child frame's scroll postion did not change - QWebElement div = webPage->mainFrame()->documentElement().findFirst("#content1"); - QMouseEvent evpres(QEvent::MouseMove, div.geometry().center(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); - webPage->event(&evpres); - scrollPosition = webPage->mainFrame()->scrollPosition(); - childScrollPosition = children.at(0)->scrollPosition(); - QVERIFY(qtwebkit_webframe_scrollRecursively(webPage->mainFrame(), 5, 5)); - QVERIFY(childScrollPosition == children.at(0)->scrollPosition()); - QVERIFY(scrollPosition == webPage->mainFrame()->scrollPosition()); - - // 4th test - // call scrollRecursively twice over childs iframe - // verify scrolled == true first time - // verify parent's scroll == true second time - // verify parent and childs scroll position changed - childScrollPosition = children.at(0)->scrollPosition(); - QVERIFY(qtwebkit_webframe_scrollRecursively(children.at(0), -10, -10)); - QVERIFY(childScrollPosition != children.at(0)->scrollPosition()); - scrollPosition = webPage->mainFrame()->scrollPosition(); - QVERIFY(qtwebkit_webframe_scrollRecursively(children.at(0), -10, -10)); - QVERIFY(scrollPosition != webPage->mainFrame()->scrollPosition()); - -} - QTEST_MAIN(tst_QWebFrame) #include "tst_qwebframe.moc" diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 0e04acc..55ee42a 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1451,6 +1451,26 @@ void tst_QWebPage::inputMethods() variant = page->inputMethodQuery(Qt::ImCurrentSelection); QString selectionValue = variant.value(); QCOMPARE(selectionValue, QString("eb")); + + //Set selection with negative length + inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 6, -5, QVariant()); + QInputMethodEvent eventSelection2("",inputAttributes); + page->event(&eventSelection2); + + //ImAnchorPosition + variant = page->inputMethodQuery(Qt::ImAnchorPosition); + anchorPosition = variant.toInt(); + QCOMPARE(anchorPosition, 1); + + //ImCursorPosition + variant = page->inputMethodQuery(Qt::ImCursorPosition); + cursorPosition = variant.toInt(); + QCOMPARE(cursorPosition, 6); + + //ImCurrentSelection + variant = page->inputMethodQuery(Qt::ImCurrentSelection); + selectionValue = variant.value(); + QCOMPARE(selectionValue, QString("tWebK")); #endif //ImSurroundingText -- cgit v0.12 From 01c5c585ea0839730e213ac414c191ce40bfe321 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 29 Mar 2010 13:58:12 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( c39615d8e78f083b23f34ac24cf7d3a7ce765122 ) Changes in WebKit/qt since the last update: * https://bugs.webkit.org/show_bug.cgi?id=34262 -- Accept XHTML MP content type as XHTML content --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 13 +++++++++++++ src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp | 2 -- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 414ba17..5bc2492 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - bd724fb2f716336a8a4b54cd2edc96851a5a26a4 + c39615d8e78f083b23f34ac24cf7d3a7ce765122 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 10aa0f2..76374f3 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,16 @@ +2010-03-29 Laszlo Gombos + + Reviewed for the Qt 4.6 branch by Simon Hausmann. + + Accept XHTML-MP content type as XHTML content + https://bugs.webkit.org/show_bug.cgi?id=34262 + + Enable processing XHTML-MP mime type as an XHTML document + even if XHTML-MP support is not enabled. + + * platform/MIMETypeRegistry.cpp: + (WebCore::initializeSupportedNonImageMimeTypes): + 2010-03-22 Jakub Wieczorek Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp b/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp index 609a1b0..758863c 100644 --- a/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp +++ b/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp @@ -200,9 +200,7 @@ static void initializeSupportedNonImageMimeTypes() "text/", "application/xml", "application/xhtml+xml", -#if ENABLE(XHTMLMP) "application/vnd.wap.xhtml+xml", -#endif "application/rss+xml", "application/atom+xml", #if ENABLE(SVG) -- cgit v0.12 From 809583a34cb69367ecb4218f798a5928de9aacec Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 29 Mar 2010 10:34:23 +0200 Subject: QVarLenghtArray: add some API to be consistant to QVector That way it is easier to have QVarLenghtArray as a drop-in replacement for QVector Reviewed-by: Joao --- src/corelib/tools/qvarlengtharray.h | 19 +++++++++++++ src/corelib/tools/qvarlengtharray.qdoc | 32 +++++++++++++++++++++- tests/auto/qvarlengtharray/tst_qvarlengtharray.cpp | 13 +++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index aecb66e..9773d4b 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -107,6 +107,10 @@ public: Q_ASSERT(idx >= 0 && idx < s); return ptr[idx]; } + inline const T &at(int idx) const { return operator[](idx); } + + T value(int i) const; + T value(int i, const T &defaultValue) const; inline void append(const T &t) { if (s == a) // i.e. s != 0 @@ -248,6 +252,21 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray::realloc(int asize, int a } } +template +Q_OUTOFLINE_TEMPLATE T QVarLengthArray::value(int i) const +{ + if (i < 0 || i >= size()) { + return T(); + } + return at(i); +} +template +Q_OUTOFLINE_TEMPLATE T QVarLengthArray::value(int i, const T &defaultValue) const +{ + return (i < 0 || i >= size()) ? defaultValue : at(i); +} + + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index bb7a3de..38901e5 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -197,7 +197,7 @@ \a i must be a valid index position in the array (i.e., 0 <= \a i < size()). - \sa data() + \sa data(), at() */ /*! \fn const T &QVarLengthArray::operator[](int i) const @@ -272,3 +272,33 @@ Constructs a copy of \a other. */ +/*! \fn const T &QVarLengthArray::at(int i) const + + Returns a reference to the item at index position \a i. + + \a i must be a valid index position in the array (i.e., 0 <= \a i + < size()). + + \sa value(), operator[]() +*/ + +/*! \fn T QVarLengthArray::value(int i) const + + Returns the value at index position \a i. + + If the index \a i is out of bounds, the function returns + a \l{default-constructed value}. If you are certain that + \a i is within bounds, you can use at() instead, which is slightly + faster. + + \sa at(), operator[]() +*/ + +/*! \fn T QVarLengthArray::value(int i, const T &defaultValue) const + + \overload + + If the index \a i is out of bounds, the function returns + \a defaultValue. +*/ + diff --git a/tests/auto/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/qvarlengtharray/tst_qvarlengtharray.cpp index 1c43069..5708726 100644 --- a/tests/auto/qvarlengtharray/tst_qvarlengtharray.cpp +++ b/tests/auto/qvarlengtharray/tst_qvarlengtharray.cpp @@ -133,6 +133,12 @@ void tst_QVarLengthArray::oldTests() QVERIFY(sa.data() == &sa[0]); QVERIFY(sa[0] == 0xfee); QVERIFY(sa[10] == 0xff); + QVERIFY(sa.at(0) == 0xfee); + QVERIFY(sa.at(10) == 0xff); + QVERIFY(sa.value(0) == 0xfee); + QVERIFY(sa.value(10) == 0xff); + QVERIFY(sa.value(1000) == 0); + QVERIFY(sa.value(1000, 12) == 12); QVERIFY(sa.size() == 512); sa.reserve(1024); QVERIFY(sa.capacity() == 1024); @@ -168,6 +174,13 @@ void tst_QVarLengthArray::oldTests() QCOMPARE(sa.size(), 12); QCOMPARE(sa[10], QString("hello")); QCOMPARE(sa[11], QString("world")); + QCOMPARE(sa.at(10), QString("hello")); + QCOMPARE(sa.at(11), QString("world")); + QCOMPARE(sa.value(10), QString("hello")); + QCOMPARE(sa.value(11), QString("world")); + QCOMPARE(sa.value(10000), QString()); + QCOMPARE(sa.value(1212112, QString("none")), QString("none")); + QCOMPARE(sa.value(-12, QString("neg")), QString("neg")); sa.append(arr, 1); QCOMPARE(sa.size(), 13); -- cgit v0.12 From 1eb54209adca3ed93426598c1dcf51ca4ba675be Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Mon, 29 Mar 2010 13:34:36 +0200 Subject: QNAM HTTP: Fix invoking a method when being destructed right now Reviewed-by: Thiago Macieira --- src/network/access/qhttpnetworkconnectionchannel.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 1d8224c..0b97cbe 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -648,7 +648,8 @@ void QHttpNetworkConnectionChannel::allDone() close(); QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } else if (alreadyPipelinedRequests.isEmpty()) { - QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); + if (qobject_cast(connection)) + QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } } @@ -753,7 +754,8 @@ void QHttpNetworkConnectionChannel::handleStatus() } break; default: - QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); + if (qobject_cast(connection)) + QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } } @@ -801,7 +803,8 @@ void QHttpNetworkConnectionChannel::closeAndResendCurrentRequest() requeueCurrentlyPipelinedRequests(); close(); resendCurrent = true; - QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); + if (qobject_cast(connection)) + QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } bool QHttpNetworkConnectionChannel::isSocketBusy() const -- cgit v0.12 From d717d2686ecdbeafee1f5cabc6832c8339cfb2b4 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 26 Mar 2010 11:56:55 +0100 Subject: Respect QPainter::pen() in QPainter::drawStaticText() QStaticText needs to support changing the pen on the painter to support rich text, but it should not override the pen unless it has been explicitly set in the rich text. We do this by marking the pen as dirty in updateState() when we record the text items. Task-number: QTBUG-8908 Reviewed-by: Gunnar --- src/gui/painting/qpainter.cpp | 2 +- src/gui/text/qstatictext.cpp | 15 ++++- tests/auto/qstatictext/tst_qstatictext.cpp | 90 ++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 1c528fe..ac5c8b7 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5901,7 +5901,7 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static QColor currentColor = oldPen.color(); for (int i=0; iitemCount; ++i) { QStaticTextItem *item = staticText_d->items + i; - if (currentColor != item->color) { + if (item->color.isValid() && currentColor != item->color) { setPen(item->color); currentColor = item->color; } diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index d685cd9..f433c78 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -388,10 +388,17 @@ namespace { m_expectedItemCount(expectedItemCount), m_expectedGlyphCount(expectedGlyphCount), m_glyphPool(glyphPool), - m_positionPool(positionPool) + m_positionPool(positionPool), + m_dirtyPen(false) { } + virtual void updateState(const QPaintEngineState &newState) + { + if (newState.state() & QPaintEngine::DirtyPen) + m_dirtyPen = true; + } + virtual void drawTextItem(const QPointF &position, const QTextItem &textItem) { const QTextItemInt &ti = static_cast(textItem); @@ -412,7 +419,8 @@ namespace { currentItem->numGlyphs = ti.glyphs.numGlyphs; currentItem->glyphs = m_glyphPool; currentItem->glyphPositions = m_positionPool; - currentItem->color = state->pen().color(); + if (m_dirtyPen) + currentItem->color = state->pen().color(); QTransform matrix = state->transform(); matrix.translate(position.x(), position.y()); @@ -435,7 +443,6 @@ namespace { virtual bool begin(QPaintDevice *) { return true; } virtual bool end() { return true; } - virtual void updateState(const QPaintEngineState &) {} virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) {} virtual Type type() const { @@ -461,6 +468,8 @@ namespace { glyph_t *m_glyphPool; QFixedPoint *m_positionPool; + + bool m_dirtyPen; }; class DrawTextItemDevice: public QPaintDevice diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index a038878..b59c10b 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -81,6 +81,10 @@ private slots: void transformationChanged(); void plainTextVsRichText(); + + void setPenPlainText(); + void setPenRichText(); + void richTextOverridesPen(); }; void tst_QStaticText::init() @@ -518,5 +522,91 @@ void tst_QStaticText::plainTextVsRichText() QCOMPARE(imagePlainText, imageRichText); } +void tst_QStaticText::setPenPlainText() +{ + QFont font = QApplication::font(); + font.setStyleStrategy(QFont::NoAntialias); + + QFontMetricsF fm(font); + QPixmap image(qCeil(fm.width("XXXXX")), qCeil(fm.height())); + image.fill(Qt::white); + { + QPainter p(&image); + p.setFont(font); + p.setPen(Qt::green); + + QStaticText staticText("XXXXX"); + staticText.setTextFormat(Qt::PlainText); + p.drawStaticText(0, fm.ascent(), staticText); + } + + QImage img = image.toImage(); + for (int x=0; xXXXXX"); + staticText.setTextFormat(Qt::RichText); + p.drawStaticText(0, fm.ascent(), staticText); + } + + QImage img = image.toImage(); + for (int x=0; xXXXXX"); + staticText.setTextFormat(Qt::RichText); + p.drawStaticText(0, fm.ascent(), staticText); + } + + QImage img = image.toImage(); + for (int x=0; x Date: Fri, 26 Mar 2010 13:38:32 +0100 Subject: Change QStaticText::setMaximumSize() to setTextWidth() To avoid having to precalculate the height of the laid out text, we now only supply a maximum text width to QStaticText. The only usage of the maximum height would be to clip the results, and clipping should be set separately from the QStaticText call, since this has no impact on the layout of the glyphs. The tests have been updated to reflect the change in logic. We also need a consistent way of specifying the position of the text. Before, the position meant "baseline position" for unbroken text and "top left position" for text with a specified layout width. We want to be consistent, and since baseline position makes no sense for multiline text, we standardize on top left position. Task-number: QTBUG-9029 Reviewed-by: Gunnar --- src/gui/painting/qpainter.cpp | 42 +++++++-------- src/gui/painting/qpainter.h | 6 +-- src/gui/text/qstatictext.cpp | 86 +++++++++++++++++------------- src/gui/text/qstatictext.h | 6 +-- src/gui/text/qstatictext_p.h | 7 ++- tests/auto/qstatictext/tst_qstatictext.cpp | 51 +++++++++++------- 6 files changed, 109 insertions(+), 89 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index ac5c8b7..7856881 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5762,19 +5762,24 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit /*! - \fn void QPainter::drawStaticText(const QPoint &position, const QStaticText &staticText) + \fn void QPainter::drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText) \since 4.7 \overload - Draws the \a staticText at the \a position. + Draws the \a staticText at the \a topLeftPosition. + + \note The y-position is used as the top of the font. + */ /*! - \fn void QPainter::drawStaticText(int x, int y, const QStaticText &staticText) + \fn void QPainter::drawStaticText(int left, int top, const QStaticText &staticText) \since 4.7 \overload - Draws the \a staticText at coordinates \a x and \a y. + Draws the \a staticText at coordinates \a left and \a top. + + \note The y-position is used as the top of the font. */ /*! @@ -5802,7 +5807,7 @@ void QPainter::drawText(const QPointF &p, const QString &str) /*! \since 4.7 - Draws the given \a staticText at the given \a position. + Draws the given \a staticText at the given \a topLeftPosition. The text will be drawn using the font and the transformation set on the painter. If the font and/or transformation set on the painter are different from the ones used to initialize @@ -5810,15 +5815,17 @@ void QPainter::drawText(const QPointF &p, const QString &str) QStaticText::prepare() to initialize \a staticText with the font and transformation with which it will later be drawn. - If \a position is not the same as when \a staticText was initialized, or when it was last drawn, - then there will be a slight overhead when translating the text to its new position. + If \a topLeftPosition is not the same as when \a staticText was initialized, or when it was + last drawn, then there will be a slight overhead when translating the text to its new position. - \note If the painter's transformation is not affine, then \a staticText will be drawn using regular - calls to drawText(), losing any potential performance improvement. + \note If the painter's transformation is not affine, then \a staticText will be drawn using + regular calls to drawText(), losing any potential for performance improvement. + + \note The y-position is used as the top of the font. \sa QStaticText */ -void QPainter::drawStaticText(const QPointF &position, const QStaticText &staticText) +void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText) { Q_D(QPainter); if (!d->engine || staticText.text().isEmpty() || pen().style() == Qt::NoPen) @@ -5830,13 +5837,13 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static // If we don't have an extended paint engine, or if the painter is projected, // we go through standard code path if (d->extended == 0 || !d->state->matrix.isAffine()) { - staticText_d->paintText(position, this); + staticText_d->paintText(topLeftPosition, this); return; } // Don't recalculate entire layout because of translation, rather add the dx and dy // into the position to move each text item the correct distance. - QPointF transformedPosition = position * d->state->matrix; + QPointF transformedPosition = topLeftPosition * d->state->matrix; QTransform matrix = d->state->matrix; // The translation has been applied to transformedPosition. Remove translation @@ -5863,14 +5870,6 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static staticTextNeedsReinit = true; } - bool restoreWhenFinished = false; - if (staticText_d->needsClipRect) { - save(); - setClipRect(QRectF(position, staticText_d->maximumSize)); - - restoreWhenFinished = true; - } - if (font() != staticText_d->font) { staticText_d->font = font(); staticTextNeedsReinit = true; @@ -5910,9 +5909,6 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static if (currentColor != oldPen.color()) setPen(oldPen); - if (restoreWhenFinished) - restore(); - if (matrix.isTranslating()) d->state->matrix = matrix; } diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 443925b..edfb67e 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -396,9 +396,9 @@ public: void setLayoutDirection(Qt::LayoutDirection direction); Qt::LayoutDirection layoutDirection() const; - void drawStaticText(const QPointF &p, const QStaticText &staticText); - inline void drawStaticText(const QPoint &p, const QStaticText &staticText); - inline void drawStaticText(int x, int y, const QStaticText &staticText); + void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText); + inline void drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText); + inline void drawStaticText(int left, int top, const QStaticText &staticText); void drawText(const QPointF &p, const QString &s); inline void drawText(const QPoint &p, const QString &s); diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index f433c78..977355e 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -143,11 +143,10 @@ QStaticText::QStaticText() If an invalid size is passed for \a size the text will be unbounded. */ -QStaticText::QStaticText(const QString &text, const QSizeF &size) +QStaticText::QStaticText(const QString &text) : data(new QStaticTextPrivate) { data->text = text; - data->maximumSize = size; data->init(); } @@ -209,7 +208,7 @@ QStaticText &QStaticText::operator=(const QStaticText &other) } /*! - Compares \a other to this QStaticText. Returns true if the texts, fonts and maximum sizes + Compares \a other to this QStaticText. Returns true if the texts, fonts and text widths are equal. */ bool QStaticText::operator==(const QStaticText &other) const @@ -217,7 +216,7 @@ bool QStaticText::operator==(const QStaticText &other) const return (data == other.data || (data->text == other.data->text && data->font == other.data->font - && data->maximumSize == other.data->maximumSize)); + && data->textWidth == other.data->textWidth)); } /*! @@ -315,33 +314,39 @@ QStaticText::PerformanceHint QStaticText::performanceHint() const } /*! - Sets the maximum size of the QStaticText to \a size. + Sets the preferred width for this QStaticText. If the text is wider than the specified width, + it will be broken into multiple lines and grow vertically. If the text cannot be split into + multiple lines, it will be larger than the specified \a textWidth. + + Setting the preferred text width to a negative number will cause the text to be unbounded. + + Use size() to get the actual size of the text. \note This function will cause the layout of the text to be recalculated. - \sa maximumSize(), size() + \sa textWidth(), size() */ -void QStaticText::setMaximumSize(const QSizeF &size) +void QStaticText::setTextWidth(qreal textWidth) { detach(); - data->maximumSize = size; + data->textWidth = textWidth; data->init(); } /*! - Returns the maximum size of the QStaticText. + Returns the preferred width for this QStaticText. - \sa setMaximumSize() + \sa setTextWidth() */ -QSizeF QStaticText::maximumSize() const +qreal QStaticText::textWidth() const { - return data->maximumSize; + return data->textWidth; } /*! Returns the size of the bounding rect for this QStaticText. - \sa maximumSize() + \sa textWidth() */ QSizeF QStaticText::size() const { @@ -349,14 +354,14 @@ QSizeF QStaticText::size() const } QStaticTextPrivate::QStaticTextPrivate() - : items(0), itemCount(0), glyphPool(0), positionPool(0), needsClipRect(false), + : items(0), itemCount(0), glyphPool(0), positionPool(0), textWidth(-1.0), useBackendOptimizations(false), textFormat(Qt::AutoText) { } QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other) - : text(other.text), font(other.font), maximumSize(other.maximumSize), matrix(other.matrix), - items(0), itemCount(0), glyphPool(0), positionPool(0), needsClipRect(false), + : text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix), + items(0), itemCount(0), glyphPool(0), positionPool(0), useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat) { } @@ -539,43 +544,50 @@ namespace { }; } -void QStaticTextPrivate::paintText(const QPointF &pos, QPainter *p) +void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p) { bool preferRichText = textFormat == Qt::RichText || (textFormat == Qt::AutoText && Qt::mightBeRichText(text)); if (!preferRichText) { - if (maximumSize.isValid()) { - QRectF boundingRect; - p->drawText(QRectF(pos, maximumSize), Qt::TextWordWrap, text, &boundingRect); - - actualSize = boundingRect.size(); - needsClipRect = boundingRect.width() > maximumSize.width() - || boundingRect.height() > maximumSize.height(); - } else { - p->drawText(pos, text); - needsClipRect = false; - - QFontMetrics fm(font); - actualSize = fm.boundingRect(text).size(); + QTextLayout textLayout; + textLayout.setText(text); + textLayout.setFont(font); + + qreal leading = QFontMetricsF(font).leading(); + qreal height = -leading; + + textLayout.beginLayout(); + while (1) { + QTextLine line = textLayout.createLine(); + if (!line.isValid()) + break; + + if (textWidth >= 0.0) + line.setLineWidth(textWidth); + height += leading; + line.setPosition(QPointF(0.0, height)); + height += line.height(); } + textLayout.endLayout(); + + actualSize = textLayout.boundingRect().size(); + textLayout.draw(p, topLeftPosition); } else { QTextDocument document; document.setDefaultFont(font); document.setDocumentMargin(0.0); + if (textWidth >= 0.0) + document.setTextWidth(textWidth); document.setHtml(text); - QPointF adjustedPos = pos - QPointF(0, QFontMetricsF(font).ascent()); - QRectF rect = maximumSize.isValid() ? QRectF(adjustedPos, maximumSize) : QRectF(); document.adjustSize(); p->save(); - p->translate(adjustedPos); - document.drawContents(p, rect); + p->translate(topLeftPosition); + document.drawContents(p); p->restore(); + actualSize = document.size(); - needsClipRect = maximumSize.isValid() - && (actualSize.width() > maximumSize.width() - || actualSize.height() > maximumSize.height()); } } diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h index 00d42e0..c37194c 100644 --- a/src/gui/text/qstatictext.h +++ b/src/gui/text/qstatictext.h @@ -66,7 +66,7 @@ public: }; QStaticText(); - QStaticText(const QString &text, const QSizeF &maximumSize = QSizeF()); + QStaticText(const QString &text); QStaticText(const QStaticText &other); ~QStaticText(); @@ -76,8 +76,8 @@ public: void setTextFormat(Qt::TextFormat textFormat); Qt::TextFormat textFormat() const; - void setMaximumSize(const QSizeF &maximumSize); - QSizeF maximumSize() const; + void setTextWidth(qreal textWidth); + qreal textWidth() const; QSizeF size() const; diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index e758244..3bbc61f 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -122,7 +122,7 @@ public: QString text; // 4 bytes per text QFont font; // 8 bytes per text - QSizeF maximumSize; // 16 bytes per text + qreal textWidth; // 8 bytes per text QSizeF actualSize; // 16 bytes per text QPointF position; // 16 bytes per text @@ -132,11 +132,10 @@ public: glyph_t *glyphPool; // 4 bytes per text QFixedPoint *positionPool; // 4 bytes per text - unsigned char needsClipRect : 1; // 1 byte per text - unsigned char useBackendOptimizations : 1; + unsigned char useBackendOptimizations : 1; // 1 byte per text unsigned char textFormat : 2; // ================ - // 171 bytes per text + // 163 bytes per text static QStaticTextPrivate *get(const QStaticText *q); }; diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index b59c10b..4e2d906 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -50,7 +50,7 @@ #include #include -// #define DEBUG_SAVE_IMAGE +#define DEBUG_SAVE_IMAGE class tst_QStaticText: public QObject { @@ -69,7 +69,7 @@ private slots: void drawToRect_data(); void drawToRect(); void setFont(); - void setMaximumSize(); + void setTextWidth(); void prepareToCorrectData(); void prepareToWrongData(); @@ -127,7 +127,7 @@ void tst_QStaticText::drawToPoint() QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); text.setTextFormat(Qt::PlainText); text.setPerformanceHint(performanceHint); - p.drawStaticText(QPointF(11, 12), text); + p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text); } QCOMPARE(imageDrawStaticText, imageDrawText); @@ -156,12 +156,19 @@ void tst_QStaticText::drawToRect() imageDrawStaticText.fill(Qt::white); { QPainter p(&imageDrawStaticText); - QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", QSizeF(10, 500)); + QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + text.setTextWidth(10), + p.setClipRect(QRectF(11, 12, 10, 500)); text.setPerformanceHint(performanceHint); text.setTextFormat(Qt::PlainText); p.drawStaticText(QPointF(11, 12), text); } +#if defined(DEBUG_SAVE_IMAGE) + imageDrawText.save("drawToRect_imageDrawText.png"); + imageDrawStaticText.save("drawToRect_imageDrawStaticText.png"); +#endif + QCOMPARE(imageDrawStaticText, imageDrawText); } @@ -187,7 +194,7 @@ void tst_QStaticText::prepareToCorrectData() QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); text.prepare(transform, p.font()); text.setTextFormat(Qt::PlainText); - p.drawStaticText(QPointF(11, 12), text); + p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text); } if (!supportsTransformations()) @@ -215,7 +222,7 @@ void tst_QStaticText::prepareToWrongData() QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); text.prepare(transform, p.font()); text.setTextFormat(Qt::PlainText); - p.drawStaticText(QPointF(11, 12), text); + p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text); } QCOMPARE(imageDrawStaticText, imageDrawText); @@ -232,10 +239,10 @@ void tst_QStaticText::setFont() imageDrawText.fill(Qt::white); { QPainter p(&imageDrawText); - p.drawText(0, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(0, 0 + QFontMetrics(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); p.setFont(font); - p.drawText(11, 120, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(11, 120 + QFontMetrics(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); } QPixmap imageDrawStaticText(1000, 1000); @@ -253,10 +260,15 @@ void tst_QStaticText::setFont() p.drawStaticText(11, 120, text); } +#if defined(DEBUG_SAVE_IMAGE) + imageDrawText.save("setFont_imageDrawText.png"); + imageDrawStaticText.save("setFont_imageDrawStaticText.png"); +#endif + QCOMPARE(imageDrawStaticText, imageDrawText); } -void tst_QStaticText::setMaximumSize() +void tst_QStaticText::setTextWidth() { QPixmap imageDrawText(1000, 1000); imageDrawText.fill(Qt::white); @@ -270,7 +282,8 @@ void tst_QStaticText::setMaximumSize() { QPainter p(&imageDrawStaticText); QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); - text.setMaximumSize(QSizeF(10, 500)); + text.setTextWidth(10); + p.setClipRect(QRectF(11, 12, 10, 500)); p.drawStaticText(QPointF(11, 12), text); } @@ -297,7 +310,7 @@ void tst_QStaticText::translatedPainter() QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); text.setTextFormat(Qt::PlainText); - p.drawStaticText(QPointF(11, 12), text); + p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text); } QCOMPARE(imageDrawStaticText, imageDrawText); @@ -329,7 +342,7 @@ void tst_QStaticText::rotatedPainter() { QPainter p(&imageDrawText); p.rotate(30.0); - p.drawText(0, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); } QPixmap imageDrawStaticText(1000, 1000); @@ -373,7 +386,7 @@ void tst_QStaticText::scaledPainter() QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); text.setTextFormat(Qt::PlainText); - p.drawStaticText(QPointF(11, 12), text); + p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text); } if (!supportsTransformations()) @@ -404,7 +417,7 @@ void tst_QStaticText::projectedPainter() QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); text.setTextFormat(Qt::PlainText); - p.drawStaticText(QPointF(11, 12), text); + p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text); } QCOMPARE(imageDrawStaticText, imageDrawText); @@ -434,7 +447,7 @@ void tst_QStaticText::rotatedScaledAndTranslatedPainter() QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit."); text.setTextFormat(Qt::PlainText); - p.drawStaticText(QPointF(11, 12), text); + p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text); } #if defined(DEBUG_SAVE_IMAGE) @@ -456,10 +469,10 @@ void tst_QStaticText::transformationChanged() p.rotate(33.0); p.scale(0.5, 0.7); - p.drawText(0, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); p.scale(7.0, 5.0); - p.drawText(0, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); } QPixmap imageDrawStaticText(1000, 1000); @@ -566,7 +579,7 @@ void tst_QStaticText::setPenRichText() QStaticText staticText; staticText.setText("XXXXX"); staticText.setTextFormat(Qt::RichText); - p.drawStaticText(0, fm.ascent(), staticText); + p.drawStaticText(0, 0, staticText); } QImage img = image.toImage(); @@ -595,7 +608,7 @@ void tst_QStaticText::richTextOverridesPen() QStaticText staticText; staticText.setText("XXXXX"); staticText.setTextFormat(Qt::RichText); - p.drawStaticText(0, fm.ascent(), staticText); + p.drawStaticText(0, 0, staticText); } QImage img = image.toImage(); -- cgit v0.12 From 732fbde53bd39d9b99e65e4aad7b028df246fce2 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 26 Mar 2010 14:00:46 +0100 Subject: Make QStaticText layout lazy To avoid the unnecessary overhead of doing the text layout every time a part of the QStaticText object is changed, we mark it as invalid instead and do the layout when we have to. This means an overhead on the first paint event for most users. The overhead can be avoided by using the QStaticText::prepare() function and will probably not be noticable anyway, since it's a one-time thing. Task-number: QTBUG-9030 Reviewed-by: Gunnar --- src/gui/painting/qpainter.cpp | 2 +- src/gui/text/qstatictext.cpp | 64 +++++++++++++++++------------- src/gui/text/qstatictext.h | 2 +- src/gui/text/qstatictext_p.h | 6 +++ tests/auto/qstatictext/tst_qstatictext.cpp | 2 +- 5 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 7856881..93f2265 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5864,7 +5864,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText // If the transform is not identical to the text transform, // we have to relayout the text (for other transformations than plain translation) - bool staticTextNeedsReinit = false; + bool staticTextNeedsReinit = staticText_d->needsRelayout; if (staticText_d->matrix != d->state->matrix) { staticText_d->matrix = d->state->matrix; staticTextNeedsReinit = true; diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 977355e..45252d8 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -99,20 +99,27 @@ QT_BEGIN_NAMESPACE point with no boundaries, and also when QPainter::drawText() is called with a bounding rectangle. - If a bounding rectangle is not required, create a QStaticText object without setting a maximum - size. The text will then occupy a single line. + If a bounding rectangle is not required, create a QStaticText object without setting a preferred + text width. The text will then occupy a single line. - If you set a maximum size on the QStaticText object, this will bound the text. The text will - be formatted so that no line exceeds the given width. When the object is painted, it will - be clipped at the given size. The position of the text is decided by the argument - passed to QPainter::drawStaticText() and can change from call to call with a minimal impact - on performance. + If you set a text width on the QStaticText object, this will bound the text. The text will + be formatted so that no line exceeds the given width. The text width set for QStaticText will + not automatically be used for clipping. To achieve clipping in addition to line breaks, use + QPainter::setClipRect(). The position of the text is decided by the argument passed to + QPainter::drawStaticText() and can change from call to call with a minimal impact on + performance. QStaticText will attempt to guess the format of the input text using Qt::mightBeRichText(). To force QStaticText to display its contents as either plain text or rich text, use the function QStaticText::setTextFormat() and pass in, respectively, Qt::PlainText and Qt::RichText. + If it's the first time the static text is drawn, or if the static text, or the painter's font + or matrix have been altered since the last time it was drawn, the text's layout has to be + recalculated. This will impose an overhead on the QPainter::drawStaticText() call where the + relayout occurs. To avoid this overhead in the paint event, you can call prepare() ahead of + time to ensure that the layout is calculated. + \sa QPainter::drawText(), QPainter::drawStaticText(), QTextLayout, QTextDocument */ @@ -147,7 +154,7 @@ QStaticText::QStaticText(const QString &text) : data(new QStaticTextPrivate) { data->text = text; - data->init(); + data->invalidate(); } /*! @@ -176,17 +183,17 @@ void QStaticText::detach() } /*! - Prepares the QStaticText object for being painted with the given \a matrix and the given - \a font to avoid overhead when the actual drawStaticText() call is made. + Prepares the QStaticText object for being painted with the given \a matrix and the given \a font + to avoid overhead when the actual drawStaticText() call is made. - When drawStaticText() is called, the layout of the QStaticText will be recalculated if the - painter's font or matrix is different from the one used for the currently cached layout. By - default, QStaticText will use a default constructed QFont and an identity matrix to create - its layout. + When drawStaticText() is called, the layout of the QStaticText will be recalculated if any part + of the QStaticText object has changed since the last time it was drawn. It will also be + recalculated if the painter's font or matrix are not the same as when the QStaticText was last + drawn. - To avoid the overhead of creating the layout the first time you draw the QStaticText with - a painter whose matrix or font are different from the defaults, you can use the prepare() - function and pass in the matrix and font you expect to use when drawing the text. + To avoid the overhead of creating the layout the first time you draw the QStaticText after + making changes, you can use the prepare() function and pass in the \a matrix and \a font you + expect to use when drawing the text. \sa QPainter::setFont(), QPainter::setMatrix() */ @@ -231,7 +238,7 @@ bool QStaticText::operator!=(const QStaticText &other) const /*! Sets the text of the QStaticText to \a text. - \note This function will cause the layout of the text to be recalculated. + \note This function will cause the layout of the text to require recalculation. \sa text() */ @@ -239,7 +246,7 @@ void QStaticText::setText(const QString &text) { detach(); data->text = text; - data->init(); + data->invalidate(); } /*! @@ -249,7 +256,7 @@ void QStaticText::setText(const QString &text) displayed as is, whereas it will be interpreted as HTML if the format is Qt::RichText. HTML tags that alter the font of the text, its color, or its layout are supported by QStaticText. - \note This function will cause the layout of the text to be recalculated. + \note This function will cause the layout of the text to require recalculation. \sa textFormat(), setText(), text() */ @@ -257,7 +264,7 @@ void QStaticText::setTextFormat(Qt::TextFormat textFormat) { detach(); data->textFormat = textFormat; - data->init(); + data->invalidate(); } /*! @@ -288,7 +295,7 @@ QString QStaticText::text() const The default is QStaticText::ModerateCaching. - \note This function will cause the layout of the text to be recalculated. + \note This function will cause the layout of the text to require recalculation. \sa performanceHint() */ @@ -300,7 +307,7 @@ void QStaticText::setPerformanceHint(PerformanceHint performanceHint) } detach(); data->useBackendOptimizations = (performanceHint == AggressiveCaching); - data->init(); + data->invalidate(); } /*! @@ -322,7 +329,7 @@ QStaticText::PerformanceHint QStaticText::performanceHint() const Use size() to get the actual size of the text. - \note This function will cause the layout of the text to be recalculated. + \note This function will cause the layout of the text to require recalculation. \sa textWidth(), size() */ @@ -330,7 +337,7 @@ void QStaticText::setTextWidth(qreal textWidth) { detach(); data->textWidth = textWidth; - data->init(); + data->invalidate(); } /*! @@ -350,18 +357,20 @@ qreal QStaticText::textWidth() const */ QSizeF QStaticText::size() const { + if (data->needsRelayout) + data->init(); return data->actualSize; } QStaticTextPrivate::QStaticTextPrivate() : items(0), itemCount(0), glyphPool(0), positionPool(0), textWidth(-1.0), - useBackendOptimizations(false), textFormat(Qt::AutoText) + needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText) { } QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other) : text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix), - items(0), itemCount(0), glyphPool(0), positionPool(0), + items(0), itemCount(0), glyphPool(0), positionPool(0), needsRelayout(true), useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat) { } @@ -634,6 +643,7 @@ void QStaticTextPrivate::init() paintText(QPointF(0, 0), &painter); } + needsRelayout = false; } QT_END_NAMESPACE diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h index c37194c..f3bef93 100644 --- a/src/gui/text/qstatictext.h +++ b/src/gui/text/qstatictext.h @@ -81,7 +81,7 @@ public: QSizeF size() const; - void prepare(const QTransform &matrix, const QFont &font); + void prepare(const QTransform &matrix = QTransform(), const QFont &font = QFont()); void setPerformanceHint(PerformanceHint performanceHint); PerformanceHint performanceHint() const; diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index 3bbc61f..f017ed1 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -118,6 +118,11 @@ public: void init(); void paintText(const QPointF &pos, QPainter *p); + void invalidate() + { + needsRelayout = true; + } + QAtomicInt ref; // 4 bytes per text QString text; // 4 bytes per text @@ -132,6 +137,7 @@ public: glyph_t *glyphPool; // 4 bytes per text QFixedPoint *positionPool; // 4 bytes per text + unsigned char needsRelayout : 1; unsigned char useBackendOptimizations : 1; // 1 byte per text unsigned char textFormat : 2; // ================ diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index 4e2d906..e7a22b3 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -50,7 +50,7 @@ #include #include -#define DEBUG_SAVE_IMAGE +// #define DEBUG_SAVE_IMAGE class tst_QStaticText: public QObject { -- cgit v0.12 From 3bdff93c991bfabcaa729a89a2b171c562633ced Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 26 Mar 2010 16:56:44 +0100 Subject: Implement proper QStaticText support in QPaintBuffer Use qt_draw_glyphs() to implement a QPaintBuffer::drawStaticText() which will actually replay via drawStaticTextItem() on engines that support it. Task-number: QTBUG-9064 Reviewed-by: Gunnar --- src/gui/painting/qpaintbuffer.cpp | 33 +++++++++++++++++++-------------- src/gui/painting/qpainter.cpp | 10 ++++++++++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index ca2077f..e1156dc 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -557,11 +557,7 @@ QString QPaintBuffer::commandDescription(int command) const debug << "Cmd_Translate:" << delta; break; } case QPaintBufferPrivate::Cmd_DrawStaticText: { - QPointF delta(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); - QVariantList variants(d_ptr->variants.at(cmd.offset).value()); - - QStaticText text(variants.at(0).value()); - debug << "Cmd_DrawStaticText:" << text.text(); + debug << "Cmd_DrawStaticText"; break; } } @@ -1272,13 +1268,14 @@ void QPaintBufferEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, con void QPaintBufferEngine::drawStaticTextItem(QStaticTextItem *staticTextItem) { - QString text = QString(staticTextItem->chars, staticTextItem->numChars); + QVariantList variants; - QStaticText staticText(text); - staticText.prepare(state()->matrix, staticTextItem->font); + variants << QVariant(staticTextItem->font); + for (int i=0; inumGlyphs; ++i) { + variants.append(staticTextItem->glyphs[i]); + variants.append(staticTextItem->glyphPositions[i].toPointF()); + } - QVariantList variants; - variants << QVariant(staticTextItem->font) << QVariant::fromValue(staticText); buffer->addCommand(QPaintBufferPrivate::Cmd_DrawStaticText, QVariant(variants)); } @@ -1761,11 +1758,19 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd) QVariantList variants(d->variants.at(cmd.offset).value()); - QFont font(variants.at(0).value()); - QStaticText text(variants.at(0).value()); - + QFont font = variants.at(0).value(); + + QVector glyphs; + QVector positions; + + for (int i=0; i<(variants.size() - 1) / 2; ++i) { + glyphs.append(variants.at(i*2 + 1).toUInt()); + positions.append(variants.at(i*2 + 2).toPointF()); + } + painter->setFont(font); - painter->drawStaticText(QPointF(0, 0), text); + + qt_draw_glyphs(painter, glyphs.constData(), positions.constData(), glyphs.size()); break; } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 93f2265..7b5fcc2 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5720,6 +5720,16 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit QFontEngine *fontEngine = state->font.d->engineForScript(QUnicodeTables::Common); + while (fontEngine->type() == QFontEngine::Multi) { + // Pick engine based on first glyph in array if we are using a multi engine. + // (all glyphs must be for same font) + int engineIdx = 0; + if (glyphCount > 0) + engineIdx = glyphArray[0] >> 24; + + fontEngine = static_cast(fontEngine)->engine(engineIdx); + } + QVarLengthArray positions; for (int i=0; i Date: Mon, 29 Mar 2010 14:22:43 +0200 Subject: Support EtchDisabledText with spin box on Windows style Reviewed-by: ogoffart Task-number: QTBUG-7525 --- src/gui/styles/qwindowsstyle.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 60c06ca..1653baa 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -3105,7 +3105,9 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On), ©.palette.brush(QPalette::Button)); copy.rect.adjust(4, 1, -5, -1); - if (!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) ) { + if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) + && proxy()->styleHint(SH_EtchDisabledText, opt, widget) ) + { QStyleOptionSpinBox lightCopy = copy; lightCopy.rect.adjust(1, 1, 1, 1); lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light()); @@ -3138,7 +3140,9 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On), ©.palette.brush(QPalette::Button)); copy.rect.adjust(4, 0, -5, -1); - if (!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) ) { + if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) + && proxy()->styleHint(SH_EtchDisabledText, opt, widget) ) + { QStyleOptionSpinBox lightCopy = copy; lightCopy.rect.adjust(1, 1, 1, 1); lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light()); -- cgit v0.12 From e1a1c2336c7344736f072bc29573662f6cb85f3e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 29 Mar 2010 14:46:05 +0200 Subject: scan some more file types by default - java & jui - js, qs & qml Task-number: QTBUG-9429 --- tools/linguist/lupdate/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 0003baa..e252780 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -409,7 +409,7 @@ static void processProjects( int main(int argc, char **argv) { QCoreApplication app(argc, argv); - m_defaultExtensions = QLatin1String("ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx"); + m_defaultExtensions = QLatin1String("java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml"); QStringList args = app.arguments(); QStringList tsFileNames; -- cgit v0.12 From 5daac41683e679d869c586e8bdf9f184fd1e3557 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 29 Mar 2010 14:46:16 +0200 Subject: jui files are no c++ ... --- tools/linguist/lupdate/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index e252780..6c9157a 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -634,6 +634,7 @@ int main(int argc, char **argv) sourceFiles << fn; if (!fn.endsWith(QLatin1String(".java")) + && !fn.endsWith(QLatin1String(".jui")) && !fn.endsWith(QLatin1String(".ui")) && !fn.endsWith(QLatin1String(".js")) && !fn.endsWith(QLatin1String(".qs")) -- cgit v0.12 From 97b2272e91e25418f63328c681cef54bdc1e43ff Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Mar 2010 14:06:12 +0200 Subject: Update PLATFORM(SPARC64) to CPU(SPARC64) --- src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h index 5b655e8..85c8743 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h @@ -239,7 +239,7 @@ inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Bar inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); } inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); } -#elif COMPILER(GCC) && !PLATFORM(SPARC64) && !defined(__SYMBIAN32__) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc +#elif COMPILER(GCC) && !CPU(SPARC64) && !defined(__SYMBIAN32__) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; } -- cgit v0.12 From cc5ae1831e54702f7bb8477ab3b14ab9832c064c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Mar 2010 14:25:16 +0200 Subject: Ensure that we return QPair in all cases. Fixes a compilation failure on AIX. Reviewed-By: Marius Storm-Olsen --- src/corelib/tools/qelapsedtimer_unix.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp index 85d7fa8..1a7bc71 100644 --- a/src/corelib/tools/qelapsedtimer_unix.cpp +++ b/src/corelib/tools/qelapsedtimer_unix.cpp @@ -97,19 +97,19 @@ static inline QPair do_gettime() #if (_POSIX_MONOTONIC_CLOCK-0 > 0) timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - return qMakePair(ts.tv_sec, ts.tv_nsec); + return qMakePair(ts.tv_sec, ts.tv_nsec); #else # if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) if (QElapsedTimer::isMonotonic()) { timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - return qMakePair(ts.tv_sec, ts.tv_nsec); + return qMakePair(ts.tv_sec, ts.tv_nsec); } # endif // use gettimeofday timeval tv; ::gettimeofday(&tv, 0); - return qMakePair(tv.tv_sec, tv.tv_usec); + return qMakePair(tv.tv_sec, tv.tv_usec); #endif } -- cgit v0.12 From 1a6d4970793f0696bf54a85346a12e83b6d03013 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Mar 2010 14:29:09 +0200 Subject: Fix compilation with Sun CC: "node.cpp", line 1337: Error: There is extra text on this line. Reviewed-by: Trust Me --- tools/qdoc3/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index bd37443..ef75f6e 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -1334,7 +1334,7 @@ QString QmlClassNode::fileBase() const void QmlClassNode::addInheritedBy(const QString& base, Node* sub) { inheritedBy.insert(base,sub); -#ifdef DEBUG_MULTIPLE-QDOCCONF_FILES +#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES qDebug() << "QmlClassNode::addInheritedBy(): insert" << base << sub->name() << inheritedBy.size(); #endif } -- cgit v0.12 From ec0fe5bb327f2533dcbb35855ca0d2a7f9a85581 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Mar 2010 15:10:14 +0200 Subject: Fix compilation on HP-UXi: _SC_MONOTONIC_CLOCK isn't defined Reviewed-by: Trust Me --- src/corelib/tools/qelapsedtimer_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp index 1a7bc71..2c4ea58 100644 --- a/src/corelib/tools/qelapsedtimer_unix.cpp +++ b/src/corelib/tools/qelapsedtimer_unix.cpp @@ -74,7 +74,7 @@ bool QElapsedTimer::isMonotonic() static int returnValue = 0; if (returnValue == 0) { -# if (_POSIX_MONOTONIC_CLOCK-0 < 0) +# if (_POSIX_MONOTONIC_CLOCK-0 < 0) || !defined(_SC_MONOTONIC_CLOCK) returnValue = -1; # elif (_POSIX_MONOTONIC_CLOCK == 0) // detect if the system support monotonic timers -- cgit v0.12 From 43e67759246cbdbe5ff337877d14b45e4f33e040 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 29 Mar 2010 15:36:43 +0200 Subject: Compile with MSVC 2005 and 2003 when no platform SDK is used Reviewed-by: Eskil --- src/gui/text/qfontengine_win.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index a133b48..d126a2e 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -39,6 +39,11 @@ ** ****************************************************************************/ +#if _WIN32_WINNT < 0x0500 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 +#endif + #include "qfontengine_p.h" #include "qtextengine_p.h" #include -- cgit v0.12 From 32a182c25104e6e49fc965a168957acff52a2b53 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Mon, 29 Mar 2010 14:44:00 +0100 Subject: Fixed bitfield-related crash on Symbian WINSCW When running on WINSCW, the nativePaintMode variable was becoming corrupted. The point at which this corruption occurs is unclear, but it can be reproduced as follows: 1. Launch qmediaplayer 2. In the Phonon::MMF::DsaVideoOutput constructor, the nativePaintMode flag is set to QWExtra::ZeroFill 3. Open a video clip 4. During start of playback, QSymbianControl::Draw is called on the native control corresponding to the DsaVideoOutput object. This checks the value of nativePaintMode; it does not match any of the valid NativePaintMode values, so an assertion fails. This crash does not occur on target, suggesting that the cause may be an error in the WINSCW compiler. Although the C++ standard allows bitfields to have boolean, integral or enumeration type, the latter is not permitted by C99. Neither increasing the number of bits allocated to nativePaintMode, nor changing it position in the list of platform-specific bitfields has any effect. After making nativePaintMode into a normal field rather than a bitfield, the crash no longer happens. Note that, since bitfields must be kept together, nativePaintMode is moved to the end of the structure. --- src/gui/kernel/qwidget_p.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 1bbc057..555647c 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -233,6 +233,15 @@ struct QWExtra { uint activated : 1; // RWindowBase::Activated has been called /** + * If this bit is set, each native widget receives the signals from the + * Symbian control immediately before and immediately after draw ops are + * sent to the window server for this control: + * void beginNativePaintEvent(const QRect &paintRect); + * void endNativePaintEvent(const QRect &paintRect); + */ + uint receiveNativePaintEvents : 1; + + /** * Defines the behaviour of QSymbianControl::Draw. */ enum NativePaintMode { @@ -257,16 +266,7 @@ struct QWExtra { Default = Blit }; - NativePaintMode nativePaintMode : 2; - - /** - * If this bit is set, each native widget receives the signals from the - * Symbian control immediately before and immediately after draw ops are - * sent to the window server for this control: - * void beginNativePaintEvent(const QRect &paintRect); - * void endNativePaintEvent(const QRect &paintRect); - */ - uint receiveNativePaintEvents : 1; + NativePaintMode nativePaintMode; #endif }; -- cgit v0.12 From 38af39aceb419e4b2eb248761fddaec92184c0f7 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 29 Mar 2010 15:55:13 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( e9151b11e974f0aa47fd40c225f88f35ced91496 ) Changes in WebKit/qt since the last update: * r56546 - https://bugs.webkit.org/show_bug.cgi?id=35112 -- [Qt] Windowed netscape plugins don't work with QGraphicsWebView on Symbian --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 19 +++++++++++++++++ .../plugins/symbian/PluginContainerSymbian.cpp | 8 ++++---- .../plugins/symbian/PluginContainerSymbian.h | 7 +++++-- .../WebCore/plugins/symbian/PluginViewSymbian.cpp | 24 +++++++++++++++------- 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 5bc2492..a8889b3 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - c39615d8e78f083b23f34ac24cf7d3a7ce765122 + e9151b11e974f0aa47fd40c225f88f35ced91496 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 76374f3..2bd506b 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,22 @@ +2010-03-25 yael aharon + + Reviewed by Laszlo Gombos. + + [Qt] Windowed netscape plugins don't work with QGraphicsWebView on Symbian + https://bugs.webkit.org/show_bug.cgi?id=35112 + + Add a proxy widget when loading a QWidget based plugin in a QGraphicsWebView. + + * plugins/symbian/PluginContainerSymbian.cpp: + (PluginContainerSymbian::PluginContainerSymbian): + (PluginContainerSymbian::focusInEvent): + * plugins/symbian/PluginContainerSymbian.h: + (WebCore::PluginContainerSymbian::proxy): + * plugins/symbian/PluginViewSymbian.cpp: + (WebCore::PluginView::updatePluginWidget): + (WebCore::PluginView::platformStart): + (WebCore::PluginView::platformDestroy): + 2010-03-29 Laszlo Gombos Reviewed for the Qt 4.6 branch by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.cpp b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.cpp index aece0e4..b839870 100644 --- a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.cpp @@ -32,12 +32,12 @@ using namespace WebCore; -PluginContainerSymbian::PluginContainerSymbian(PluginView* view, QWidget* parent) - : m_parent(parent) +PluginContainerSymbian::PluginContainerSymbian(PluginView* view, QWidget* parent, QGraphicsProxyWidget* proxy) + : QWidget(parent) , m_pluginView(view) + , m_proxy(proxy) , m_hasPendingGeometryChange(false) { - setParent(m_parent); } PluginContainerSymbian::~PluginContainerSymbian() @@ -62,7 +62,7 @@ void PluginContainerSymbian::adjustGeometry() } } -void PluginContainerSymbian::focusInEvent(QFocusEvent* event) +void PluginContainerSymbian::focusInEvent(QFocusEvent*) { if (Page* page = m_pluginView->parentFrame()->page()) page->focusController()->setActive(true); diff --git a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.h b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.h index fce4a71..fead872 100644 --- a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.h +++ b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginContainerSymbian.h @@ -22,6 +22,8 @@ #include +class QGraphicsProxyWidget; + namespace WebCore { class PluginView; @@ -29,18 +31,19 @@ namespace WebCore { class PluginContainerSymbian : public QWidget { Q_OBJECT public: - PluginContainerSymbian(PluginView*, QWidget* parent); + PluginContainerSymbian(PluginView*, QWidget* parent, QGraphicsProxyWidget* proxy = 0); ~PluginContainerSymbian(); void requestGeometry(const QRect&, const QRegion& clip = QRegion()); void adjustGeometry(); + QGraphicsProxyWidget* proxy() { return m_proxy; } protected: virtual void focusInEvent(QFocusEvent*); virtual void focusOutEvent(QFocusEvent*); private: PluginView* m_pluginView; - QWidget* m_parent; + QGraphicsProxyWidget* m_proxy; QRect m_windowRect; QRegion m_clipRegion; bool m_hasPendingGeometryChange; diff --git a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp index cf69723..86f5f6c 100644 --- a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp @@ -52,6 +52,8 @@ #include "runtime.h" #include "runtime_root.h" #include "QWebPageClient.h" +#include "qgraphicswebview.h" +#include #include #include #include @@ -84,6 +86,7 @@ void PluginView::updatePluginWidget() IntRect oldClipRect = m_clipRect; m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size()); + m_clipRect = windowClipRect(); m_clipRect.move(-m_windowRect.x(), -m_windowRect.y()); if (m_windowRect == oldWindowRect && m_clipRect == oldClipRect) @@ -425,12 +428,15 @@ bool PluginView::platformStart() if (m_isWindowed) { QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); - // FIXME this will not work for QGraphicsView. - // But we cannot use winId because it will create a window and on S60, - // QWidgets should not create a window. - Q_ASSERT(qobject_cast(client->pluginParent())); - setPlatformWidget(new PluginContainerSymbian(this, - qobject_cast(client->pluginParent()))); + QGraphicsProxyWidget* proxy = 0; + if (QGraphicsWebView *webView = qobject_cast(client->pluginParent())) + proxy = new QGraphicsProxyWidget(webView); + + PluginContainerSymbian* container = new PluginContainerSymbian(this, proxy ? 0 : client->ownerWidget(), proxy); + setPlatformWidget(container); + if (proxy) + proxy->setWidget(container); + m_npWindow.type = NPWindowTypeWindow; m_npWindow.window = (void*)platformPluginWidget(); @@ -446,7 +452,11 @@ bool PluginView::platformStart() void PluginView::platformDestroy() { - delete platformPluginWidget(); + QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); + if (QGraphicsWebView *webView = qobject_cast(client->pluginParent())) + delete static_cast(platformPluginWidget())->proxy(); + else + delete platformPluginWidget(); } void PluginView::halt() -- cgit v0.12 From b3eac3f43b087ee7939a607cd8a6e5ed398f6716 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 29 Mar 2010 16:22:52 +0200 Subject: Fix QComboBox ignoring foreground role in some styles Basically all styles using SH_Combobox_Popup would not previously respect the foreground role set. We need to set it for multiple color roles since styles sometimes interpret them differently. Reviewed-by: ogoffart Task-number: QTBUG-8796 --- src/gui/widgets/qcombobox.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index c16f18a..b1a27f2 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -108,7 +108,15 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt const QModelIndex &index) const { QStyleOptionMenuItem menuOption; - menuOption.palette = option.palette.resolve(QApplication::palette("QMenu")); + + QPalette resolvedpalette = option.palette.resolve(QApplication::palette("QMenu")); + QVariant value = index.data(Qt::ForegroundRole); + if (qVariantCanConvert(value)) { + resolvedpalette.setBrush(QPalette::WindowText, qvariant_cast(value)); + resolvedpalette.setBrush(QPalette::ButtonText, qvariant_cast(value)); + resolvedpalette.setBrush(QPalette::Text, qvariant_cast(value)); + } + menuOption.palette = resolvedpalette; menuOption.state = QStyle::State_None; if (mCombo->window()->isActiveWindow()) menuOption.state = QStyle::State_Active; -- cgit v0.12 From 0c5524e73848b95276f13c384d2c711188936deb Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Mon, 29 Mar 2010 14:55:24 +0100 Subject: Fixed crash in Phonon MMF backend during application shutdown During application shutdown, DsaVideoPlayer::handleVideoWindowChanged is called. At this point, the application's main window has been closed and therefore QApplication::activeWindow() returns 0. This leads to a crash. This patch ensures that a null return value from QApplication::activeWindow(), and the resulting zero value of DsaVideoPlayer::m_window, are handled gracefully. Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/videoplayer_dsa.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp index 21cdb16..732d2d9 100644 --- a/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp +++ b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp @@ -162,7 +162,10 @@ void MMF::DsaVideoPlayer::prepareCompleted() void MMF::DsaVideoPlayer::handleVideoWindowChanged() { if (!m_window) { - m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); + if (QWidget *window = QApplication::activeWindow()) + m_window = window->effectiveWinId()->DrawableWindow(); + else + m_window = 0; m_videoScreenRect = TRect(); } @@ -213,6 +216,9 @@ void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters) TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal); TRACE_ENTRY_0(); + if (!m_window) + return; + #ifndef QT_NO_DEBUG getDsaRegion(m_wsSession, *m_window); #endif -- cgit v0.12 From 8bd8a376cde068d0682142a6e25f25ed5931e2ee Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 29 Mar 2010 17:51:46 +0200 Subject: Don't detect EGLImage presence by testing function pointers Might fix the Symbian build failures... who knows with Symbian. Reviewed-By: TrustMe --- src/openvg/qpixmapdata_vg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 7550446..32fabb5 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -487,7 +487,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); - if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { + if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) { cleanup(); driver.Close(); return; @@ -606,7 +606,7 @@ void* QVGPixmapData::toNativeType(NativeType type) pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); - if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { + if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) { driver.Close(); return 0; } -- cgit v0.12 From 2be0e2ef4ec6702aaaebf7096fd527e2e161334a Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 29 Mar 2010 18:12:15 +0200 Subject: Add some #warnings to debug Symbian EGL build failure This should probably be reverted before we release. Reviewed-By: TrustMe --- src/gui/egl/qegl_p.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index c659796..53abe4a 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -110,6 +110,30 @@ QT_BEGIN_NAMESPACE #define EGLAPIENTRY #endif +// Try to get some info to debug the symbian build failues: +#ifdef Q_OS_SYMBIAN + +#ifdef EGL_KHR_image +#warning "EGL_KHR_image is defined" +#else +#warning "EGL_KHR_image is NOT defined" +#endif + +#ifdef EGL_KHR_image_base +#warning "EGL_KHR_image_base is defined" +#else +#warning "EGL_KHR_image_base is NOT defined" +#endif + +#ifdef EGL_EGLEXT_PROTOTYPES +#warning "EGL_EGLEXT_PROTOTYPES is defined" +#else +#warning "EGL_EGLEXT_PROTOTYPES NOT not defined" +#endif + +#endif + + #if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) typedef void *EGLImageKHR; -- cgit v0.12 From ffd4c014747f6842b9103d67204b5b54626bf876 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 29 Mar 2010 18:47:50 +0200 Subject: Do not override alternate background color in Plastique This palette tweak is no longer needed now that we set alternate row color on application startup. It also breaks on systems such as GNOME and KDE where you can configure this color. Reviewed-by: ogoffart Task-number: QTBUG-6516 --- src/gui/styles/qplastiquestyle.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 4ae9f79..fbb5e4d 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -5846,7 +5846,6 @@ void QPlastiqueStyle::polish(QApplication *app) void QPlastiqueStyle::polish(QPalette &pal) { QWindowsStyle::polish(pal); - pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110)); #ifdef Q_WS_MAC pal.setBrush(QPalette::Shadow, Qt::black); #endif -- cgit v0.12 From 9e3304246acf5b58a2ce86eed082784da818a8f0 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 29 Mar 2010 18:49:31 +0200 Subject: Work-around Symbian 10.1's broken egl.h In Symbian 10.1, egl.h itself includes eglext.h. This leads to EGL_KHR_image & EGL_KHR_image_base being defined, but not the actual function prototypes for eglCreateImageKHR/eglDestroyImageKHR. But, because the extension defines were set, Qt assumed (wrongly) that the EGL library would define eglCreateImageKHR. This left these functions undefined. The work-around is to check the define EGL_EGLEXT_PROTOTYPES and still define the function pointers if it isn't set. Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 2 +- src/gui/egl/qegl_p.h | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index f36904d..498245c 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -528,7 +528,7 @@ QEglProperties QEglContext::configProperties() const return QEglProperties(config()); } -#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) +#if (defined(EGL_KHR_image) || defined(EGL_KHR_image_base)) && !defined(EGL_EGLEXT_PROTOTYPES) _eglCreateImageKHR eglCreateImageKHR = 0; _eglDestroyImageKHR eglDestroyImageKHR = 0; #endif diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index 53abe4a..540cd3d 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -134,20 +134,25 @@ QT_BEGIN_NAMESPACE #endif +// Declare/define the bits of EGL_KHR_image_base we need: #if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) - typedef void *EGLImageKHR; #define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) #define EGL_IMAGE_PRESERVED_KHR 0x30D2 +#endif +// It is possible that something has included eglext.h (like Symbian 10.1's broken egl.h), in +// which case, EGL_KHR_image/EGL_KHR_image_base will be defined. They may have also defined +// the actual function prototypes, but generally EGL_EGLEXT_PROTOTYPES will be defined in that +// case and we shouldn't re-define them here. +#if (defined(EGL_KHR_image) || defined(EGL_KHR_image_base)) && !defined(EGL_EGLEXT_PROTOTYPES) typedef EGLImageKHR (EGLAPIENTRY *_eglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); typedef EGLBoolean (EGLAPIENTRY *_eglDestroyImageKHR)(EGLDisplay, EGLImageKHR); // Defined in qegl.cpp: extern Q_GUI_EXPORT _eglCreateImageKHR eglCreateImageKHR; extern Q_GUI_EXPORT _eglDestroyImageKHR eglDestroyImageKHR; - -#endif // !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base) +#endif // (defined(EGL_KHR_image) || defined(EGL_KHR_image_base)) && !defined(EGL_EGLEXT_PROTOTYPES) #if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_pixmap) #define EGL_NATIVE_PIXMAP_KHR 0x30B0 -- cgit v0.12 From 15ecc59edab06a21fb7d724af13ca544decbc0eb Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 29 Mar 2010 19:01:26 +0200 Subject: Adding QFontDatabase::removeAllApplicationFonts() It was missing and not covered by the standard autotests, so its missing was not detected for quite some time. Task-number: QTBUG-8423 Reviewed-By: Shane Kearns --- src/gui/text/qfontdatabase_s60.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 87a73df..fceb401 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -332,6 +332,11 @@ bool QFontDatabase::removeApplicationFont(int handle) return false; } +bool QFontDatabase::removeAllApplicationFonts() +{ + return false; +} + bool QFontDatabase::supportsThreadedFontRendering() { return false; -- cgit v0.12 From 3d3af93505f7b90e399aab4c8fa2bceae18fedf6 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 29 Mar 2010 19:01:48 +0200 Subject: Exporting QFontDatabase::removeAllApplicationFonts() It was missing and not covered by the standard autotests, so its missing was not detected for quite some time. Task-number: QTBUG-8423 Reviewed-By: Shane Kearns --- src/s60installs/bwins/QtGuiu.def | 1 + src/s60installs/eabi/QtGuiu.def | 1 + 2 files changed, 2 insertions(+) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 8e758d0..6a4f07b 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12601,4 +12601,5 @@ EXPORTS ?setPixelFormat@QEglProperties@@QAEXW4Format@QImage@@@Z @ 12600 NONAME ABSENT ; void QEglProperties::setPixelFormat(enum QImage::Format) ?currentContext@QEglContext@@CAPAV1@W4API@QEgl@@@Z @ 12601 NONAME ABSENT ; class QEglContext * QEglContext::currentContext(enum QEgl::API) ?errorString@QEglContext@@SA?AVQString@@H@Z @ 12602 NONAME ABSENT ; class QString QEglContext::errorString(int) + ?removeAllApplicationFonts@QFontDatabase@@SA_NXZ @12603 ; NONAME ; bool QFontDatabase::removeAllApplicationFonts() diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 373f66d..a3fc452 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -11805,4 +11805,5 @@ EXPORTS _ZN24QImagePixmapCleanupHooks34executePixmapDataModificationHooksEP11QPixmapData @ 11804 NONAME _ZN9QS60Style10timerEventEP11QTimerEvent @ 11805 NONAME _ZN9QS60Style11eventFilterEP7QObjectP6QEvent @ 11806 NONAME + _ZN13QFontDatabase25removeAllApplicationFontsEv @ 11807 NONAME -- cgit v0.12 From 3e5745ea75d73869918889cb374c3d651bed0991 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 29 Mar 2010 17:36:02 +0200 Subject: QScriptEngine: Fix reentrency involving creation and desctructions of QScriptEngines the currentIdentifierTable table, which is a static thread local variable, could be corrupted. The main change is to fix the QScriptEngine constructor not to alter the currentIdentifierTable This showed a lot of cases where APIShim guards where missings. The problem was seen with creator, related to QTBUG-9426 Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 15 +++-- src/script/api/qscriptvalue.cpp | 78 +++++++++++++++++++------- src/script/api/qscriptvalueiterator.cpp | 11 ++++ tests/auto/qscriptengine/tst_qscriptengine.cpp | 21 +++++++ 4 files changed, 101 insertions(+), 24 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index b322523..70f798e 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -875,7 +875,7 @@ QScriptEnginePrivate::QScriptEnginePrivate() return; } JSC::initializeThreading(); - + JSC::IdentifierTable *oldTable = JSC::currentIdentifierTable(); globalData = JSC::JSGlobalData::create().releaseRef(); globalData->clientData = new QScript::GlobalClientData(this); JSC::JSGlobalObject *globalObject = new (globalData)QScript::GlobalObject(); @@ -911,11 +911,12 @@ QScriptEnginePrivate::QScriptEnginePrivate() activeAgent = 0; agentLineNumber = -1; processEventsInterval = -1; + JSC::setCurrentIdentifierTable(oldTable); } QScriptEnginePrivate::~QScriptEnginePrivate() { - JSC::setCurrentIdentifierTable(globalData->identifierTable); + QScript::APIShim shim(this); //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events QHash::const_iterator it; @@ -3277,6 +3278,7 @@ bool QScriptEnginePrivate::hasDemarshalFunction(int type) const bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr) { Q_D(QScriptEngine); + QScript::APIShim shim(d); return QScriptEnginePrivate::convertValue(d->currentFrame, d->scriptValueToJSCValue(value), type, ptr); } @@ -3289,8 +3291,12 @@ bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr) if (vp) { switch (vp->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = vp->engine ? vp->engine->currentFrame : 0; - return QScriptEnginePrivate::convertValue(exec, vp->jscValue, type, ptr); + if (vp->engine) { + QScript::APIShim shim(vp->engine); + return QScriptEnginePrivate::convertValue(vp->engine->currentFrame, vp->jscValue, type, ptr); + } else { + return QScriptEnginePrivate::convertValue(0, vp->jscValue, type, ptr); + } } case QScriptValuePrivate::Number: return QScriptEnginePrivate::convertNumber(vp->numberValue, type, ptr); @@ -3341,6 +3347,7 @@ void QScriptEngine::registerCustomType(int type, MarshalFunction mf, void QScriptEngine::installTranslatorFunctions(const QScriptValue &object) { Q_D(QScriptEngine); + QScript::APIShim shim(d); JSC::ExecState* exec = d->currentFrame; JSC::JSValue jscObject = d->scriptValueToJSCValue(object); JSC::JSGlobalObject *glob = d->originalGlobalObject(); diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 4cd84a4..3aab268 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -561,6 +561,7 @@ QScriptValue QScriptValue::scope() const Q_D(const QScriptValue); if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); // ### make hidden property JSC::JSValue result = d->property("__qt_scope__", QScriptValue::ResolveLocal); return d->engine->scriptValueFromJSCValue(result); @@ -650,11 +651,12 @@ static Type type(const QScriptValue &v) return Object; } -QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference) +static QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference) { Q_ASSERT(object.isObject()); QScriptValuePrivate *pp = QScriptValuePrivate::get(object); Q_ASSERT(pp->engine != 0); + QScript::APIShim shim(pp->engine); JSC::ExecState *exec = pp->engine->currentFrame; JSC::JSValue savedException; QScriptEnginePrivate::saveException(exec, &savedException); @@ -848,6 +850,7 @@ bool QScriptValue::equals(const QScriptValue &other) const if (!eng_p) eng_p = other.d_ptr->engine; if (eng_p) { + QScript::APIShim shim(eng_p); JSC::ExecState *exec = eng_p->currentFrame; JSC::JSValue savedException; QScriptEnginePrivate::saveException(exec, &savedException); @@ -940,9 +943,12 @@ QString QScriptValue::toString() const return QString(); switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toString(exec, d->jscValue); - } + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toString(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toString(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToString(d->numberValue); case QScriptValuePrivate::String: @@ -970,8 +976,12 @@ qsreal QScriptValue::toNumber() const return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toNumber(exec, d->jscValue); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toNumber(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toNumber(0, d->jscValue); + } } case QScriptValuePrivate::Number: return d->numberValue; @@ -993,8 +1003,12 @@ bool QScriptValue::toBoolean() const return false; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toBool(exec, d->jscValue); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toBool(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToBool(d->numberValue); @@ -1025,8 +1039,12 @@ bool QScriptValue::toBool() const return false; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toBool(exec, d->jscValue); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toBool(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToBool(d->numberValue); @@ -1055,8 +1073,12 @@ qint32 QScriptValue::toInt32() const return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toInt32(exec, d->jscValue); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toInt32(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toInt32(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToInt32(d->numberValue); @@ -1085,8 +1107,12 @@ quint32 QScriptValue::toUInt32() const return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toUInt32(exec, d->jscValue); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toUInt32(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toUInt32(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToUInt32(d->numberValue); @@ -1115,8 +1141,12 @@ quint16 QScriptValue::toUInt16() const return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toUInt16(exec, d->jscValue); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toUInt16(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toUInt16(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToUInt16(d->numberValue); @@ -1145,8 +1175,12 @@ qsreal QScriptValue::toInteger() const return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toInteger(exec, d->jscValue); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toInteger(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toInteger(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToInteger(d->numberValue); @@ -1185,8 +1219,12 @@ QVariant QScriptValue::toVariant() const return QVariant(); switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - return QScriptEnginePrivate::toVariant(exec, d->jscValue); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toVariant(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toVariant(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QVariant(d->numberValue); diff --git a/src/script/api/qscriptvalueiterator.cpp b/src/script/api/qscriptvalueiterator.cpp index 7fd7093..460dddb 100644 --- a/src/script/api/qscriptvalueiterator.cpp +++ b/src/script/api/qscriptvalueiterator.cpp @@ -85,6 +85,17 @@ public: : initialized(false) {} + ~QScriptValueIteratorPrivate() + { + if (!initialized) + return; + QScriptEnginePrivate *eng_p = engine(); + if (!eng_p) + return; + QScript::APIShim shim(eng_p); + propertyNames.clear(); //destroying the identifiers need to be done under the APIShim guard + } + QScriptValuePrivate *object() const { return QScriptValuePrivate::get(objectValue); diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index 0615b63..3c6c7b2 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -161,6 +161,7 @@ private slots: void qRegExpInport_data(); void qRegExpInport(); + void reentrency(); }; tst_QScriptEngine::tst_QScriptEngine() @@ -4577,5 +4578,25 @@ void tst_QScriptEngine::qRegExpInport() } } +static QScriptValue createAnotherEngine(QScriptContext *, QScriptEngine *) +{ + QScriptEngine eng; + eng.evaluate("function foo(x, y) { return x + y; }" ); + eng.evaluate("hello = 5; world = 6" ); + return eng.evaluate("foo(hello,world)").toInt32(); +} + + +void tst_QScriptEngine::reentrency() +{ + QScriptEngine eng; + eng.globalObject().setProperty("foo", eng.newFunction(createAnotherEngine)); + eng.evaluate("function bar() { return foo(); } hello = 9; function getHello() { return hello; }"); + QCOMPARE(eng.evaluate("foo() + getHello() + foo()").toInt32(), 5+6 + 9 + 5+6); + QCOMPARE(eng.evaluate("foo").call().toInt32(), 5+6); + QCOMPARE(eng.evaluate("hello").toInt32(), 9); + QCOMPARE(eng.evaluate("foo() + hello").toInt32(), 5+6+9); +} + QTEST_MAIN(tst_QScriptEngine) #include "tst_qscriptengine.moc" -- cgit v0.12 From 7e8092fc70357b69835d8edc9e38f3286fe8727f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 29 Mar 2010 22:48:20 +0200 Subject: QScript: More missing APIShim Fixes crash in tst_QScriptValueIterator::remove on windows --- src/script/api/qscriptvalueiterator.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/script/api/qscriptvalueiterator.cpp b/src/script/api/qscriptvalueiterator.cpp index 460dddb..ecda5fc 100644 --- a/src/script/api/qscriptvalueiterator.cpp +++ b/src/script/api/qscriptvalueiterator.cpp @@ -292,6 +292,7 @@ QScriptValue QScriptValueIterator::value() const Q_D(const QScriptValueIterator); if (!d || !d->initialized || !d->engine()) return QScriptValue(); + QScript::APIShim shim(d->engine()); JSC::JSValue jsValue = d->object()->property(*d->current); return d->engine()->scriptValueFromJSCValue(jsValue); } @@ -307,6 +308,7 @@ void QScriptValueIterator::setValue(const QScriptValue &value) Q_D(QScriptValueIterator); if (!d || !d->initialized || !d->engine()) return; + QScript::APIShim shim(d->engine()); JSC::JSValue jsValue = d->engine()->scriptValueToJSCValue(value); d->object()->setProperty(*d->current, jsValue); } @@ -322,6 +324,7 @@ QScriptValue::PropertyFlags QScriptValueIterator::flags() const Q_D(const QScriptValueIterator); if (!d || !d->initialized || !d->engine()) return 0; + QScript::APIShim shim(d->engine()); return d->object()->propertyFlags(*d->current); } @@ -336,6 +339,7 @@ void QScriptValueIterator::remove() Q_D(QScriptValueIterator); if (!d || !d->initialized || !d->engine()) return; + QScript::APIShim shim(d->engine()); d->object()->setProperty(*d->current, JSC::JSValue()); d->propertyNames.erase(d->current); } -- cgit v0.12 From 30ada569454de1ec1d10bf7261d413ddd9b962a5 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 30 Mar 2010 01:58:07 +0200 Subject: Fix QFileSystemModel to not install useless watchers on the filesystem When someone call setRootPath we need to remove the previous watcher. This save memory and also it avoids Qt Creator to run out of filesystem watcher which then leads to a crash. If you call setRootPath on the previous path all changes that might happen in between will be propagated in the model. Task-number:QTBUG-8632 Reviewed-by:Friedemann Kleint --- src/gui/dialogs/qfilesystemmodel.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index 6fd947c..3757ad7 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -1361,6 +1361,16 @@ QModelIndex QFileSystemModel::setRootPath(const QString &newPath) if (!showDrives && !newPathDir.exists()) return d->index(rootPath()); + //We remove the watcher on the previous path + if (!rootPath().isEmpty()) { + //This remove the watcher for the old rootPath + d->fileInfoGatherer.removePath(rootPath()); + //This line "marks" the node as dirty, so the next fetchMore + //call on the path will ask the gatherer to install a watcher again + //But it doesn't re-fetch everything + d->node(rootPath())->populatedChildren = false; + } + // We have a new valid root path d->rootDir = newPathDir; QModelIndex newRootIndex; -- cgit v0.12 From 3546fcbd83b2a255894e6ad9aa673f6feaba6fe7 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 30 Mar 2010 10:42:43 +1000 Subject: Don't fill the video widget borders or background by default. Can be enabled by settings setAutoFillBackground or the Qt::WA_OpaquePaintEvent to true. Reviewed-by: Dmytro Poplavskiy --- demos/multimedia/player/videowidget.cpp | 6 ++++ src/multimedia/base/qvideowidget.cpp | 33 +++++++++++++++++----- .../mediaplayer/vmr9videowindowcontrol.cpp | 1 + 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/demos/multimedia/player/videowidget.cpp b/demos/multimedia/player/videowidget.cpp index 3bf36c3..be864ec 100644 --- a/demos/multimedia/player/videowidget.cpp +++ b/demos/multimedia/player/videowidget.cpp @@ -47,6 +47,12 @@ VideoWidget::VideoWidget(QWidget *parent) : QVideoWidget(parent) { setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + + QPalette p = palette(); + p.setColor(QPalette::Window, Qt::black); + setPalette(p); + + setAttribute(Qt::WA_OpaquePaintEvent); } void VideoWidget::keyPressEvent(QKeyEvent *event) diff --git a/src/multimedia/base/qvideowidget.cpp b/src/multimedia/base/qvideowidget.cpp index 3820af9..467d7c6 100644 --- a/src/multimedia/base/qvideowidget.cpp +++ b/src/multimedia/base/qvideowidget.cpp @@ -218,13 +218,23 @@ void QRendererVideoWidgetBackend::paintEvent(QPaintEvent *event) { QPainter painter(m_widget); + if (m_widget->testAttribute(Qt::WA_OpaquePaintEvent)) { + QRegion borderRegion = event->region(); + borderRegion = borderRegion.subtracted(m_boundingRect); + + QBrush brush = m_widget->palette().window(); + + QVector rects = borderRegion.rects(); + for (QVector::iterator it = rects.begin(), end = rects.end(); it != end; ++it) { + painter.fillRect(*it, brush); + } + } + if (m_surface->isActive() && m_boundingRect.intersects(event->rect())) { m_surface->paint(&painter, m_boundingRect, m_sourceRect); m_surface->setReady(true); } else { - painter.fillRect(event->rect(), m_widget->palette().background()); - #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) if (m_updatePaintDevice && (painter.paintEngine()->type() == QPaintEngine::OpenGL || painter.paintEngine()->type() == QPaintEngine::OpenGL2)) { @@ -239,6 +249,7 @@ void QRendererVideoWidgetBackend::paintEvent(QPaintEvent *event) } #endif } + } void QRendererVideoWidgetBackend::formatChanged(const QVideoSurfaceFormat &format) @@ -364,6 +375,12 @@ void QWindowVideoWidgetBackend::resizeEvent(QResizeEvent *) void QWindowVideoWidgetBackend::paintEvent(QPaintEvent *event) { + if (m_widget->testAttribute(Qt::WA_OpaquePaintEvent)) { + QPainter painter(m_widget); + + painter.fillRect(event->rect(), m_widget->palette().window()); + } + m_windowControl->repaint(); event->accept(); @@ -545,10 +562,6 @@ QVideoWidget::QVideoWidget(QWidget *parent) , d_ptr(new QVideoWidgetPrivate) { d_ptr->q_ptr = this; - - QPalette palette = QWidget::palette(); - palette.setColor(QPalette::Background, Qt::black); - setPalette(palette); } /*! @@ -602,6 +615,7 @@ void QVideoWidget::setMediaObject(QMediaObject *object) QVideoWidgetControl *widgetControl = qobject_cast( d->service->control(QVideoWidgetControl_iid)); + widgetControl = 0; if (widgetControl != 0) { d->widgetBackend = new QVideoWidgetControlBackend(widgetControl, this); } else { @@ -913,8 +927,13 @@ void QVideoWidget::paintEvent(QPaintEvent *event) { Q_D(QVideoWidget); - if (d->currentBackend) + if (d->currentBackend) { d->currentBackend->paintEvent(event); + } else if (testAttribute(Qt::WA_OpaquePaintEvent)) { + QPainter painter(this); + + painter.fillRect(event->rect(), palette().window()); + } } #include "moc_qvideowidget.cpp" diff --git a/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.cpp b/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.cpp index e25dd99..1c6df2c 100644 --- a/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.cpp +++ b/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.cpp @@ -61,6 +61,7 @@ Vmr9VideoWindowControl::Vmr9VideoWindowControl(QObject *parent) if (IVMRFilterConfig9 *config = com_cast(m_filter, IID_IVMRFilterConfig9)) { config->SetRenderingMode(VMR9Mode_Windowless); config->SetNumberOfStreams(1); + config->SetRenderingPrefs(RenderPrefs9_DoNotRenderBorder); config->Release(); } } -- cgit v0.12 From 003b2755cc307676cb7f84a4a5ef7e23dfd75ce1 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Mon, 29 Mar 2010 15:59:42 +1000 Subject: Force a repaint on changes in the native size of video frames. This ensures old frame data is cleared when swithing to progressively smaller frame sizes. Reviewed-by: Derick Hawcroft --- src/multimedia/base/qvideowidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/multimedia/base/qvideowidget.cpp b/src/multimedia/base/qvideowidget.cpp index 467d7c6..486efc0 100644 --- a/src/multimedia/base/qvideowidget.cpp +++ b/src/multimedia/base/qvideowidget.cpp @@ -259,6 +259,7 @@ void QRendererVideoWidgetBackend::formatChanged(const QVideoSurfaceFormat &forma updateRects(); m_widget->updateGeometry(); + m_widget->update(); } void QRendererVideoWidgetBackend::frameChanged() @@ -521,6 +522,7 @@ void QVideoWidgetPrivate::_q_fullScreenChanged(bool fullScreen) void QVideoWidgetPrivate::_q_dimensionsChanged() { q_func()->updateGeometry(); + q_func()->update(); } /*! -- cgit v0.12 From 87fae30fc63460e0ed2cc98f55a22e28d7520311 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 30 Mar 2010 03:01:27 +0200 Subject: Add a a layout property in QGraphicsWidget. Reviewed-by:michael brasser --- src/gui/graphicsview/qgraphicswidget.cpp | 1 + src/gui/graphicsview/qgraphicswidget.h | 2 ++ tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 131ee87..654a432 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -801,6 +801,7 @@ void QGraphicsWidget::setLayout(QGraphicsLayout *l) l->setParentLayoutItem(this); l->d_func()->reparentChildItems(this); l->invalidate(); + emit layoutChanged(); } /*! diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 468a134..730674c 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -82,6 +82,7 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) + Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); @@ -176,6 +177,7 @@ public: Q_SIGNALS: void geometryChanged(); + void layoutChanged(); public Q_SLOTS: bool close(); diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 5a3a54c..b78ef26 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -942,6 +942,7 @@ void tst_QGraphicsWidget::layout() layout->addItem(item); children.append(item); } + QSignalSpy spy(&widget, SIGNAL(layoutChanged())); widget.setLayout(layout); QTRY_COMPARE(widget.layout(), static_cast(layout)); @@ -950,7 +951,7 @@ void tst_QGraphicsWidget::layout() QCOMPARE(item->parentWidget(), (QGraphicsWidget *)&widget); QVERIFY(item->geometry() != QRectF(0, 0, -1, -1)); } - + QCOMPARE(spy.count(), 1); // don't crash widget.setLayout(0); } -- cgit v0.12 From 66a58d87c2d54bd4332ec9a8607222ac5c6521f1 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 30 Mar 2010 11:08:40 +1000 Subject: Remove debug code disabling the video widget output control. Reviewed-by: Derick Hawcroft --- src/multimedia/base/qvideowidget.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/multimedia/base/qvideowidget.cpp b/src/multimedia/base/qvideowidget.cpp index 486efc0..b791abd 100644 --- a/src/multimedia/base/qvideowidget.cpp +++ b/src/multimedia/base/qvideowidget.cpp @@ -617,7 +617,6 @@ void QVideoWidget::setMediaObject(QMediaObject *object) QVideoWidgetControl *widgetControl = qobject_cast( d->service->control(QVideoWidgetControl_iid)); - widgetControl = 0; if (widgetControl != 0) { d->widgetBackend = new QVideoWidgetControlBackend(widgetControl, this); } else { -- cgit v0.12 From 1d094129c0c3994df4e59cd9eda6981a7b131903 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 30 Mar 2010 03:10:10 +0200 Subject: struct -> class, it's better. Reviewed-by:TrustMe --- src/gui/graphicsview/qgraphicsitem_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 669ae1b..eb5fac7 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -74,7 +74,8 @@ class QGraphicsItemPrivate; #ifndef QDECLARATIVELISTPROPERTY #define QDECLARATIVELISTPROPERTY template -struct QDeclarativeListProperty { +class QDeclarativeListProperty { +public: typedef void (*AppendFunction)(QDeclarativeListProperty *, T*); typedef int (*CountFunction)(QDeclarativeListProperty *); typedef T *(*AtFunction)(QDeclarativeListProperty *, int); -- cgit v0.12 From a1d30018e104bbc17ccebae742f72c0e39e1e7f6 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Tue, 30 Mar 2010 11:48:41 +1000 Subject: Fixed compilation on 64 bits Mac OS 10.5 Reviewed-by: Justin McPherson --- src/multimedia/base/qpaintervideosurface_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multimedia/base/qpaintervideosurface_mac.mm b/src/multimedia/base/qpaintervideosurface_mac.mm index 899b98f..ee03990 100644 --- a/src/multimedia/base/qpaintervideosurface_mac.mm +++ b/src/multimedia/base/qpaintervideosurface_mac.mm @@ -52,7 +52,7 @@ #include #include - +#include QT_BEGIN_NAMESPACE -- cgit v0.12 From 0d7a0b1bf2ab50621ed662a3e178d2ad5add4114 Mon Sep 17 00:00:00 2001 From: Wolfgang Beck Date: Tue, 30 Mar 2010 11:53:42 +1000 Subject: MONILITY-645 Merging bearer header. --- src/network/bearer/qnetworkconfigmanager.h | 23 ++++++++++++++++----- src/network/bearer/qnetworkconfiguration.h | 30 ++++++++++++++++++++++------ src/network/bearer/qnetworksession.h | 28 +++++++++++++++++++------- src/plugins/bearer/nativewifi/platformdefs.h | 4 ++++ src/plugins/bearer/platformdefs_win.h | 4 ++++ 5 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h index bb4d8a0..19951f8 100644 --- a/src/network/bearer/qnetworkconfigmanager.h +++ b/src/network/bearer/qnetworkconfigmanager.h @@ -42,17 +42,26 @@ #ifndef QNETWORKCONFIGURATIONMANAGER_H #define QNETWORKCONFIGURATIONMANAGER_H +#ifdef QT_MOBILITY_BEARER +# include "qmobilityglobal.h" +#endif + #include #include QT_BEGIN_HEADER -QT_BEGIN_NAMESPACE - -QT_MODULE(Network) +#ifndef QT_MOBILITY_BEARER + QT_BEGIN_NAMESPACE + #define QNetworkConfigurationManagerExport Q_NETWORK_EXPORT + QT_MODULE(Network) +#else + QTM_BEGIN_NAMESPACE + #define QNetworkConfigurationManagerExport Q_BEARER_EXPORT +#endif class QNetworkConfigurationManagerPrivate; -class Q_NETWORK_EXPORT QNetworkConfigurationManager : public QObject +class QNetworkConfigurationManagerExport QNetworkConfigurationManager : public QObject { Q_OBJECT @@ -94,7 +103,11 @@ Q_SIGNALS: Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkConfigurationManager::Capabilities) -QT_END_NAMESPACE +#ifndef QT_MOBILITY_BEARER + QT_END_NAMESPACE +#else + QTM_END_NAMESPACE +#endif QT_END_HEADER diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h index dad6198..3b49d0a 100644 --- a/src/network/bearer/qnetworkconfiguration.h +++ b/src/network/bearer/qnetworkconfiguration.h @@ -42,19 +42,33 @@ #ifndef QNETWORKCONFIGURATION_H #define QNETWORKCONFIGURATION_H -#include +#ifndef QT_MOBILITY_BEARER +# include +#else +# include "qmobilityglobal.h" +#endif + #include #include #include -QT_BEGIN_HEADER +#if defined(Q_OS_WIN) && defined(interface) +#undef interface +#endif -QT_BEGIN_NAMESPACE +QT_BEGIN_HEADER -QT_MODULE(Network) +#ifndef QT_MOBILITY_BEARER + QT_BEGIN_NAMESPACE + QT_MODULE(Network) + #define QNetworkConfigurationExport Q_NETWORK_EXPORT +#else + QTM_BEGIN_NAMESPACE + #define QNetworkConfigurationExport Q_BEARER_EXPORT +#endif class QNetworkConfigurationPrivate; -class Q_NETWORK_EXPORT QNetworkConfiguration +class QNetworkConfigurationExport QNetworkConfiguration { public: QNetworkConfiguration(); @@ -108,7 +122,11 @@ private: QExplicitlySharedDataPointer d; }; -QT_END_NAMESPACE +#ifndef QT_MOBILITY_BEARER + QT_END_NAMESPACE +#else + QTM_END_NAMESPACE +#endif QT_END_HEADER diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h index 596f527..2681d1f 100644 --- a/src/network/bearer/qnetworksession.h +++ b/src/network/bearer/qnetworksession.h @@ -54,12 +54,19 @@ QT_BEGIN_HEADER -QT_BEGIN_NAMESPACE - -QT_MODULE(Network) +#ifndef QT_MOBILITY_BEARER + #include + QT_BEGIN_NAMESPACE + QT_MODULE(Network) + #define QNetworkSessionExport Q_NETWORK_EXPORT +#else + #include "qmobilityglobal.h" + QTM_BEGIN_NAMESPACE + #define QNetworkSessionExport Q_BEARER_EXPORT +#endif class QNetworkSessionPrivate; -class Q_NETWORK_EXPORT QNetworkSession : public QObject +class QNetworkSessionExport QNetworkSession : public QObject { Q_OBJECT public: @@ -80,8 +87,11 @@ public: OperationNotSupportedError, InvalidConfigurationError }; - - explicit QNetworkSession(const QNetworkConfiguration& connConfig, QObject* parent =0); +#ifndef QT_MOBILITY_BEARER + QNetworkSession(const QNetworkConfiguration& connConfig, QObject* parent =0); +#else + explicit QNetworkSession(const QNetworkConfiguration& connConfig, QObject* parent =0); +#endif virtual ~QNetworkSession(); bool isOpen() const; @@ -131,7 +141,11 @@ private: friend class QNetworkSessionPrivate; }; -QT_END_NAMESPACE +#ifndef QT_MOBILITY_BEARER + QT_END_NAMESPACE +#else + QTM_END_NAMESPACE +#endif QT_END_HEADER diff --git a/src/plugins/bearer/nativewifi/platformdefs.h b/src/plugins/bearer/nativewifi/platformdefs.h index 57ae852..d67525a 100644 --- a/src/plugins/bearer/nativewifi/platformdefs.h +++ b/src/plugins/bearer/nativewifi/platformdefs.h @@ -52,6 +52,8 @@ #define WLAN_AVAILABLE_NETWORK_HAS_PROFILE 2 #define DOT11_SSID_MAX_LENGTH 32 +QT_BEGIN_NAMESPACE + struct WLAN_NOTIFICATION_DATA { DWORD NotificationSource; DWORD NotificationCode; @@ -319,4 +321,6 @@ extern WlanScanProto local_WlanScan; extern WlanFreeMemoryProto local_WlanFreeMemory; extern WlanCloseHandleProto local_WlanCloseHandle; +QT_END_NAMESPACE + #endif // PLATFORMDEFS_H diff --git a/src/plugins/bearer/platformdefs_win.h b/src/plugins/bearer/platformdefs_win.h index 37d099c..1a10ba7 100644 --- a/src/plugins/bearer/platformdefs_win.h +++ b/src/plugins/bearer/platformdefs_win.h @@ -47,6 +47,8 @@ #undef interface #include +QT_BEGIN_NAMESPACE + #ifndef NS_NLA #define NS_NLA 15 @@ -131,4 +133,6 @@ enum NDIS_PHYSICAL_MEDIUM { #define IOCTL_NDIS_QUERY_GLOBAL_STATS \ CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, 0, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +QT_END_NAMESPACE + #endif -- cgit v0.12 From b353f98da10f4b8b80f6be70951f147d580999e8 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 30 Mar 2010 14:33:12 +1000 Subject: Fix compile error on mingw. Compile error seems to be going back and forth between mingw and wince compilers. Prefer correctness and portability over brevity by initializing each field of the struct one-by-one to guarantee portability between compilers. Reviewed-by: Lincoln Ramsay --- src/corelib/io/qwindowspipewriter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index eb42c20..3eb2411 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -100,7 +100,10 @@ qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) void QWindowsPipeWriter::run() { - OVERLAPPED overl = {0, 0, {{ 0 }}, 0}; + OVERLAPPED overl; + overl.Internal = 0; + overl.InternalHigh = 0; + overl.Pointer = 0; overl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); forever { lock.lock(); -- cgit v0.12 From 8c4f8e259d60c98361d20f495e3af252bcef24a0 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Tue, 30 Mar 2010 16:11:03 +1000 Subject: Fix typo in phonon/symbian. Reviewed-by: Dmytro Poplavskiy --- src/3rdparty/phonon/phonon/factory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp index 24be0f3..2785dff 100644 --- a/src/3rdparty/phonon/phonon/factory.cpp +++ b/src/3rdparty/phonon/phonon/factory.cpp @@ -143,7 +143,7 @@ bool FactoryPrivate::createBackend() * sophisticated, so we make sure the Helix backend is attempted * to be loaded first, and the MMF backend is used for backup. */ { - const int helix = plugins.indexof(QLatin1String("hxphonon")); + const int helix = plugins.indexOf(QLatin1String("hxphonon")); if (helix != -1) plugins.move(helix, 0); } -- cgit v0.12 From 5107b4c5e670b7357b9eb0f8f81f9810eaa9647b Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Tue, 30 Mar 2010 17:34:10 +1000 Subject: Move basic focusscope examples into auto tests. --- examples/declarative/declarative.pro | 1 - examples/declarative/focusscope/test.qml | 76 ------ examples/declarative/focusscope/test2.qml | 40 --- examples/declarative/focusscope/test3.qml | 52 ---- examples/declarative/focusscope/test4.qml | 75 ------ examples/declarative/focusscope/test5.qml | 83 ------ tests/auto/declarative/declarative.pro | 1 + .../qdeclarativefocusscope/data/test.qml | 77 ++++++ .../qdeclarativefocusscope/data/test2.qml | 39 +++ .../qdeclarativefocusscope/data/test3.qml | 52 ++++ .../qdeclarativefocusscope/data/test4.qml | 76 ++++++ .../qdeclarativefocusscope/data/test5.qml | 84 +++++++ .../qdeclarativefocusscope.pro | 6 + .../tst_qdeclarativefocusscope.cpp | 278 +++++++++++++++++++++ 14 files changed, 613 insertions(+), 327 deletions(-) delete mode 100644 examples/declarative/focusscope/test.qml delete mode 100644 examples/declarative/focusscope/test2.qml delete mode 100644 examples/declarative/focusscope/test3.qml delete mode 100644 examples/declarative/focusscope/test4.qml delete mode 100644 examples/declarative/focusscope/test5.qml create mode 100644 tests/auto/declarative/qdeclarativefocusscope/data/test.qml create mode 100644 tests/auto/declarative/qdeclarativefocusscope/data/test2.qml create mode 100644 tests/auto/declarative/qdeclarativefocusscope/data/test3.qml create mode 100644 tests/auto/declarative/qdeclarativefocusscope/data/test4.qml create mode 100644 tests/auto/declarative/qdeclarativefocusscope/data/test5.qml create mode 100644 tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro create mode 100644 tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp diff --git a/examples/declarative/declarative.pro b/examples/declarative/declarative.pro index bddfbee..0f58738 100644 --- a/examples/declarative/declarative.pro +++ b/examples/declarative/declarative.pro @@ -21,7 +21,6 @@ sources.files = \ effects \ fillmode \ focus \ - focusscope \ fonts \ gridview \ layouts \ diff --git a/examples/declarative/focusscope/test.qml b/examples/declarative/focusscope/test.qml deleted file mode 100644 index e4332e7..0000000 --- a/examples/declarative/focusscope/test.qml +++ /dev/null @@ -1,76 +0,0 @@ -import Qt 4.6 - -Rectangle { - color: "white" - width: 800 - height: 600 - - Keys.onDigit9Pressed: console.log("Error - Root") - - FocusScope { - id: myScope - focus: true - - Keys.onDigit9Pressed: console.log("Error - FocusScope") - - Rectangle { - height: 120 - width: 420 - - color: "transparent" - border.width: 5 - border.color: myScope.wantsFocus?"blue":"black" - - Rectangle { - id: item1 - x: 10; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: wantsFocus?"blue":"black" - Keys.onDigit9Pressed: console.log("Top Left"); - KeyNavigation.right: item2 - focus: true - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.focus?"red":"transparent" - } - } - - Rectangle { - id: item2 - x: 310; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: wantsFocus?"blue":"black" - KeyNavigation.left: item1 - Keys.onDigit9Pressed: console.log("Top Right"); - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.focus?"red":"transparent" - } - } - } - KeyNavigation.down: item3 - } - - Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box indicates active focus\nUse arrow keys to navigate\nPress \"9\" to print currently focused item" } - - Rectangle { - id: item3 - x: 10; y: 300 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: wantsFocus?"blue":"black" - - Keys.onDigit9Pressed: console.log("Bottom Left"); - KeyNavigation.up: myScope - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.focus?"red":"transparent" - } - } - -} diff --git a/examples/declarative/focusscope/test2.qml b/examples/declarative/focusscope/test2.qml deleted file mode 100644 index 5b6971a..0000000 --- a/examples/declarative/focusscope/test2.qml +++ /dev/null @@ -1,40 +0,0 @@ -import Qt 4.6 - -Rectangle { - color: "white" - width: 800 - height: 600 - - Text { text: "All five rectangles should be red" } - - FocusScope { - y: 100 - focus: true - Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } - - FocusScope { - y: 100 - focus: true - Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } - - FocusScope { - y: 100 - focus: true - Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } - - FocusScope { - y: 100 - focus: true - Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } - - FocusScope { - y: 100 - focus: true - Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } - } - } - } - } - } - -} diff --git a/examples/declarative/focusscope/test3.qml b/examples/declarative/focusscope/test3.qml deleted file mode 100644 index 9344d07..0000000 --- a/examples/declarative/focusscope/test3.qml +++ /dev/null @@ -1,52 +0,0 @@ -import Qt 4.6 - -Rectangle { - color: "white" - width: 800 - height: 600 - - ListModel { - id: model - ListElement { name: "1" } - ListElement { name: "2" } - ListElement { name: "3" } - ListElement { name: "4" } - ListElement { name: "5" } - ListElement { name: "6" } - ListElement { name: "6" } - ListElement { name: "8" } - ListElement { name: "9" } - } - - Component { - id: verticalDelegate - FocusScope { - id: root - width: 50; height: 50; - Keys.onDigit9Pressed: console.log("Error - " + name) - Rectangle { - focus: true - Keys.onDigit9Pressed: console.log(name) - width: 50; height: 50; - color: root.ListView.isCurrentItem?"red":"green" - Text { text: name; anchors.centerIn: parent } - } - } - } - - ListView { - width: 800; height: 50; orientation: "Horizontal" - focus: true - model: model - delegate: verticalDelegate - preferredHighlightBegin: 100 - preferredHighlightEnd: 100 - highlightRangeMode: "StrictlyEnforceRange" - } - - - Text { - y: 100; x: 50 - text: "Currently selected element should be red\nPressing \"9\" should print the number of the currently selected item\nBe sure to scroll all the way to the right, pause, and then all the way to the left." - } -} diff --git a/examples/declarative/focusscope/test4.qml b/examples/declarative/focusscope/test4.qml deleted file mode 100644 index cc96df9..0000000 --- a/examples/declarative/focusscope/test4.qml +++ /dev/null @@ -1,75 +0,0 @@ -import Qt 4.6 - -Rectangle { - color: "white" - width: 800 - height: 600 - - Keys.onDigit9Pressed: console.log("Error - Root") - - FocusScope { - id: myScope - - Keys.onDigit9Pressed: console.log("Error - FocusScope") - - Rectangle { - height: 120 - width: 420 - - color: "transparent" - border.width: 5 - border.color: myScope.wantsFocus?"blue":"black" - - Rectangle { - id: item1 - x: 10; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: wantsFocus?"blue":"black" - Keys.onDigit9Pressed: console.log("Error - Top Left"); - KeyNavigation.right: item2 - focus: true - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.focus?"red":"transparent" - } - } - - Rectangle { - id: item2 - x: 310; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: wantsFocus?"blue":"black" - KeyNavigation.left: item1 - Keys.onDigit9Pressed: console.log("Error - Top Right"); - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.focus?"red":"transparent" - } - } - } - KeyNavigation.down: item3 - } - - Text { x:100; y:170; text: "There should be no blue borders, or red squares.\nPressing \"9\" should do nothing.\nArrow keys should have no effect." } - - Rectangle { - id: item3 - x: 10; y: 300 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: wantsFocus?"blue":"black" - - Keys.onDigit9Pressed: console.log("Error - Bottom Left"); - KeyNavigation.up: myScope - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.focus?"red":"transparent" - } - } - -} diff --git a/examples/declarative/focusscope/test5.qml b/examples/declarative/focusscope/test5.qml deleted file mode 100644 index da98350..0000000 --- a/examples/declarative/focusscope/test5.qml +++ /dev/null @@ -1,83 +0,0 @@ -import Qt 4.6 - -Rectangle { - color: "white" - width: 800 - height: 600 - - Keys.onReturnPressed: console.log("Error - Root") - - FocusScope { - id: myScope - focus: true - - Keys.onReturnPressed: console.log("Error - FocusScope") - - Rectangle { - height: 120 - width: 420 - - color: "transparent" - border.width: 5 - border.color: myScope.wantsFocus?"blue":"black" - - Rectangle { - x: 10; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: item1.wantsFocus?"blue":"black" - } - - TextEdit { - id: item1 - x: 20; y: 20 - width: 90; height: 90 - color: "white" - font.pixelSize: 20 - Keys.onReturnPressed: console.log("Top Left"); - KeyNavigation.right: item2 - focus: true - wrap: true - text: "Box 1" - } - - Rectangle { - id: item2 - x: 310; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: wantsFocus?"blue":"black" - KeyNavigation.left: item1 - Keys.onReturnPressed: console.log("Top Right"); - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.focus?"red":"transparent" - } - } - } - KeyNavigation.down: item3 - } - - Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box or flashing cursor indicates active focus\nUse arrow keys to navigate\nPress Ctrl-Return to print currently focused item" } - - Rectangle { - x: 10; y: 300 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: item3.wantsFocus?"blue":"black" - } - - TextEdit { - id: item3 - x: 20; y: 310 - width: 90; height: 90 - color: "white" - font.pixelSize: 20 - text: "Box 3" - - Keys.onReturnPressed: console.log("Bottom Left"); - KeyNavigation.up: myScope - wrap: true - } -} diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index bebc54e..2d88058 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -23,6 +23,7 @@ SUBDIRS += \ qdeclarativeborderimage \ # Cover qdeclarativeflickable \ # Cover qdeclarativeflipable \ # Cover + qdeclarativefocusscope \ # Cover qdeclarativegridview \ # Cover qdeclarativeitem \ # Cover qdeclarativelistview \ # Cover diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/test.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test.qml new file mode 100644 index 0000000..647e5bf --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/data/test.qml @@ -0,0 +1,77 @@ +import Qt 4.6 + +Rectangle { + color: "white" + width: 800 + height: 600 + + Keys.onDigit9Pressed: console.log("Error - Root") + + FocusScope { + id: myScope + focus: true + + Keys.onDigit9Pressed: console.log("Error - FocusScope") + + Rectangle { + objectName: "item0" + height: 120 + width: 420 + + color: "transparent" + border.width: 5 + //border.color: myScope.wantsFocus?"blue":"black" + + Rectangle { + id: item1; objectName: "item1" + x: 10; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: wantsFocus?"blue":"black" + Keys.onDigit9Pressed: console.debug("Top Left"); + KeyNavigation.right: item2 + focus: true + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.focus?"red":"transparent" + } + } + + Rectangle { + id: item2; objectName: "item2" + x: 310; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: wantsFocus?"blue":"black" + KeyNavigation.left: item1 + Keys.onDigit9Pressed: console.log("Top Right"); + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.focus?"red":"transparent" + } + } + } + KeyNavigation.down: item3 + } + + Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box indicates active focus\nUse arrow keys to navigate\nPress \"9\" to print currently focused item" } + + Rectangle { + id: item3; objectName: "item3" + x: 10; y: 300 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: wantsFocus?"blue":"black" + + Keys.onDigit9Pressed: console.log("Bottom Left"); + KeyNavigation.up: myScope + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.focus?"red":"transparent" + } + } + +} diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/test2.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test2.qml new file mode 100644 index 0000000..277fda4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/data/test2.qml @@ -0,0 +1,39 @@ +import Qt 4.6 + +Rectangle { + color: "white" + width: 800 + height: 600 + + Text { text: "All five rectangles should be red" } + + FocusScope { + y: 100 + focus: true; objectName: "item1" + Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } + + FocusScope { + y: 100 + focus: true; objectName: "item2" + Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } + + FocusScope { + y: 100 + focus: true; objectName: "item3" + Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } + + FocusScope { + y: 100 + focus: true; objectName: "item4" + Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } + + FocusScope { + y: 100 + focus: true; objectName: "item5" + Rectangle { width: 50; height: 50; color: parent.wantsFocus?"red":"blue" } + } + } + } + } + } +} diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/test3.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test3.qml new file mode 100644 index 0000000..9344d07 --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/data/test3.qml @@ -0,0 +1,52 @@ +import Qt 4.6 + +Rectangle { + color: "white" + width: 800 + height: 600 + + ListModel { + id: model + ListElement { name: "1" } + ListElement { name: "2" } + ListElement { name: "3" } + ListElement { name: "4" } + ListElement { name: "5" } + ListElement { name: "6" } + ListElement { name: "6" } + ListElement { name: "8" } + ListElement { name: "9" } + } + + Component { + id: verticalDelegate + FocusScope { + id: root + width: 50; height: 50; + Keys.onDigit9Pressed: console.log("Error - " + name) + Rectangle { + focus: true + Keys.onDigit9Pressed: console.log(name) + width: 50; height: 50; + color: root.ListView.isCurrentItem?"red":"green" + Text { text: name; anchors.centerIn: parent } + } + } + } + + ListView { + width: 800; height: 50; orientation: "Horizontal" + focus: true + model: model + delegate: verticalDelegate + preferredHighlightBegin: 100 + preferredHighlightEnd: 100 + highlightRangeMode: "StrictlyEnforceRange" + } + + + Text { + y: 100; x: 50 + text: "Currently selected element should be red\nPressing \"9\" should print the number of the currently selected item\nBe sure to scroll all the way to the right, pause, and then all the way to the left." + } +} diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/test4.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test4.qml new file mode 100644 index 0000000..d8bd390 --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/data/test4.qml @@ -0,0 +1,76 @@ +import Qt 4.6 + +Rectangle { + color: "white" + width: 800 + height: 600 + + Keys.onDigit9Pressed: console.log("Error - Root") + + FocusScope { + id: myScope + + Keys.onDigit9Pressed: console.log("Error - FocusScope") + + Rectangle { + objectName: "item0" + height: 120 + width: 420 + + color: "transparent" + border.width: 5 + //border.color: myScope.wantsFocus?"blue":"black" + + Rectangle { + id: item1; objectName: "item1" + x: 10; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: wantsFocus?"blue":"black" + Keys.onDigit9Pressed: console.log("Error - Top Left"); + KeyNavigation.right: item2 + focus: true + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.focus?"red":"transparent" + } + } + + Rectangle { + id: item2; objectName: "item2" + x: 310; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: wantsFocus?"blue":"black" + KeyNavigation.left: item1 + Keys.onDigit9Pressed: console.log("Error - Top Right"); + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.focus?"red":"transparent" + } + } + } + KeyNavigation.down: item3 + } + + Text { x:100; y:170; text: "There should be no blue borders, or red squares.\nPressing \"9\" should do nothing.\nArrow keys should have no effect." } + + Rectangle { + id: item3; objectName: "item3" + x: 10; y: 300 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: wantsFocus?"blue":"black" + + Keys.onDigit9Pressed: console.log("Error - Bottom Left"); + KeyNavigation.up: myScope + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.focus?"red":"transparent" + } + } + +} diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/test5.qml b/tests/auto/declarative/qdeclarativefocusscope/data/test5.qml new file mode 100644 index 0000000..0b75ec4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/data/test5.qml @@ -0,0 +1,84 @@ +import Qt 4.6 + +Rectangle { + color: "white" + width: 800 + height: 600 + + Keys.onReturnPressed: console.log("Error - Root") + + FocusScope { + id: myScope + focus: true + + Keys.onReturnPressed: console.log("Error - FocusScope") + + Rectangle { + objectName: "item0" + height: 120 + width: 420 + + color: "transparent" + border.width: 5 + //border.color: myScope.wantsFocus?"blue":"black" + + Rectangle { + x: 10; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: item1.wantsFocus?"blue":"black" + } + + TextEdit { + id: item1; objectName: "item1" + x: 20; y: 20 + width: 90; height: 90 + color: "white" + font.pixelSize: 20 + Keys.onReturnPressed: console.log("Top Left"); + KeyNavigation.right: item2 + focus: true + wrap: true + text: "Box 1" + } + + Rectangle { + id: item2; objectName: "item2" + x: 310; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: wantsFocus?"blue":"black" + KeyNavigation.left: item1 + Keys.onReturnPressed: console.log("Top Right"); + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.focus?"red":"transparent" + } + } + } + KeyNavigation.down: item3 + } + + Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box or flashing cursor indicates active focus\nUse arrow keys to navigate\nPress Ctrl-Return to print currently focused item" } + + Rectangle { + x: 10; y: 300 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: item3.wantsFocus?"blue":"black" + } + + TextEdit { + id: item3; objectName: "item3" + x: 20; y: 310 + width: 90; height: 90 + color: "white" + font.pixelSize: 20 + text: "Box 3" + + Keys.onReturnPressed: console.log("Bottom Left"); + KeyNavigation.up: myScope + wrap: true + } +} diff --git a/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro b/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro new file mode 100644 index 0000000..4d7a9b3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qdeclarativefocusscope.cpp +macx:CONFIG -= app_bundle + +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp new file mode 100644 index 0000000..1bd8331 --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp @@ -0,0 +1,278 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class tst_qdeclarativefocusscope : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativefocusscope() {} + + template + T *findItem(QGraphicsObject *parent, const QString &id); + +private slots: + void basic(); + void nested(); + void noFocus(); + void textEdit(); +}; + +/* + Find an item with the specified id. +*/ +template +T *tst_qdeclarativefocusscope::findItem(QGraphicsObject *parent, const QString &objectName) +{ + const QMetaObject &mo = T::staticMetaObject; + QList children = parent->childItems(); + for (int i = 0; i < children.count(); ++i) { + QDeclarativeItem *item = qobject_cast(children.at(i)->toGraphicsObject()); + if (item) { + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + return static_cast(item); + } + item = findItem(item, objectName); + if (item) + return static_cast(item); + } + } + return 0; +} + +void tst_qdeclarativefocusscope::basic() +{ + QDeclarativeView *view = new QDeclarativeView; + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test.qml")); + + QDeclarativeRectangle *item0 = findItem(view->rootObject(), QLatin1String("item0")); + QDeclarativeRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QDeclarativeRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QDeclarativeRectangle *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + qApp->setActiveWindow(view); + qApp->processEvents(); + +#ifdef Q_WS_X11 + // to be safe and avoid failing setFocus with window managers + qt_x11_wait_for_window_manager(view); +#endif + + QVERIFY(view->hasFocus()); + QVERIFY(view->scene()->hasFocus()); + QVERIFY(item0->wantsFocus() == true); + QVERIFY(item1->hasFocus() == true); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->hasFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->wantsFocus() == true); + QVERIFY(item1->hasFocus() == false); + QVERIFY(item2->hasFocus() == true); + QVERIFY(item3->hasFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QVERIFY(item0->wantsFocus() == false); + QVERIFY(item1->hasFocus() == false); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->hasFocus() == true); + + delete view; +} + +void tst_qdeclarativefocusscope::nested() +{ + QDeclarativeView *view = new QDeclarativeView; + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test2.qml")); + + QDeclarativeFocusScope *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QDeclarativeFocusScope *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QDeclarativeFocusScope *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QDeclarativeFocusScope *item4 = findItem(view->rootObject(), QLatin1String("item4")); + QDeclarativeFocusScope *item5 = findItem(view->rootObject(), QLatin1String("item5")); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + QVERIFY(item4 != 0); + QVERIFY(item5 != 0); + + view->show(); + qApp->setActiveWindow(view); + qApp->processEvents(); + +#ifdef Q_WS_X11 + // to be safe and avoid failing setFocus with window managers + qt_x11_wait_for_window_manager(view); +#endif + + QVERIFY(view->hasFocus()); + QVERIFY(view->scene()->hasFocus()); + + QVERIFY(item1->wantsFocus() == true); + QVERIFY(item1->hasFocus() == false); + QVERIFY(item2->wantsFocus() == true); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->wantsFocus() == true); + QVERIFY(item3->hasFocus() == false); + QVERIFY(item4->wantsFocus() == true); + QVERIFY(item4->hasFocus() == false); + QVERIFY(item5->wantsFocus() == true); + QVERIFY(item5->hasFocus() == true); + delete view; +} + +void tst_qdeclarativefocusscope::noFocus() +{ + QDeclarativeView *view = new QDeclarativeView; + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test4.qml")); + + QDeclarativeRectangle *item0 = findItem(view->rootObject(), QLatin1String("item0")); + QDeclarativeRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QDeclarativeRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QDeclarativeRectangle *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + qApp->setActiveWindow(view); + qApp->processEvents(); + +#ifdef Q_WS_X11 + // to be safe and avoid failing setFocus with window managers + qt_x11_wait_for_window_manager(view); +#endif + + QVERIFY(view->hasFocus()); + QVERIFY(view->scene()->hasFocus()); + QVERIFY(item0->wantsFocus() == false); + QVERIFY(item1->hasFocus() == false); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->hasFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->wantsFocus() == false); + QVERIFY(item1->hasFocus() == false); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->hasFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QVERIFY(item0->wantsFocus() == false); + QVERIFY(item1->hasFocus() == false); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->hasFocus() == false); + + delete view; +} + +void tst_qdeclarativefocusscope::textEdit() +{ + QDeclarativeView *view = new QDeclarativeView; + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test5.qml")); + + QDeclarativeRectangle *item0 = findItem(view->rootObject(), QLatin1String("item0")); + QDeclarativeTextEdit *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QDeclarativeRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QDeclarativeTextEdit *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + qApp->setActiveWindow(view); + qApp->processEvents(); + +#ifdef Q_WS_X11 + // to be safe and avoid failing setFocus with window managers + qt_x11_wait_for_window_manager(view); +#endif + + QVERIFY(view->hasFocus()); + QVERIFY(view->scene()->hasFocus()); + QVERIFY(item0->wantsFocus() == true); + QVERIFY(item1->hasFocus() == true); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->hasFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->wantsFocus() == true); + QVERIFY(item1->hasFocus() == true); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->hasFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->wantsFocus() == true); + QVERIFY(item1->hasFocus() == false); + QVERIFY(item2->hasFocus() == true); + QVERIFY(item3->hasFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QVERIFY(item0->wantsFocus() == false); + QVERIFY(item1->hasFocus() == false); + QVERIFY(item2->hasFocus() == false); + QVERIFY(item3->hasFocus() == true); + + delete view; +} + +QTEST_MAIN(tst_qdeclarativefocusscope) + +#include "tst_qdeclarativefocusscope.moc" -- cgit v0.12 From bc4fe607fe65dca24460d4f612c5815b4767e988 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 30 Mar 2010 10:39:21 +0200 Subject: One more test for chinese codecs Relates to QT-2627 --- tests/auto/qtextcodec/tst_qtextcodec.cpp | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/auto/qtextcodec/tst_qtextcodec.cpp b/tests/auto/qtextcodec/tst_qtextcodec.cpp index 1c64ade..4e7123f 100644 --- a/tests/auto/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/qtextcodec/tst_qtextcodec.cpp @@ -2178,6 +2178,45 @@ void tst_QTextCodec::moreToFromUnicode_data() { koi8_u_ba.append(x); } QTest::newRow("KOI8-U") << QByteArray("KOI8-U") << koi8_u_ba; + + + QByteArray big5_ba; + for (unsigned char u=0xa1; u<=0xf9; u++) { + if (u==0xc8) { + continue; + } + for (unsigned char v=0x40; v<=0x7e; v++) { + big5_ba.append(u); + big5_ba.append(v); + } + unsigned char v_up; + switch (u) { + case 0xa3: v_up=0xbf; break; + case 0xc7: v_up=0xfc; break; + case 0xf9: v_up=0xd5; break; + default: v_up=0xfe; + } + + for (unsigned char v=0xa1; v<=v_up; v++) { + if (u==0xa2 && (v==0xcc || v==0xce)) { + continue; + } + big5_ba.append(u); + big5_ba.append(v); + } + } + + QTest::newRow("BIG5") << QByteArray("BIG5") << big5_ba; + + QByteArray gb2312_ba; + for (unsigned char u=0xa1; u<=0xf7; u++) { + for (unsigned char v=0xa1; v<=0xfe; v++) { + gb2312_ba.append(u); + gb2312_ba.append(v); + } + } + + QTest::newRow("GB2312") << QByteArray("GB2312") << gb2312_ba; } void tst_QTextCodec::moreToFromUnicode() -- cgit v0.12 From 966768a637a607abd9c26917e62be994c397864f Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 30 Mar 2010 10:48:47 +0200 Subject: Fix a crash in QGtkStyle when theme not available subElementRect failed to verify that the theme was resolved before accessing certain data structures. Reviewed-by: ogoffart Task-number: QTBUG-9240 --- src/gui/styles/qgtkstyle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index b5f052b..ddae3d8 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -3398,6 +3398,9 @@ QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, Q_D(const QGtkStyle); QRect r = QCleanlooksStyle::subElementRect(element, option, widget); + if (!d->isThemeAvailable()) + return r; + switch (element) { case SE_ProgressBarLabel: case SE_ProgressBarContents: -- cgit v0.12 From c6dbce5e54da4c33ae50fad9aab21457a9219f94 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 30 Mar 2010 18:52:54 +1000 Subject: Optimization: Use internal QGraphicsItemPrivate::setItemParentHelper() This brings the "data" property inline with the "children" property. Improves the declarative/creation/itemtree_qml test by 13%. --- src/declarative/graphicsitems/qdeclarativeitem.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 29490e3..05e13a7 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -1510,11 +1510,19 @@ QDeclarativeAnchors *QDeclarativeItem::anchors() void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty *prop, QObject *o) { - QGraphicsObject *i = qobject_cast(o); - if (i) { - i->setParentItem(static_cast(prop->object)); + if (!o) + return; + + QDeclarativeItem *that = static_cast(prop->object); + + // This test is measurably (albeit only slightly) faster than qobject_cast<>() + const QMetaObject *mo = o->metaObject(); + while (mo && mo != &QGraphicsObject::staticMetaObject) mo = mo->d.superdata; + + if (mo) { + QGraphicsItemPrivate::get(static_cast(o))->setParentItemHelper(that, 0, 0); } else { - o->setParent(static_cast(prop->object)); + o->setParent(that); } } -- cgit v0.12 From 568475d98d77c3ade027eb88e571ca8b84088002 Mon Sep 17 00:00:00 2001 From: John Layt Date: Tue, 30 Mar 2010 10:55:33 +0200 Subject: Fix QDate::isLeapYear() for years < 1 The current formula for isLeapYear() assumes that years -4, -8, etc are leap years in the Julian Calendar. This is not the case, leap years in fact fall in -1, -5, -9, etc as there is no year 0 in the Julian Calendar (count back 4 years from 4AD to confirm). The julianDayFromDate() and getDateFromJulianDay() functions correctly calculate this, but isValid() uses isLeapYear() and so causes setDate() to incorrectly reject valid dates. Sample test code to round-trip a jd to ymd and back to jd: QDate testDate; QDate loopDate = QDate::fromJulianDay(1); while ( loopDate.toJulianDay() <= 5373484 ) { // <= 9999-12-31 testDate.setDate( loopDate.year(), loopDate.month(), loopDate.day() ); if ( !testDate.isValid() || loopDate != testDate ) { qDebug() << "Round Trip failed : " << loopDate.toJulianDay() << " = " << loopDate.year() << loopDate.month() << loopDate.day() << " = " << testDate.toJulianDay(); } loopDate.addDays(1); } Before the fix, 29 Feb 1 BC (year = -1) and all other BC leap days returned by year() month() day() would result in setDate() failing. After the fix the round trip works fine. Merge-request: 2282 Reviewed-by: Olivier Goffart --- src/corelib/tools/qdatetime.cpp | 5 ++++- tests/auto/qdate/tst_qdate.cpp | 50 ++++++++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 54a4205..3e34d62 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -1336,7 +1336,10 @@ bool QDate::isValid(int year, int month, int day) bool QDate::isLeapYear(int y) { if (y < 1582) { - return qAbs(y) % 4 == 0; + if ( y < 1) { // No year 0 in Julian calendar, so -1, -5, -9 etc are leap years + ++y; + } + return y % 4 == 0; } else { return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0; } diff --git a/tests/auto/qdate/tst_qdate.cpp b/tests/auto/qdate/tst_qdate.cpp index 7223291..60772eb 100644 --- a/tests/auto/qdate/tst_qdate.cpp +++ b/tests/auto/qdate/tst_qdate.cpp @@ -99,6 +99,7 @@ private slots: void standaloneShortMonthName() const; void longMonthName() const; void standaloneLongMonthName() const; + void roundtrip() const; }; Q_DECLARE_METATYPE(QDate) @@ -668,17 +669,18 @@ void tst_QDate::toString_format() void tst_QDate::isLeapYear() { - QVERIFY(QDate::isLeapYear(-4444)); - QVERIFY(!QDate::isLeapYear(-4443)); - QVERIFY(QDate::isLeapYear(-8)); - QVERIFY(!QDate::isLeapYear(-7)); - QVERIFY(QDate::isLeapYear(-4)); + QVERIFY(QDate::isLeapYear(-4445)); + QVERIFY(!QDate::isLeapYear(-4444)); + QVERIFY(!QDate::isLeapYear(-6)); + QVERIFY(QDate::isLeapYear(-5)); + QVERIFY(!QDate::isLeapYear(-4)); QVERIFY(!QDate::isLeapYear(-3)); QVERIFY(!QDate::isLeapYear(-2)); - QVERIFY(!QDate::isLeapYear(-1)); - QVERIFY(!QDate::isLeapYear(1)); - QVERIFY(!QDate::isLeapYear(1)); + QVERIFY(QDate::isLeapYear(-1)); + QVERIFY(!QDate::isLeapYear(0)); // Doesn't exist QVERIFY(!QDate::isLeapYear(1)); + QVERIFY(!QDate::isLeapYear(2)); + QVERIFY(!QDate::isLeapYear(3)); QVERIFY(QDate::isLeapYear(4)); QVERIFY(!QDate::isLeapYear(7)); QVERIFY(QDate::isLeapYear(8)); @@ -910,5 +912,37 @@ void tst_QDate::standaloneLongMonthName() const } } +void tst_QDate::roundtrip() const +{ + // Test round trip, this exercises setDate(), isValid(), isLeapYear(), + // year(), month(), day(), julianDayFromDate(), and getDateFromJulianDay() + // to ensure they are internally consistent (but doesn't guarantee correct) + + // Test Julian round trip in both BC and AD + QDate testDate; + QDate loopDate = QDate::fromJulianDay(1684899); // 1 Jan 100 BC + while ( loopDate.toJulianDay() <= 1757948 ) { // 31 Dec 100 AD + testDate.setDate( loopDate.year(), loopDate.month(), loopDate.day() ); + QCOMPARE( loopDate.toJulianDay(), testDate.toJulianDay() ); + loopDate = loopDate.addDays(1); + } + + // Test Julian and Gregorian round trip during changeover period + loopDate = QDate::fromJulianDay(2298153); // 1 Jan 1580 AD + while ( loopDate.toJulianDay() <= 2300334 ) { // 31 Dec 1585 AD + testDate.setDate( loopDate.year(), loopDate.month(), loopDate.day() ); + QCOMPARE( loopDate.toJulianDay(), testDate.toJulianDay() ); + loopDate = loopDate.addDays(1); + } + + // Test Gregorian round trip during current useful period + loopDate = QDate::fromJulianDay(2378497); // 1 Jan 1900 AD + while ( loopDate.toJulianDay() <= 2488433 ) { // 31 Dec 2100 AD + testDate.setDate( loopDate.year(), loopDate.month(), loopDate.day() ); + QCOMPARE( loopDate.toJulianDay(), testDate.toJulianDay() ); + loopDate = loopDate.addDays(1); + } +} + QTEST_APPLESS_MAIN(tst_QDate) #include "tst_qdate.moc" -- cgit v0.12 From 3becb116bbbd9f87764cebe6813a254abc291c04 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 30 Mar 2010 12:10:46 +0200 Subject: Fix installation of qmldir files The old pro files did not actually install the qmldir files in clean builds. These ones should work. Reviewed-by: Harald Fernengel --- src/imports/multimedia/multimedia.pro | 2 +- src/imports/particles/particles.pro | 2 +- src/imports/webkit/webkit.pro | 2 +- src/imports/widgets/widgets.pro | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/imports/multimedia/multimedia.pro b/src/imports/multimedia/multimedia.pro index 8792e2b..78618fc 100644 --- a/src/imports/multimedia/multimedia.pro +++ b/src/imports/multimedia/multimedia.pro @@ -20,7 +20,7 @@ SOURCES += \ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir +qmldir.files += $$PWD/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH symbian:{ diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro index 53d9c24..a46db8c 100644 --- a/src/imports/particles/particles.pro +++ b/src/imports/particles/particles.pro @@ -14,7 +14,7 @@ HEADERS += \ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir +qmldir.files += $$PWD/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH symbian:{ diff --git a/src/imports/webkit/webkit.pro b/src/imports/webkit/webkit.pro index a11f87f..7463a7f 100644 --- a/src/imports/webkit/webkit.pro +++ b/src/imports/webkit/webkit.pro @@ -11,7 +11,7 @@ HEADERS += qdeclarativewebview_p.h \ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir +qmldir.files += $$PWD/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH symbian:{ diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro index bf2576d..cccd8b4 100644 --- a/src/imports/widgets/widgets.pro +++ b/src/imports/widgets/widgets.pro @@ -15,7 +15,7 @@ HEADERS += \ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH -qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir +qmldir.files += $$PWD/qmldir qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH symbian:{ -- cgit v0.12 From 84c7f73e8405b7e89202a2d3dcab140a656d618a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 30 Mar 2010 12:06:10 +0200 Subject: Compile on MingW MingW apparently doesn't support the GDI function GetCharABCWidthsI(), so the getGlyphBearings()-optimization is disabled for that compiler. Reviewed-by: Friedemann Kleint --- src/gui/text/qfontengine_win.cpp | 2 ++ src/gui/text/qfontengine_win_p.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index a133b48..92fb7de 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -649,6 +649,7 @@ static const ushort char_table[] = { static const int char_table_entries = sizeof(char_table)/sizeof(ushort); +#ifndef Q_CC_MINGW void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing) { HDC hdc = shared_dc(); @@ -673,6 +674,7 @@ void QFontEngineWin::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal * } #endif } +#endif // Q_CC_MINGW qreal QFontEngineWin::minLeftBearing() const { diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index f19e48e..68b53b5 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -106,7 +106,9 @@ public: virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform); virtual QImage alphaRGBMapForGlyph(glyph_t t, int margin, const QTransform &xform); +#ifndef Q_CC_MINGW virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0); +#endif int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const; void getCMap(); -- cgit v0.12 From 12f0835ca0a8c6b4cb2a516616882fa03ccfd05b Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 30 Mar 2010 09:42:05 +0100 Subject: Added additional logging to Phonon MMF backend In addition to dumping the widget tree which contains the VideoOutput widget, the backend now also dumps the widget tree from the application's active window. This is to allow debugging of problems which stem from the fact that the VideoOutput widget subtree root is not the application's main window. In addition to dumping the Qt widget tree, the backend now also requests the window server to dump the entire window tree. Together, these changes allow easier debugging of video visibility- related problems. Reviewed-by: trustme --- src/3rdparty/phonon/mmf/abstractvideooutput.cpp | 8 ++++++++ src/3rdparty/phonon/mmf/abstractvideoplayer.cpp | 8 +++++++- src/3rdparty/phonon/mmf/videooutput_dsa.cpp | 6 ++++++ src/3rdparty/phonon/mmf/videoplayer_dsa.cpp | 25 +++++++++++++++++++++++-- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractvideooutput.cpp b/src/3rdparty/phonon/mmf/abstractvideooutput.cpp index 3fe66fc..a8aabfd 100644 --- a/src/3rdparty/phonon/mmf/abstractvideooutput.cpp +++ b/src/3rdparty/phonon/mmf/abstractvideooutput.cpp @@ -28,6 +28,8 @@ along with this library. If not, see . #include #include +#include // for QApplication::activeWindow + #include QT_BEGIN_NAMESPACE @@ -162,6 +164,12 @@ void MMF::AbstractVideoOutput::dump() const QScopedPointer visitor(new ObjectDump::QVisitor); visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs ObjectDump::addDefaultAnnotators(*visitor); + + if (QWidget *window = QApplication::activeWindow()) { + TRACE("Dumping from root window 0x%08x:", window); + ObjectDump::dumpTreeFromLeaf(*window, *visitor); + } + TRACE("Dumping tree from leaf 0x%08x:", this); ObjectDump::dumpTreeFromLeaf(*this, *visitor); diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp index 8cb9db5..c2bcce0 100644 --- a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp @@ -193,11 +193,14 @@ qint64 MMF::AbstractVideoPlayer::totalTime() const void MMF::AbstractVideoPlayer::videoWindowChanged() { - TRACE_CONTEXT(AbstractVideoPlayer::videoOutputRegionChanged, EVideoInternal); + TRACE_CONTEXT(AbstractVideoPlayer::videoWindowChanged, EVideoInternal); TRACE_ENTRY("state %d", state()); m_window = m_videoOutput ? m_videoOutput->videoWindow() : 0; + if (m_videoOutput) + m_videoOutput->dump(); + handleVideoWindowChanged(); TRACE_EXIT_0(); @@ -253,6 +256,9 @@ void MMF::AbstractVideoPlayer::MvpuoPrepareComplete(TInt aError) TRAPD(err, getVideoClipParametersL(aError)); if (KErrNone == err) { + if (m_videoOutput) + m_videoOutput->dump(); + maxVolumeChanged(m_player->MaxVolume()); if (m_videoOutput) diff --git a/src/3rdparty/phonon/mmf/videooutput_dsa.cpp b/src/3rdparty/phonon/mmf/videooutput_dsa.cpp index a5e2ac8..4f9ad7f 100644 --- a/src/3rdparty/phonon/mmf/videooutput_dsa.cpp +++ b/src/3rdparty/phonon/mmf/videooutput_dsa.cpp @@ -101,11 +101,17 @@ void MMF::DsaVideoOutput::ancestorMoved() void MMF::DsaVideoOutput::beginNativePaintEvent(const QRect & /*controlRect*/) { + TRACE_CONTEXT(DsaVideoOutput::beginNativePaintEvent, EVideoInternal); + TRACE_ENTRY_0(); + emit beginVideoWindowNativePaint(); } void MMF::DsaVideoOutput::endNativePaintEvent(const QRect & /*controlRect*/) { + TRACE_CONTEXT(DsaVideoOutput::endNativePaintEvent, EVideoInternal); + TRACE_ENTRY_0(); + // Ensure that draw ops are executed into the WSERV output framebuffer CCoeEnv::Static()->WsSession().Flush(); diff --git a/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp index 732d2d9..226d079 100644 --- a/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp +++ b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp @@ -190,6 +190,9 @@ public: void getDsaRegion(RWsSession &session, const RWindowBase &window) { + // Dump complete window tree + session.LogCommand(RWsSession::ELoggingStatusDump); + RDirectScreenAccess dsa(session); TInt err = dsa.Construct(); CDummyAO ao; @@ -214,7 +217,7 @@ void getDsaRegion(RWsSession &session, const RWindowBase &window) void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters) { TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal); - TRACE_ENTRY_0(); + TRACE_ENTRY("parameters 0x%x", parameters); if (!m_window) return; @@ -265,17 +268,32 @@ void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters) void MMF::DsaVideoPlayer::startDirectScreenAccess() { + TRACE_CONTEXT(DsaVideoPlayer::startDirectScreenAccess, EVideoInternal); + TRACE_ENTRY("dsaActive %d", m_dsaActive); + + int err = KErrNone; + if (!m_dsaActive) { - TRAPD(err, m_player->StartDirectScreenAccessL()); + TRAP(err, m_player->StartDirectScreenAccessL()); if (KErrNone == err) m_dsaActive = true; else setError(tr("Video display error"), err); } + + if (m_videoOutput) + m_videoOutput->dump(); + + TRACE_EXIT("error %d", err); } bool MMF::DsaVideoPlayer::stopDirectScreenAccess() { + TRACE_CONTEXT(DsaVideoPlayer::stopDirectScreenAccess, EVideoInternal); + TRACE_ENTRY("dsaActive %d", m_dsaActive); + + int err = KErrNone; + const bool dsaWasActive = m_dsaActive; if (m_dsaActive) { TRAPD(err, m_player->StopDirectScreenAccessL()); @@ -284,6 +302,9 @@ bool MMF::DsaVideoPlayer::stopDirectScreenAccess() else setError(tr("Video display error"), err); } + + TRACE_EXIT("error %d", err); + return dsaWasActive; } -- cgit v0.12 From 2d9260e863ff2e3a5bb77d37b2b9b90072bce825 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 30 Mar 2010 13:03:10 +0200 Subject: qdoc: Added
elements to some html output for class references. Task: QTBUG-9504 --- tools/qdoc3/codemarker.cpp | 2 +- tools/qdoc3/codemarker.h | 24 +++++++++++--- tools/qdoc3/cppcodemarker.cpp | 76 ++++++++++++++++++++++++++++--------------- tools/qdoc3/htmlgenerator.cpp | 8 ++++- tools/qdoc3/qscodemarker.cpp | 18 +++++----- 5 files changed, 86 insertions(+), 42 deletions(-) diff --git a/tools/qdoc3/codemarker.cpp b/tools/qdoc3/codemarker.cpp index 15f2c2d..818a91f 100644 --- a/tools/qdoc3/codemarker.cpp +++ b/tools/qdoc3/codemarker.cpp @@ -457,7 +457,7 @@ bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status) void CodeMarker::append(QList
& sectionList, const FastSection& fs) { if (!fs.isEmpty()) { - Section section(fs.name,fs.singularMember,fs.pluralMember); + Section section(fs.name,fs.divClass,fs.singularMember,fs.pluralMember); section.members = fs.memberMap.values(); section.reimpMembers = fs.reimpMemberMap.values(); section.inherited = fs.inherited; diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h index 1b21753..aab8a9c 100644 --- a/tools/qdoc3/codemarker.h +++ b/tools/qdoc3/codemarker.h @@ -58,6 +58,7 @@ class Tree; struct Section { QString name; + QString divClass; QString singularMember; QString pluralMember; NodeList members; @@ -66,9 +67,11 @@ struct Section Section() { } Section(const QString& name0, + const QString& divClass0, const QString& singularMember0, const QString& pluralMember0) - : name(name0), + : name(name0), + divClass(divClass0), singularMember(singularMember0), pluralMember(pluralMember0) { } void appendMember(Node* node) { members.append(node); } @@ -79,6 +82,7 @@ struct FastSection { const InnerNode *innerNode; QString name; + QString divClass; QString singularMember; QString pluralMember; QMap memberMap; @@ -86,20 +90,30 @@ struct FastSection QList > inherited; FastSection(const InnerNode *innerNode0, - const QString& name0 = "", - const QString& singularMember0 = "member", - const QString& pluralMember0 = "members") + const QString& name0, + const QString& divClass0, + const QString& singularMember0, + const QString& pluralMember0) : innerNode(innerNode0), name(name0), + divClass(divClass0), singularMember(singularMember0), pluralMember(pluralMember0) { } bool isEmpty() const { - return (memberMap.isEmpty() && inherited.isEmpty() && + return (memberMap.isEmpty() && + inherited.isEmpty() && reimpMemberMap.isEmpty()); } }; +#if 0 + const QString& name0 = "", + const QString& divClass0 = "", + const QString& singularMember0 = "member", + const QString& pluralMember0 = "members") +#endif + class CodeMarker { public: diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp index 3ff6ebe..c4ee054 100644 --- a/tools/qdoc3/cppcodemarker.cpp +++ b/tools/qdoc3/cppcodemarker.cpp @@ -482,55 +482,66 @@ QList
CppCodeMarker::sections(const InnerNode *inner, if (style == Summary) { FastSection privateFunctions(classe, "Private Functions", + "", "private function", "private functions"); - FastSection privateSlots(classe, "Private Slots", "private slot", "private slots"); - FastSection privateTypes(classe, "Private Types", "private type", "private types"); + FastSection privateSlots(classe, "Private Slots", "", "private slot", "private slots"); + FastSection privateTypes(classe, "Private Types", "", "private type", "private types"); FastSection protectedFunctions(classe, "Protected Functions", + "", "protected function", "protected functions"); FastSection protectedSlots(classe, "Protected Slots", + "", "protected slot", "protected slots"); FastSection protectedTypes(classe, "Protected Types", + "", "protected type", "protected types"); FastSection protectedVariables(classe, "Protected Variables", + "", "protected type", "protected variables"); FastSection publicFunctions(classe, "Public Functions", + "", "public function", "public functions"); - FastSection publicSignals(classe, "Signals", "signal", "signals"); - FastSection publicSlots(classe, "Public Slots", "public slot", "public slots"); - FastSection publicTypes(classe, "Public Types", "public type", "public types"); + FastSection publicSignals(classe, "Signals", "", "signal", "signals"); + FastSection publicSlots(classe, "Public Slots", "", "public slot", "public slots"); + FastSection publicTypes(classe, "Public Types", "", "public type", "public types"); FastSection publicVariables(classe, "Public Variables", - "public type", + "", + "public variable", "public variables"); - FastSection properties(classe, "Properties", "property", "properties"); + FastSection properties(classe, "Properties", "", "property", "properties"); FastSection relatedNonMembers(classe, "Related Non-Members", + "", "related non-member", "related non-members"); FastSection staticPrivateMembers(classe, "Static Private Members", + "", "static private member", "static private members"); FastSection staticProtectedMembers(classe, "Static Protected Members", + "", "static protected member", "static protected members"); FastSection staticPublicMembers(classe, "Static Public Members", + "", "static public member", "static public members"); - FastSection macros(inner, "Macros", "macro", "macros"); + FastSection macros(inner, "Macros", "", "macro", "macros"); NodeList::ConstIterator r = classe->relatedNodes().begin(); while (r != classe->relatedNodes().end()) { @@ -666,12 +677,12 @@ QList
CppCodeMarker::sections(const InnerNode *inner, append(sections, macros); } else if (style == Detailed) { - FastSection memberFunctions(classe,"Member Function Documentation"); - FastSection memberTypes(classe,"Member Type Documentation"); - FastSection memberVariables(classe,"Member Variable Documentation"); - FastSection properties(classe,"Property Documentation"); - FastSection relatedNonMembers(classe,"Related Non-Members"); - FastSection macros(classe,"Macro Documentation"); + FastSection memberFunctions(classe,"Member Function Documentation","func","member","members"); + FastSection memberTypes(classe,"Member Type Documentation","types","member","members"); + FastSection memberVariables(classe,"Member Variable Documentation","vars","member","members"); + FastSection properties(classe,"Property Documentation","prop","member","members"); + FastSection relatedNonMembers(classe,"Related Non-Members","relnonmem","member","members"); + FastSection macros(classe,"Macro Documentation","macros","member","members"); NodeList::ConstIterator r = classe->relatedNodes().begin(); while (r != classe->relatedNodes().end()) { @@ -717,7 +728,7 @@ QList
CppCodeMarker::sections(const InnerNode *inner, append(sections, macros); } else { - FastSection all(classe); + FastSection all(classe,"","","member","members"); QStack stack; stack.push(classe); @@ -747,25 +758,29 @@ QList
CppCodeMarker::sections(const InnerNode *inner, if (style == Summary || style == Detailed) { FastSection namespaces(inner, "Namespaces", + style == Detailed ? "nmspace" : "", "namespace", "namespaces"); FastSection classes(inner, "Classes", + style == Detailed ? "classes" : "", "class", "classes"); FastSection types(inner, - style == Summary ? - "Types" : "Type Documentation", + style == Summary ? "Types" : "Type Documentation", + style == Detailed ? "types" : "", "type", "types"); FastSection functions(inner, style == Summary ? "Functions" : "Function Documentation", + style == Detailed ? "func" : "", "function", "functions"); FastSection macros(inner, style == Summary ? "Macros" : "Macro Documentation", + style == Detailed ? "macros" : "", "macro", "macros"); @@ -1116,26 +1131,32 @@ QList
CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, if (style == Summary) { FastSection qmlproperties(qmlClassNode, "Properties", + "", "property", "properties"); FastSection qmlattachedproperties(qmlClassNode, "Attached Properties", + "", "property", "properties"); FastSection qmlsignals(qmlClassNode, - "Signals", - "signal", - "signals"); + "Signals", + "", + "signal", + "signals"); FastSection qmlattachedsignals(qmlClassNode, "Attached Signals", + "", "signal", "signals"); FastSection qmlmethods(qmlClassNode, "Methods", + "", "method", "methods"); FastSection qmlattachedmethods(qmlClassNode, "Attached Methods", + "", "method", "methods"); @@ -1179,12 +1200,15 @@ QList
CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, append(sections,qmlattachedmethods); } else if (style == Detailed) { - FastSection qmlproperties(qmlClassNode, "Property Documentation"); - FastSection qmlattachedproperties(qmlClassNode,"Attached Property Documentation"); - FastSection qmlsignals(qmlClassNode,"Signal Documentation"); - FastSection qmlattachedsignals(qmlClassNode,"Attached Signal Documentation"); - FastSection qmlmethods(qmlClassNode,"Method Documentation"); - FastSection qmlattachedmethods(qmlClassNode,"Attached Method Documentation"); + FastSection qmlproperties(qmlClassNode, "Property Documentation","qmlprop","member","members"); + FastSection qmlattachedproperties(qmlClassNode,"Attached Property Documentation","qmlattprop", + "member","members"); + FastSection qmlsignals(qmlClassNode,"Signal Documentation","qmlsig","member","members"); + FastSection qmlattachedsignals(qmlClassNode,"Attached Signal Documentation","qmlattsig", + "member","members"); + FastSection qmlmethods(qmlClassNode,"Method Documentation","qmlmeth","member","members"); + FastSection qmlattachedmethods(qmlClassNode,"Attached Method Documentation","qmlattmeth", + "member","members"); NodeList::ConstIterator c = qmlClassNode->childNodes().begin(); while (c != qmlClassNode->childNodes().end()) { if ((*c)->subType() == Node::QmlPropertyGroup) { diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index cd3da3e..fb9fa95 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -696,7 +696,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, QList
sections; QList
::ConstIterator s; for (int i=0; idoc().isEmpty()) { out() << "
\n" + << "
\n" << "

" << "Detailed Description" << "

\n"; generateBody(inner, marker); + out() << "
\n"; generateAlsoList(inner, marker); } @@ -1365,6 +1367,8 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, s = sections.begin(); while (s != sections.end()) { out() << "
\n"; + if (!(*s).divClass.isEmpty()) + out() << "
\n"; out() << "

" << protectEnc((*s).name) << "

\n"; NodeList::ConstIterator m = (*s).members.begin(); @@ -1414,6 +1418,8 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, } ++m; } + if (!(*s).divClass.isEmpty()) + out() << "
\n"; ++s; } generateFooter(inner); diff --git a/tools/qdoc3/qscodemarker.cpp b/tools/qdoc3/qscodemarker.cpp index 89c9c5c..d4b8e80 100644 --- a/tools/qdoc3/qscodemarker.cpp +++ b/tools/qdoc3/qscodemarker.cpp @@ -279,11 +279,11 @@ QList
QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle sty const ClassNode *classe = static_cast(inner); if ( style == Summary ) { - FastSection enums(classe, "Enums", "enum", "enums"); - FastSection functions(classe, "Functions", "function", "functions"); - FastSection readOnlyProperties(classe, "Read-Only Properties", "property", "properties"); - FastSection signalz(classe, "Signals", "signal", "signals"); - FastSection writableProperties(classe, "Writable Properties", "property", "properties"); + FastSection enums(classe, "Enums", "", "enum", "enums"); + FastSection functions(classe, "Functions", "", "function", "functions"); + FastSection readOnlyProperties(classe, "", "Read-Only Properties", "property", "properties"); + FastSection signalz(classe, "Signals", "", "signal", "signals"); + FastSection writableProperties(classe, "", "Writable Properties", "property", "properties"); QStack stack; stack.push( classe ); @@ -328,9 +328,9 @@ QList
QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle sty append( sections, functions ); append( sections, signalz ); } else if ( style == Detailed ) { - FastSection enums( classe, "Enum Documentation" ); - FastSection functionsAndSignals( classe, "Function and Signal Documentation" ); - FastSection properties( classe, "Property Documentation" ); + FastSection enums( classe, "Enum Documentation", "", "member", "members"); + FastSection functionsAndSignals( classe, "Function and Signal Documentation", "", "member", "members"); + FastSection properties( classe, "Property Documentation", "", "member", "members"); NodeList::ConstIterator c = classe->childNodes().begin(); while ( c != classe->childNodes().end() ) { @@ -349,7 +349,7 @@ QList
QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle sty append( sections, properties ); append( sections, functionsAndSignals ); } else { // ( style == SeparateList ) - FastSection all( classe ); + FastSection all(classe, "", "", "member", "members"); QStack stack; stack.push( classe ); -- cgit v0.12 From fb9493870fa3212b0f7a917aa92a0a30d77f3b1e Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 30 Mar 2010 13:47:13 +0200 Subject: Hack .pro files on windows to define QT_NO_EGL Temporary fix until configure.exe can be re-compiled. Reviewed-By: TrustMe --- src/gui/gui.pro | 1 + tests/auto/qgl/qgl.pro | 1 + tests/auto/qglbuffer/qglbuffer.pro | 2 ++ tests/auto/qglthreads/qglthreads.pro | 2 ++ 4 files changed, 6 insertions(+) diff --git a/src/gui/gui.pro b/src/gui/gui.pro index cbdbb5c..b22f732 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -41,6 +41,7 @@ include(math3d/math3d.pri) include(effects/effects.pri) contains(QT_CONFIG, egl): include(egl/egl.pri) +win32:!wince*: DEFINES += QT_NO_EGL embedded: QT += network diff --git a/tests/auto/qgl/qgl.pro b/tests/auto/qgl/qgl.pro index 5f058f9..20f8018 100644 --- a/tests/auto/qgl/qgl.pro +++ b/tests/auto/qgl/qgl.pro @@ -7,6 +7,7 @@ requires(contains(QT_CONFIG,opengl)) QT += opengl contains(QT_CONFIG,egl):DEFINES += QGL_EGL +win32:!wince*: DEFINES += QT_NO_EGL SOURCES += tst_qgl.cpp RESOURCES = qgl.qrc diff --git a/tests/auto/qglbuffer/qglbuffer.pro b/tests/auto/qglbuffer/qglbuffer.pro index 07d05bb..5627d2d 100644 --- a/tests/auto/qglbuffer/qglbuffer.pro +++ b/tests/auto/qglbuffer/qglbuffer.pro @@ -6,4 +6,6 @@ load(qttest_p4) requires(contains(QT_CONFIG,opengl)) QT += opengl +win32:!wince*: DEFINES += QT_NO_EGL + SOURCES += tst_qglbuffer.cpp diff --git a/tests/auto/qglthreads/qglthreads.pro b/tests/auto/qglthreads/qglthreads.pro index 73b75d4..883eef2 100644 --- a/tests/auto/qglthreads/qglthreads.pro +++ b/tests/auto/qglthreads/qglthreads.pro @@ -2,6 +2,8 @@ load(qttest_p4) requires(contains(QT_CONFIG,opengl)) QT += opengl +win32:!wince*: DEFINES += QT_NO_EGL + HEADERS += tst_qglthreads.h SOURCES += tst_qglthreads.cpp -- cgit v0.12 From 1441db525dd0f5a3b2f45549cfa4173adac1a877 Mon Sep 17 00:00:00 2001 From: mae Date: Tue, 30 Mar 2010 14:34:00 +0200 Subject: Fix qml plugin loading with specified path in qmldir The fix makes it possible to specify an ABSOLUTE path as well, e.g.: plugin mimehunt C:\sys\bin --- src/declarative/qml/qdeclarativeengine.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index abac086..bb742ee 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1463,13 +1463,14 @@ public: QDeclarativeDirComponents importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) { QFile file(absoluteFilePath); - QString dir = QFileInfo(file).path(); QString filecontent; if (file.open(QFile::ReadOnly)) { filecontent = QString::fromUtf8(file.readAll()); if (qmlImportTrace()) qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; } + QDir dir = QFileInfo(file).dir(); + QDeclarativeDirParser qmldirParser; qmldirParser.setSource(filecontent); qmldirParser.parse(); @@ -1479,9 +1480,13 @@ public: foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { - QDir pluginDir(dir + QDir::separator() + plugin.path); - if (dir.startsWith(QLatin1Char(':'))) + + QDir pluginDir = dir.absoluteFilePath(plugin.path); + + // hack for resources, should probably go away + if (absoluteFilePath.startsWith(QLatin1Char(':'))) pluginDir = QDir(QCoreApplication::applicationDirPath()); + QString resolvedFilePath = QDeclarativeEnginePrivate::get(engine) ->resolvePlugin(pluginDir, -- cgit v0.12 From 6e173f50f6b04057040b1e5c4125e3f1b6f885ce Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 30 Mar 2010 13:57:10 +0200 Subject: Fix setting font for QStaticText on Linux and Mac When using the fallback in QStaticText we have to update its font to the current painter's font, otherwise we will override the painter's font with the one cached in the QStaticText object. Reviewed-by: Olivier --- src/gui/painting/qpainter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 7b5fcc2..898a996 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5844,6 +5844,11 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText QStaticTextPrivate *staticText_d = const_cast(QStaticTextPrivate::get(&staticText)); + if (font() != staticText_d->font) { + staticText_d->font = font(); + staticText_d->needsRelayout = true; + } + // If we don't have an extended paint engine, or if the painter is projected, // we go through standard code path if (d->extended == 0 || !d->state->matrix.isAffine()) { @@ -5880,11 +5885,6 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText staticTextNeedsReinit = true; } - if (font() != staticText_d->font) { - staticText_d->font = font(); - staticTextNeedsReinit = true; - } - // Recreate the layout of the static text because the matrix or font has changed if (staticTextNeedsReinit) staticText_d->init(); -- cgit v0.12 From 1dece0c73feb0307f90acdc127891fa6313da4cd Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 30 Mar 2010 14:20:56 +0200 Subject: Support the pen set on the painter in QStaticText when using rich text When using rich text, QStaticText should still respect the painter's pen color as the default. Since QTextDocument does not respect the pen set on the painter, we need to set its default style sheet to include the pen color as well. Reviewed-by: Olivier --- src/gui/text/qstatictext.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 45252d8..5f31ef0 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -584,6 +584,11 @@ void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p) textLayout.draw(p, topLeftPosition); } else { QTextDocument document; + QColor color = p->pen().color(); + document.setDefaultStyleSheet(QString::fromLatin1("body { color: #%1%2%3 }") + .arg(QString::number(color.red(), 16), 2, QLatin1Char('0')) + .arg(QString::number(color.green(), 16), 2, QLatin1Char('0')) + .arg(QString::number(color.blue(), 16), 2, QLatin1Char('0'))); document.setDefaultFont(font); document.setDocumentMargin(0.0); if (textWidth >= 0.0) -- cgit v0.12 From 601b68cbff1d0fc3f718d658384e75fce189381a Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Tue, 30 Mar 2010 15:40:36 +0300 Subject: QS60Style: Custom QPushButton: Heigth is calculated wrongly If button contains a layout with widgets instead of having direct label and icon, QS60Style calculates the size of the content incorrectly. This is regression for a fix to QTBUG-7586. Now style ignores orginal size of pushbutton and tries to calculate correct height by itself. Issue is fixed by selecting teh bigger of orginal height and calculated height. Task-number: QT-3197 Reviewed-by: Alessandro Portale --- src/gui/styles/qs60style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 000696c..f49acc4 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2433,7 +2433,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, const int contentHeight = qMax(qMax(iconHeight, decoratorHeight) + pixelMetric(PM_ButtonMargin), textHeight + 2*pixelMetric(PM_ButtonMargin)); - sz.setHeight(contentHeight); + sz.setHeight(qMax(sz.height(), contentHeight)); sz += QSize(2 * pixelMetric(PM_ButtonMargin), 0); } break; -- cgit v0.12 From 853894dca607a0266f3c6d23c937dd5f55e551af Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 30 Mar 2010 14:55:24 +0200 Subject: Fix QStaticText test on Mac Avoid taking fast path in drawText() since this is optimized and does not draw text completely accurate on a floating point font engine. Rather we use the slightly slower but more accurate drawText() which takes a rectangle so that the results are identical to the ones produced by drawStaticText(). Reviewed-by: TrustMe --- tests/auto/qstatictext/tst_qstatictext.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index e7a22b3..c7801ac 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -239,10 +239,10 @@ void tst_QStaticText::setFont() imageDrawText.fill(Qt::white); { QPainter p(&imageDrawText); - p.drawText(0, 0 + QFontMetrics(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(QRectF(0, 0, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); p.setFont(font); - p.drawText(11, 120 + QFontMetrics(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(QRectF(11, 120, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); } QPixmap imageDrawStaticText(1000, 1000); @@ -342,7 +342,7 @@ void tst_QStaticText::rotatedPainter() { QPainter p(&imageDrawText); p.rotate(30.0); - p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(QRectF(0, 0, 1000, 100), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); } QPixmap imageDrawStaticText(1000, 1000); @@ -469,10 +469,10 @@ void tst_QStaticText::transformationChanged() p.rotate(33.0); p.scale(0.5, 0.7); - p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(QRectF(0, 0, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); p.scale(7.0, 5.0); - p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); + p.drawText(QRectF(0, 0, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); } QPixmap imageDrawStaticText(1000, 1000); -- cgit v0.12 From f39a71a6c44e5011a169dfa6840a33a9b5075c77 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Mar 2010 15:33:13 +0200 Subject: Autotest: don't allow choosing between debug/release mode. You can't build for debug mode on Windows if Qt wasn't built in debug mode. So force the selection to be exactly what Qt was built. Reviewed-by: Trust Me --- tests/auto/qsharedpointer/externaltests.cpp | 17 +++-------------- tests/auto/qsharedpointer/externaltests.h | 3 --- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 2 +- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/tests/auto/qsharedpointer/externaltests.cpp b/tests/auto/qsharedpointer/externaltests.cpp index eb2f27d..0b1ef19 100644 --- a/tests/auto/qsharedpointer/externaltests.cpp +++ b/tests/auto/qsharedpointer/externaltests.cpp @@ -140,7 +140,6 @@ namespace QTest { QExternalTestPrivate() : qtModules(QExternalTest::QtCore | QExternalTest::QtGui | QExternalTest::QtTest), appType(QExternalTest::AutoApplication), - debugMode(true), exitCode(-1) { } @@ -156,7 +155,6 @@ namespace QTest { QByteArray programHeader; QExternalTest::QtModules qtModules; QExternalTest::ApplicationType appType; - bool debugMode; QString temporaryDir; QByteArray sourceCode; @@ -190,16 +188,6 @@ namespace QTest { delete d; } - bool QExternalTest::isDebugMode() const - { - return d->debugMode; - } - - void QExternalTest::setDebugMode(bool enable) - { - d->debugMode = enable; - } - QList QExternalTest::qmakeSettings() const { return d->qmakeLines; @@ -524,10 +512,11 @@ namespace QTest { "INCLUDEPATH += . "); projectFile.write(QFile::encodeName(QDir::currentPath())); - if (debugMode) +#ifndef QT_NO_DEBUG projectFile.write("\nCONFIG += debug\n"); - else +#else projectFile.write("\nCONFIG += release\n"); +#endif QByteArray extraSources = QFile::encodeName(extraProgramSources.join(" ")); if (!extraSources.isEmpty()) { diff --git a/tests/auto/qsharedpointer/externaltests.h b/tests/auto/qsharedpointer/externaltests.h index 5e79a7d..1170cd5 100644 --- a/tests/auto/qsharedpointer/externaltests.h +++ b/tests/auto/qsharedpointer/externaltests.h @@ -91,9 +91,6 @@ namespace QTest { QApplicationGuiServer }; - bool isDebugMode() const; - void setDebugMode(bool enable); - QList qmakeSettings() const; void setQmakeSettings(const QList &settings); diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 7cfa868..cb32c9a 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -1717,11 +1717,11 @@ void tst_QSharedPointer::invalidConstructs() #endif QTest::QExternalTest test; - test.setDebugMode(true); test.setQtModules(QTest::QExternalTest::QtCore); test.setExtraProgramSources(QStringList() << SRCDIR "forwarddeclared.cpp"); test.setProgramHeader( "#define QT_SHAREDPOINTER_TRACK_POINTERS\n" + "#define QT_DEBUG\n" "#include \n" "#include \n" "\n" -- cgit v0.12 From c626bf34e14ea05c986053c0f87e02f4b0bd8cdd Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 29 Mar 2010 20:37:20 +0200 Subject: no need for CONFIG += ordered here --- tools/linguist/linguist.pro | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/linguist/linguist.pro b/tools/linguist/linguist.pro index e1c8a63..85ecd5a 100644 --- a/tools/linguist/linguist.pro +++ b/tools/linguist/linguist.pro @@ -4,5 +4,3 @@ SUBDIRS = \ lrelease \ lupdate \ lconvert -CONFIG += ordered - -- cgit v0.12 From 5f8bf77862a425c39a683358aafa4d52db1b8ac3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 29 Mar 2010 21:04:51 +0200 Subject: speed up by removing nonsense why first determine how to make no newline just to make a newline right afterwards? --- configure | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/configure b/configure index 9a3ee32..de72c46 100755 --- a/configure +++ b/configure @@ -7780,12 +7780,7 @@ for file in .projects .projects.3; do QMAKE="$outpath/bin/qmake" QMAKE_ARGS="$QMAKE_SWITCHES $QMAKE_SPEC_ARGS" if [ "$file" = ".projects.3" ]; then - if echo '\c' | grep '\c' >/dev/null; then - echo -n " (fast)" - else - echo " (fast)\c" - fi - echo + echo " (fast)" cat >"${OUTDIR}/Makefile" < Date: Mon, 29 Mar 2010 21:08:58 +0200 Subject: do not detect the echo-without-newline syntax over and over this is a) more maintainable and b) faster, as it was done in the makefile generation loop as well. --- configure | 42 ++++++++++++------------------------------ 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/configure b/configure index de72c46..0cf7542 100755 --- a/configure +++ b/configure @@ -173,6 +173,12 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +# detect the "echo without newline" style. usage: echo $ECHO_N "$ECHO_C" +if echo '\c' | grep '\c' >/dev/null; then + ECHO_N=-n +else + ECHO_C='\c' +fi #------------------------------------------------------------------------------- # window system detection @@ -399,11 +405,7 @@ elif [ $COMMERCIAL_USER = "yes" ]; then else if [ -z "$LicenseKeyExt" ]; then echo - if echo '\c' | grep '\c' >/dev/null; then - echo -n "Please enter your license key: " - else - echo "Please enter your license key: \c" - fi + echo $ECHO_N "Please enter your license key: $ECHO_C" read LicenseKeyExt Licensee="Unknown user" fi @@ -3966,11 +3968,7 @@ elif [ "$Edition" = "OpenSource" ]; then echo "Type 'yes' to accept this license offer." echo "Type 'no' to decline this license offer." echo - if echo '\c' | grep '\c' >/dev/null; then - echo -n "Do you accept the terms of $affix license? " - else - echo "Do you accept the terms of $affix license? \c" - fi + echo $ECHO_N "Do you accept the terms of $affix license? $ECHO_C" read acceptance fi echo @@ -4001,11 +3999,7 @@ elif [ "$Edition" = "Preview" ]; then echo "Type 'yes' to accept this license offer." echo "Type 'no' to decline this license offer." echo - if echo '\c' | grep '\c' >/dev/null; then - echo -n "Do you accept the terms of the license? " - else - echo "Do you accept the terms of the license? \c" - fi + echo $ECHO_N "Do you accept the terms of the license? $ECHO_C" read acceptance fi echo @@ -4091,11 +4085,7 @@ elif [ "$Edition" != "OpenSource" ]; then echo "Type 'yes' to accept this license offer." echo "Type 'no' to decline this license offer." echo - if echo '\c' | grep '\c' >/dev/null; then - echo -n "Do you accept the terms of the $TheLicense? " - else - echo "Do you accept the terms of the $TheLicense? \c" - fi + echo $ECHO_N "Do you accept the terms of the $TheLicense? $ECHO_C" read acceptance fi echo @@ -7390,11 +7380,7 @@ else fi if [ "$OPT_VERBOSE" = "yes" ]; then - if echo '\c' | grep '\c' >/dev/null; then - echo -n "qmake vars .......... " - else - echo "qmake vars .......... \c" - fi + echo $ECHO_N "qmake vars .......... $ECHO_C" cat "$QMAKE_VARS_FILE" | tr '\n' ' ' echo "qmake switches ...... $QMAKE_SWITCHES" fi @@ -7771,11 +7757,7 @@ for file in .projects .projects.3; do continue; fi QMAKE_SPEC_ARGS="-spec $SPEC" - if echo '\c' | grep '\c' >/dev/null; then - echo -n " for $a" - else - echo " for $a\c" - fi + echo $ECHO_N " for $a$ECHO_C" QMAKE="$outpath/bin/qmake" QMAKE_ARGS="$QMAKE_SWITCHES $QMAKE_SPEC_ARGS" -- cgit v0.12 From 09ce407aaa4a00013a606bf0011faf6cbc654c72 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 30 Mar 2010 15:56:26 +0200 Subject: Doc: Added links and notes to modules, ActiveQt and XMLPatterns docs. Reviewed-by: Trust Me --- doc/src/frameworks-technologies/activeqt.qdoc | 5 ++++- doc/src/modules.qdoc | 11 +++++++++++ src/xmlpatterns/api/qxmlresultitems.cpp | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/src/frameworks-technologies/activeqt.qdoc b/doc/src/frameworks-technologies/activeqt.qdoc index 5e8473f..6273337 100644 --- a/doc/src/frameworks-technologies/activeqt.qdoc +++ b/doc/src/frameworks-technologies/activeqt.qdoc @@ -70,7 +70,10 @@ controls. \endlist - The ActiveQt framework consists of two frameworks: + For more information about using ActiveX with Qt, see + \l{Building ActiveX servers and controls with Qt}. + + The ActiveQt framework consists of two modules: \list \o The \l{Using ActiveX controls and COM objects in Qt}{QAxContainer} diff --git a/doc/src/modules.qdoc b/doc/src/modules.qdoc index 44d6ed6..2b749de 100644 --- a/doc/src/modules.qdoc +++ b/doc/src/modules.qdoc @@ -517,6 +517,13 @@ This module is part of the \l{Qt Full Framework Edition} and the \l{Open Source Versions of Qt}. + \section1 Further Links + + General overviews of XQuery and XSchema can be found in the + \l{Using XML Technologies} document. + + An introduction to the XQuery language can be found in \l{A Short Path to XQuery}. + \section1 License Information The XML Schema implementation provided by this module contains the \c xml.xsd file @@ -855,6 +862,8 @@ \brief The QAxContainer module is a Windows-only extension for accessing ActiveX controls and COM objects. + QAxServer is part of the \l{ActiveQt Framework}. + \section1 License Information The QAxContainer module is not covered by the \l{GNU General Public License (GPL)}, @@ -905,6 +914,8 @@ \brief The QAxServer module is a Windows-only static library that you can use to turn a standard Qt binary into a COM server. + QAxServer is part of the \l{ActiveQt Framework}. + \section1 License Information The QAxContainer module is not covered by the \l{GNU General Public License (GPL)}, diff --git a/src/xmlpatterns/api/qxmlresultitems.cpp b/src/xmlpatterns/api/qxmlresultitems.cpp index c474082..98c5bdc 100644 --- a/src/xmlpatterns/api/qxmlresultitems.cpp +++ b/src/xmlpatterns/api/qxmlresultitems.cpp @@ -70,6 +70,10 @@ QT_BEGIN_NAMESPACE sequence and returns it, and current() always returns the QXmlItem that next() returned the last time it was called. + \note When using the QXmlResultItems overload of QXmlQuery::evaluateTo() + to execute a query, it is advisable to create a new instance of this + class for each new set of results rather than reusing an old instance. + \sa QXmlItem::isNode(), QXmlItem::isAtomicValue(), QXmlNodeModelIndex */ -- cgit v0.12 From dbbd84e61bf433495268c639670f9b9f82eb56f4 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 30 Mar 2010 16:15:21 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( ecfa4583e573ce4dff1f0df12f6bdba3022376e5 ) Changes in WebKit/qt since the last update: * r56370 - https://bugs.webkit.org/show_bug.cgi?id=34350 -- [Symbian] More efficient aligned memory allocation for JSC Collector --- src/3rdparty/webkit/JavaScriptCore/ChangeLog | 28 +++++ .../webkit/JavaScriptCore/JavaScriptCore.pri | 6 + .../webkit/JavaScriptCore/runtime/Collector.cpp | 47 ++------ .../webkit/JavaScriptCore/runtime/Collector.h | 9 ++ .../wtf/symbian/BlockAllocatorSymbian.cpp | 132 +++++++++++++++++++++ .../wtf/symbian/BlockAllocatorSymbian.h | 120 +++++++++++++++++++ src/3rdparty/webkit/VERSION | 2 +- 7 files changed, 305 insertions(+), 39 deletions(-) create mode 100644 src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp create mode 100644 src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 6446773..8932b3b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,31 @@ +2010-03-22 Siddharth Mathur + + Reviewed by Laszlo Gombos. + + [Symbian] More efficient aligned memory allocation for JSC Collector + https://bugs.webkit.org/show_bug.cgi?id=34350 + + * JavaScriptCore.pri: Added 2 new Symbian source files and HAL linkage + + * runtime/Collector.cpp: Reduced port-specific code and added private data member + (JSC::Heap::Heap): + (JSC::Heap::~Heap): + (JSC::Heap::destroy): + (JSC::Heap::allocateBlock): + (JSC::Heap::freeBlockPtr): + + * runtime/Collector.h: Added private data member + + * wtf/symbian: Added. + * wtf/symbian/BlockAllocatorSymbian.cpp: Added. + (WTF::AlignedBlockAllocator::AlignedBlockAllocator): Helper class to allocate + aligned blocks more efficiently as required by Collector + (WTF::AlignedBlockAllocator::alloc): + (WTF::AlignedBlockAllocator::free): + (WTF::AlignedBlockAllocator::destroy): + (WTF::AlignedBlockAllocator::~AlignedBlockAllocator): + * wtf/symbian/BlockAllocatorSymbian.h: Added. + 2010-02-09 Janne Koskinen Reviewed by Laszlo Gombos. diff --git a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri index bb531e5..a0f9f8e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pri @@ -9,6 +9,10 @@ CONFIG(debug, debug|release) { OBJECTS_DIR = obj/release } +symbian { + LIBS += -lhal +} + INCLUDEPATH = \ $$PWD \ $$PWD/.. \ @@ -23,6 +27,7 @@ INCLUDEPATH = \ $$PWD/runtime \ $$PWD/wrec \ $$PWD/wtf \ + $$PWD/wtf/symbian \ $$PWD/wtf/unicode \ $$PWD/yarr \ $$PWD/API \ @@ -243,6 +248,7 @@ SOURCES += \ profiler/TreeProfile.cpp \ wtf/DateMath.cpp \ wtf/FastMalloc.cpp \ + wtf/symbian/BlockAllocatorSymbian.cpp \ wtf/Threading.cpp \ wtf/qt/MainThreadQt.cpp diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp index 8b647a0..6626182 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp @@ -52,11 +52,6 @@ #include #include -#elif PLATFORM(SYMBIAN) -#include -#include -#include - #elif PLATFORM(WIN_OS) #include @@ -124,11 +119,6 @@ const size_t ALLOCATIONS_PER_COLLECTION = 4000; // a PIC branch in Mach-O binaries, see . #define MIN_ARRAY_SIZE (static_cast(14)) -#if PLATFORM(SYMBIAN) -const size_t MAX_NUM_BLOCKS = 256; // Max size of collector heap set to 16 MB -static RHeap* userChunk = 0; -#endif - #if ENABLE(JSC_MULTIPLE_THREADS) #if PLATFORM(DARWIN) @@ -165,29 +155,11 @@ Heap::Heap(JSGlobalData* globalData) , m_currentThreadRegistrar(0) #endif , m_globalData(globalData) +#if PLATFORM(SYMBIAN) + , m_blockallocator(JSCCOLLECTOR_VIRTUALMEM_RESERVATION, BLOCK_SIZE) +#endif { ASSERT(globalData); - -#if PLATFORM(SYMBIAN) - // Symbian OpenC supports mmap but currently not the MAP_ANON flag. - // Using fastMalloc() does not properly align blocks on 64k boundaries - // and previous implementation was flawed/incomplete. - // UserHeap::ChunkHeap allows allocation of continuous memory and specification - // of alignment value for (symbian) cells within that heap. - // - // Clarification and mapping of terminology: - // RHeap (created by UserHeap::ChunkHeap below) is continuos memory chunk, - // which can dynamically grow up to 8 MB, - // that holds all CollectorBlocks of this session (static). - // Each symbian cell within RHeap maps to a 64kb aligned CollectorBlock. - // JSCell objects are maintained as usual within CollectorBlocks. - if (!userChunk) { - userChunk = UserHeap::ChunkHeap(0, 0, MAX_NUM_BLOCKS * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); - if (!userChunk) - CRASH(); - } -#endif // PLATFORM(SYMBIAN) - memset(&primaryHeap, 0, sizeof(CollectorHeap)); memset(&numberHeap, 0, sizeof(CollectorHeap)); } @@ -233,7 +205,9 @@ void Heap::destroy() t = next; } #endif - +#if PLATFORM(SYMBIAN) + m_blockallocator.destroy(); +#endif m_globalData = 0; } @@ -247,12 +221,9 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock() // FIXME: tag the region as a JavaScriptCore heap when we get a registered VM tag: . vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT); #elif PLATFORM(SYMBIAN) - // Allocate a 64 kb aligned CollectorBlock - unsigned char* mask = reinterpret_cast(userChunk->Alloc(BLOCK_SIZE)); - if (!mask) + void* address = m_blockallocator.alloc(); + if (!address) CRASH(); - uintptr_t address = reinterpret_cast(mask); - memset(reinterpret_cast(address), 0, BLOCK_SIZE); #elif PLATFORM(WINCE) void* address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); @@ -339,7 +310,7 @@ NEVER_INLINE void Heap::freeBlock(CollectorBlock* block) #if PLATFORM(DARWIN) && !PLATFORM(QT) vm_deallocate(current_task(), reinterpret_cast(block), BLOCK_SIZE); #elif PLATFORM(SYMBIAN) - userChunk->Free(reinterpret_cast(block)); + m_blockallocator.free(reinterpret_cast(block)); #elif PLATFORM(WINCE) VirtualFree(block, 0, MEM_RELEASE); #elif PLATFORM(WIN_OS) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h index 9ca9d18..086e519 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h @@ -35,6 +35,10 @@ #include #endif +#if PLATFORM(SYMBIAN) +#include +#endif + #define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= CELL_SIZE, class_fits_in_cell) namespace JSC { @@ -157,6 +161,11 @@ namespace JSC { pthread_key_t m_currentThreadRegistrar; #endif +#if PLATFORM(SYMBIAN) + // Allocates collector blocks with correct alignment + WTF::AlignedBlockAllocator m_blockallocator; +#endif + JSGlobalData* m_globalData; }; diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp new file mode 100644 index 0000000..cc8fd15 --- /dev/null +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if PLATFORM(SYMBIAN) + +#include "BlockAllocatorSymbian.h" + + +namespace WTF { + +/** Efficiently allocates blocks of size blockSize with blockSize alignment. + * Primarly designed for JSC Collector's needs. + * Not thread-safe. + */ +AlignedBlockAllocator::AlignedBlockAllocator(TUint32 reservationSize, TUint32 blockSize ) + : m_reservation(reservationSize), + m_blockSize(blockSize) +{ + + // Get system's page size value. + SYMBIAN_PAGESIZE(m_pageSize); + + // We only accept multiples of system page size for both initial reservation and the alignment/block size + m_reservation = SYMBIAN_ROUNDUPTOMULTIPLE(m_reservation, m_pageSize); + __ASSERT_ALWAYS(SYMBIAN_ROUNDUPTOMULTIPLE(m_blockSize, m_pageSize), User::Panic(_L("AlignedBlockAllocator1"), KErrArgument)); + + // Calculate max. bit flags we need to carve a reservationSize range into blockSize-sized blocks + m_map.numBits = m_reservation / m_blockSize; + const TUint32 bitsPerWord = 8*sizeof(TUint32); + const TUint32 numWords = (m_map.numBits + bitsPerWord -1) / bitsPerWord; + + m_map.bits = new TUint32[numWords]; + __ASSERT_ALWAYS(m_map.bits, User::Panic(_L("AlignedBlockAllocator2"), KErrNoMemory)); + m_map.clearAll(); + + // Open a Symbian RChunk, and reserve requested virtual address range + // Any thread in this process can operate this rchunk due to EOwnerProcess access rights. + TInt ret = m_chunk.CreateDisconnectedLocal(0 , 0, (TInt)m_reservation , EOwnerProcess); + if (ret != KErrNone) + User::Panic(_L("AlignedBlockAllocator3"), ret); + + // This is the offset to m_chunk.Base() required to make it m_blockSize-aligned + m_offset = SYMBIAN_ROUNDUPTOMULTIPLE(TUint32(m_chunk.Base()), m_blockSize) - TUint(m_chunk.Base()); + +} + +void* AlignedBlockAllocator::alloc() +{ + + TInt freeRam = 0; + void* address = 0; + + // Look up first free slot in bit map + const TInt freeIdx = m_map.findFree(); + + // Pseudo OOM: We ate up the address space we reserved.. + // ..even though the device may have free RAM left + if (freeIdx < 0) + return 0; + + TInt ret = m_chunk.Commit(m_offset + (m_blockSize * freeIdx), m_blockSize); + if (ret != KErrNone) + return 0; // True OOM: Device didn't have physical RAM to spare + + // Updated bit to mark region as in use. + m_map.set(freeIdx); + + // Calculate address of committed region (block) + address = (void*)( (m_chunk.Base() + m_offset) + (TUint)(m_blockSize * freeIdx) ); + + return address; +} + +void AlignedBlockAllocator::free(void* block) +{ + // Calculate index of block to be freed + TInt idx = TUint(static_cast(block) - m_chunk.Base() - m_offset) / m_blockSize; + + __ASSERT_DEBUG(idx >= 0 && idx < m_map.numBits, User::Panic(_L("AlignedBlockAllocator4"), KErrCorrupt)); // valid index check + __ASSERT_DEBUG(m_map.get(idx), User::Panic(_L("AlignedBlockAllocator5"), KErrCorrupt)); // in-use flag check + + // Return committed region to system RAM pool (the physical RAM becomes usable by others) + TInt ret = m_chunk.Decommit(m_offset + m_blockSize * idx, m_blockSize); + + // mark this available again + m_map.clear(idx); +} + +void AlignedBlockAllocator::destroy() +{ + // release everything! + m_chunk.Decommit(0, m_chunk.MaxSize()); + m_map.clearAll(); +} + +AlignedBlockAllocator::~AlignedBlockAllocator() +{ + destroy(); + m_chunk.Close(); + delete [] m_map.bits; +} + +} // end of namespace + +#endif // SYMBIAN diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h b/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h new file mode 100644 index 0000000..21422f6 --- /dev/null +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BlockAllocatorSymbian_h +#define BlockAllocatorSymbian_h + +#include +#include +#include + + +#define SYMBIAN_PAGESIZE(x) (HAL::Get(HALData::EMemoryPageSize, x)); +#define SYMBIAN_FREERAM(x) (HAL::Get(HALData::EMemoryRAMFree, x)); +#define SYMBIAN_ROUNDUPTOMULTIPLE(x, multipleof) ( (x + multipleof - 1) & ~(multipleof - 1) ) + +// Set sane defaults if -D wasn't provided via compiler args +#ifndef JSCCOLLECTOR_VIRTUALMEM_RESERVATION +#if defined(__WINS__) + // Emulator has limited virtual address space + #define JSCCOLLECTOR_VIRTUALMEM_RESERVATION (4*1024*1024) +#else + // HW has plenty of virtual addresses + #define JSCCOLLECTOR_VIRTUALMEM_RESERVATION (128*1024*1024) +#endif +#endif + +namespace WTF { + +/** + * Allocates contiguous region of size blockSize with blockSize-aligned address. + * blockSize must be a multiple of system page size (typically 4K on Symbian/ARM) + * + * @param reservationSize Virtual address range to be reserved upon creation of chunk (bytes). + * @param blockSize Size of a single allocation. Returned address will also be blockSize-aligned. + */ +class AlignedBlockAllocator { + public: + AlignedBlockAllocator(TUint32 reservationSize, TUint32 blockSize); + ~AlignedBlockAllocator(); + void destroy(); + void* alloc(); + void free(void* data); + + private: + RChunk m_chunk; // Symbian chunk that lets us reserve/commit/decommit + TUint m_offset; // offset of first committed region from base + TInt m_pageSize; // cached value of system page size, typically 4K on Symbian + TUint32 m_reservation; + TUint32 m_blockSize; + + // Tracks comitted/decommitted state of a blockSize region + struct { + + TUint32 *bits; // array of bit flags + TUint32 numBits; // number of regions to keep track of + + bool get(TUint32 n) const + { + return !!(bits[n >> 5] & (1 << (n & 0x1F))); + } + + void set(TUint32 n) + { + bits[n >> 5] |= (1 << (n & 0x1F)); + } + + void clear(TUint32 n) + { + bits[n >> 5] &= ~(1 << (n & 0x1F)); + } + + void clearAll() + { + for (TUint32 i = 0; i < numBits; i++) + clear(i); + } + + TInt findFree() const + { + for (TUint32 i = 0; i < numBits; i++) { + if (!get(i)) + return i; + } + return -1; + } + + } m_map; + +}; + +} + +#endif // end of BlockAllocatorSymbian_h + + diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index a8889b3..4de7ad8 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - e9151b11e974f0aa47fd40c225f88f35ced91496 + ecfa4583e573ce4dff1f0df12f6bdba3022376e5 -- cgit v0.12 From c8fc2b44213ded1bd789b4cd3106c4f0b0bfa78b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Mar 2010 17:21:42 +0200 Subject: Fix compilation on WinCE and MinGW by memsetting the OVERLAPPED struct. Apparently the SDKs cannot agree on the contents of this struct, so let's memset the entire thing. --- src/corelib/io/qwindowspipewriter.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 3eb2411..417439f 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qwindowspipewriter_p.h" +#include QT_BEGIN_NAMESPACE @@ -101,9 +102,7 @@ qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) void QWindowsPipeWriter::run() { OVERLAPPED overl; - overl.Internal = 0; - overl.InternalHigh = 0; - overl.Pointer = 0; + memset(&overl, 0, sizeof overl); overl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); forever { lock.lock(); -- cgit v0.12 From 359e6ae3900930656b7359210105426a1771bf19 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 30 Mar 2010 17:47:26 +0200 Subject: Doc: Updated the qdoc manual with i18n info. Fixed a code example. Reviewed-by: Trust Me --- tools/qdoc3/doc/examples/main.cpp | 2 +- tools/qdoc3/doc/qdoc-manual.qdoc | 106 ++++++++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/tools/qdoc3/doc/examples/main.cpp b/tools/qdoc3/doc/examples/main.cpp index e2cf6c5..e439d3e 100644 --- a/tools/qdoc3/doc/examples/main.cpp +++ b/tools/qdoc3/doc/examples/main.cpp @@ -46,7 +46,7 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); - QPushButton *hello("Hello world!"); + QPushButton hello("Hello world!"); hello.resize(100, 30); hello.show(); diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc index e2f670c..482af46 100644 --- a/tools/qdoc3/doc/qdoc-manual.qdoc +++ b/tools/qdoc3/doc/qdoc-manual.qdoc @@ -78,10 +78,10 @@ \endlist \o \l{QDoc Configuration} \list - \o \l{General Variables} + \o \l{General Configuration Variables} \o \l{Creating Help Project Files} - \o \l{C++ Specific Variables} - \o \l{HTML Specific Variables} + \o \l{C++ Specific Configuration Variables} + \o \l{HTML Specific Configuration Variables} \o \l{Supporting Derived Projects} \o \l{QDoc Compatibility} \o \l{qt.qdocconf} @@ -1425,6 +1425,7 @@ \quotefromfile examples/main.cpp + \skipto QApplication \printline QApplication This line includes the QApplication class @@ -1652,6 +1653,7 @@ can press and release. \quotefromfile examples/main.cpp + \skipto QApplication \skipline QApplication \printline QPushButton @@ -6974,7 +6976,7 @@ \page 21-0-qdoc-configuration.html \previouspage Title Commands \contentspage QDoc Manual - Table of Contents - \nextpage General Variables + \nextpage General Configuration Variables \title QDoc Configuration @@ -7094,9 +7096,9 @@ \section2 Categories \list - \o \l {General Variables} - \o \l {C++ Specific Variables} - \o \l {HTML Specific Variables} + \o \l {General Configuration Variables} + \o \l {C++ Specific Configuration Variables} + \o \l {HTML Specific Configuration Variables} \endlist \section1 Configuration File Examples @@ -7133,7 +7135,7 @@ \contentspage QDoc Manual - Table of Contents \nextpage Creating Help Project Files - \title General Variables + \title General Configuration Variables With the general QDoc configuration variables, you can define where QDoc will find the various source files it needs to generate @@ -7215,7 +7217,7 @@ QDoc originally used a hard-coded value of four spaces for code indentation to ensure that code snippets could be easily distinguished from surrounding text. Since we can use - \l{HTML Specific Variables#HTML.stylesheets}{stylesheets} to + \l{HTML Specific Configuration Variables#HTML.stylesheets}{stylesheets} to adjust the appearance of certain types of HTML elements, this level of indentation is not always required. @@ -7572,7 +7574,7 @@ \code header.fileextensions += *.H \endcode - + \warning The above assignment may not work as described. See also \l headerdirs. @@ -7730,6 +7732,27 @@ bold font, and that \\raisedaster renders a '*'. \row + \o \bold naturallanguage \target naturallanguage + \o \bold {The \c naturallanguage variable specifies the natural + language used for the documentation generated by qdoc.} + + For example: + + \code + naturallanguage = zh-Hans + \endcode + + By default, the natural language is \c en for compatibility + with legacy documentation. + + qdoc will add the natural language information to the HTML + it generates, using the \c lang and \c xml:lang attributes. + + See also \l sourceencoding, \l outputencoding, + \l{http://www.w3.org/TR/xhtml1/#C_7}{C.7. The lang and xml:lang Attributes} and + \l{http://www.w3.org/TR/i18n-html-tech-lang/#ri20040429.113217290}{Best Practice 13: Using Hans and Hant codes}. + + \row \o \bold outputdir \target outputdir \o \bold {The \c outputdir variable specifies the directory where QDoc will put the generated documentation.} @@ -7754,6 +7777,31 @@ directory, all files from the previous run will be lost. \row + \o \bold outputencoding \target outputencoding + \o \bold {The \c outputencoding variable specifies the encoding + used for the documentation generated by qdoc.} + + For example: + + \code + outputencoding = UTF-8 + \endcode + + By default, the output encoding is \c ISO-8859-1 (Latin1) for + compatibility with legacy documentation. When generating + documentation for some languages, particularly non-European + languages, this is not sufficient and an encoding such as UTF-8 + is required. + + qdoc will encode HTML using this encoding and generate the + correct declarations to indicate to browsers which encoding + is being used. The \l naturallanguage configuration variable + should also be specified to provide browsers with a complete + set of character encoding and language information. + + See also \l outputencoding and \l naturallanguage. + + \row \o \bold outputformats \target outputformats \o \bold {The \c outputformats variable specifies the format of the generated documentation.} @@ -7831,6 +7879,30 @@ See also \l sources and \l sources.fileextensions. \row + \o \bold sourceencoding \target sourceencoding + \o \bold {The \c sourceencoding variable specifies the encoding + used for the source code and documentation.} + + For example: + + \code + sourceencoding = UTF-8 + \endcode + + By default, the source encoding is \c ISO-8859-1 (Latin1) for + compatibility with legacy documentation. For some languages, + particularly non-European languages, this is not sufficient + and an encoding such as UTF-8 is required. + + Although qdoc will use the encoding to read source and + documentation files, limitations of C++ compilers may prevent + you from using non-ASCII characters in source code comments. + In cases like these, it is possible to write API documentation + completely in documentation files. + + See also \l naturallanguage and \l outputencoding. + + \row \o \bold sources \target sources \o \bold {The \c sources variable allows you to specify individual source files in addition to those located in the @@ -7973,9 +8045,9 @@ /*! \page 22-creating-help-project-files.html - \previouspage General Variables + \previouspage General Configuration Variables \contentspage QDoc Manual - Table of Contents - \nextpage C++ Specific Variables + \nextpage C++ Specific Configuration Variables \title Creating Help Project Files @@ -8023,9 +8095,9 @@ \page 23-qdoc-configuration-cppvariables.html \previouspage Creating Help Project Files \contentspage QDoc Manual - Table of Contents - \nextpage HTML Specific Variables + \nextpage HTML Specific Configuration Variables - \title C++ Specific Variables + \title C++ Specific Configuration Variables The C++ specific configuration variables are provided to avoid erroneous documentation due to non-standard C++ constructs. @@ -8159,11 +8231,11 @@ /*! \page 24-qdoc-configuration-htmlvariables.html - \previouspage C++ Specific Variables + \previouspage C++ Specific Configuration Variables \contentspage QDoc Manual - Table of Contents \nextpage Supporting Derived Projects - \title HTML Specific Variables + \title HTML Specific Configuration Variables The HTML specific configuration variables define the generated documentation's style, or define the contents of the @@ -8289,7 +8361,7 @@ /*! \page 25-qdoc-configuration-derivedprojects.html - \previouspage HTML Specific Variables + \previouspage HTML Specific Configuration Variables \contentspage QDoc Manual - Table of Contents \nextpage QDoc Compatibility -- cgit v0.12 From e1edc775a5fdfd0e9e940abcc5050944eb396f8b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Mar 2010 18:17:55 +0200 Subject: Fix bad merge from 4.6. Revert qgraphicsview.h to its prior 4.7 state and symbian.conf to the current qt-4.7-from-4.6 (7c613a9ef4610fa2e0e1630eb3cd2b474875631d) state. symbian.conf may be bad, needs reviewing. --- mkspecs/common/symbian/symbian.conf | 115 +++++++-------------------------- src/gui/graphicsview/qgraphicswidget.h | 6 +- 2 files changed, 27 insertions(+), 94 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index d66d227..bd5768b 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -1,19 +1,19 @@ # -# qmake configuration for symbian-* +# qmake configuration for all symbian mkspecs # TEMPLATE = app -CONFIG += qt warn_on release incremental +CONFIG += qt warn_on release incremental link_prl sis_targets QT += core gui QMAKE_INCREMENTAL_STYLE = sublib DEFINES += UNICODE QT_KEYPAD_NAVIGATION QT_SOFTKEYS_ENABLED QT_USE_MATH_H_FLOATS + QMAKE_COMPILER_DEFINES += SYMBIAN QMAKE_EXT_OBJ = .o QMAKE_EXT_RES = _res.o -QMAKE_CC = gcc QMAKE_LEX = flex QMAKE_LEXFLAGS = QMAKE_YACC = byacc @@ -28,9 +28,13 @@ QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses VERSION_FLAGS.ARMCC = ARMCC_4_0 -QMAKE_CXX = g++ QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -QMAKE_CXXFLAGS.CW = +# Symbian build system applies -cwd source on the MWCC command line. +# this causes problems with include paths, -cwd include uses the same +# rules for include paths as ARMCC +# This should really be fixed in raptor, as using CXXFLAGS means we pass +# both on the command line and rely on the compiler using the last specified +QMAKE_CXXFLAGS.CW = -cwd include QMAKE_CXXFLAGS.ARMCC = --visibility_inlines_hidden QMAKE_CXXFLAGS.ARMCC_4_0 = --import_all_vtbl QMAKE_CXXFLAGS.GCCE = -fvisibility-inlines-hidden @@ -49,12 +53,6 @@ QMAKE_CXXFLAGS_EXCEPTIONS_OFF = QMAKE_INCDIR = QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] -QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src -QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< -QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src -QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< - -QMAKE_LINK = QMAKE_LFLAGS = QMAKE_LFLAGS.ARMCC = QMAKE_LFLAGS_EXCEPTIONS_ON = @@ -68,12 +66,13 @@ QMAKE_LINK_OBJECT_MAX = QMAKE_LINK_OBJECT_SCRIPT= QMAKE_LIBS = -llibc -llibm -leuser -llibdl -QMAKE_LIBS_CORE = $$QMAKE_LIBS -llibpthread -lefsrv -QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lhal -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository +QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal +QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL QMAKE_LIBS_OPENGL = QMAKE_LIBS_OPENVG = -llibOpenVG -lfbscli -lbitgdi -lgdi +QMAKE_LIBS_THREAD = -llibpthread QMAKE_LIBS_COMPAT = QMAKE_LIBS_QT_ENTRY = -llibcrt0.lib QMAKE_LIBS_S60 = -lavkon @@ -86,9 +85,10 @@ contains(QMAKE_HOST.os,Windows) { QMAKE_COPY = copy /y QMAKE_COPY_DIR = xcopy /s /q /y /i QMAKE_MOVE = move - QMAKE_DEL_FILE = del + QMAKE_DEL_FILE = del 2> NUL QMAKE_MKDIR = mkdir QMAKE_DEL_DIR = rmdir + QMAKE_DEL_TREE = rmdir /s /q QMAKE_CHK_DIR_EXISTS = if not exist } else { QMAKE_COPY = cp @@ -97,87 +97,18 @@ contains(QMAKE_HOST.os,Windows) { QMAKE_DEL_FILE = rm -f QMAKE_MKDIR = mkdir QMAKE_DEL_DIR = rmdir + QMAKE_DEL_TREE = rm -rf QMAKE_CHK_DIR_EXISTS = test -d } -QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc.exe -QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic.exe -QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc.exe - -QMAKE_IDL = midl -QMAKE_LIB = ar -ru -QMAKE_RC = windres -QMAKE_ZIP = zip -r -9 +QMAKE_IDL = midl +QMAKE_LIB = ar -ru +QMAKE_RC = windres +QMAKE_ZIP = zip -r -9 -QMAKE_STRIP = strip -QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f +QT_ARCH = symbian load(qt_config) -load(platform_paths) -load(add_mmp_rules) - -symbian-abld { -# Versions of abld prior to Symbian^3 have a bug where you cannot remove something from the command line without replacing it -# Rather than figure out which version of abld we're using, we'll replace the command with a macro *that should never be used* - MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA = "OPTION_REPLACE ARMCC --export_all_vtbl -D__QT_NOEFFECTMACRO_DONOTUSE" -} else { - MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA = "OPTION_REPLACE ARMCC --export_all_vtbl // don't use --export_all_vtbl" -} -MMP_RULES += PAGED BYTEPAIRCOMPRESSTARGET -MMP_RULES += $$MMP_RULES_DONT_EXPORT_ALL_CLASS_IMPEDIMENTA -SYMBIAN_PLATFORMS = WINSCW GCCE ARMV5 ARMV6 - -INCLUDEPATH = \ - $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian/stl-off \ - $$[QT_INSTALL_PREFIX]/mkspecs/common/symbian \ - $${EPOCROOT}epoc32/include \ - $$OS_LAYER_LIBC_SYSTEMINCLUDE \ - $$INCLUDEPATH - -# Ensure '.' directory is the first in include path. -# RVCT seems to do this automatically, but WINSCW compiler does not, so add it here. -MMP_RULES += "USERINCLUDE ." - -# pkg_depends_webkit, pkg_depends_core, and pkg_platform_dependencies can be removed by developer -# if multiple languages need to be supported by pkg file. In that case the developer should declare -# multiple language compatible dependency statements him/herself. - -default_deployment.pkg_prerules += pkg_depends_webkit pkg_depends_qt pkg_platform_dependencies - -# Supports S60 3.0, 3.1, 3.2 and 5.0 by default -pkg_platform_dependencies = \ - "; Default HW/platform dependencies" \ - "[0x101F7961],0,0,0,{\"S60ProductID\"}" \ - "[0x102032BE],0,0,0,{\"S60ProductID\"}" \ - "[0x102752AE],0,0,0,{\"S60ProductID\"}" \ - "[0x1028315F],0,0,0,{\"S60ProductID\"}" \ - " " - -DEPLOYMENT += default_deployment - -exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/Series60v5.0.sis )|exists($${EPOCROOT}epoc32/data/z/system/install/Series60v5.0.sis) { - S60_VERSION = 5.0 -} else { - exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/Series60v3.2.sis )|exists($${EPOCROOT}epoc32/data/z/system/install/Series60v3.2.sis) { - S60_VERSION = 3.2 - } else { - S60_VERSION = 3.1 - MMP_RULES -= PAGED BYTEPAIRCOMPRESSTARGET - } -} - -QMAKE_CXXFLAGS_FAST_VFP.ARMCC = --fpmode fast -# [TODO] QMAKE_CXXFLAGS_FAST_VFP.GCCE = - -symbian { - armfpu = $$find(MMP_RULES, "ARMFPU") - !isEmpty(armfpu) { - vfpv2 = $$find(MMP_RULES, "vfpv2") - !isEmpty(vfpv2) { - # we will respect fpu setting obtained from configure, but, - # if vfpv2 or softvfp+vfpv2 used we want to force RunFast VFP mode - QMAKE_CXXFLAGS.ARMCC += $${QMAKE_CXXFLAGS_FAST_VFP.ARMCC} - # [TODO] QMAKE_CXXFLAGS.GCCE += $${QMAKE_CXXFLAGS_FAST_VFP.GCCE} - } - } -} +load(symbian/platform_paths) diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 730674c..87c669b 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -82,7 +82,7 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) - Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged) + Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); @@ -103,6 +103,9 @@ public: QPalette palette() const; void setPalette(const QPalette &palette); + bool autoFillBackground() const; + void setAutoFillBackground(bool enabled); + void resize(const QSizeF &size); inline void resize(qreal w, qreal h) { resize(QSizeF(w, h)); } QSizeF size() const; @@ -177,7 +180,6 @@ public: Q_SIGNALS: void geometryChanged(); - void layoutChanged(); public Q_SLOTS: bool close(); -- cgit v0.12 From a7f9db7091db3356434f188abd814e9deebe3d78 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Mar 2010 18:34:45 +0200 Subject: Re-fix compilation: re-add symbols introduced in Qt 4.6.3 to Qt 4.7 --- src/gui/graphicsview/qgraphicswidget.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 87c669b..894b84e 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -82,6 +82,7 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) + Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged) Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); @@ -180,6 +181,7 @@ public: Q_SIGNALS: void geometryChanged(); + void layoutChanged(); public Q_SLOTS: bool close(); -- cgit v0.12 From c9175338b3e2f4cf05e1d6cd5a518a06c4bb08a6 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 30 Mar 2010 18:28:36 +0200 Subject: Fix out-of-source symbian build for external apps --- mkspecs/features/symbian/qt.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/symbian/qt.prf b/mkspecs/features/symbian/qt.prf index bcb2867..9fc9814 100644 --- a/mkspecs/features/symbian/qt.prf +++ b/mkspecs/features/symbian/qt.prf @@ -47,5 +47,5 @@ isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x020000 0x800000 # Workaround for the fact that Gnupoc and Symbian chose different approaches to # the letter casing of headers. contains(CONFIG, is_using_gnupoc) { - INCLUDEPATH += $$QMAKESPEC/../../common/symbian/header-wrappers + INCLUDEPATH += $${PWD}/../../common/symbian/header-wrappers } -- cgit v0.12 From 165b20e0d2c6abd041e319fe918a7030a3a6844c Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 30 Mar 2010 18:31:20 +0200 Subject: Remove stray non-latin1 character --- src/s60main/qts60main_mcrt0.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s60main/qts60main_mcrt0.cpp b/src/s60main/qts60main_mcrt0.cpp index 66ce8b6..0f0723e 100644 --- a/src/s60main/qts60main_mcrt0.cpp +++ b/src/s60main/qts60main_mcrt0.cpp @@ -40,7 +40,7 @@ // MCRT0.CPP // -// © Portions copyright (c) 2005-2006 Nokia Corporation. All rights reserved. +// Portions copyright (c) 2005-2006 Nokia Corporation. All rights reserved. // Copyright (c) Symbian Software Ltd 1997-2004. All rights reserved. // -- cgit v0.12 From faff1c60a2a7f6ebef90249e759bdf822c8b17de Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 30 Mar 2010 18:46:51 +0200 Subject: Make s60main static lib not depend on QtCore Inline all the code that is used from QtCore as we should not assume QtCore is present for a static library linked into random 3rd party applications. --- src/s60main/qts60main.cpp | 6 ++++-- src/s60main/qts60main_mcrt0.cpp | 47 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/s60main/qts60main.cpp b/src/s60main/qts60main.cpp index 5fbeea5..7b85901 100644 --- a/src/s60main/qts60main.cpp +++ b/src/s60main/qts60main.cpp @@ -41,7 +41,7 @@ // INCLUDE FILES #include // must be before e32base.h so uncaught_exception gets defined #include -#include +#include GLDEF_C TInt QtMainWrapper(); @@ -51,7 +51,9 @@ GLDEF_C TInt QtMainWrapper(); */ GLDEF_C TInt E32Main() { - CTrapCleanup *cleanupStack = q_check_ptr(CTrapCleanup::New()); + CTrapCleanup *cleanupStack = CTrapCleanup::New(); + if (!(cleanupStack)) + throw std::bad_alloc(); TInt err = 0; TRAP(err, err = QtMainWrapper()); delete cleanupStack; diff --git a/src/s60main/qts60main_mcrt0.cpp b/src/s60main/qts60main_mcrt0.cpp index 0f0723e..28c3ac6 100644 --- a/src/s60main/qts60main_mcrt0.cpp +++ b/src/s60main/qts60main_mcrt0.cpp @@ -50,9 +50,8 @@ #include // must be before e32base.h so uncaught_exception gets defined #include #include "estlib.h" +#include -// Needed for QT_TRYCATCH_LEAVING. -#include #ifdef __ARMCC__ __asm int CallMain(int argc, char *argv[], char *envp[]) @@ -75,6 +74,18 @@ extern "C" GLDEF_C int __GccGlueInit() extern "C" IMPORT_C void exit(int ret); +namespace { +class QSymbianLeaveException : public std::exception +{ +public: + inline QSymbianLeaveException(int err) : error(err) {} + inline const char* what() const throw() { return "Symbian leave exception"; } + +public: + int error; +}; +} + GLDEF_C TInt QtMainWrapper() { int argc = 0; @@ -83,7 +94,37 @@ GLDEF_C TInt QtMainWrapper() // get args & environment __crt0(argc, argv, envp); //Call user(application)'s main - TRAPD(ret, QT_TRYCATCH_LEAVING(ret = CALLMAIN(argc, argv, envp);)); + + TInt _err = KErrNone; + TRAPD(ret, + try { + ret = CALLMAIN(argc, argv, envp); + } catch (const std::exception &____ex) { + _err = KErrGeneral; + const std::type_info& type = typeid(____ex); + + if (type == typeid (std::bad_alloc)) { + _err = KErrNoMemory; + } else if (type == typeid(::QSymbianLeaveException)) { + _err = static_cast(____ex).error; + } else { + if (type == typeid(std::invalid_argument)) + _err = KErrArgument; + else if (type == typeid(std::out_of_range)) + // std::out_of_range is of type logic_error which by definition means that it is + // "presumably detectable before the program executes". + // std::out_of_range is used to report an argument is not within the expected range. + // The description of KErrArgument says an argument is out of range. Hence the mapping. + _err = KErrArgument; + else if (type == typeid(std::overflow_error)) + _err = KErrOverflow; + else if (type == typeid(std::underflow_error)) + _err = KErrUnderflow; + } + } + User::LeaveIfError(_err); + ); + delete[] argv; delete[] envp; return ret; -- cgit v0.12 From 3cb1aba46a1e2e5b1d71360c6a9bd160d73d8aec Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 30 Mar 2010 18:48:11 +0200 Subject: Fix qmake with the symbian makespec failing when project has a dash in it --- mkspecs/features/symbian/symbian_building.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/symbian/symbian_building.prf b/mkspecs/features/symbian/symbian_building.prf index 9ccfd2f..ef03b0a 100644 --- a/mkspecs/features/symbian/symbian_building.prf +++ b/mkspecs/features/symbian/symbian_building.prf @@ -1,7 +1,7 @@ # we have some module specific options (defined in qt.prf) lets add them -eval(TMPVAR = \$\$QMAKE_$${TARGET}_CXXFLAGS) +!contains(TARGET, ".*[ -].*"):eval(TMPVAR = \$\$QMAKE_$${TARGET}_CXXFLAGS) !isEmpty(TMPVAR):QMAKE_CXXFLAGS += $$TMPVAR -eval(TMPVAR = \$\$QMAKE_$${TARGET}_LFLAGS) +!contains(TARGET, ".*[ -].*"):eval(TMPVAR = \$\$QMAKE_$${TARGET}_LFLAGS) !isEmpty(TMPVAR) { QMAKE_LFLAGS += $$TMPVAR } else :linux-gcce { # lets provide a simple default. Without elf2e32 complains -- cgit v0.12 From 328e75ba8abe51cc8e296975513ca6e882df5a1b Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 30 Mar 2010 19:33:00 +0200 Subject: Fix building on public symbian SDK. the capability CAP_GENERAL_DLL is apparently an alias, so replace it with the extended version --- demos/declarative/minehunt/minehunt.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demos/declarative/minehunt/minehunt.pro b/demos/declarative/minehunt/minehunt.pro index 03059c7..0b0eac6 100644 --- a/demos/declarative/minehunt/minehunt.pro +++ b/demos/declarative/minehunt/minehunt.pro @@ -26,9 +26,9 @@ INSTALLS = sources MinehuntCore_sources target symbian:{ load(data_caging_paths) TARGET.EPOCALLOWDLLDATA = 1 - TARGET.CAPABILITY = CAP_GENERAL_DLL + TARGET.CAPABILITY = all -tcb include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - + importFiles.sources = minehunt.dll \ MinehuntCore/Explosion.qml \ MinehuntCore/pics \ -- cgit v0.12 From 7e3df09fea0d3177d07f0262d034065e90eb3263 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 30 Mar 2010 19:36:46 +0200 Subject: Work around bad naming of exported class in symbian sdk causing conflict The symbian SDK has a Time class defined which means that the compiler complains about the name already being used. Lets just disable the compile as this is not worth disturbing the example over. --- examples/declarative/declarative.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/declarative/declarative.pro b/examples/declarative/declarative.pro index bddfbee..1c53e28 100644 --- a/examples/declarative/declarative.pro +++ b/examples/declarative/declarative.pro @@ -8,6 +8,9 @@ SUBDIRS = \ plugins \ widgets +# plugins uses a 'Time' class that conflicts with symbian e32std.h also defining a class of the same name +symbian:SUBDIRS -= plugins + # These examples contain no C++ and can simply be copied sources.files = \ animations \ -- cgit v0.12 From 456fdf4e5fe05e94955df0fc7d76c384a0bcfbc5 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 30 Mar 2010 19:49:58 +0200 Subject: Re-add line that was lost during webkit update. Doing a 'make sis' expects the dll in the libdir, so place it there. This fixes out-of-source building to always put the dll in the exepcted dir. https://bugs.webkit.org/show_bug.cgi?id=36749 --- src/3rdparty/webkit/WebCore/WebCore.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index e24e9e2..06e3a84 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -12,6 +12,7 @@ symbian: { TARGET.UID3 = 0xE00267C2 } webkitlibs.sources = QtWebKit$${QT_LIBINFIX}.dll + CONFIG(QTDIR_build)|: webkitlibs.sources = $$QMAKE_LIBDIR_QT/$$webkitlibs.sources webkitlibs.path = /sys/bin vendorinfo = \ "; Localised Vendor name" \ -- cgit v0.12 From aaf6f2b44b29889b6acfc74fcf0949fc5c5a8b3d Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 31 Mar 2010 09:18:20 +1000 Subject: See if we can get the visual tests working on qws. --- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index 2794ab8..f527dc8 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -124,6 +124,10 @@ void tst_qmlvisual::visual() arguments << "-script" << testdata << "-scriptopts" << "play,testimages,testerror,exitoncomplete,exitonfailure" << file << "-graphicssystem" << "raster"; +#ifdef Q_WS_QWS + arguments << "-qws"; +#endif + QProcess p; p.start(qmlruntime, arguments); QVERIFY(p.waitForFinished()); -- cgit v0.12 From 0d41d766d13bc6ee8a068aef4b88567c111d0e0c Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 31 Mar 2010 08:51:00 +1000 Subject: Another "off by 1" problem in OpenVG - in paths this time. Summary so far: paths and images do not need the 0.5 adjustment to the transform, but glyphs do. Not sure why glyphs do, but the fonts definitely look wrong without the adjustment. Task-number: QT-3192 Reviewed-by: trustme --- src/openvg/qpaintengine_vg.cpp | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index ce6e21b..ebf34f5 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -183,6 +183,7 @@ public: qreal penScale; // Pen scaling factor from "transform". QTransform pathTransform; // Calculated VG path transformation. + QTransform glyphTransform; // Calculated VG glyph transformation. QTransform imageTransform; // Calculated VG image transformation. bool pathTransformSet; // True if path transform set in the VG context. @@ -500,24 +501,31 @@ extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) { - VGfloat devh = pdev->height() - 1; + VGfloat devh = pdev->height(); // Construct the VG transform by combining the Qt transform with // the following viewport transformation: - // | 1 0 0 | | 1 0 0.5 | | 1 0 0.5 | - // | 0 -1 devh | * | 0 1 -0.5 | = | 0 -1 (0.5 + devh) | - // | 0 0 1 | | 0 0 1 | | 0 0 1 | + // | 1 0 0 | + // | 0 -1 devh | + // | 0 0 1 | + // The glyph transform uses a slightly different transformation: + // | 1 0 0 | | 1 0 0.5 | | 1 0 0.5 | + // | 0 -1 devh - 1 | * | 0 1 -0.5 | = | 0 -1 (devh - 0.5) | + // | 0 0 1 | | 0 0 1 | | 0 0 1 | // The full VG transform is effectively: // 1. Apply the user's transformation matrix. - // 2. Translate by (0.5, -0.5) to correct for Qt and VG putting - // the centre of the pixel at different positions. + // 2. Translate glyphs by an extra (0.5, -0.5). // 3. Flip the co-ordinate system upside down. QTransform viewport(1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, - 0.5f, devh + 0.5f, 1.0f); + 0.0f, devh, 1.0f); + QTransform gviewport(1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, + 0.5f, devh - 0.5f, 1.0f); // Compute the path transform and determine if it is projective. pathTransform = transform * viewport; + glyphTransform = transform * gviewport; bool projective = (pathTransform.m13() != 0.0f || pathTransform.m23() != 0.0f || pathTransform.m33() != 1.0f); @@ -526,6 +534,7 @@ void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) // so we will have to convert the co-ordinates ourselves. // Change the matrix to just the viewport transformation. pathTransform = viewport; + glyphTransform = gviewport; simpleTransform = false; } else { simpleTransform = true; @@ -533,13 +542,7 @@ void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) pathTransformSet = false; // The image transform is always the full transformation, - // because it can be projective. It also does not need the - // (0.5, -0.5) translation because vgDrawImage() implicitly - // adds 0.5 to each co-ordinate. - QTransform viewport2(1.0f, 0.0f, 0.0f, - 0.0f, -1.0f, 0.0f, - 0.0f, devh + 1, 1.0f); - imageTransform = transform * viewport2; + imageTransform = transform * viewport; // Calculate the scaling factor to use for turning cosmetic pens // into ordinary non-cosmetic pens. @@ -3317,7 +3320,7 @@ void QVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) } // Set the transformation to use for drawing the current glyphs. - QTransform glyphTransform(d->pathTransform); + QTransform glyphTransform(d->glyphTransform); glyphTransform.translate(p.x(), p.y()); #if defined(QVG_NO_IMAGE_GLYPHS) glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY); @@ -3650,10 +3653,10 @@ void QVGCompositionHelper::fillBackground } else { // Set the path transform to the default viewport transformation. - VGfloat devh = screenSize.height() - 1; + VGfloat devh = screenSize.height(); QTransform viewport(1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, - -0.5f, devh + 0.5f, 1.0f); + 0.0f, devh, 1.0f); d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport); // Set the brush to use to fill the background. @@ -3689,10 +3692,10 @@ void QVGCompositionHelper::drawCursorPixmap } // Set the image transformation and modes. - VGfloat devh = screenSize.height() - 1; + VGfloat devh = screenSize.height(); QTransform transform(1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, - -0.5f, devh + 0.5f, 1.0f); + 0.0f, devh, 1.0f); transform.translate(offset.x(), offset.y()); d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform); d->setImageMode(VG_DRAW_IMAGE_NORMAL); -- cgit v0.12 From f17e398f661d903a9fda0bfb3725fd881656e9d4 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 31 Mar 2010 01:39:26 +0200 Subject: Add a workaround for a bug in Mac filesystem watcher. Reviewed-by:TrustMe --- src/gui/dialogs/qfilesystemmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index 3757ad7..24faa59 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -1362,7 +1362,7 @@ QModelIndex QFileSystemModel::setRootPath(const QString &newPath) return d->index(rootPath()); //We remove the watcher on the previous path - if (!rootPath().isEmpty()) { + if (!rootPath().isEmpty() && rootPath() != QLatin1String(".")) { //This remove the watcher for the old rootPath d->fileInfoGatherer.removePath(rootPath()); //This line "marks" the node as dirty, so the next fetchMore -- cgit v0.12 From 4e4c0055d59978850796ff8c1b5015e17459e8d2 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 31 Mar 2010 02:17:28 +0200 Subject: Revert "Add a a layout property in QGraphicsWidget." This reverts commit 87fae30fc63460e0ed2cc98f55a22e28d7520311. This drop the support of QML on top of 4.6 --- src/gui/graphicsview/qgraphicswidget.cpp | 1 - src/gui/graphicsview/qgraphicswidget.h | 2 -- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 654a432..131ee87 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -801,7 +801,6 @@ void QGraphicsWidget::setLayout(QGraphicsLayout *l) l->setParentLayoutItem(this); l->d_func()->reparentChildItems(this); l->invalidate(); - emit layoutChanged(); } /*! diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 730674c..468a134 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -82,7 +82,6 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) - Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); @@ -177,7 +176,6 @@ public: Q_SIGNALS: void geometryChanged(); - void layoutChanged(); public Q_SLOTS: bool close(); diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index b78ef26..5a3a54c 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -942,7 +942,6 @@ void tst_QGraphicsWidget::layout() layout->addItem(item); children.append(item); } - QSignalSpy spy(&widget, SIGNAL(layoutChanged())); widget.setLayout(layout); QTRY_COMPARE(widget.layout(), static_cast(layout)); @@ -951,7 +950,7 @@ void tst_QGraphicsWidget::layout() QCOMPARE(item->parentWidget(), (QGraphicsWidget *)&widget); QVERIFY(item->geometry() != QRectF(0, 0, -1, -1)); } - QCOMPARE(spy.count(), 1); + // don't crash widget.setLayout(0); } -- cgit v0.12 From ebd1c45822aca087be994c898cfb01cd41599429 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 31 Mar 2010 02:19:42 +0200 Subject: Revert "Better handling for NOTIFY in QGraphicsWidget regarding geometry changes" This reverts commit 13bccd4ade76dd8a9c1cc067cc2b8da69c11def2. Conflicts: src/gui/graphicsview/qgraphicswidget.cpp Drop the support of QML on top of 4.6 --- src/gui/graphicsview/qgraphicswidget.cpp | 3 ++- src/gui/graphicsview/qgraphicswidget.h | 7 ++++--- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 131ee87..7be0096 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -392,7 +392,7 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) } QSizeF oldSize = size(); QGraphicsLayoutItem::setGeometry(newGeom); - emit geometryChanged(); + // Send resize event bool resized = newGeom.size() != oldSize; if (resized) { @@ -403,6 +403,7 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) emit widthChanged(); if (oldSize.height() != newGeom.size().height()) emit heightChanged(); + emit sizeChanged(); QApplication::sendEvent(this, &re); } } diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 468a134..56b5f88 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -73,7 +73,7 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(QPalette palette READ palette WRITE setPalette) Q_PROPERTY(QFont font READ font WRITE setFont) Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection) - Q_PROPERTY(QSizeF size READ size WRITE resize NOTIFY geometryChanged) + Q_PROPERTY(QSizeF size READ size WRITE resize NOTIFY sizeChanged) Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize) Q_PROPERTY(QSizeF preferredSize READ preferredSize WRITE setPreferredSize) Q_PROPERTY(QSizeF maximumSize READ maximumSize WRITE setMaximumSize) @@ -81,10 +81,11 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy) Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) - Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) + Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); + QGraphicsLayout *layout() const; void setLayout(QGraphicsLayout *layout); void adjustSize(); @@ -175,7 +176,7 @@ public: #endif Q_SIGNALS: - void geometryChanged(); + void sizeChanged(); public Q_SLOTS: bool close(); diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 5a3a54c..ff3d19f 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -767,7 +767,7 @@ void tst_QGraphicsWidget::geometry() { SubQGraphicsWidget widget; QCOMPARE(widget.geometry(), QRectF(widget.pos(), widget.size())); - QSignalSpy spy(&widget, SIGNAL(geometryChanged())); + QSignalSpy spy(&widget, SIGNAL(sizeChanged())); QFETCH(QPointF, pos); QFETCH(QSizeF, size); widget.setPos(pos); -- cgit v0.12 From 6cb935dd89a391f792f8ad42012b5c7c38712f17 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 31 Mar 2010 02:24:39 +0200 Subject: Revert "Add NOTIFY to size property so QML bindings are working fine." This reverts commit 79a02c86c445e50630bcae62a4505f212281ec8b. Conflicts: src/gui/graphicsview/qgraphicswidget.cpp This drop the support of QML on top of 4.6 --- src/gui/graphicsview/qgraphicswidget.cpp | 5 ----- src/gui/graphicsview/qgraphicswidget.h | 5 +---- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 4 +--- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 7be0096..3548fe3 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -399,11 +399,6 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) QGraphicsSceneResizeEvent re; re.setOldSize(oldSize); re.setNewSize(newGeom.size()); - if (oldSize.width() != newGeom.size().width()) - emit widthChanged(); - if (oldSize.height() != newGeom.size().height()) - emit heightChanged(); - emit sizeChanged(); QApplication::sendEvent(this, &re); } } diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 56b5f88..f1d382b 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -73,7 +73,7 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(QPalette palette READ palette WRITE setPalette) Q_PROPERTY(QFont font READ font WRITE setFont) Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection) - Q_PROPERTY(QSizeF size READ size WRITE resize NOTIFY sizeChanged) + Q_PROPERTY(QSizeF size READ size WRITE resize) Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize) Q_PROPERTY(QSizeF preferredSize READ preferredSize WRITE setPreferredSize) Q_PROPERTY(QSizeF maximumSize READ maximumSize WRITE setMaximumSize) @@ -175,9 +175,6 @@ public: using QObject::children; #endif -Q_SIGNALS: - void sizeChanged(); - public Q_SLOTS: bool close(); diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index ff3d19f..e04d99d 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -767,13 +767,11 @@ void tst_QGraphicsWidget::geometry() { SubQGraphicsWidget widget; QCOMPARE(widget.geometry(), QRectF(widget.pos(), widget.size())); - QSignalSpy spy(&widget, SIGNAL(sizeChanged())); + QFETCH(QPointF, pos); QFETCH(QSizeF, size); widget.setPos(pos); widget.resize(size); - if (!size.isNull()) - QCOMPARE(spy.count(), 1); QCOMPARE(widget.geometry(), QRectF(pos, size)); } -- cgit v0.12 From 70e3d8e58fa26708b8c3edc637e5a4668423e874 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 31 Mar 2010 10:15:46 +1000 Subject: Cleanup MouseArea visual tests. --- .../qdeclarativemousearea/data/drag.0.png | Bin 0 -> 1563 bytes .../qdeclarativemousearea/data/drag.1.png | Bin 0 -> 1570 bytes .../qdeclarativemousearea/data/drag.2.png | Bin 0 -> 1553 bytes .../qdeclarativemousearea/data/drag.3.png | Bin 0 -> 1563 bytes .../qdeclarativemousearea/data/drag.4.png | Bin 0 -> 1569 bytes .../qdeclarativemousearea/data/drag.5.png | Bin 0 -> 1569 bytes .../qdeclarativemousearea/data/drag.6.png | Bin 0 -> 1566 bytes .../qdeclarativemousearea/data/drag.7.png | Bin 0 -> 1566 bytes .../qdeclarativemousearea/data/drag.8.png | Bin 0 -> 1567 bytes .../qmlvisual/qdeclarativemousearea/data/drag.qml | 5207 +++++++++++++++++ .../data/mousearea-visual.qml | 5867 ++++++++++++++++++++ .../qdeclarativemousearea/data/mouseregion.0.png | Bin 0 -> 471 bytes .../qdeclarativemousearea/data/mouseregion.1.png | Bin 0 -> 474 bytes .../qdeclarativemousearea/data/mouseregion.10.png | Bin 0 -> 479 bytes .../qdeclarativemousearea/data/mouseregion.11.png | Bin 0 -> 479 bytes .../qdeclarativemousearea/data/mouseregion.12.png | Bin 0 -> 479 bytes .../qdeclarativemousearea/data/mouseregion.13.png | Bin 0 -> 479 bytes .../qdeclarativemousearea/data/mouseregion.14.png | Bin 0 -> 479 bytes .../qdeclarativemousearea/data/mouseregion.15.png | Bin 0 -> 479 bytes .../qdeclarativemousearea/data/mouseregion.16.png | Bin 0 -> 1454 bytes .../qdeclarativemousearea/data/mouseregion.17.png | Bin 0 -> 1454 bytes .../qdeclarativemousearea/data/mouseregion.18.png | Bin 0 -> 1454 bytes .../qdeclarativemousearea/data/mouseregion.19.png | Bin 0 -> 1454 bytes .../qdeclarativemousearea/data/mouseregion.2.png | Bin 0 -> 474 bytes .../qdeclarativemousearea/data/mouseregion.20.png | Bin 0 -> 1454 bytes .../qdeclarativemousearea/data/mouseregion.21.png | Bin 0 -> 1454 bytes .../qdeclarativemousearea/data/mouseregion.22.png | Bin 0 -> 1454 bytes .../qdeclarativemousearea/data/mouseregion.3.png | Bin 0 -> 474 bytes .../qdeclarativemousearea/data/mouseregion.4.png | Bin 0 -> 481 bytes .../qdeclarativemousearea/data/mouseregion.5.png | Bin 0 -> 481 bytes .../qdeclarativemousearea/data/mouseregion.6.png | Bin 0 -> 481 bytes .../qdeclarativemousearea/data/mouseregion.7.png | Bin 0 -> 481 bytes .../qdeclarativemousearea/data/mouseregion.8.png | Bin 0 -> 479 bytes .../qdeclarativemousearea/data/mouseregion.9.png | Bin 0 -> 479 bytes .../qmlvisual/qdeclarativemousearea/drag.qml | 26 + .../qdeclarativemousearea/mousearea-visual.qml | 135 + .../qdeclarativemouseregion/data/drag.0.png | Bin 1563 -> 0 bytes .../qdeclarativemouseregion/data/drag.1.png | Bin 1570 -> 0 bytes .../qdeclarativemouseregion/data/drag.2.png | Bin 1553 -> 0 bytes .../qdeclarativemouseregion/data/drag.3.png | Bin 1563 -> 0 bytes .../qdeclarativemouseregion/data/drag.4.png | Bin 1569 -> 0 bytes .../qdeclarativemouseregion/data/drag.5.png | Bin 1569 -> 0 bytes .../qdeclarativemouseregion/data/drag.6.png | Bin 1566 -> 0 bytes .../qdeclarativemouseregion/data/drag.7.png | Bin 1566 -> 0 bytes .../qdeclarativemouseregion/data/drag.8.png | Bin 1567 -> 0 bytes .../qdeclarativemouseregion/data/drag.qml | 5207 ----------------- .../qdeclarativemouseregion/data/mouseregion.0.png | Bin 471 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.1.png | Bin 474 -> 0 bytes .../data/mouseregion.10.png | Bin 479 -> 0 bytes .../data/mouseregion.11.png | Bin 479 -> 0 bytes .../data/mouseregion.12.png | Bin 479 -> 0 bytes .../data/mouseregion.13.png | Bin 479 -> 0 bytes .../data/mouseregion.14.png | Bin 479 -> 0 bytes .../data/mouseregion.15.png | Bin 479 -> 0 bytes .../data/mouseregion.16.png | Bin 1454 -> 0 bytes .../data/mouseregion.17.png | Bin 1454 -> 0 bytes .../data/mouseregion.18.png | Bin 1454 -> 0 bytes .../data/mouseregion.19.png | Bin 1454 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.2.png | Bin 474 -> 0 bytes .../data/mouseregion.20.png | Bin 1454 -> 0 bytes .../data/mouseregion.21.png | Bin 1454 -> 0 bytes .../data/mouseregion.22.png | Bin 1454 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.3.png | Bin 474 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.4.png | Bin 481 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.5.png | Bin 481 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.6.png | Bin 481 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.7.png | Bin 481 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.8.png | Bin 479 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.9.png | Bin 479 -> 0 bytes .../qdeclarativemouseregion/data/mouseregion.qml | 5867 -------------------- .../qmlvisual/qdeclarativemouseregion/drag.qml | 21 - .../qdeclarativemouseregion/mouseregion.qml | 124 - tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 2 + 73 files changed, 11237 insertions(+), 11219 deletions(-) create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.0.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.1.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.2.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.3.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.4.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.5.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.6.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.7.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.8.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.qml create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mousearea-visual.qml create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.0.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.1.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.10.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.11.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.12.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.13.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.14.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.15.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.16.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.17.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.18.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.19.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.2.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.20.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.21.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.22.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.3.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.4.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.5.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.6.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.7.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.8.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.9.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/drag.qml create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemousearea/mousearea-visual.qml delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.0.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.1.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.2.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.3.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.4.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.5.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.6.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.7.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.8.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.qml delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.0.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.1.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.10.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.11.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.12.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.13.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.14.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.15.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.16.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.17.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.18.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.19.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.2.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.20.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.21.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.22.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.3.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.4.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.5.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.6.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.7.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.8.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.9.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.qml delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/drag.qml delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativemouseregion/mouseregion.qml diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.0.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.0.png new file mode 100644 index 0000000..cf36d60 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.1.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.1.png new file mode 100644 index 0000000..6069df8 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.2.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.2.png new file mode 100644 index 0000000..b8bd5f3 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.3.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.3.png new file mode 100644 index 0000000..cf36d60 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.4.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.4.png new file mode 100644 index 0000000..831d6b4 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.5.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.5.png new file mode 100644 index 0000000..f7079dc Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.6.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.6.png new file mode 100644 index 0000000..a5f4451 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.6.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.7.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.7.png new file mode 100644 index 0000000..e1261d0 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.7.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.8.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.8.png new file mode 100644 index 0000000..653905e Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.8.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.qml b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.qml new file mode 100644 index 0000000..5a131e9 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/drag.qml @@ -0,0 +1,5207 @@ +import Qt.VisualTest 4.6 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 32 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 48 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 64 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 80 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 96 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 112 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 128 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 144 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 160 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 176 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 192 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 208 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 224 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 240 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 256 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 272 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 288 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 304 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 320 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 336 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 352 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 368 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 384 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 400 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 416 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 432 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 448 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 464 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 480 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 496 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 512 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 528 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 544 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 560 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 576 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 592 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 608 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 624 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 640 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 656 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 672 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 688 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 704 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 720 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 736 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 752 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 768 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 784 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 800 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 816 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 832 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 848 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 864 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 880 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 896 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 912 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 928 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 944 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 960 + image: "drag.0.png" + } + Frame { + msec: 976 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 992 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1008 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1024 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1040 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1056 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1072 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1088 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1104 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1120 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1136 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1152 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1168 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1184 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1200 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1216 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1232 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1248 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1264 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1280 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1296 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1312 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1328 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1344 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1360 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1376 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1392 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1408 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1424 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1440 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1456 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1472 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1488 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1504 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1520 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1536 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1552 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1568 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1584 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1600 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1616 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1632 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1648 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1664 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1680 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1696 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1712 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1728 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1744 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1760 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1776 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1792 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 16; y: 54 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1808 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 1824 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 16; y: 55 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 17; y: 55 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1840 + hash: "b6b4b2c7acddd23609caa9727911b981" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 17; y: 55 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1856 + hash: "b6b4b2c7acddd23609caa9727911b981" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 18; y: 55 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1872 + hash: "022610222cfbcf9e9a8991cdb60c7bbb" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 19; y: 54 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1888 + hash: "9b5201a3201a102b20592d81218b5e74" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 22; y: 49 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 29; y: 42 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1904 + hash: "a6c6df34bb552249393ba208ad327691" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 37; y: 35 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1920 + image: "drag.1.png" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 47; y: 27 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1936 + hash: "978543d8f9688605625f40b960d79c28" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 59; y: 21 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 73; y: 15 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1952 + hash: "6170ab3a7e51278ac4462b89fe7781b4" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 87; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1968 + hash: "32866f0aa5b13b3ab68661f49336439e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 100; y: 5 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1984 + hash: "26dc17c16eed46d37932cfe48d182b62" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 111; y: 1 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 121; y: -3 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2000 + hash: "ba70936fb44396fac184cc7ba0e94a90" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 130; y: -6 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2016 + hash: "bae13291d4f031c34d80428d83367ede" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 140; y: -8 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2032 + hash: "0a2fbfdc27bb6662553f637f1c325475" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 151; y: -9 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 160; y: -9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2048 + hash: "cdab85736dfcc4424d42e0e96094eded" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 170; y: -9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2064 + hash: "76d51ce9ad69560d983d8d86d50f7bd0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 174; y: -9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2080 + hash: "b5ada9e80f7f894aa141d5e3cfa5d69e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 176; y: -9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2096 + hash: "446d35fc7b9c0fe4bf0bfe0182f994f6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 183; y: -5 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2112 + hash: "cced849d314835d43ebd93bcfe396c12" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 188; y: -3 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2128 + hash: "09696d700944c373f82d7c6f75d51c51" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 193; y: 0 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2144 + hash: "af56586db93c49637c9bfbb17cac9001" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 199; y: 2 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 203; y: 5 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2160 + hash: "66fc1b30b4037aad3975036faccbb7a7" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 209; y: 8 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2176 + hash: "3f443d9c89d6ba1b36ca9635bc32de1a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 217; y: 11 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2192 + hash: "df47db8cc7bb466b298749a6449d3d70" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 227; y: 15 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 234; y: 18 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 241; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2208 + hash: "c1146fdc0e628d050442606096e52b10" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 252; y: 23 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2224 + hash: "22f44c43f300fd7ff2b4d87d93756178" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 272; y: 30 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2240 + hash: "bf11dc9a9679692abde5d116a169eecf" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 299; y: 38 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 329; y: 48 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2256 + hash: "e63f1960f342639ac412010ffcefb049" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 360; y: 57 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2272 + hash: "ae0228419ec9358025c3026a39abd671" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 392; y: 65 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2288 + hash: "6d2272e2bea21c280100ed8de5b95d4e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 422; y: 72 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 451; y: 76 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2304 + hash: "1628c6fa5feabd90924452bc9f55054d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 476; y: 78 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2320 + hash: "f696791eb0a317b0efb69407616bec9f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 497; y: 78 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2336 + hash: "f696791eb0a317b0efb69407616bec9f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 513; y: 77 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 527; y: 76 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2352 + hash: "1628c6fa5feabd90924452bc9f55054d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 538; y: 75 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2368 + hash: "a5d3d247e22a2852a60fe07ab40345a5" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 548; y: 74 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2384 + hash: "a453fb6bcdd87f819782d8d8c46b56ee" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 556; y: 74 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 563; y: 75 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2400 + hash: "a5d3d247e22a2852a60fe07ab40345a5" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 570; y: 76 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2416 + hash: "1628c6fa5feabd90924452bc9f55054d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 576; y: 78 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2432 + hash: "f696791eb0a317b0efb69407616bec9f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 582; y: 78 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 585; y: 80 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2448 + hash: "8f061986df633c21dcad767ee857988c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 589; y: 81 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2464 + hash: "2cc110a6fb800171d7d752693ede1e4e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 592; y: 82 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2480 + hash: "319fc3053e02a8b161f33a79d9839bb1" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 595; y: 85 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 597; y: 89 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2496 + hash: "42915c8866746316cf1083a2d55410fb" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 601; y: 95 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2512 + hash: "5df34b3ae292de9a9cd8ff09347e7bd4" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 606; y: 103 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2528 + hash: "1f9bc3c955983ea85f568797cb4f7365" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 609; y: 113 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 613; y: 124 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2544 + hash: "3f156dc64a12c672874acf5456ef4a31" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 618; y: 136 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2560 + hash: "d4d9fe5b5f138e06a87039ebf8695d03" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 619; y: 142 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2576 + hash: "383fe813021ee2791930200b2f88a802" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 620; y: 148 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 622; y: 155 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2592 + hash: "a235544bd5e791dfa329bd0b87358bfa" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 625; y: 163 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2608 + hash: "a87497cf47db3209610b532efe7eb380" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 629; y: 174 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2624 + hash: "abe69b4e4b7508028226f9b73c38058a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 634; y: 194 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 642; y: 225 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2640 + hash: "51c72fa2fa4c8765d882fe65dc0d697d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 649; y: 260 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2656 + hash: "79da7ed21bd6fc16b7264d4403e763cc" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 655; y: 291 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2672 + hash: "b2828b6340a57fa45416469b23b7cef0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 658; y: 316 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 659; y: 340 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2688 + hash: "64a5351f2d746b338c34c7ea9ba6e1fe" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 660; y: 370 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2704 + hash: "9eedb7a6875210084fd2ec95d3505512" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 661; y: 408 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2720 + hash: "b88eb8fa8a0cfc263dc7b655ddc29db0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 661; y: 448 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2736 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 660; y: 487 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 659; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2752 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 658; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2768 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 658; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2784 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 658; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 658; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2800 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 657; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2816 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 656; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2832 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 654; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 652; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2848 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 651; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2864 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 650; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2880 + image: "drag.2.png" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 650; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 648; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2896 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 647; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2912 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 646; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2928 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 645; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 644; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2944 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 643; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2960 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 642; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2976 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 641; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 640; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2992 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 640; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3008 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 639; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3024 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 639; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 638; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3040 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 636; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3056 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 625; y: 505 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3072 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 611; y: 505 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3088 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 582; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 546; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3104 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 505; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3120 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 460; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3136 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 408; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 354; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3152 + hash: "c2997fdde10812f02791bfed5f158ac3" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 300; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3168 + hash: "23a6dfbd09e5b44d04f252cedaeb68af" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 250; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3184 + hash: "f74422989711f86a0840ffc98e8a29e9" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 206; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 163; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3200 + hash: "fa922246d254a7c46d2d1d6ec91a2b02" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 140; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 122; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3216 + hash: "ef216cb8c2bf58db7d58bd8a2e4eb38d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 101; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3232 + hash: "a383228d22e64b8a7758c959288eaca8" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 64; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3248 + hash: "636ca2a8e91c49ef6c8b1c93b830f345" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 36; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 16; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3264 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -1; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3280 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3296 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3312 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3328 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3344 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3360 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3376 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 505 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3392 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 504 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 504 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3408 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 505 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3424 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3440 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3456 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3472 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3488 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3504 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3520 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3536 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3552 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Frame { + msec: 3568 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3584 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3600 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3616 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Frame { + msec: 3632 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 491 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3648 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 428 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3664 + hash: "9fa1e3686467f28cb013fe093dab388c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 342 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3680 + hash: "7ef97d10862f80d53e0b3b4446661deb" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 264 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 203 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3696 + hash: "c679866b3965b7b5f48b843d6efccf42" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 160 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3712 + hash: "de4bd9ad3cbb9bb19bf75f871b044072" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 144 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3728 + hash: "c5349bbddc03edd5ee3537e2a738f1ad" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 136 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 132 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3744 + hash: "bcbe9ec2687a6030385f08d3dc17becf" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 130 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3760 + hash: "3ad767f63eaccb9e64a9f704900f2530" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 129 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3776 + hash: "421a1ffde15fda0e7846bc095ed2ea37" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 128 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 128 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3792 + hash: "55c260da304a6b1119af83f6a4efcff0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 123 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3808 + hash: "f231cc521db801b4ec71248812e12db8" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 104 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3824 + hash: "b489b6b604e7f7699cac9e42d0725323" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 68 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 35 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3840 + image: "drag.3.png" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 13 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3856 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 2 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3872 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -6 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -12 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3888 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3904 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -46 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3920 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -65 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -70 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3936 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -74 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3952 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -76 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3968 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -76 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3984 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -76 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4000 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -77 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4016 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -78 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4032 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4048 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -78 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4064 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4080 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4096 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -77 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4112 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4128 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4144 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: -78 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4160 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -3; y: -84 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4176 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -2; y: -105 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 1; y: -151 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4192 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4208 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4224 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4240 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4256 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4272 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4288 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4304 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4320 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4336 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4352 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4368 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Frame { + msec: 4384 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 3; y: -151 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4400 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 4; y: -149 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4416 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 5; y: -147 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4432 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 5; y: -143 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 6; y: -138 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4448 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 7; y: -130 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4464 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 9; y: -117 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4480 + hash: "668cc6d9d699b947a7c0f3ff4b26853f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 13; y: -94 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 20; y: -63 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4496 + hash: "b1b54f7bf8ab9cf98d96f9b34192434b" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 29; y: -24 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4512 + hash: "a6c6df34bb552249393ba208ad327691" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 39; y: 15 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4528 + hash: "a05eb803b1f1f3574a2f2e08fe37bd35" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 49; y: 50 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 58; y: 74 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4544 + hash: "3c2f3db46673c2640a26832900b609cb" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 65; y: 91 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4560 + hash: "d0539a9791874f48634bb3cb9f78d9db" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 71; y: 103 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4576 + hash: "f2d862a0b81e2578799d64aef2e6bddc" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 77; y: 112 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 81; y: 121 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4592 + hash: "295ef097845e30064c4d810a7718896c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 86; y: 128 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4608 + hash: "22a4a17d82ac402c0e8372861609ff1c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 92; y: 136 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4624 + hash: "a70e81b1435afd77b9079c58685ef9d0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 98; y: 143 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 104; y: 151 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4640 + hash: "d66fefd68fcd96834548c18797eee4bd" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 111; y: 159 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4656 + hash: "fcc435dc6f2643cd21a7cfac078880af" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 118; y: 166 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4672 + hash: "736edfcf33245d46aaea199634896c17" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 123; y: 173 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 129; y: 183 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4688 + hash: "7b7ab312d0c6f4bfc87a2ae467324f4e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 137; y: 197 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4704 + hash: "d78ce756fc27055eeee15001419b7fb5" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 146; y: 215 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4720 + hash: "4f15a726939d7f489d1fe58ebb5bcd0a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 157; y: 235 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 168; y: 255 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4736 + hash: "72184d71fd2fdc6786a43045db0be68f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 180; y: 274 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4752 + hash: "3b3f3f34218bf238f310412cb8c4968d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 192; y: 293 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4768 + hash: "24c00a7154471431d43b1db957ad6424" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 205; y: 316 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 221; y: 343 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4784 + hash: "30081a33ab007ff2c7ba6cc293a5aec3" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 237; y: 371 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4800 + image: "drag.4.png" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 253; y: 396 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4816 + hash: "c0cadb7730838d553b146804c37506b0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 268; y: 419 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 276; y: 429 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 284; y: 438 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4832 + hash: "101c007d0e2cf82331ba1cab4880e8a2" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 291; y: 448 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4848 + hash: "72e46df7427420c5e942a97831723d3f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 307; y: 468 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4864 + hash: "4b7a009b46982a1e9e31250d7ebf0a20" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 323; y: 492 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 341; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4880 + hash: "a3ba70933b6452fad0cdc4192e04be23" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 359; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4896 + hash: "c2ee16182222b403f914eb5550ac6f91" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 378; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4912 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 397; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 416; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4928 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 432; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4944 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 445; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4960 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 456; y: 506 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 466; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4976 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 475; y: 506 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4992 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 482; y: 505 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5008 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 488; y: 504 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 492; y: 503 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5024 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 496; y: 503 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5040 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 500; y: 502 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5056 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 507; y: 501 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5072 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 512; y: 500 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 516; y: 498 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5088 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 521; y: 494 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5104 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 525; y: 486 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5120 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 532; y: 472 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 542; y: 445 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5136 + hash: "9356ce797d12ae076af947cd0e658551" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 553; y: 414 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5152 + hash: "76a8d3b8465f08fdc4586c7766667eff" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 563; y: 389 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5168 + hash: "569e56ba99776d03dd3140e53bc77f56" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 569; y: 373 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 573; y: 363 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5184 + hash: "7139c72a2458685006da79d9cf11bc44" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 577; y: 354 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5200 + hash: "a83d5ef213edec4c8f938ab04afb5c4f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 580; y: 344 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5216 + hash: "5533602bc8a473c162966142d4bddebd" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 584; y: 321 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 586; y: 301 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5232 + hash: "7a79d6e31874428233e9c141d70522fd" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 588; y: 264 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5248 + hash: "b14f4daeb25cd71baae36f4cec111813" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 591; y: 238 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5264 + hash: "e2b2513d2918ffb85bab5fff5a8be644" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 592; y: 225 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 593; y: 216 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5280 + hash: "af0cbb3423491917db1fdaa8350d48b0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 594; y: 209 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5296 + hash: "b9c107f0a13ad37ae05b4d5f9e5f5442" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 594; y: 200 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5312 + hash: "0bbc0c7a4a40ee6b19565c04c23b565d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 594; y: 182 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 593; y: 146 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5328 + hash: "49494e8526a1417c151c7cac7099b9e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 590; y: 107 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5344 + hash: "5e0839c4414cc8ddc5241c658fd3bf88" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 585; y: 80 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5360 + hash: "8f061986df633c21dcad767ee857988c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 582; y: 67 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5376 + hash: "d78c0a4fa0ccad407a565fab3a5c95b9" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 579; y: 61 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 576; y: 57 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5392 + hash: "cee6816f84911bc2262afe28d8996719" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 573; y: 55 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5408 + hash: "2cc6cd514ef7299dd60bf1a735b81d36" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 569; y: 51 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5424 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 564; y: 44 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 557; y: 35 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5440 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 548; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5456 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 540; y: 14 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 532; y: 5 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5472 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 524; y: -1 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5488 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 517; y: -5 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5504 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 510; y: -9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5520 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 501; y: -14 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 492; y: -18 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5536 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 483; y: -21 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5552 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 476; y: -21 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5568 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 470; y: -19 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 464; y: -15 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5584 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 458; y: -9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5600 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 452; y: -3 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5616 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 446; y: 4 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 439; y: 11 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5632 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 432; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5648 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 424; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5664 + hash: "68c40f3551d7d10e61c5ffbb6948c7e6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 413; y: 42 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 400; y: 59 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5680 + hash: "9bc8a652f43c0e3cae9492f5dff624e7" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 392; y: 70 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 385; y: 79 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5696 + hash: "5465128afe72d9618cd9abc47f4ce72f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 378; y: 88 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5712 + hash: "ad739c2028caf8f89d8ae04d509c7854" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 366; y: 102 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 353; y: 114 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5728 + hash: "97cd37f639a7bea76a2f68774c0753db" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 339; y: 126 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5744 + hash: "d24fc8a57dd34e6ddb726426247ec219" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 324; y: 140 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5760 + image: "drag.5.png" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 308; y: 158 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 288; y: 181 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5776 + hash: "7af87eb80fa9d87fe8d8b5e4a2fff5e1" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 266; y: 208 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5792 + hash: "73623f4a857fd4d5150c2eeef1341540" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 243; y: 237 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5808 + hash: "076c4b60d9ec197950ade51e3f1be791" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 217; y: 265 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 191; y: 291 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5824 + hash: "22b7d7765c634763fa86912ea262efca" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 167; y: 314 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5840 + hash: "1267c017931bda0b88b4672f46d499e0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 147; y: 331 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5856 + hash: "b6a545e4c14b809f4ebcffbcb59a8e4f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 132; y: 344 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 121; y: 354 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5872 + hash: "b1085cb508d4613c76e99bc879c62cbf" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 111; y: 363 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5888 + hash: "365fd1260c2109e6d5bd0a97ce3a7e4e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 100; y: 370 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5904 + hash: "3a7d001313b23cbbb7f3d842ab40f41b" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 86; y: 377 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 66; y: 385 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5920 + hash: "c5bda48bb2eaee54d6d8416592830327" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 45; y: 394 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5936 + hash: "5d0fd6d8a6ced4f197fe3b09e7e9155b" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 29; y: 402 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5952 + hash: "79e2825f98644c061ae5216ae1823e4b" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 16; y: 410 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 6; y: 417 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5968 + hash: "22a3978f2f3a0cde67f459527af3b3f2" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 0; y: 422 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 427 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5984 + hash: "1511bec94911dd272f78a726e15bf76e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 432 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6000 + hash: "0f892f7e570cdc703e492248c9f54b6c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 439 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6016 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 447 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 452 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6032 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 457 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6048 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 459 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6064 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 464 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 465 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6080 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 467 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6096 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 468 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6112 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 468 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 468 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6128 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 468 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6144 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 468 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6160 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 469 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 470 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6176 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 470 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6192 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Frame { + msec: 6208 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 470 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6224 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -3; y: 470 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -3; y: 470 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6240 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -2; y: 470 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6256 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -1; y: 470 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6272 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -1; y: 468 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 0; y: 467 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6288 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 0; y: 464 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6304 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 0; y: 458 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6320 + hash: "ec34aa6937d2c081bdf11660a5eb461a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -3; y: 441 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 408 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6336 + hash: "58413f9b01f1e0b49519d8b6a3011607" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 366 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6352 + hash: "b3992d2f9c1383c710ee325a94117a8b" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 327 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6368 + hash: "bd415044fcf6218d8184cb0206105e65" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 300 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 288 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6384 + hash: "e7296140fe8b28bed77e95e588c0e463" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 280 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6400 + hash: "9ff532223ccccd663809187465e478c2" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 276 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6416 + hash: "4de9ca75503db05df5d8274d75c202e5" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 271 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 259 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6432 + hash: "a83b5bc409207e986055081b4ed3faa6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 227 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6448 + hash: "7fdbd00dd3553241f30fd6568a8ab646" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 190 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6464 + hash: "5ebaa67eaadc1ede8c46964fa1dffff1" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -4; y: 169 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: -2; y: 160 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6480 + hash: "de4bd9ad3cbb9bb19bf75f871b044072" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 1; y: 156 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6496 + hash: "9d762cd4dd6508cf8b54c47b76f4ef37" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 5; y: 155 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6512 + hash: "bdf17c384f4f824a89a06b88ba17c15f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 10; y: 154 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 25; y: 152 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6528 + hash: "f279f28995785afd143726aef7673b50" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 52; y: 149 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6544 + hash: "53b6b82a61d017e12afb01a728d8d856" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 80; y: 148 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6560 + hash: "9a48039175cab1360a0cf5cc195e2082" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 98; y: 148 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 112; y: 150 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6576 + hash: "cfc3991e30eef6c2edb66cb6060b2bde" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 123; y: 153 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6592 + hash: "737d8907f62768e623ba76866a509d1e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 134; y: 155 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6608 + hash: "dea2a596f7d85f29728b33d126d997e5" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 145; y: 158 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 157; y: 161 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6624 + hash: "3969a0bbb284ab1d5efd20cf93b0422d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 168; y: 164 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6640 + hash: "071ff25e49f7f16a727ff58c42ff766e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 176; y: 169 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6656 + hash: "454abec991a4675763f379c256919fa7" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 184; y: 173 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 189; y: 177 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6672 + hash: "6de741c4e6057dc8580106155c4ac627" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 194; y: 184 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6688 + hash: "e35853e99cd205b7ccabdf632b238584" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 199; y: 192 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6704 + hash: "15a70a0196227c6bce50ed70cd6383c8" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 204; y: 201 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 211; y: 210 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6720 + image: "drag.6.png" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 217; y: 217 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6736 + hash: "5e951eb6017a060287e398fcaf4aeba9" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 224; y: 223 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6752 + hash: "ddd0f27027e23a45aef131296c781865" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 235; y: 228 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 246; y: 232 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6768 + hash: "715102a252756e5a8c4f459d808aec6a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 257; y: 235 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6784 + hash: "42b9c1b894247ddbd85f4a4aca5695f1" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 267; y: 239 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6800 + hash: "b67b4bdd412ed5160901803c60c6f19e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 275; y: 239 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 280; y: 239 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6816 + hash: "3490cc41c2b1f9301c209bdb8f052add" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 281; y: 239 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6832 + hash: "df32868d564ebbc41c359409b5a69e7d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 282; y: 239 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6848 + hash: "b9cb430a6f677e67c87322e0aff53fb1" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 282; y: 239 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6864 + hash: "b9cb430a6f677e67c87322e0aff53fb1" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 281; y: 239 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6880 + hash: "df32868d564ebbc41c359409b5a69e7d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 280; y: 239 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6896 + hash: "3490cc41c2b1f9301c209bdb8f052add" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 279; y: 240 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6912 + hash: "e23a88f49a73cd2a9326095dd380ab55" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 277; y: 240 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6928 + hash: "ffffc1aed27fe77c2fe5c035eab706a9" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 277; y: 240 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6944 + hash: "ffffc1aed27fe77c2fe5c035eab706a9" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 276; y: 240 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6960 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 276; y: 240 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6976 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 6992 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 276; y: 240 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 7008 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7024 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7040 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7056 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7072 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7088 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7104 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7120 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7136 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7152 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7168 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7184 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7200 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7216 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7232 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7248 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7264 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7280 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7296 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7312 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7328 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7344 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7360 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7376 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7392 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7408 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7424 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7440 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7456 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7472 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7488 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7504 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7520 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7536 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7552 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7568 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7584 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7600 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7616 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7632 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7648 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7664 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7680 + image: "drag.7.png" + } + Frame { + msec: 7696 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7712 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7728 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7744 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7760 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7776 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7792 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7808 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7824 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7840 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7856 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7872 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7888 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7904 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7920 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7936 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7952 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7968 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 7984 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } + Frame { + msec: 8000 + hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mousearea-visual.qml b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mousearea-visual.qml new file mode 100644 index 0000000..cc374fd --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mousearea-visual.qml @@ -0,0 +1,5867 @@ +import Qt.VisualTest 4.6 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 32 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 48 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 64 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 80 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 96 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 112 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 128 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 144 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 160 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 176 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 192 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 208 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 224 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 240 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 256 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 272 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 288 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 304 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 320 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 336 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 352 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 368 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 384 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 400 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 416 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 432 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 448 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 464 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 480 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 496 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 512 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 528 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 544 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 560 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 576 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 592 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 608 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 624 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 640 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 656 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 672 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 688 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 704 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 720 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 736 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 752 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 768 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 784 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 800 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 816 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 832 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 848 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 864 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 880 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 896 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 912 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 928 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 944 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 960 + image: "mouseregion.0.png" + } + Frame { + msec: 976 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 992 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1008 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1024 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1040 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1056 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1072 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1088 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1104 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1120 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1136 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1152 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1168 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1184 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1200 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1216 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1232 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1248 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1264 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1280 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1296 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1312 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1328 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1344 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1360 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1376 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1392 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1408 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1424 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1440 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1456 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1472 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1488 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1504 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1520 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1536 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1552 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1568 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1584 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1600 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1616 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1632 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1648 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Frame { + msec: 1664 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 2; y: 29 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 7; y: 32 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1680 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 19; y: 40 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 33; y: 48 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1696 + hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 49; y: 54 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1712 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 67; y: 56 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 74; y: 56 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1728 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 78; y: 57 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 81; y: 57 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1744 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 82; y: 56 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 83; y: 55 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1760 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 83; y: 54 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1776 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 83; y: 53 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1792 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Frame { + msec: 1808 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Frame { + msec: 1824 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Frame { + msec: 1840 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Frame { + msec: 1856 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Frame { + msec: 1872 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 83; y: 52 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 82; y: 51 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1888 + hash: "337f0f4af627bbdf8807135ce39d5070" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 80; y: 50 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 78; y: 48 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1904 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 75; y: 46 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 73; y: 45 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1920 + image: "mouseregion.1.png" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 71; y: 43 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 68; y: 41 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1936 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 66; y: 40 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1952 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 64; y: 39 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 63; y: 37 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1968 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 61; y: 36 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 60; y: 36 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1984 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 58; y: 34 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 57; y: 33 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2000 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 56; y: 32 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2016 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 55; y: 30 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 54; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2032 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2048 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2064 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2080 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2096 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2112 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2128 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 54; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2144 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2160 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2176 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2192 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2208 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2224 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2240 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 54; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2256 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2272 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2288 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2304 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2320 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2336 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2352 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2368 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2384 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2400 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2416 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2432 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2448 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2464 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2480 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2496 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2512 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2528 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2544 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2560 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2576 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2592 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2608 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2624 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2640 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 2 + button: 2 + buttons: 2 + x: 54; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2656 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2672 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2688 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2704 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2720 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2736 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2752 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 3 + button: 2 + buttons: 0 + x: 54; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2768 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2784 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2800 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2816 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2832 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2848 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2864 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 2880 + image: "mouseregion.2.png" + } + Frame { + msec: 2896 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 55; y: 29 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 58; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2912 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 62; y: 29 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 67; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2928 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 75; y: 30 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2944 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 91; y: 34 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 99; y: 34 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2960 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 107; y: 34 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 113; y: 34 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2976 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 119; y: 34 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 124; y: 33 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2992 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 128; y: 33 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 131; y: 32 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3008 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 132; y: 32 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 132; y: 31 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3024 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3040 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3056 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3072 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3088 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3104 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3120 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3136 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3152 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3168 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3184 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3200 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3216 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3232 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3248 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3264 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3280 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3296 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3312 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3328 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3344 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3360 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3376 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3392 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3408 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3424 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3440 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3456 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3472 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3488 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3504 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3520 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3536 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3552 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 133; y: 31 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3568 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3584 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 133; y: 31 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3600 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3616 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3632 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3648 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3664 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3680 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3696 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 133; y: 31 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3712 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3728 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3744 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3760 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3776 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3792 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3808 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3824 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3840 + image: "mouseregion.3.png" + } + Frame { + msec: 3856 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3872 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3888 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3904 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3920 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3936 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3952 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3968 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 3984 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4000 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4016 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4032 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4048 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4064 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4080 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4096 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4112 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4128 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4144 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4160 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4176 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4192 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4208 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4224 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4240 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4256 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4272 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4288 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4304 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4320 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 2 + button: 2 + buttons: 2 + x: 133; y: 31 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4336 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4352 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4368 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4384 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4400 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4416 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Frame { + msec: 4432 + hash: "73f1639b9e2164c7b974042934c0d151" + } + Mouse { + type: 3 + button: 2 + buttons: 0 + x: 133; y: 31 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4448 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4464 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4480 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4496 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4512 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4528 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4544 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4560 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4576 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4592 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4608 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4624 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4640 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4656 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4672 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4688 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4704 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4720 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4736 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 133; y: 32 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 136; y: 32 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4752 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 142; y: 32 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 148; y: 32 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4768 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 155; y: 32 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 161; y: 32 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4784 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 166; y: 31 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4800 + image: "mouseregion.4.png" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 168; y: 31 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 170; y: 30 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4816 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 171; y: 29 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4832 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4848 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4864 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 4880 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 172; y: 28 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 175; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4896 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 178; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4912 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 182; y: 24 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 187; y: 22 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4928 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 191; y: 22 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 195; y: 21 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4944 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 200; y: 21 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 206; y: 21 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4960 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 211; y: 21 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 215; y: 21 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4976 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 218; y: 21 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 221; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4992 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 224; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5008 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 225; y: 20 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 226; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5024 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 227; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5040 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5056 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5072 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 228; y: 20 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 229; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5088 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 231; y: 20 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 232; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5104 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 233; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5120 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5136 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5152 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5168 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 233; y: 21 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 234; y: 22 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5184 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 237; y: 23 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5200 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 239; y: 24 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 242; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5216 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 244; y: 25 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 245; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5232 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5248 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5264 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5280 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5296 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5312 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5328 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5344 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5360 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5376 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5392 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5408 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5424 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5440 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5456 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5472 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5488 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5504 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5520 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5536 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5552 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5568 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5584 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5600 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5616 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5632 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5648 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5664 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5680 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5696 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5712 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5728 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5744 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5760 + image: "mouseregion.5.png" + } + Frame { + msec: 5776 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5792 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5808 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5824 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5840 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5856 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5872 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5888 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5904 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5920 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5936 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5952 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5968 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 5984 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6000 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6016 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6032 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6048 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6064 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6080 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6096 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6112 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6128 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6144 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6160 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6176 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6192 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6208 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6224 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6240 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6256 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6272 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6288 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6304 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6320 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6336 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6352 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6368 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6384 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6400 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6416 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6432 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6448 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6464 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6480 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6496 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6512 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6528 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6544 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6560 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6576 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6592 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6608 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6624 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6640 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6656 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6672 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6688 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6704 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6720 + image: "mouseregion.6.png" + } + Frame { + msec: 6736 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 4 + button: 1 + buttons: 1 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6752 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6768 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6784 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6800 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6816 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6832 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 6848 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6864 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6880 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6896 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6912 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6928 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6944 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6960 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6976 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 6992 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7008 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7024 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7040 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7056 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7072 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7088 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7104 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7120 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7136 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7152 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7168 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7184 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7200 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 7216 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7232 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7248 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7264 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7280 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7296 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7312 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7328 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7344 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7360 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7376 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7392 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7408 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7424 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7440 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7456 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7472 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7488 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7504 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7520 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7536 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7552 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7568 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7584 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7600 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7616 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7632 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7648 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7664 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7680 + image: "mouseregion.7.png" + } + Frame { + msec: 7696 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7712 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7728 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7744 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7760 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7776 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7792 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7808 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7824 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7840 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7856 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7872 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7888 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7904 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7920 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7936 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7952 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7968 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 7984 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 8000 + hash: "12edb0902e4d480c9052b00edc1a0a42" + } + Frame { + msec: 8016 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8032 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8048 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8064 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8080 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8096 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8112 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8128 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8144 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8160 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8176 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8192 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8208 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8224 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8240 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8256 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8272 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8288 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8304 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8320 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8336 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 247; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8352 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8368 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8384 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8400 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8416 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8432 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8448 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8464 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8480 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8496 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8512 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8528 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 248; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8544 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 254; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 259; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8560 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 264; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 268; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8576 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 273; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 277; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8592 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 281; y: 24 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 284; y: 24 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8608 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 287; y: 24 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 289; y: 24 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8624 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 292; y: 24 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8640 + image: "mouseregion.8.png" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 294; y: 24 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 295; y: 24 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8656 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 297; y: 24 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 299; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8672 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 301; y: 25 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 304; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8688 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 307; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8704 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 310; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 312; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8720 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 314; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 315; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8736 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 317; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 318; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8752 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 319; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8768 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 320; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8784 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 322; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 323; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8800 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 325; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 327; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8816 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 330; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 333; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8832 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 336; y: 26 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 338; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8848 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 339; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8864 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 340; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8880 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 8896 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 340; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8912 + hash: "d1f2fc2133f3d6554e41982196662c2a" + } + Frame { + msec: 8928 + hash: "d1f2fc2133f3d6554e41982196662c2a" + } + Frame { + msec: 8944 + hash: "d1f2fc2133f3d6554e41982196662c2a" + } + Frame { + msec: 8960 + hash: "d1f2fc2133f3d6554e41982196662c2a" + } + Frame { + msec: 8976 + hash: "d1f2fc2133f3d6554e41982196662c2a" + } + Frame { + msec: 8992 + hash: "d1f2fc2133f3d6554e41982196662c2a" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 340; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9008 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9024 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9040 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9056 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9072 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9088 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9104 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9120 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9136 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9152 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9168 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9184 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9200 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9216 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9232 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9248 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9264 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9280 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9296 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9312 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9328 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9344 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9360 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9376 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9392 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9408 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9424 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9440 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9456 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9472 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9488 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9504 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9520 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9536 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9552 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9568 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9584 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 9600 + image: "mouseregion.9.png" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 339; y: 26 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9616 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 336; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9632 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 332; y: 25 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 326; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9648 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 320; y: 25 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 312; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9664 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 292; y: 25 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 283; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9680 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 261; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9696 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 252; y: 25 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 243; y: 25 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9712 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 225; y: 29 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 207; y: 33 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9728 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 189; y: 35 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 169; y: 39 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9744 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 161; y: 40 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 145; y: 44 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9760 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 138; y: 45 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9776 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 133; y: 48 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 127; y: 50 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9792 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 122; y: 52 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 118; y: 56 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9808 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 114; y: 57 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 110; y: 60 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9824 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 109; y: 61 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9840 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 107; y: 62 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 106; y: 63 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9856 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 103; y: 63 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 100; y: 64 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9872 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 96; y: 64 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 92; y: 65 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9888 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 88; y: 65 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9904 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 85; y: 66 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 82; y: 67 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9920 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 79; y: 69 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 77; y: 70 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9936 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 74; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 70; y: 72 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9952 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 67; y: 74 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 64; y: 75 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9968 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 62; y: 76 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 9984 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 61; y: 76 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 60; y: 77 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10000 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10016 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10032 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 59; y: 77 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10048 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 58; y: 77 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 57; y: 77 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10064 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 56; y: 76 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10080 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10096 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10112 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10128 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10144 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10160 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10176 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10192 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10208 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10224 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Frame { + msec: 10240 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 57; y: 76 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 59; y: 75 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10256 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 62; y: 75 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10272 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 65; y: 74 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 69; y: 74 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10288 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 72; y: 73 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 76; y: 73 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10304 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 80; y: 72 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 84; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10320 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 87; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 90; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10336 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 93; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10352 + hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 96; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 99; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10368 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 102; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 106; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10384 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 108; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 110; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10400 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 113; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 115; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10416 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 118; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 121; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10432 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 123; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10448 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 126; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 128; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10464 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 130; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 132; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10480 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 133; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10496 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 134; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10512 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10528 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 135; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 136; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10544 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 137; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 138; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10560 + image: "mouseregion.10.png" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 140; y: 71 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 10576 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10592 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10608 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10624 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10640 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10656 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10672 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10688 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10704 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10720 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10736 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10752 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10768 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10784 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10800 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10816 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10832 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10848 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10864 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10880 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10896 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10912 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10928 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10944 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10960 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10976 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 10992 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11008 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11024 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11040 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11056 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11072 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11088 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11104 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11120 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11136 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11152 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11168 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11184 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11200 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11216 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11232 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11248 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11264 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 11280 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11296 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11312 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11328 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11344 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11360 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 11376 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11392 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11408 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11424 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11440 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11456 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11472 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11488 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11504 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11520 + image: "mouseregion.11.png" + } + Frame { + msec: 11536 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11552 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11568 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11584 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11600 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11616 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11632 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11648 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11664 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11680 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11696 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11712 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 2 + buttons: 2 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 11728 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11744 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11760 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11776 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11792 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11808 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11824 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 2 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 11840 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11856 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11872 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11888 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11904 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11920 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11936 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11952 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11968 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 11984 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12000 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12016 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12032 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12048 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 4 + button: 2 + buttons: 2 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12064 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12080 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12096 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12112 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12128 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12144 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12160 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12176 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12192 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12208 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 2 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12224 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12240 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12256 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12272 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12288 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12304 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12320 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12336 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12352 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12368 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12384 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12400 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12416 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12432 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12448 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 2 + buttons: 3 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12464 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12480 + image: "mouseregion.12.png" + } + Frame { + msec: 12496 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12512 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12528 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 2 + buttons: 1 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12544 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12560 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12576 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12592 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12608 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12624 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12640 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12656 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12672 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12688 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12704 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12720 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12736 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12752 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12768 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12784 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12800 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12816 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12832 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 4 + button: 1 + buttons: 1 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12848 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12864 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12880 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12896 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12912 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12928 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12944 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12960 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 12976 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 12992 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13008 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13024 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13040 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13056 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13072 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13088 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 4 + button: 1 + buttons: 1 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13104 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13120 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13136 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13152 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13168 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13184 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13200 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13216 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13232 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13248 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13264 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13280 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13296 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13312 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13328 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13344 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13360 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13376 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13392 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13408 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13424 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13440 + image: "mouseregion.13.png" + } + Frame { + msec: 13456 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13472 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13488 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13504 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13520 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13536 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13552 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13568 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13584 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13600 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13616 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13632 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 2 + button: 2 + buttons: 2 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13648 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13664 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13680 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13696 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13712 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 2 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13728 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13744 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13760 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13776 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13792 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13808 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 4 + button: 2 + buttons: 2 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13824 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13840 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13856 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13872 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13888 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13904 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 3 + button: 2 + buttons: 0 + x: 141; y: 71 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 13920 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13936 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13952 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13968 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 13984 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14000 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14016 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14032 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14048 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14064 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14080 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14096 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14112 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14128 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14144 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14160 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14176 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 141; y: 70 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 148; y: 68 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14192 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 152; y: 68 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 158; y: 68 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14208 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 164; y: 68 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14224 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 171; y: 66 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 187; y: 62 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 205; y: 60 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14240 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 223; y: 56 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14256 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 239; y: 52 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 255; y: 46 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14272 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 269; y: 40 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 285; y: 34 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14288 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 299; y: 28 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 313; y: 20 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14304 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 320; y: 18 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 326; y: 15 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14320 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Mouse { + type: 5 + button: 0 + buttons: 0 + x: 340; y: 7 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 14336 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14352 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14368 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14384 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14400 + image: "mouseregion.14.png" + } + Frame { + msec: 14416 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14432 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14448 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14464 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14480 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14496 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14512 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14528 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14544 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14560 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14576 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14592 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14608 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14624 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14640 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14656 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14672 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14688 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14704 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14720 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14736 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14752 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14768 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14784 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14800 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14816 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14832 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14848 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14864 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14880 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14896 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14912 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } + Frame { + msec: 14928 + hash: "194ebac4ae7d95bf427f8161885a13e1" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.0.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.0.png new file mode 100644 index 0000000..c249c21 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.1.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.1.png new file mode 100644 index 0000000..a96bf1b Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.10.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.10.png new file mode 100644 index 0000000..7420ca7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.10.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.11.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.11.png new file mode 100644 index 0000000..7420ca7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.11.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.12.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.12.png new file mode 100644 index 0000000..7420ca7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.12.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.13.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.13.png new file mode 100644 index 0000000..7420ca7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.13.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.14.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.14.png new file mode 100644 index 0000000..7420ca7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.14.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.15.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.15.png new file mode 100644 index 0000000..e797cc9 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.15.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.16.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.16.png new file mode 100644 index 0000000..7951309 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.16.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.17.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.17.png new file mode 100644 index 0000000..7951309 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.17.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.18.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.18.png new file mode 100644 index 0000000..7951309 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.18.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.19.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.19.png new file mode 100644 index 0000000..7951309 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.19.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.2.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.2.png new file mode 100644 index 0000000..a96bf1b Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.20.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.20.png new file mode 100644 index 0000000..7951309 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.20.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.21.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.21.png new file mode 100644 index 0000000..7951309 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.21.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.22.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.22.png new file mode 100644 index 0000000..7951309 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.22.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.3.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.3.png new file mode 100644 index 0000000..a96bf1b Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.4.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.4.png new file mode 100644 index 0000000..1fe365a Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.5.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.5.png new file mode 100644 index 0000000..1fe365a Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.6.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.6.png new file mode 100644 index 0000000..1fe365a Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.6.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.7.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.7.png new file mode 100644 index 0000000..1fe365a Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.7.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.8.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.8.png new file mode 100644 index 0000000..7420ca7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.8.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.9.png b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.9.png new file mode 100644 index 0000000..7420ca7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/data/mouseregion.9.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/drag.qml b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/drag.qml new file mode 100644 index 0000000..21c46d8 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/drag.qml @@ -0,0 +1,26 @@ +import Qt 4.6 + +/* +this test shows a blue box being dragged around -- first roughly tracing the +borders of the window, then doing a rough 'x'-shape, then moving to around the middle. +*/ + +Rectangle{ + width:400 + height:440 + color: "white" + Rectangle{ + id: draggable + width:40; height:40; color: "lightsteelblue" + y:20 + MouseArea{ + anchors.fill: parent + drag.target: draggable + drag.axis: "XandYAxis" + drag.minimumX: 0 + drag.maximumX: 360 + drag.minimumY: 20 + drag.maximumY: 400 + } + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemousearea/mousearea-visual.qml b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/mousearea-visual.qml new file mode 100644 index 0000000..3019006 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativemousearea/mousearea-visual.qml @@ -0,0 +1,135 @@ +import Qt 4.6 + +/* +This test displays 6 red rects -- 4 in the top row, 2 in the bottom. + +Sequence: +1. the bottom-left rect turns blue, then green +2. the second rect in the top row turns blue +3. the third rect in the top row turns blue +4. the last rect in the top row quickly turns blue then back to red +5. the bottom-left rect turns blue, then green +*/ + +Rectangle { + id: root + width: 400 + height: 100 + + // Left click on me + Rectangle { + width: 98; height: 48 + color: "red" + MouseArea { + id: mr1 + anchors.fill: parent + enabled: false + onClicked: { parent.color = "blue"; root.error = "mr1 should ignore presses"; } + } + } + + // Left click, then right click + Rectangle { + x: 100 + width: 98; height: 48 + color: "red" + MouseArea { + id: mr2 + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: { + if (mouse.button == Qt.RightButton) { + parent.color = "blue"; + } else { + parent.color = "green"; + root.error = "mr1 should ignore presses"; + } + } + } + } + + // press and hold me + Rectangle { + x: 200 + width: 98; height: 48 + color: "red" + MouseArea { + id: mr3 + anchors.fill: parent + onPressAndHold: { + parent.color = "blue"; + } + } + } + + // click me + Rectangle { + x: 300 + width: 98; height: 48 + color: "red" + MouseArea { + id: mr4 + anchors.fill: parent + onPressed: { + parent.color = "blue"; + } + onReleased: { + parent.color = "red"; + } + } + } + + // move into and out of me + Rectangle { + x: 0 + y: 50 + width: 98; height: 48 + color: "red" + MouseArea { + id: mr5 + anchors.fill: parent + hoverEnabled: true + onEntered: { + parent.color = "blue"; + } + onExited: { + parent.color = "green"; + } + } + } + + // click, then double click me + Rectangle { + x: 100 + y: 50 + width: 98; height: 48 + color: "red" + MouseArea { + id: mr6 + anchors.fill: parent + onClicked: { + parent.color = "blue"; + } + onDoubleClicked: { + parent.color = "green"; + } + } + } + + // click, then double click me - nothing should happen + Rectangle { + x: 100 + y: 50 + width: 98; height: 48 + color: "red" + MouseArea { + id: mr7 + anchors.fill: parent + enabled: false + onClicked: { parent.color = "blue" } + onPressed: { parent.color = "yellow" } + onReleased: { parent.color = "cyan" } + onDoubleClicked: { parent.color = "green" } + } + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.0.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.0.png deleted file mode 100644 index cf36d60..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.0.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.1.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.1.png deleted file mode 100644 index 6069df8..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.1.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.2.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.2.png deleted file mode 100644 index b8bd5f3..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.2.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.3.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.3.png deleted file mode 100644 index cf36d60..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.3.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.4.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.4.png deleted file mode 100644 index 831d6b4..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.4.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.5.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.5.png deleted file mode 100644 index f7079dc..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.5.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.6.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.6.png deleted file mode 100644 index a5f4451..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.6.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.7.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.7.png deleted file mode 100644 index e1261d0..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.7.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.8.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.8.png deleted file mode 100644 index 653905e..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.8.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.qml b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.qml deleted file mode 100644 index 5a131e9..0000000 --- a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/drag.qml +++ /dev/null @@ -1,5207 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { - msec: 0 - } - Frame { - msec: 16 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 32 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 48 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 64 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 80 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 96 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 112 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 128 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 144 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 160 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 176 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 192 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 208 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 224 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 240 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 256 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 272 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 288 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 304 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 320 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 336 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 352 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 368 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 384 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 400 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 416 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 432 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 448 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 464 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 480 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 496 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 512 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 528 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 544 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 560 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 576 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 592 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 608 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 624 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 640 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 656 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 672 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 688 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 704 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 720 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 736 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 752 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 768 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 784 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 800 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 816 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 832 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 848 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 864 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 880 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 896 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 912 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 928 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 944 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 960 - image: "drag.0.png" - } - Frame { - msec: 976 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 992 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1008 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1024 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1040 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1056 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1072 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1088 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1104 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1120 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1136 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1152 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1168 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1184 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1200 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1216 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1232 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1248 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1264 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1280 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1296 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1312 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1328 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1344 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1360 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1376 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1392 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1408 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1424 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1440 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1456 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1472 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1488 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1504 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1520 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1536 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1552 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1568 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1584 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1600 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1616 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1632 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1648 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1664 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1680 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1696 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1712 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1728 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1744 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1760 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1776 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1792 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 16; y: 54 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1808 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 1824 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 16; y: 55 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 17; y: 55 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1840 - hash: "b6b4b2c7acddd23609caa9727911b981" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 17; y: 55 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1856 - hash: "b6b4b2c7acddd23609caa9727911b981" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 18; y: 55 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1872 - hash: "022610222cfbcf9e9a8991cdb60c7bbb" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 19; y: 54 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1888 - hash: "9b5201a3201a102b20592d81218b5e74" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 22; y: 49 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 29; y: 42 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1904 - hash: "a6c6df34bb552249393ba208ad327691" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 37; y: 35 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1920 - image: "drag.1.png" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 47; y: 27 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1936 - hash: "978543d8f9688605625f40b960d79c28" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 59; y: 21 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 73; y: 15 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1952 - hash: "6170ab3a7e51278ac4462b89fe7781b4" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 87; y: 9 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1968 - hash: "32866f0aa5b13b3ab68661f49336439e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 100; y: 5 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1984 - hash: "26dc17c16eed46d37932cfe48d182b62" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 111; y: 1 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 121; y: -3 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2000 - hash: "ba70936fb44396fac184cc7ba0e94a90" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 130; y: -6 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2016 - hash: "bae13291d4f031c34d80428d83367ede" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 140; y: -8 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2032 - hash: "0a2fbfdc27bb6662553f637f1c325475" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 151; y: -9 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 160; y: -9 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2048 - hash: "cdab85736dfcc4424d42e0e96094eded" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 170; y: -9 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2064 - hash: "76d51ce9ad69560d983d8d86d50f7bd0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 174; y: -9 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2080 - hash: "b5ada9e80f7f894aa141d5e3cfa5d69e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 176; y: -9 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2096 - hash: "446d35fc7b9c0fe4bf0bfe0182f994f6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 183; y: -5 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2112 - hash: "cced849d314835d43ebd93bcfe396c12" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 188; y: -3 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2128 - hash: "09696d700944c373f82d7c6f75d51c51" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 193; y: 0 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2144 - hash: "af56586db93c49637c9bfbb17cac9001" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 199; y: 2 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 203; y: 5 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2160 - hash: "66fc1b30b4037aad3975036faccbb7a7" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 209; y: 8 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2176 - hash: "3f443d9c89d6ba1b36ca9635bc32de1a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 217; y: 11 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2192 - hash: "df47db8cc7bb466b298749a6449d3d70" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 227; y: 15 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 234; y: 18 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 241; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2208 - hash: "c1146fdc0e628d050442606096e52b10" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 252; y: 23 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2224 - hash: "22f44c43f300fd7ff2b4d87d93756178" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 272; y: 30 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2240 - hash: "bf11dc9a9679692abde5d116a169eecf" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 299; y: 38 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 329; y: 48 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2256 - hash: "e63f1960f342639ac412010ffcefb049" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 360; y: 57 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2272 - hash: "ae0228419ec9358025c3026a39abd671" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 392; y: 65 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2288 - hash: "6d2272e2bea21c280100ed8de5b95d4e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 422; y: 72 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 451; y: 76 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2304 - hash: "1628c6fa5feabd90924452bc9f55054d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 476; y: 78 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2320 - hash: "f696791eb0a317b0efb69407616bec9f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 497; y: 78 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2336 - hash: "f696791eb0a317b0efb69407616bec9f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 513; y: 77 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 527; y: 76 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2352 - hash: "1628c6fa5feabd90924452bc9f55054d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 538; y: 75 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2368 - hash: "a5d3d247e22a2852a60fe07ab40345a5" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 548; y: 74 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2384 - hash: "a453fb6bcdd87f819782d8d8c46b56ee" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 556; y: 74 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 563; y: 75 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2400 - hash: "a5d3d247e22a2852a60fe07ab40345a5" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 570; y: 76 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2416 - hash: "1628c6fa5feabd90924452bc9f55054d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 576; y: 78 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2432 - hash: "f696791eb0a317b0efb69407616bec9f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 582; y: 78 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 585; y: 80 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2448 - hash: "8f061986df633c21dcad767ee857988c" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 589; y: 81 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2464 - hash: "2cc110a6fb800171d7d752693ede1e4e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 592; y: 82 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2480 - hash: "319fc3053e02a8b161f33a79d9839bb1" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 595; y: 85 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 597; y: 89 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2496 - hash: "42915c8866746316cf1083a2d55410fb" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 601; y: 95 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2512 - hash: "5df34b3ae292de9a9cd8ff09347e7bd4" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 606; y: 103 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2528 - hash: "1f9bc3c955983ea85f568797cb4f7365" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 609; y: 113 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 613; y: 124 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2544 - hash: "3f156dc64a12c672874acf5456ef4a31" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 618; y: 136 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2560 - hash: "d4d9fe5b5f138e06a87039ebf8695d03" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 619; y: 142 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2576 - hash: "383fe813021ee2791930200b2f88a802" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 620; y: 148 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 622; y: 155 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2592 - hash: "a235544bd5e791dfa329bd0b87358bfa" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 625; y: 163 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2608 - hash: "a87497cf47db3209610b532efe7eb380" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 629; y: 174 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2624 - hash: "abe69b4e4b7508028226f9b73c38058a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 634; y: 194 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 642; y: 225 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2640 - hash: "51c72fa2fa4c8765d882fe65dc0d697d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 649; y: 260 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2656 - hash: "79da7ed21bd6fc16b7264d4403e763cc" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 655; y: 291 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2672 - hash: "b2828b6340a57fa45416469b23b7cef0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 658; y: 316 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 659; y: 340 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2688 - hash: "64a5351f2d746b338c34c7ea9ba6e1fe" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 660; y: 370 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2704 - hash: "9eedb7a6875210084fd2ec95d3505512" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 661; y: 408 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2720 - hash: "b88eb8fa8a0cfc263dc7b655ddc29db0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 661; y: 448 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2736 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 660; y: 487 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 659; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2752 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 658; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2768 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 658; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2784 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 658; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 658; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2800 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 657; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2816 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 656; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2832 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 654; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 652; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2848 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 651; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2864 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 650; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2880 - image: "drag.2.png" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 650; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 648; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2896 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 647; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2912 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 646; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2928 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 645; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 644; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2944 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 643; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2960 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 642; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2976 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 641; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 640; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2992 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 640; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3008 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 639; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3024 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 639; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 638; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3040 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 636; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3056 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 625; y: 505 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3072 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 611; y: 505 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3088 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 582; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 546; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3104 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 505; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3120 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 460; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3136 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 408; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 354; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3152 - hash: "c2997fdde10812f02791bfed5f158ac3" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 300; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3168 - hash: "23a6dfbd09e5b44d04f252cedaeb68af" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 250; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3184 - hash: "f74422989711f86a0840ffc98e8a29e9" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 206; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 163; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3200 - hash: "fa922246d254a7c46d2d1d6ec91a2b02" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 140; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 122; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3216 - hash: "ef216cb8c2bf58db7d58bd8a2e4eb38d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 101; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3232 - hash: "a383228d22e64b8a7758c959288eaca8" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 64; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3248 - hash: "636ca2a8e91c49ef6c8b1c93b830f345" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 36; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 16; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3264 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -1; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3280 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3296 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3312 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3328 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3344 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3360 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3376 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 505 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3392 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 504 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 504 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3408 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 505 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3424 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3440 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3456 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3472 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3488 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3504 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3520 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3536 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3552 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Frame { - msec: 3568 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3584 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3600 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3616 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Frame { - msec: 3632 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 491 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3648 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 428 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3664 - hash: "9fa1e3686467f28cb013fe093dab388c" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 342 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3680 - hash: "7ef97d10862f80d53e0b3b4446661deb" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 264 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 203 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3696 - hash: "c679866b3965b7b5f48b843d6efccf42" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 160 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3712 - hash: "de4bd9ad3cbb9bb19bf75f871b044072" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 144 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3728 - hash: "c5349bbddc03edd5ee3537e2a738f1ad" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 136 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 132 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3744 - hash: "bcbe9ec2687a6030385f08d3dc17becf" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 130 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3760 - hash: "3ad767f63eaccb9e64a9f704900f2530" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 129 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3776 - hash: "421a1ffde15fda0e7846bc095ed2ea37" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 128 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 128 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3792 - hash: "55c260da304a6b1119af83f6a4efcff0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 123 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3808 - hash: "f231cc521db801b4ec71248812e12db8" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 104 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3824 - hash: "b489b6b604e7f7699cac9e42d0725323" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 68 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 35 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3840 - image: "drag.3.png" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 13 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3856 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 2 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3872 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -6 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -12 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3888 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3904 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -46 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3920 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -65 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -70 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3936 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -74 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3952 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -76 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3968 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -76 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3984 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -76 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4000 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -77 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4016 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -78 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4032 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4048 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -78 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4064 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4080 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4096 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -77 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4112 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4128 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4144 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: -78 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4160 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -3; y: -84 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4176 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -2; y: -105 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 1; y: -151 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4192 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4208 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4224 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4240 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4256 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4272 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4288 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4304 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4320 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4336 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4352 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4368 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Frame { - msec: 4384 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 3; y: -151 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4400 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 4; y: -149 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4416 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 5; y: -147 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4432 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 5; y: -143 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 6; y: -138 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4448 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 7; y: -130 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4464 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 9; y: -117 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4480 - hash: "668cc6d9d699b947a7c0f3ff4b26853f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 13; y: -94 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 20; y: -63 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4496 - hash: "b1b54f7bf8ab9cf98d96f9b34192434b" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 29; y: -24 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4512 - hash: "a6c6df34bb552249393ba208ad327691" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 39; y: 15 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4528 - hash: "a05eb803b1f1f3574a2f2e08fe37bd35" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 49; y: 50 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 58; y: 74 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4544 - hash: "3c2f3db46673c2640a26832900b609cb" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 65; y: 91 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4560 - hash: "d0539a9791874f48634bb3cb9f78d9db" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 71; y: 103 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4576 - hash: "f2d862a0b81e2578799d64aef2e6bddc" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 77; y: 112 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 81; y: 121 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4592 - hash: "295ef097845e30064c4d810a7718896c" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 86; y: 128 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4608 - hash: "22a4a17d82ac402c0e8372861609ff1c" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 92; y: 136 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4624 - hash: "a70e81b1435afd77b9079c58685ef9d0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 98; y: 143 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 104; y: 151 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4640 - hash: "d66fefd68fcd96834548c18797eee4bd" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 111; y: 159 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4656 - hash: "fcc435dc6f2643cd21a7cfac078880af" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 118; y: 166 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4672 - hash: "736edfcf33245d46aaea199634896c17" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 123; y: 173 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 129; y: 183 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4688 - hash: "7b7ab312d0c6f4bfc87a2ae467324f4e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 137; y: 197 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4704 - hash: "d78ce756fc27055eeee15001419b7fb5" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 146; y: 215 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4720 - hash: "4f15a726939d7f489d1fe58ebb5bcd0a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 157; y: 235 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 168; y: 255 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4736 - hash: "72184d71fd2fdc6786a43045db0be68f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 180; y: 274 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4752 - hash: "3b3f3f34218bf238f310412cb8c4968d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 192; y: 293 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4768 - hash: "24c00a7154471431d43b1db957ad6424" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 205; y: 316 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 221; y: 343 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4784 - hash: "30081a33ab007ff2c7ba6cc293a5aec3" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 237; y: 371 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4800 - image: "drag.4.png" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 253; y: 396 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4816 - hash: "c0cadb7730838d553b146804c37506b0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 268; y: 419 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 276; y: 429 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 284; y: 438 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4832 - hash: "101c007d0e2cf82331ba1cab4880e8a2" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 291; y: 448 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4848 - hash: "72e46df7427420c5e942a97831723d3f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 307; y: 468 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4864 - hash: "4b7a009b46982a1e9e31250d7ebf0a20" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 323; y: 492 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 341; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4880 - hash: "a3ba70933b6452fad0cdc4192e04be23" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 359; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4896 - hash: "c2ee16182222b403f914eb5550ac6f91" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 378; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4912 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 397; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 416; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4928 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 432; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4944 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 445; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4960 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 456; y: 506 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 466; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4976 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 475; y: 506 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4992 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 482; y: 505 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5008 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 488; y: 504 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 492; y: 503 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5024 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 496; y: 503 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5040 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 500; y: 502 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5056 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 507; y: 501 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5072 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 512; y: 500 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 516; y: 498 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5088 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 521; y: 494 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5104 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 525; y: 486 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5120 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 532; y: 472 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 542; y: 445 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5136 - hash: "9356ce797d12ae076af947cd0e658551" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 553; y: 414 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5152 - hash: "76a8d3b8465f08fdc4586c7766667eff" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 563; y: 389 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5168 - hash: "569e56ba99776d03dd3140e53bc77f56" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 569; y: 373 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 573; y: 363 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5184 - hash: "7139c72a2458685006da79d9cf11bc44" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 577; y: 354 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5200 - hash: "a83d5ef213edec4c8f938ab04afb5c4f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 580; y: 344 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5216 - hash: "5533602bc8a473c162966142d4bddebd" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 584; y: 321 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 586; y: 301 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5232 - hash: "7a79d6e31874428233e9c141d70522fd" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 588; y: 264 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5248 - hash: "b14f4daeb25cd71baae36f4cec111813" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 591; y: 238 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5264 - hash: "e2b2513d2918ffb85bab5fff5a8be644" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 592; y: 225 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 593; y: 216 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5280 - hash: "af0cbb3423491917db1fdaa8350d48b0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 594; y: 209 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5296 - hash: "b9c107f0a13ad37ae05b4d5f9e5f5442" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 594; y: 200 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5312 - hash: "0bbc0c7a4a40ee6b19565c04c23b565d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 594; y: 182 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 593; y: 146 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5328 - hash: "49494e8526a1417c151c7cac7099b9e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 590; y: 107 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5344 - hash: "5e0839c4414cc8ddc5241c658fd3bf88" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 585; y: 80 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5360 - hash: "8f061986df633c21dcad767ee857988c" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 582; y: 67 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5376 - hash: "d78c0a4fa0ccad407a565fab3a5c95b9" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 579; y: 61 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 576; y: 57 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5392 - hash: "cee6816f84911bc2262afe28d8996719" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 573; y: 55 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5408 - hash: "2cc6cd514ef7299dd60bf1a735b81d36" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 569; y: 51 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5424 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 564; y: 44 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 557; y: 35 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5440 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 548; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5456 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 540; y: 14 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 532; y: 5 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5472 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 524; y: -1 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5488 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 517; y: -5 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5504 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 510; y: -9 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5520 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 501; y: -14 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 492; y: -18 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5536 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 483; y: -21 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5552 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 476; y: -21 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5568 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 470; y: -19 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 464; y: -15 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5584 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 458; y: -9 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5600 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 452; y: -3 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5616 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 446; y: 4 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 439; y: 11 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5632 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 432; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5648 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 424; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5664 - hash: "68c40f3551d7d10e61c5ffbb6948c7e6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 413; y: 42 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 400; y: 59 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5680 - hash: "9bc8a652f43c0e3cae9492f5dff624e7" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 392; y: 70 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 385; y: 79 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5696 - hash: "5465128afe72d9618cd9abc47f4ce72f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 378; y: 88 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5712 - hash: "ad739c2028caf8f89d8ae04d509c7854" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 366; y: 102 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 353; y: 114 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5728 - hash: "97cd37f639a7bea76a2f68774c0753db" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 339; y: 126 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5744 - hash: "d24fc8a57dd34e6ddb726426247ec219" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 324; y: 140 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5760 - image: "drag.5.png" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 308; y: 158 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 288; y: 181 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5776 - hash: "7af87eb80fa9d87fe8d8b5e4a2fff5e1" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 266; y: 208 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5792 - hash: "73623f4a857fd4d5150c2eeef1341540" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 243; y: 237 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5808 - hash: "076c4b60d9ec197950ade51e3f1be791" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 217; y: 265 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 191; y: 291 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5824 - hash: "22b7d7765c634763fa86912ea262efca" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 167; y: 314 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5840 - hash: "1267c017931bda0b88b4672f46d499e0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 147; y: 331 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5856 - hash: "b6a545e4c14b809f4ebcffbcb59a8e4f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 132; y: 344 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 121; y: 354 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5872 - hash: "b1085cb508d4613c76e99bc879c62cbf" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 111; y: 363 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5888 - hash: "365fd1260c2109e6d5bd0a97ce3a7e4e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 100; y: 370 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5904 - hash: "3a7d001313b23cbbb7f3d842ab40f41b" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 86; y: 377 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 66; y: 385 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5920 - hash: "c5bda48bb2eaee54d6d8416592830327" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 45; y: 394 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5936 - hash: "5d0fd6d8a6ced4f197fe3b09e7e9155b" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 29; y: 402 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5952 - hash: "79e2825f98644c061ae5216ae1823e4b" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 16; y: 410 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 6; y: 417 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5968 - hash: "22a3978f2f3a0cde67f459527af3b3f2" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 0; y: 422 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 427 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5984 - hash: "1511bec94911dd272f78a726e15bf76e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 432 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6000 - hash: "0f892f7e570cdc703e492248c9f54b6c" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 439 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6016 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 447 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 452 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6032 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 457 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6048 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 459 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6064 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 464 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 465 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6080 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 467 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6096 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 468 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6112 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 468 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 468 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6128 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 468 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6144 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 468 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6160 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 469 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 470 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6176 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 470 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6192 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Frame { - msec: 6208 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 470 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6224 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -3; y: 470 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -3; y: 470 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6240 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -2; y: 470 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6256 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -1; y: 470 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6272 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -1; y: 468 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 0; y: 467 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6288 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 0; y: 464 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6304 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 0; y: 458 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6320 - hash: "ec34aa6937d2c081bdf11660a5eb461a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -3; y: 441 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 408 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6336 - hash: "58413f9b01f1e0b49519d8b6a3011607" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 366 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6352 - hash: "b3992d2f9c1383c710ee325a94117a8b" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 327 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6368 - hash: "bd415044fcf6218d8184cb0206105e65" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 300 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 288 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6384 - hash: "e7296140fe8b28bed77e95e588c0e463" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 280 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6400 - hash: "9ff532223ccccd663809187465e478c2" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 276 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6416 - hash: "4de9ca75503db05df5d8274d75c202e5" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 271 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 259 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6432 - hash: "a83b5bc409207e986055081b4ed3faa6" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 227 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6448 - hash: "7fdbd00dd3553241f30fd6568a8ab646" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 190 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6464 - hash: "5ebaa67eaadc1ede8c46964fa1dffff1" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -4; y: 169 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: -2; y: 160 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6480 - hash: "de4bd9ad3cbb9bb19bf75f871b044072" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 1; y: 156 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6496 - hash: "9d762cd4dd6508cf8b54c47b76f4ef37" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 5; y: 155 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6512 - hash: "bdf17c384f4f824a89a06b88ba17c15f" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 10; y: 154 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 25; y: 152 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6528 - hash: "f279f28995785afd143726aef7673b50" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 52; y: 149 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6544 - hash: "53b6b82a61d017e12afb01a728d8d856" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 80; y: 148 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6560 - hash: "9a48039175cab1360a0cf5cc195e2082" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 98; y: 148 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 112; y: 150 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6576 - hash: "cfc3991e30eef6c2edb66cb6060b2bde" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 123; y: 153 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6592 - hash: "737d8907f62768e623ba76866a509d1e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 134; y: 155 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6608 - hash: "dea2a596f7d85f29728b33d126d997e5" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 145; y: 158 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 157; y: 161 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6624 - hash: "3969a0bbb284ab1d5efd20cf93b0422d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 168; y: 164 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6640 - hash: "071ff25e49f7f16a727ff58c42ff766e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 176; y: 169 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6656 - hash: "454abec991a4675763f379c256919fa7" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 184; y: 173 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 189; y: 177 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6672 - hash: "6de741c4e6057dc8580106155c4ac627" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 194; y: 184 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6688 - hash: "e35853e99cd205b7ccabdf632b238584" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 199; y: 192 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6704 - hash: "15a70a0196227c6bce50ed70cd6383c8" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 204; y: 201 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 211; y: 210 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6720 - image: "drag.6.png" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 217; y: 217 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6736 - hash: "5e951eb6017a060287e398fcaf4aeba9" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 224; y: 223 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6752 - hash: "ddd0f27027e23a45aef131296c781865" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 235; y: 228 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 246; y: 232 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6768 - hash: "715102a252756e5a8c4f459d808aec6a" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 257; y: 235 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6784 - hash: "42b9c1b894247ddbd85f4a4aca5695f1" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 267; y: 239 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6800 - hash: "b67b4bdd412ed5160901803c60c6f19e" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 275; y: 239 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 280; y: 239 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6816 - hash: "3490cc41c2b1f9301c209bdb8f052add" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 281; y: 239 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6832 - hash: "df32868d564ebbc41c359409b5a69e7d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 282; y: 239 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6848 - hash: "b9cb430a6f677e67c87322e0aff53fb1" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 282; y: 239 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6864 - hash: "b9cb430a6f677e67c87322e0aff53fb1" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 281; y: 239 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6880 - hash: "df32868d564ebbc41c359409b5a69e7d" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 280; y: 239 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6896 - hash: "3490cc41c2b1f9301c209bdb8f052add" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 279; y: 240 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6912 - hash: "e23a88f49a73cd2a9326095dd380ab55" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 277; y: 240 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6928 - hash: "ffffc1aed27fe77c2fe5c035eab706a9" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 277; y: 240 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6944 - hash: "ffffc1aed27fe77c2fe5c035eab706a9" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 276; y: 240 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6960 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Mouse { - type: 5 - button: 0 - buttons: 1 - x: 276; y: 240 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6976 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 6992 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 276; y: 240 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 7008 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7024 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7040 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7056 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7072 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7088 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7104 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7120 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7136 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7152 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7168 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7184 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7200 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7216 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7232 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7248 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7264 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7280 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7296 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7312 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7328 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7344 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7360 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7376 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7392 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7408 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7424 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7440 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7456 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7472 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7488 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7504 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7520 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7536 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7552 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7568 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7584 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7600 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7616 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7632 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7648 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7664 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7680 - image: "drag.7.png" - } - Frame { - msec: 7696 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7712 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7728 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7744 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7760 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7776 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7792 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7808 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7824 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7840 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7856 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7872 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7888 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7904 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7920 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7936 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7952 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7968 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 7984 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } - Frame { - msec: 8000 - hash: "2c1ce07ab6ce0072f6cb205f1e5297e0" - } -} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.0.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.0.png deleted file mode 100644 index c249c21..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.0.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.1.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.1.png deleted file mode 100644 index a96bf1b..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.1.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.10.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.10.png deleted file mode 100644 index 7420ca7..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.10.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.11.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.11.png deleted file mode 100644 index 7420ca7..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.11.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.12.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.12.png deleted file mode 100644 index 7420ca7..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.12.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.13.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.13.png deleted file mode 100644 index 7420ca7..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.13.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.14.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.14.png deleted file mode 100644 index 7420ca7..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.14.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.15.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.15.png deleted file mode 100644 index e797cc9..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.15.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.16.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.16.png deleted file mode 100644 index 7951309..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.16.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.17.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.17.png deleted file mode 100644 index 7951309..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.17.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.18.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.18.png deleted file mode 100644 index 7951309..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.18.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.19.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.19.png deleted file mode 100644 index 7951309..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.19.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.2.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.2.png deleted file mode 100644 index a96bf1b..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.2.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.20.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.20.png deleted file mode 100644 index 7951309..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.20.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.21.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.21.png deleted file mode 100644 index 7951309..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.21.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.22.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.22.png deleted file mode 100644 index 7951309..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.22.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.3.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.3.png deleted file mode 100644 index a96bf1b..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.3.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.4.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.4.png deleted file mode 100644 index 1fe365a..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.4.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.5.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.5.png deleted file mode 100644 index 1fe365a..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.5.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.6.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.6.png deleted file mode 100644 index 1fe365a..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.6.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.7.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.7.png deleted file mode 100644 index 1fe365a..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.7.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.8.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.8.png deleted file mode 100644 index 7420ca7..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.8.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.9.png b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.9.png deleted file mode 100644 index 7420ca7..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.9.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.qml b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.qml deleted file mode 100644 index cc374fd..0000000 --- a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/data/mouseregion.qml +++ /dev/null @@ -1,5867 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { - msec: 0 - } - Frame { - msec: 16 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 32 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 48 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 64 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 80 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 96 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 112 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 128 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 144 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 160 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 176 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 192 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 208 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 224 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 240 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 256 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 272 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 288 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 304 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 320 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 336 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 352 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 368 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 384 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 400 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 416 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 432 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 448 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 464 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 480 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 496 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 512 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 528 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 544 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 560 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 576 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 592 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 608 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 624 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 640 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 656 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 672 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 688 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 704 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 720 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 736 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 752 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 768 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 784 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 800 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 816 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 832 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 848 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 864 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 880 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 896 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 912 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 928 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 944 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 960 - image: "mouseregion.0.png" - } - Frame { - msec: 976 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 992 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1008 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1024 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1040 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1056 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1072 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1088 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1104 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1120 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1136 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1152 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1168 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1184 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1200 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1216 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1232 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1248 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1264 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1280 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1296 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1312 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1328 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1344 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1360 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1376 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1392 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1408 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1424 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1440 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1456 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1472 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1488 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1504 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1520 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1536 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1552 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1568 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1584 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1600 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1616 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1632 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1648 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Frame { - msec: 1664 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 2; y: 29 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 7; y: 32 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1680 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 19; y: 40 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 33; y: 48 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1696 - hash: "1121bb51fc2d4c5c7ef3ae2c44794b49" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 49; y: 54 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1712 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 67; y: 56 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 74; y: 56 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1728 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 78; y: 57 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 81; y: 57 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1744 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 82; y: 56 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 83; y: 55 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1760 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 83; y: 54 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1776 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 83; y: 53 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1792 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Frame { - msec: 1808 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Frame { - msec: 1824 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Frame { - msec: 1840 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Frame { - msec: 1856 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Frame { - msec: 1872 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 83; y: 52 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 82; y: 51 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1888 - hash: "337f0f4af627bbdf8807135ce39d5070" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 80; y: 50 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 78; y: 48 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1904 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 75; y: 46 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 73; y: 45 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1920 - image: "mouseregion.1.png" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 71; y: 43 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 68; y: 41 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1936 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 66; y: 40 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1952 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 64; y: 39 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 63; y: 37 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1968 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 61; y: 36 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 60; y: 36 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 1984 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 58; y: 34 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 57; y: 33 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2000 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 56; y: 32 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2016 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 55; y: 30 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 54; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2032 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2048 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2064 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2080 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2096 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2112 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2128 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 54; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2144 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2160 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2176 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2192 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2208 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2224 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2240 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 54; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2256 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2272 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2288 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2304 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2320 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2336 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2352 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2368 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2384 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2400 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2416 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2432 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2448 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2464 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2480 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2496 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2512 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2528 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2544 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2560 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2576 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2592 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2608 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2624 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2640 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 2 - button: 2 - buttons: 2 - x: 54; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2656 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2672 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2688 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2704 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2720 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2736 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2752 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 3 - button: 2 - buttons: 0 - x: 54; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2768 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2784 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2800 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2816 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2832 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2848 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2864 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 2880 - image: "mouseregion.2.png" - } - Frame { - msec: 2896 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 55; y: 29 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 58; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2912 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 62; y: 29 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 67; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2928 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 75; y: 30 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2944 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 91; y: 34 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 99; y: 34 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2960 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 107; y: 34 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 113; y: 34 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2976 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 119; y: 34 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 124; y: 33 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2992 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 128; y: 33 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 131; y: 32 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3008 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 132; y: 32 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 132; y: 31 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3024 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3040 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3056 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3072 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3088 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3104 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3120 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3136 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3152 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3168 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3184 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3200 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3216 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3232 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3248 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3264 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3280 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3296 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3312 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3328 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3344 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3360 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3376 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3392 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3408 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3424 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3440 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3456 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3472 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3488 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3504 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3520 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3536 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3552 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 133; y: 31 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3568 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3584 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 133; y: 31 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3600 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3616 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3632 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3648 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3664 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3680 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3696 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 133; y: 31 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 3712 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3728 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3744 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3760 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3776 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3792 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3808 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3824 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3840 - image: "mouseregion.3.png" - } - Frame { - msec: 3856 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3872 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3888 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3904 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3920 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3936 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3952 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3968 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 3984 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4000 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4016 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4032 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4048 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4064 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4080 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4096 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4112 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4128 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4144 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4160 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4176 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4192 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4208 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4224 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4240 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4256 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4272 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4288 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4304 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4320 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 2 - button: 2 - buttons: 2 - x: 133; y: 31 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4336 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4352 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4368 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4384 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4400 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4416 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Frame { - msec: 4432 - hash: "73f1639b9e2164c7b974042934c0d151" - } - Mouse { - type: 3 - button: 2 - buttons: 0 - x: 133; y: 31 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4448 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4464 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4480 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4496 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4512 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4528 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4544 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4560 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4576 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4592 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4608 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4624 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4640 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4656 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4672 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4688 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4704 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4720 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4736 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 133; y: 32 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 136; y: 32 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4752 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 142; y: 32 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 148; y: 32 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4768 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 155; y: 32 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 161; y: 32 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4784 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 166; y: 31 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4800 - image: "mouseregion.4.png" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 168; y: 31 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 170; y: 30 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4816 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 171; y: 29 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4832 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4848 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4864 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 4880 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 172; y: 28 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 175; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4896 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 178; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4912 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 182; y: 24 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 187; y: 22 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4928 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 191; y: 22 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 195; y: 21 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4944 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 200; y: 21 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 206; y: 21 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4960 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 211; y: 21 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 215; y: 21 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4976 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 218; y: 21 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 221; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 4992 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 224; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5008 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 225; y: 20 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 226; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5024 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 227; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5040 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5056 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5072 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 228; y: 20 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 229; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5088 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 231; y: 20 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 232; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5104 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 233; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5120 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5136 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5152 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5168 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 233; y: 21 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 234; y: 22 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5184 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 237; y: 23 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5200 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 239; y: 24 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 242; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5216 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 244; y: 25 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 245; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5232 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5248 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5264 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5280 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5296 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5312 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5328 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5344 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5360 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5376 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5392 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5408 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5424 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5440 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5456 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5472 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5488 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5504 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5520 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5536 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5552 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5568 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5584 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5600 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5616 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5632 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5648 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5664 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5680 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5696 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5712 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5728 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5744 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5760 - image: "mouseregion.5.png" - } - Frame { - msec: 5776 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5792 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5808 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5824 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5840 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5856 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5872 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5888 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5904 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5920 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5936 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 5952 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5968 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 5984 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6000 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6016 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6032 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6048 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6064 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6080 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6096 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6112 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6128 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6144 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6160 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6176 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6192 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6208 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6224 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6240 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6256 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6272 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6288 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6304 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6320 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6336 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6352 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6368 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6384 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6400 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6416 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6432 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6448 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6464 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6480 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6496 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6512 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6528 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6544 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6560 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6576 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6592 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6608 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6624 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6640 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6656 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6672 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6688 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6704 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6720 - image: "mouseregion.6.png" - } - Frame { - msec: 6736 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 4 - button: 1 - buttons: 1 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6752 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6768 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6784 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6800 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6816 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6832 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 6848 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6864 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6880 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6896 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6912 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6928 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6944 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6960 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6976 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 6992 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7008 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7024 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7040 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7056 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7072 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7088 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7104 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7120 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7136 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7152 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7168 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7184 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7200 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 7216 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7232 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7248 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7264 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7280 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7296 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7312 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7328 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7344 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7360 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7376 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7392 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7408 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7424 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7440 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7456 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7472 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7488 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7504 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7520 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7536 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7552 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7568 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7584 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7600 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7616 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7632 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7648 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7664 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7680 - image: "mouseregion.7.png" - } - Frame { - msec: 7696 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7712 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7728 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7744 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7760 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7776 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7792 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7808 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7824 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7840 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7856 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7872 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7888 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7904 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7920 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7936 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7952 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7968 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 7984 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 8000 - hash: "12edb0902e4d480c9052b00edc1a0a42" - } - Frame { - msec: 8016 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8032 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8048 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8064 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8080 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8096 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8112 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8128 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8144 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8160 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8176 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8192 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8208 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8224 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8240 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8256 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8272 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8288 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8304 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8320 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8336 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 247; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8352 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8368 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8384 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8400 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8416 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8432 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8448 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8464 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8480 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8496 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8512 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8528 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 248; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8544 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 254; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 259; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8560 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 264; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 268; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8576 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 273; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 277; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8592 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 281; y: 24 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 284; y: 24 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8608 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 287; y: 24 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 289; y: 24 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8624 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 292; y: 24 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8640 - image: "mouseregion.8.png" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 294; y: 24 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 295; y: 24 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8656 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 297; y: 24 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 299; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8672 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 301; y: 25 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 304; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8688 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 307; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8704 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 310; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 312; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8720 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 314; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 315; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8736 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 317; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 318; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8752 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 319; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8768 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 320; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8784 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 322; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 323; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8800 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 325; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 327; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8816 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 330; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 333; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8832 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 336; y: 26 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 338; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8848 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 339; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8864 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 340; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8880 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 8896 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 340; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 8912 - hash: "d1f2fc2133f3d6554e41982196662c2a" - } - Frame { - msec: 8928 - hash: "d1f2fc2133f3d6554e41982196662c2a" - } - Frame { - msec: 8944 - hash: "d1f2fc2133f3d6554e41982196662c2a" - } - Frame { - msec: 8960 - hash: "d1f2fc2133f3d6554e41982196662c2a" - } - Frame { - msec: 8976 - hash: "d1f2fc2133f3d6554e41982196662c2a" - } - Frame { - msec: 8992 - hash: "d1f2fc2133f3d6554e41982196662c2a" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 340; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9008 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9024 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9040 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9056 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9072 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9088 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9104 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9120 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9136 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9152 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9168 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9184 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9200 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9216 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9232 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9248 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9264 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9280 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9296 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9312 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9328 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9344 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9360 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9376 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9392 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9408 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9424 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9440 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9456 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9472 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9488 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9504 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9520 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9536 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9552 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9568 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9584 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 9600 - image: "mouseregion.9.png" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 339; y: 26 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9616 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 336; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9632 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 332; y: 25 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 326; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9648 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 320; y: 25 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 312; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9664 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 292; y: 25 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 283; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9680 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 261; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9696 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 252; y: 25 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 243; y: 25 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9712 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 225; y: 29 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 207; y: 33 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9728 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 189; y: 35 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 169; y: 39 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9744 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 161; y: 40 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 145; y: 44 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9760 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 138; y: 45 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9776 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 133; y: 48 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 127; y: 50 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9792 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 122; y: 52 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 118; y: 56 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9808 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 114; y: 57 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 110; y: 60 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9824 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 109; y: 61 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9840 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 107; y: 62 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 106; y: 63 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9856 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 103; y: 63 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 100; y: 64 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9872 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 96; y: 64 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 92; y: 65 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9888 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 88; y: 65 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9904 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 85; y: 66 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 82; y: 67 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9920 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 79; y: 69 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 77; y: 70 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9936 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 74; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 70; y: 72 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9952 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 67; y: 74 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 64; y: 75 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9968 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 62; y: 76 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 9984 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 61; y: 76 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 60; y: 77 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10000 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10016 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10032 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 59; y: 77 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10048 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 58; y: 77 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 57; y: 77 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10064 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 56; y: 76 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10080 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10096 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10112 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10128 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10144 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10160 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10176 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10192 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10208 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10224 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Frame { - msec: 10240 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 57; y: 76 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 59; y: 75 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10256 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 62; y: 75 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10272 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 65; y: 74 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 69; y: 74 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10288 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 72; y: 73 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 76; y: 73 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10304 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 80; y: 72 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 84; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10320 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 87; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 90; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10336 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 93; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10352 - hash: "6627c7a1a4da7e642f4b4b24ca5e8e7a" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 96; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 99; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10368 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 102; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 106; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10384 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 108; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 110; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10400 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 113; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 115; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10416 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 118; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 121; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10432 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 123; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10448 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 126; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 128; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10464 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 130; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 132; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10480 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 133; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10496 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 134; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10512 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10528 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 135; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 136; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10544 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 137; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 138; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10560 - image: "mouseregion.10.png" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 140; y: 71 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 10576 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10592 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10608 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10624 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10640 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10656 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10672 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10688 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10704 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10720 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10736 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10752 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10768 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10784 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10800 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10816 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10832 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10848 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10864 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10880 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10896 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10912 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10928 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10944 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10960 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10976 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 10992 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11008 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11024 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11040 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11056 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11072 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11088 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11104 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11120 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11136 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11152 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11168 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11184 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11200 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11216 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11232 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11248 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11264 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 11280 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11296 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11312 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11328 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11344 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11360 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 11376 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11392 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11408 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11424 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11440 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11456 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11472 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11488 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11504 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11520 - image: "mouseregion.11.png" - } - Frame { - msec: 11536 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11552 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11568 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11584 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11600 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11616 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11632 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11648 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11664 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11680 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11696 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11712 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 2 - buttons: 2 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 11728 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11744 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11760 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11776 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11792 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11808 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11824 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 2 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 11840 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11856 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11872 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11888 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11904 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11920 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11936 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11952 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11968 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 11984 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12000 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12016 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12032 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12048 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 4 - button: 2 - buttons: 2 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12064 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12080 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12096 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12112 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12128 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12144 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12160 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12176 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12192 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12208 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 2 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12224 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12240 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12256 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12272 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12288 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12304 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12320 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12336 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12352 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12368 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12384 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12400 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12416 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12432 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12448 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 2 - buttons: 3 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12464 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12480 - image: "mouseregion.12.png" - } - Frame { - msec: 12496 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12512 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12528 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 2 - buttons: 1 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12544 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12560 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12576 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12592 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12608 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12624 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12640 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12656 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12672 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12688 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12704 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12720 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12736 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12752 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12768 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12784 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12800 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12816 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12832 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 4 - button: 1 - buttons: 1 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12848 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12864 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12880 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12896 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12912 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12928 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12944 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12960 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 12976 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 12992 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13008 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13024 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13040 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13056 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13072 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13088 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 4 - button: 1 - buttons: 1 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13104 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13120 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13136 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13152 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13168 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13184 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13200 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13216 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13232 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13248 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13264 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13280 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13296 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13312 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13328 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13344 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13360 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13376 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13392 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13408 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13424 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13440 - image: "mouseregion.13.png" - } - Frame { - msec: 13456 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13472 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13488 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13504 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13520 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13536 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13552 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13568 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13584 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13600 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13616 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13632 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 2 - button: 2 - buttons: 2 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13648 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13664 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13680 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13696 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13712 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 2 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13728 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13744 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13760 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13776 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13792 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13808 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 4 - button: 2 - buttons: 2 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13824 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13840 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13856 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13872 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13888 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13904 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 3 - button: 2 - buttons: 0 - x: 141; y: 71 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 13920 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13936 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13952 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13968 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 13984 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14000 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14016 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14032 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14048 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14064 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14080 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14096 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14112 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14128 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14144 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14160 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14176 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 141; y: 70 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 148; y: 68 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14192 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 152; y: 68 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 158; y: 68 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14208 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 164; y: 68 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14224 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 171; y: 66 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 187; y: 62 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 205; y: 60 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14240 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 223; y: 56 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14256 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 239; y: 52 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 255; y: 46 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14272 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 269; y: 40 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 285; y: 34 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14288 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 299; y: 28 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 313; y: 20 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14304 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 320; y: 18 - modifiers: 0 - sendToViewport: true - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 326; y: 15 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14320 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Mouse { - type: 5 - button: 0 - buttons: 0 - x: 340; y: 7 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 14336 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14352 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14368 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14384 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14400 - image: "mouseregion.14.png" - } - Frame { - msec: 14416 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14432 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14448 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14464 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14480 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14496 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14512 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14528 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14544 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14560 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14576 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14592 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14608 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14624 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14640 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14656 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14672 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14688 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14704 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14720 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14736 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14752 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14768 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14784 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14800 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14816 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14832 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14848 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14864 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14880 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14896 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14912 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } - Frame { - msec: 14928 - hash: "194ebac4ae7d95bf427f8161885a13e1" - } -} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/drag.qml b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/drag.qml deleted file mode 100644 index dbb2a24..0000000 --- a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/drag.qml +++ /dev/null @@ -1,21 +0,0 @@ -import Qt 4.6 - -Rectangle{ - width:400 - height:440 - color: "white" - Rectangle{ - id: draggable - width:40; height:40; color: "lightsteelblue" - y:20 - MouseArea{ - anchors.fill: parent - drag.target: draggable - drag.axis: "XandYAxis" - drag.minimumX: 0 - drag.maximumX: 360 - drag.minimumY: 20 - drag.maximumY: 400 - } - } -} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/mouseregion.qml b/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/mouseregion.qml deleted file mode 100644 index 3c722d0..0000000 --- a/tests/auto/declarative/qmlvisual/qdeclarativemouseregion/mouseregion.qml +++ /dev/null @@ -1,124 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: root - width: 400 - height: 100 - - // Left click on me - Rectangle { - width: 98; height: 48 - color: "red" - MouseArea { - id: mr1 - anchors.fill: parent - enabled: false - onClicked: { parent.color = "blue"; root.error = "mr1 should ignore presses"; } - } - } - - // Left click, then right click - Rectangle { - x: 100 - width: 98; height: 48 - color: "red" - MouseArea { - id: mr2 - anchors.fill: parent - acceptedButtons: Qt.RightButton - onClicked: { - if (mouse.button == Qt.RightButton) { - parent.color = "blue"; - } else { - parent.color = "green"; - root.error = "mr1 should ignore presses"; - } - } - } - } - - // press and hold me - Rectangle { - x: 200 - width: 98; height: 48 - color: "red" - MouseArea { - id: mr3 - anchors.fill: parent - onPressAndHold: { - parent.color = "blue"; - } - } - } - - // click me - Rectangle { - x: 300 - width: 98; height: 48 - color: "red" - MouseArea { - id: mr4 - anchors.fill: parent - onPressed: { - parent.color = "blue"; - } - onReleased: { - parent.color = "red"; - } - } - } - - // move into and out of me - Rectangle { - x: 0 - y: 50 - width: 98; height: 48 - color: "red" - MouseArea { - id: mr5 - anchors.fill: parent - hoverEnabled: true - onEntered: { - parent.color = "blue"; - } - onExited: { - parent.color = "green"; - } - } - } - - // click, then double click me - Rectangle { - x: 100 - y: 50 - width: 98; height: 48 - color: "red" - MouseArea { - id: mr6 - anchors.fill: parent - onClicked: { - parent.color = "blue"; - } - onDoubleClicked: { - parent.color = "green"; - } - } - } - - // click, then double click me - nothing should happen - Rectangle { - x: 100 - y: 50 - width: 98; height: 48 - color: "red" - MouseArea { - id: mr7 - anchors.fill: parent - enabled: false - onClicked: { parent.color = "blue" } - onPressed: { parent.color = "yellow" } - onReleased: { parent.color = "cyan" } - onDoubleClicked: { parent.color = "green" } - } - } -} diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index f527dc8..91f8486 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -101,6 +101,8 @@ void tst_qmlvisual::visual_data() files << findQmlFiles(QDir(QT_TEST_SOURCE_DIR)); else { //these are tests we think are stable and useful enough to be run by the CI system + files << QT_TEST_SOURCE_DIR "/qdeclarativemousearea/mousearea-visual.qml"; + files << QT_TEST_SOURCE_DIR "/qdeclarativemousearea/drag.qml"; files << QT_TEST_SOURCE_DIR "/animation/pauseAnimation/pauseAnimation-visual.qml"; files << QT_TEST_SOURCE_DIR "/animation/parentAnimation/parentAnimation-visual.qml"; files << QT_TEST_SOURCE_DIR "/animation/reanchor/reanchor.qml"; -- cgit v0.12 From 82a306e7dda06909801f576bbbbebb59dc41c563 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 31 Mar 2010 02:30:41 +0200 Subject: Revert "struct -> class, it's better." This reverts commit 1d094129c0c3994df4e59cd9eda6981a7b131903. --- src/gui/graphicsview/qgraphicsitem_p.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index eb5fac7..669ae1b 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -74,8 +74,7 @@ class QGraphicsItemPrivate; #ifndef QDECLARATIVELISTPROPERTY #define QDECLARATIVELISTPROPERTY template -class QDeclarativeListProperty { -public: +struct QDeclarativeListProperty { typedef void (*AppendFunction)(QDeclarativeListProperty *, T*); typedef int (*CountFunction)(QDeclarativeListProperty *); typedef T *(*AtFunction)(QDeclarativeListProperty *, int); -- cgit v0.12 From 880e4935410769b8337d75f219bef70493c4bb2c Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 31 Mar 2010 02:31:23 +0200 Subject: Revert "Add a children private property needed for QML to support QGraphicsObject" This reverts commit 4be83fa7337c5a4eb7b0ce085aa5854af5d33252. Conflicts: src/gui/graphicsview/qgraphicswidget.cpp This drops the support of QML on top of 4.6 --- src/gui/graphicsview/qgraphicsitem.cpp | 103 --------------------- src/gui/graphicsview/qgraphicsitem.h | 7 -- src/gui/graphicsview/qgraphicsitem_p.h | 67 -------------- src/gui/graphicsview/qgraphicswidget.cpp | 8 -- src/gui/graphicsview/qgraphicswidget_p.cpp | 51 ---------- src/gui/graphicsview/qgraphicswidget_p.h | 9 -- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 28 ------ 7 files changed, 273 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 1b707b0..42abe59 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -5225,8 +5225,6 @@ void QGraphicsItemPrivate::addChild(QGraphicsItem *child) needSortChildren = 1; // ### maybe 0 child->d_ptr->siblingIndex = children.size(); children.append(child); - if (isObject) - emit static_cast(q_ptr)->childrenChanged(); } /*! @@ -5249,8 +5247,6 @@ void QGraphicsItemPrivate::removeChild(QGraphicsItem *child) // the child is not guaranteed to be at the index after the list is sorted. // (see ensureSortedChildren()). child->d_ptr->siblingIndex = -1; - if (isObject) - emit static_cast(q_ptr)->childrenChanged(); } /*! @@ -7458,88 +7454,6 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) } } -void QGraphicsItemPrivate::append(QDeclarativeListProperty *list, QGraphicsObject *item) -{ - QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0); -} - -/*! - Returns a list of this item's children. - - The items are sorted by stacking order. This takes into account both the - items' insertion order and their Z-values. - -*/ -QDeclarativeListProperty QGraphicsItemPrivate::childrenList() -{ - Q_Q(QGraphicsItem); - if (isObject) { - QGraphicsObject *that = static_cast(q); - return QDeclarativeListProperty(that, &children, QGraphicsItemPrivate::append); - } else { - //QGraphicsItem is not supported for this property - return QDeclarativeListProperty(); - } -} - -/*! - \internal - Returns the width of the item - Reimplemented by QGraphicsWidget -*/ -qreal QGraphicsItemPrivate::width() const -{ - return 0; -} - -/*! - \internal - Set the width of the item - Reimplemented by QGraphicsWidget -*/ -void QGraphicsItemPrivate::setWidth(qreal w) -{ - Q_UNUSED(w); -} - -/*! - \internal - Reset the width of the item - Reimplemented by QGraphicsWidget -*/ -void QGraphicsItemPrivate::resetWidth() -{ -} - -/*! - \internal - Returns the height of the item - Reimplemented by QGraphicsWidget -*/ -qreal QGraphicsItemPrivate::height() const -{ - return 0; -} - -/*! - \internal - Set the height of the item - Reimplemented by QGraphicsWidget -*/ -void QGraphicsItemPrivate::setHeight(qreal h) -{ - Q_UNUSED(h); -} - -/*! - \internal - Reset the height of the item - Reimplemented by QGraphicsWidget -*/ -void QGraphicsItemPrivate::resetHeight() -{ -} - /*! \property QGraphicsObject::parent \brief the parent of the item @@ -7726,23 +7640,6 @@ void QGraphicsItemPrivate::resetHeight() \sa scale, rotation, QGraphicsItem::transformOriginPoint() */ -/*! - \fn void QGraphicsObject::widthChanged() - \internal -*/ - -/*! - \fn void QGraphicsObject::heightChanged() - \internal -*/ - -/*! - - \fn QGraphicsObject::childrenChanged() - - This signal gets emitted whenever the children list changes - \internal -*/ /*! \class QAbstractGraphicsShapeItem diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 5023f60..d72833b 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -547,10 +547,6 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint) - Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), QDeclarativeListProperty children READ childrenList DESIGNABLE false NOTIFY childrenChanged) - Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL) - Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL) - Q_CLASSINFO("DefaultProperty", "children") Q_INTERFACES(QGraphicsItem) public: QGraphicsObject(QGraphicsItem *parent = 0); @@ -575,9 +571,6 @@ Q_SIGNALS: void zChanged(); void rotationChanged(); void scaleChanged(); - void childrenChanged(); - void widthChanged(); - void heightChanged(); protected: QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 669ae1b..ea04e0b 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -71,62 +71,6 @@ QT_BEGIN_NAMESPACE class QGraphicsItemPrivate; -#ifndef QDECLARATIVELISTPROPERTY -#define QDECLARATIVELISTPROPERTY -template -struct QDeclarativeListProperty { - typedef void (*AppendFunction)(QDeclarativeListProperty *, T*); - typedef int (*CountFunction)(QDeclarativeListProperty *); - typedef T *(*AtFunction)(QDeclarativeListProperty *, int); - typedef void (*ClearFunction)(QDeclarativeListProperty *); - - QDeclarativeListProperty() - : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {} - QDeclarativeListProperty(QObject *o, QList &list) - : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at), - clear(qlist_clear), dummy1(0), dummy2(0) {} - QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0, - ClearFunction r = 0) - : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {} - - bool operator==(const QDeclarativeListProperty &o) const { - return object == o.object && - data == o.data && - append == o.append && - count == o.count && - at == o.at && - clear == o.clear; - } - - QObject *object; - void *data; - - AppendFunction append; - - CountFunction count; - AtFunction at; - - ClearFunction clear; - - void *dummy1; - void *dummy2; - -private: - static void qlist_append(QDeclarativeListProperty *p, T *v) { - ((QList *)p->data)->append(v); - } - static int qlist_count(QDeclarativeListProperty *p) { - return ((QList *)p->data)->count(); - } - static T *qlist_at(QDeclarativeListProperty *p, int idx) { - return ((QList *)p->data)->at(idx); - } - static void qlist_clear(QDeclarativeListProperty *p) { - return ((QList *)p->data)->clear(); - } -}; -#endif - class QGraphicsItemCache { public: @@ -293,7 +237,6 @@ public: void resolveDepth(); void addChild(QGraphicsItem *child); void removeChild(QGraphicsItem *child); - QDeclarativeListProperty childrenList(); void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, const QVariant *thisPointerVariant); void childrenBoundingRectHelper(QTransform *x, QRectF *rect); @@ -480,21 +423,11 @@ public: inline QTransform transformToParent() const; inline void ensureSortedChildren(); - static void append(QDeclarativeListProperty *list, QGraphicsObject *item); static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b); void ensureSequentialSiblingIndex(); inline void sendScenePosChange(); virtual void siblingOrderChange(); - // Private Properties - virtual qreal width() const; - virtual void setWidth(qreal); - virtual void resetWidth(); - - virtual qreal height() const; - virtual void setHeight(qreal); - virtual void resetHeight(); - QRectF childrenBoundingRect; QRectF needsRepaint; QMap paintedViewBoundingRects; diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 3548fe3..4c5cffa 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -324,14 +324,6 @@ void QGraphicsWidget::resize(const QSizeF &size) */ /*! - - \fn QGraphicsWidget::geometryChanged() - - This signal gets emitted whenever the geometry of the item changes - \internal -*/ - -/*! \property QGraphicsWidget::geometry \brief the geometry of the widget diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 6e397b6..1835c74 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -44,7 +44,6 @@ #ifndef QT_NO_GRAPHICSVIEW #include -#include #include "qgraphicswidget_p.h" #include "qgraphicslayout.h" #include "qgraphicsscene_p.h" @@ -826,56 +825,6 @@ void QGraphicsWidgetPrivate::setLayout_helper(QGraphicsLayout *l) } } -qreal QGraphicsWidgetPrivate::width() const -{ - Q_Q(const QGraphicsWidget); - return q->geometry().width(); -} - -void QGraphicsWidgetPrivate::setWidth(qreal w) -{ - if (qIsNaN(w)) - return; - Q_Q(QGraphicsWidget); - if (q->geometry().width() == w) - return; - - QRectF oldGeom = q->geometry(); - - q->setGeometry(QRectF(q->x(), q->y(), w, height())); -} - -void QGraphicsWidgetPrivate::resetWidth() -{ - Q_Q(QGraphicsWidget); - q->setGeometry(QRectF(q->x(), q->y(), 0, height())); -} - -qreal QGraphicsWidgetPrivate::height() const -{ - Q_Q(const QGraphicsWidget); - return q->geometry().height(); -} - -void QGraphicsWidgetPrivate::setHeight(qreal h) -{ - if (qIsNaN(h)) - return; - Q_Q(QGraphicsWidget); - if (q->geometry().height() == h) - return; - - QRectF oldGeom = q->geometry(); - - q->setGeometry(QRectF(q->x(), q->y(), width(), h)); -} - -void QGraphicsWidgetPrivate::resetHeight() -{ - Q_Q(QGraphicsWidget); - q->setGeometry(QRectF(q->x(), q->y(), width(), 0)); -} - QT_END_NAMESPACE #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index f34a755..2c5b3bf 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -130,15 +130,6 @@ public: void windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event); bool hasDecoration() const; - // Private Properties - qreal width() const; - void setWidth(qreal); - void resetWidth(); - - qreal height() const; - void setHeight(qreal); - void resetHeight(); - // State inline int attributeToBitIndex(Qt::WidgetAttribute att) const { diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index e04d99d..4a874be 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -111,8 +111,6 @@ private slots: void fontPropagationSceneChange(); void geometry_data(); void geometry(); - void width(); - void height(); void getContentsMargins_data(); void getContentsMargins(); void initStyleOption_data(); @@ -775,32 +773,6 @@ void tst_QGraphicsWidget::geometry() QCOMPARE(widget.geometry(), QRectF(pos, size)); } -void tst_QGraphicsWidget::width() -{ - QGraphicsWidget w; - QCOMPARE(w.property("width").toReal(), qreal(0)); - QSignalSpy spy(&w, SIGNAL(widthChanged())); - w.setProperty("width", qreal(50)); - QCOMPARE(w.property("width").toReal(), qreal(50)); - QCOMPARE(spy.count(), 1); - //calling old school setGeometry should work too - w.setGeometry(0, 0, 200, 200); - QCOMPARE(spy.count(), 2); -} - -void tst_QGraphicsWidget::height() -{ - QGraphicsWidget w; - QCOMPARE(w.property("height").toReal(), qreal(0)); - QSignalSpy spy(&w, SIGNAL(heightChanged())); - w.setProperty("height", qreal(50)); - QCOMPARE(w.property("height").toReal(), qreal(50)); - QCOMPARE(spy.count(), 1); - //calling old school setGeometry should work too - w.setGeometry(0, 0, 200, 200); - QCOMPARE(spy.count(), 2); -} - void tst_QGraphicsWidget::getContentsMargins_data() { QTest::addColumn("left"); -- cgit v0.12 From ffb3275775874a94a6882d5098ac963ad54c9bec Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Wed, 31 Mar 2010 10:40:42 +1000 Subject: Fixed incorrectly clipped video when rendered on QGLWidget Don't enable GL stencil/scissor test inside of native GL rendering block if it was not enabled by QPaintEngine (QGLWidget viewport case). Reviewed-by: Andrew den Exter --- src/multimedia/base/qpaintervideosurface.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/multimedia/base/qpaintervideosurface.cpp b/src/multimedia/base/qpaintervideosurface.cpp index b8028d8f..2fe941b 100644 --- a/src/multimedia/base/qpaintervideosurface.cpp +++ b/src/multimedia/base/qpaintervideosurface.cpp @@ -737,10 +737,15 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint( const QRectF &target, QPainter *painter, const QRectF &source) { if (m_frame.isValid()) { + bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST); + bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); + painter->beginNativePainting(); - glEnable(GL_STENCIL_TEST); - glEnable(GL_SCISSOR_TEST); + if (stencilTestEnabled) + glEnable(GL_STENCIL_TEST); + if (scissorTestEnabled) + glEnable(GL_SCISSOR_TEST); const float txLeft = source.left() / m_frameSize.width(); const float txRight = source.right() / m_frameSize.width(); @@ -815,9 +820,6 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint( glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_FRAGMENT_PROGRAM_ARB); - glDisable(GL_STENCIL_TEST); - glDisable(GL_SCISSOR_TEST); - painter->endNativePainting(); } return QAbstractVideoSurface::NoError; @@ -1063,10 +1065,15 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint( const QRectF &target, QPainter *painter, const QRectF &source) { if (m_frame.isValid()) { + bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST); + bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); + painter->beginNativePainting(); - glEnable(GL_STENCIL_TEST); - glEnable(GL_SCISSOR_TEST); + if (stencilTestEnabled) + glEnable(GL_STENCIL_TEST); + if (scissorTestEnabled) + glEnable(GL_SCISSOR_TEST); const int width = QGLContext::currentContext()->device()->width(); const int height = QGLContext::currentContext()->device()->height(); @@ -1158,9 +1165,6 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint( m_program.release(); - - glDisable(GL_SCISSOR_TEST); - glDisable(GL_STENCIL_TEST); painter->endNativePainting(); } return QAbstractVideoSurface::NoError; -- cgit v0.12 From 577229a5cb2fe0a9e0806238808ed3c9aeb3d3cc Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 23 Mar 2010 04:37:35 +0100 Subject: Show only one dialog when using QFileDialog on Mac. The completer was trying to populate the combobox for completion even if the dialog was hidden (the native one is shown). Task-number:QTBUG-8624 Reviewed-by:richard --- src/gui/dialogs/qfiledialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index ef2b223..3b5fb9f 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -723,9 +723,15 @@ void QFileDialog::setVisible(bool visible) // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below // updates the state correctly, but skips showing the non-native version: setAttribute(Qt::WA_DontShowOnScreen); + //So the completer don't try to complete and therefore to show a popup + d->completer->setModel(0); } else { d->nativeDialogInUse = false; setAttribute(Qt::WA_DontShowOnScreen, false); + if (d->proxyModel != 0) + d->completer->setModel(d->proxyModel); + else + d->completer->setModel(d->model); } } -- cgit v0.12 From 525e6207b5e5c9cce82ed6e76a65571f56971f92 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 24 Mar 2010 02:09:13 +0100 Subject: Micro optimization after feedback from Jan-Arve. Reviewed-by:janarve --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 450dea7..02a1ecb 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3631,7 +3631,7 @@ void QGraphicsItem::setPos(const QPointF &pos) return; // Update and repositition. - if (!(d_ptr->flags & ItemSendsGeometryChanges) && !(d_ptr->flags & ItemSendsScenePositionChanges)) { + if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) { d_ptr->setPosHelper(pos); return; } -- cgit v0.12 From be8c03e36b527d1ce8e99e470320938e8f138385 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 31 Mar 2010 11:14:46 +1000 Subject: Move gitignore to right level, update for Linux. --- imports/.gitignore | 5 +++++ imports/Qt/.gitignore | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 imports/.gitignore delete mode 100644 imports/Qt/.gitignore diff --git a/imports/.gitignore b/imports/.gitignore new file mode 100644 index 0000000..3b18f12 --- /dev/null +++ b/imports/.gitignore @@ -0,0 +1,5 @@ +*.dll +*.dso +*.so +*.so.debug +qmldir diff --git a/imports/Qt/.gitignore b/imports/Qt/.gitignore deleted file mode 100644 index bc54bd5..0000000 --- a/imports/Qt/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.dll -*.dso -- cgit v0.12 From 07f6fe57bf15ac06a6e0672abd1fa4acdc61548e Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 31 Mar 2010 11:15:25 +1000 Subject: doc --- src/declarative/graphicsitems/qdeclarativeimage.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 23a2350..3145c43 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -275,6 +275,10 @@ qreal QDeclarativeImage::paintedHeight() const used by a loaded image. The image will be scaled down if its intrinsic size is greater than this value. + If only one dimension of the size is set (and the other left at 0), the + unset dimension will be set in proportion to the set dimension to preserve + the source image aspect ratio. The fillMode is independent of this. + Unlike setting the width and height properties, which merely scale the painting of the image, this property affects the number of pixels stored. -- cgit v0.12 From c9fcfbfd995c6ad81d8c65761c1b18a41783c17e Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 31 Mar 2010 11:14:54 +1000 Subject: Add test. --- .../qdeclarativeecmascript/data/compiled.qml | 38 ++++++++++++++++++++++ .../tst_qdeclarativeecmascript.cpp | 37 +++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml b/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml new file mode 100644 index 0000000..4207a1f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml @@ -0,0 +1,38 @@ +import Qt 4.6 + +QtObject { + property real test1: a + b + property real test2: a - b + property bool test3: (a < b) + property bool test4: (a > b) + property bool test5: (a == b) + property bool test6: (a != b) + + property int test7: c + d + property int test8: d - c + property bool test9: (c < d) + property bool test10: (c > d) + property bool test11: (c == d) + property bool test12: (c != d) + + property string test13: e + f + property string test14: e + " " + f + property bool test15: (e == f) + property bool test16: (e != f) + + property int test17: a + property real test18: d + property int test19: g + property real test20: g + property string test21: g + property string test22: h + + property real a: 4.5 + property real b: 11.2 + property int c: 9 + property int d: 176 + property string e: "Hello" + property string f: "World" + property var g: 6.7 + property var h: "!" +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index b218d30..09e77a3 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -129,6 +129,7 @@ private slots: void ownership(); void qlistqobjectMethods(); void strictlyEquals(); + void compiled(); void bug1(); void dynamicCreationCrash(); @@ -2026,6 +2027,42 @@ void tst_qdeclarativeecmascript::strictlyEquals() delete object; } +void tst_qdeclarativeecmascript::compiled() +{ + QDeclarativeComponent component(&engine, TEST_FILE("compiled.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toReal(), qreal(15.7)); + QCOMPARE(object->property("test2").toReal(), qreal(-6.7)); + QCOMPARE(object->property("test3").toBool(), true); + QCOMPARE(object->property("test4").toBool(), false); + QCOMPARE(object->property("test5").toBool(), false); + QCOMPARE(object->property("test6").toBool(), true); + + QCOMPARE(object->property("test7").toInt(), 185); + QCOMPARE(object->property("test8").toInt(), 167); + QCOMPARE(object->property("test9").toBool(), true); + QCOMPARE(object->property("test10").toBool(), false); + QCOMPARE(object->property("test11").toBool(), false); + QCOMPARE(object->property("test12").toBool(), true); + + QCOMPARE(object->property("test13").toString(), QLatin1String("HelloWorld")); + QCOMPARE(object->property("test14").toString(), QLatin1String("Hello World")); + QCOMPARE(object->property("test15").toBool(), false); + QCOMPARE(object->property("test16").toBool(), true); + + QCOMPARE(object->property("test17").toInt(), 4); + QCOMPARE(object->property("test18").toReal(), qreal(176)); + //QCOMPARE(object->property("test19").toInt(), 6); + QCOMPARE(object->property("test20").toReal(), qreal(6.7)); + QCOMPARE(object->property("test21").toString(), QLatin1String("6.7")); + QCOMPARE(object->property("test22").toString(), QLatin1String("!")); + + delete object; +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" -- cgit v0.12 From 603b797d745c4129f5d2a151c9146358e36eb668 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 31 Mar 2010 11:16:22 +1000 Subject: Declarative examples cleanup. --- .../declarative/animations/property-animation.qml | 4 +- examples/declarative/behaviors/SideRect.qml | 16 +++++ .../declarative/behaviors/behavior-example.qml | 79 ++++++++++++++++++++++ examples/declarative/behaviours/SideRect.qml | 17 ----- .../declarative/behaviours/behavior-example.qml | 72 -------------------- 5 files changed, 97 insertions(+), 91 deletions(-) create mode 100644 examples/declarative/behaviors/SideRect.qml create mode 100644 examples/declarative/behaviors/behavior-example.qml delete mode 100644 examples/declarative/behaviours/SideRect.qml delete mode 100644 examples/declarative/behaviours/behavior-example.qml diff --git a/examples/declarative/animations/property-animation.qml b/examples/declarative/animations/property-animation.qml index 401feb5..fd5eb3c 100644 --- a/examples/declarative/animations/property-animation.qml +++ b/examples/declarative/animations/property-animation.qml @@ -40,7 +40,7 @@ Item { anchors.horizontalCenter: parent.horizontalCenter source: "images/face-smile.png"; y: minHeight - // Animate the y property. Setting repeat to true makes the + // Animate the y property. Setting loops to Animation.Infinite makes the // animation repeat indefinitely, otherwise it would only run once. SequentialAnimation on y { loops: Animation.Infinite @@ -50,7 +50,7 @@ Item { from: smiley.minHeight; to: smiley.maxHeight easing.type: "OutExpo"; duration: 300 } - + // Then move back to minHeight in 1 second, using the OutBounce easing function NumberAnimation { from: smiley.maxHeight; to: smiley.minHeight diff --git a/examples/declarative/behaviors/SideRect.qml b/examples/declarative/behaviors/SideRect.qml new file mode 100644 index 0000000..7caac45 --- /dev/null +++ b/examples/declarative/behaviors/SideRect.qml @@ -0,0 +1,16 @@ +import Qt 4.6 + +Rectangle { + id: myRect + + property string text + + width: 75; height: 50; radius: 6 + color: "#646464"; border.width: 4; border.color: "white" + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onEntered: { focusRect.x = myRect.x; focusRect.y = myRect.y; focusRect.text = myRect.text } + } +} diff --git a/examples/declarative/behaviors/behavior-example.qml b/examples/declarative/behaviors/behavior-example.qml new file mode 100644 index 0000000..8da1ada --- /dev/null +++ b/examples/declarative/behaviors/behavior-example.qml @@ -0,0 +1,79 @@ +import Qt 4.6 + +Rectangle { + color: "#343434" + width: 600; height: 400 + + Rectangle { + anchors.centerIn: parent + width: 200; height: 200; radius: 30 + color: "transparent"; border.width: 4; border.color: "white" + + + SideRect { + id: leftRect + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.left + text: "Left" + } + + SideRect { + id: rightRect + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.right + text: "Right" + } + + SideRect { + id: topRect + anchors.verticalCenter: parent.top + anchors.horizontalCenter: parent.horizontalCenter + text: "Top" + } + + SideRect { + id: bottomRect + anchors.verticalCenter: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + text: "Bottom" + } + + + Rectangle { + id: focusRect + + property string text + + color: "firebrick" + x: 62.5; y: 75; width: 75; height: 50 + radius: 6; border.width: 4; border.color: "white" + + // Setting an 'elastic' behavior on the focusRect's x property. + Behavior on x { + NumberAnimation { easing.type: "OutElastic"; easing.amplitude: 3.0; easing.period: 2.0; duration: 300 } + } + + // Setting an 'elastic' behavior on the focusRect's y property. + Behavior on y { + NumberAnimation { easing.type: "OutElastic"; easing.amplitude: 3.0; easing.period: 2.0; duration: 300 } + } + + Text { + id: focusText + text: focusRect.text + anchors.centerIn: parent + color: "white"; font.pixelSize: 16; font.bold: true + + // Setting a behavior on the focusText's x property: + // Set the opacity to 0, set the new text value, then set the opacity back to 1. + Behavior on text { + SequentialAnimation { + NumberAnimation { target: focusText; property: "opacity"; to: 0; duration: 150 } + PropertyAction { } + NumberAnimation { target: focusText; property: "opacity"; to: 1; duration: 150 } + } + } + } + } + } +} diff --git a/examples/declarative/behaviours/SideRect.qml b/examples/declarative/behaviours/SideRect.qml deleted file mode 100644 index 63b7db2..0000000 --- a/examples/declarative/behaviours/SideRect.qml +++ /dev/null @@ -1,17 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: myRect - - property string text - - color: "black" - width: 75; height: 50 - radius: 5 - border.width: 10; border.color: "white"; - MouseArea { - anchors.fill: parent - hoverEnabled: true - onEntered: { focusRect.x = myRect.x; focusRect.y = myRect.y; focusRect.text = myRect.text } - } -} diff --git a/examples/declarative/behaviours/behavior-example.qml b/examples/declarative/behaviours/behavior-example.qml deleted file mode 100644 index c84bf62..0000000 --- a/examples/declarative/behaviours/behavior-example.qml +++ /dev/null @@ -1,72 +0,0 @@ -import Qt 4.6 - -Rectangle { - color: "black" - width: 400; height: 400 - - Rectangle { - color: "transparent" - anchors.centerIn: parent - width: 200; height: 200 - radius: 30 - border.width: 10; border.color: "white"; - - SideRect { - id: leftRect - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.left - text: "Left" - } - - SideRect { - id: rightRect - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.right - text: "Right" - } - - SideRect { - id: topRect - anchors.verticalCenter: parent.top - anchors.horizontalCenter: parent.horizontalCenter - text: "Top" - } - - SideRect { - id: bottomRect - anchors.verticalCenter: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - text: "Bottom" - } - - - Rectangle { - id: focusRect - - property string text - - color: "red" - width: 75; height: 50 - radius: 5 - border.width: 10; border.color: "white"; - x: 100-37; y: 100-25 - Behavior on x { NumberAnimation { duration: 300 } } - Behavior on y { NumberAnimation { duration: 300 } } - Text { - id: focusText - text: focusRect.text; - Behavior on text { - SequentialAnimation { - NumberAnimation { target: focusText; property: "opacity"; to: 0; duration: 150 } - PropertyAction {} - NumberAnimation { target: focusText; property: "opacity"; to: 1; duration: 150 } - } - } - anchors.centerIn: parent; - color: "white"; - font.pixelSize: 16 - font.bold: true - } - } - } -} -- cgit v0.12 From 7850ee84483b34ef2e97517c3bc9cfb93ea1bf1c Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Wed, 31 Mar 2010 10:44:39 +1000 Subject: Update mouseX(Y) when clicking on a mouse area This fixes the original commit, 56aa9370dbafa8ee4, for QTBUG-9383. We need to emit a positionChanged signal to update the mouseX(Y) for the mouse area. Reviewed-by: Martin Jones --- .../graphicsitems/qdeclarativemousearea.cpp | 1 + .../data/updateMousePosOnClick.qml | 20 ++++++++++++ .../tst_qdeclarativemousearea.cpp | 36 ++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 tests/auto/declarative/qdeclarativemousearea/data/updateMousePosOnClick.qml diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index dde3366..6126a6f 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -640,6 +640,7 @@ bool QDeclarativeMouseArea::setPressed(bool p) QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress); if (d->pressed) { emit pressed(&me); + emit positionChanged(&me); } else { emit released(&me); if (isclick) diff --git a/tests/auto/declarative/qdeclarativemousearea/data/updateMousePosOnClick.qml b/tests/auto/declarative/qdeclarativemousearea/data/updateMousePosOnClick.qml new file mode 100644 index 0000000..0da7c45 --- /dev/null +++ b/tests/auto/declarative/qdeclarativemousearea/data/updateMousePosOnClick.qml @@ -0,0 +1,20 @@ +import Qt 4.6 + +Rectangle { + color: "#ffffff" + width: 320; height: 240 + MouseArea { + id: mouseRegion + objectName: "mouseregion" + anchors.fill: parent + Rectangle { + id: ball + objectName: "ball" + width: 20; height: 20 + radius: 10 + color: "#0000ff" + x: { mouseRegion.mouseX } + y: mouseRegion.mouseY + } + } +} diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp index 769cf32..9b664e5 100644 --- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp +++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include class tst_QDeclarativeMouseArea: public QObject @@ -49,6 +50,7 @@ class tst_QDeclarativeMouseArea: public QObject Q_OBJECT private slots: void dragProperties(); + void updateMouseAreaPosOnClick(); private: QDeclarativeView *createView(const QString &filename); }; @@ -121,6 +123,8 @@ void tst_QDeclarativeMouseArea::dragProperties() QCOMPARE(xmaxSpy.count(),1); QCOMPARE(yminSpy.count(),1); QCOMPARE(ymaxSpy.count(),1); + + delete canvas; } QDeclarativeView *tst_QDeclarativeMouseArea::createView(const QString &filename) @@ -133,6 +137,38 @@ QDeclarativeView *tst_QDeclarativeMouseArea::createView(const QString &filename) return canvas; } +void tst_QDeclarativeMouseArea::updateMouseAreaPosOnClick() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/updateMousePosOnClick.qml"); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QDeclarativeMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); + QVERIFY(mouseRegion != 0); + + QDeclarativeRectangle *rect = canvas->rootObject()->findChild("ball"); + QVERIFY(rect != 0); + + QCOMPARE(mouseRegion->mouseX(), rect->x()); + QCOMPARE(mouseRegion->mouseY(), rect->y()); + + QGraphicsScene *scene = canvas->scene(); + QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress); + event.setScenePos(QPointF(100, 100)); + event.setButton(Qt::LeftButton); + event.setButtons(Qt::LeftButton); + QApplication::sendEvent(scene, &event); + + QCOMPARE(mouseRegion->mouseX(), 100.0); + QCOMPARE(mouseRegion->mouseY(), 100.0); + + QCOMPARE(mouseRegion->mouseX(), rect->x()); + QCOMPARE(mouseRegion->mouseY(), rect->y()); + + delete canvas; +} + QTEST_MAIN(tst_QDeclarativeMouseArea) #include "tst_qdeclarativemousearea.moc" -- cgit v0.12 From 3b1e8bf54eeb0050f55720ffc90a2b77a73ca4df Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 31 Mar 2010 11:20:04 +1000 Subject: Update examples/declarative.pro --- examples/declarative/declarative.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/declarative/declarative.pro b/examples/declarative/declarative.pro index 0f58738..5fc1cf0 100644 --- a/examples/declarative/declarative.pro +++ b/examples/declarative/declarative.pro @@ -12,7 +12,7 @@ SUBDIRS = \ sources.files = \ animations \ aspectratio \ - behaviours \ + behaviors \ border-image \ clocks \ connections \ -- cgit v0.12 From f31145a524f1d0098fb1c523e288359e023e926b Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 31 Mar 2010 11:47:33 +1000 Subject: example of WebView onAlert, and of popups in general. --- examples/declarative/webview/alerts.html | 5 +++ examples/declarative/webview/alerts.qml | 58 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 examples/declarative/webview/alerts.html create mode 100644 examples/declarative/webview/alerts.qml diff --git a/examples/declarative/webview/alerts.html b/examples/declarative/webview/alerts.html new file mode 100644 index 0000000..82caddf --- /dev/null +++ b/examples/declarative/webview/alerts.html @@ -0,0 +1,5 @@ + + +

This is a web page. It fires an alert when clicked. + + diff --git a/examples/declarative/webview/alerts.qml b/examples/declarative/webview/alerts.qml new file mode 100644 index 0000000..ab2e860 --- /dev/null +++ b/examples/declarative/webview/alerts.qml @@ -0,0 +1,58 @@ +import Qt 4.6 +import org.webkit 1.0 + +WebView { + id: webView + onAlert: popup.show(message) + width: 120 + height: 150 + url: "alerts.html" + + Rectangle { + id: popup + + color: "red" + border.color: "black" + border.width: 2 + radius: 4 + + y: parent.height // off "screen" + anchors.horizontalCenter: parent.horizontalCenter + width: label.width+5 + height: label.height+5 + + opacity: 0 + + function show(t) { + label.text = t + popup.state = "visible" + timer.start() + } + states: State { + name: "visible" + PropertyChanges { target: popup; opacity: 1 } + PropertyChanges { target: popup; y: (webView.height-popup.height)/2 } + } + + transitions: [ + Transition { from: ""; PropertyAnimation { properties: "opacity,y"; duration: 65 } }, + Transition { from: "visible"; PropertyAnimation { properties: "opacity,y"; duration: 500 } } + ] + + Timer { + id: timer + interval: 1000 + onTriggered: popup.state = "" + } + + Text { + id: label + anchors.centerIn: parent + color: "white" + font.pixelSize: 20 + width: webView.width*0.75 + wrap: true + horizontalAlignment: "AlignHCenter" + } + } +} -- cgit v0.12 From e479a0468eb5e3a57d1f20f423c60894d7a1a7a3 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 31 Mar 2010 11:54:06 +1000 Subject: doc Task-number: QTBUG-9372 --- src/imports/webkit/qdeclarativewebview.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index be3fca2..1ff1078 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -1218,6 +1218,14 @@ QString QDeclarativeWebPage::chooseFile(QWebFrame *originatingFrame, const QStri return oldFile; } +/*! + \qmlsignal WebView::alert(message) + + This signal is emitted when the web engine sends a JavaScript alert. The \a message is the text + to be displayed in the alert to the user. +*/ + + void QDeclarativeWebPage::javaScriptAlert(QWebFrame *originatingFrame, const QString& msg) { Q_UNUSED(originatingFrame) -- cgit v0.12 From 75e9dc39dda515847961a04d402754d93d0b3326 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 31 Mar 2010 12:30:33 +1000 Subject: Test openUrlExternally --- .../qdeclarativeqt/data/openUrlExternally.qml | 5 +++++ .../qdeclarativeqt/tst_qdeclarativeqt.cpp | 26 ++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeqt/data/openUrlExternally.qml diff --git a/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally.qml b/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally.qml new file mode 100644 index 0000000..70bd74d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeqt/data/openUrlExternally.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +QtObject { + Component.onCompleted: Qt.openUrlExternally("test:url") +} diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index 4987557..48d5235 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -261,10 +262,31 @@ void tst_qdeclarativeqt::tint() delete object; } +class MyUrlHandler : public QObject +{ + Q_OBJECT +public: + MyUrlHandler() : called(0) { } + int called; + QUrl last; + +public slots: + void noteCall(const QUrl &url) { called++; last = url; } +}; + void tst_qdeclarativeqt::openUrlExternally() { - QEXPECT_FAIL("", "How do we test this?", Abort); - QVERIFY(false); + MyUrlHandler handler; + + QDesktopServices::setUrlHandler("test", &handler, "noteCall"); + + QDeclarativeComponent component(&engine, TEST_FILE("openUrlExternally.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(handler.called,1); + QCOMPARE(handler.last, QUrl("test:url")); + + QDesktopServices::unsetUrlHandler("test"); } void tst_qdeclarativeqt::md5() -- cgit v0.12 From 63f7da63891f07202453759d29a9657c3f9681a4 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 31 Mar 2010 12:08:03 +1000 Subject: More testing. --- tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml | 6 ++++++ .../qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml b/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml index 4207a1f..2fec9da 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml @@ -1,6 +1,7 @@ import Qt 4.6 QtObject { + //real property real test1: a + b property real test2: a - b property bool test3: (a < b) @@ -8,6 +9,7 @@ QtObject { property bool test5: (a == b) property bool test6: (a != b) + //int property int test7: c + d property int test8: d - c property bool test9: (c < d) @@ -15,17 +17,20 @@ QtObject { property bool test11: (c == d) property bool test12: (c != d) + //string property string test13: e + f property string test14: e + " " + f property bool test15: (e == f) property bool test16: (e != f) + //type conversion property int test17: a property real test18: d property int test19: g property real test20: g property string test21: g property string test22: h + property bool test23: i property real a: 4.5 property real b: 11.2 @@ -35,4 +40,5 @@ QtObject { property string f: "World" property var g: 6.7 property var h: "!" + property var i: true } diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 09e77a3..77dd4b8 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -2055,10 +2055,12 @@ void tst_qdeclarativeecmascript::compiled() QCOMPARE(object->property("test17").toInt(), 4); QCOMPARE(object->property("test18").toReal(), qreal(176)); - //QCOMPARE(object->property("test19").toInt(), 6); + QEXPECT_FAIL("", "QTBUG-9538", Continue); + QCOMPARE(object->property("test19").toInt(), 6); QCOMPARE(object->property("test20").toReal(), qreal(6.7)); QCOMPARE(object->property("test21").toString(), QLatin1String("6.7")); QCOMPARE(object->property("test22").toString(), QLatin1String("!")); + QCOMPARE(object->property("test23").toBool(), true); delete object; } -- cgit v0.12 From ff711bebd7a8857bc78b9a2854591489fcb15497 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 31 Mar 2010 13:05:00 +1000 Subject: VisibleArea is not a creatable type. --- src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index 7bc74ce..97a22cf 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -130,7 +130,6 @@ void QDeclarativeItemModule::defineModule() qmlRegisterType("Qt",4,6,"TextEdit"); qmlRegisterType("Qt",4,6,"TextInput"); qmlRegisterType("Qt",4,6,"ViewSection"); - qmlRegisterType("Qt",4,6,"VisibleArea"); qmlRegisterType("Qt",4,6,"VisualDataModel"); qmlRegisterType("Qt",4,6,"VisualItemModel"); @@ -148,6 +147,7 @@ void QDeclarativeItemModule::defineModule() qmlRegisterType(); qmlRegisterType(); qmlRegisterType(); + qmlRegisterType(); #ifdef QT_WEBKIT_LIB qmlRegisterType(); #endif -- cgit v0.12 From 8c757e4b84748c19e5f66da432d8af2e7db40cde Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 31 Mar 2010 14:14:19 +1000 Subject: Minor cleanup for visual test framework. --- tools/qml/main.cpp | 2 +- tools/qml/qdeclarativetester.cpp | 381 +++++++++++++++++++++++++++++++++++++++ tools/qml/qdeclarativetester.h | 286 +++++++++++++++++++++++++++++ tools/qml/qfxtester.cpp | 381 --------------------------------------- tools/qml/qfxtester.h | 286 ----------------------------- tools/qml/qml.pro | 4 +- tools/qml/qmlruntime.cpp | 2 +- 7 files changed, 671 insertions(+), 671 deletions(-) create mode 100644 tools/qml/qdeclarativetester.cpp create mode 100644 tools/qml/qdeclarativetester.h delete mode 100644 tools/qml/qfxtester.cpp delete mode 100644 tools/qml/qfxtester.h diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 8062e8e..5099e49 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -47,7 +47,7 @@ #include #include #include -#include "qfxtester.h" +#include "qdeclarativetester.h" #include "qdeclarativefolderlistmodel.h" QT_USE_NAMESPACE diff --git a/tools/qml/qdeclarativetester.cpp b/tools/qml/qdeclarativetester.cpp new file mode 100644 index 0000000..6245124 --- /dev/null +++ b/tools/qml/qdeclarativetester.cpp @@ -0,0 +1,381 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + + +QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions opts, + QDeclarativeView *parent) +: QAbstractAnimation(parent), m_script(script), m_view(parent), filterEvents(true), options(opts), + testscript(0), hasCompleted(false), hasFailed(false) +{ + parent->viewport()->installEventFilter(this); + parent->installEventFilter(this); + QUnifiedTimer::instance()->setConsistentTiming(true); + if (options & QDeclarativeViewer::Play) + this->run(); + start(); +} + +QDeclarativeTester::~QDeclarativeTester() +{ + if (!hasFailed && + options & QDeclarativeViewer::Record && + options & QDeclarativeViewer::SaveOnExit) + save(); +} + +int QDeclarativeTester::duration() const +{ + return -1; +} + +void QDeclarativeTester::addMouseEvent(Destination dest, QMouseEvent *me) +{ + MouseEvent e(me); + e.destination = dest; + m_mouseEvents << e; +} + +void QDeclarativeTester::addKeyEvent(Destination dest, QKeyEvent *ke) +{ + KeyEvent e(ke); + e.destination = dest; + m_keyEvents << e; +} + +bool QDeclarativeTester::eventFilter(QObject *o, QEvent *e) +{ + if (!filterEvents) + return false; + + Destination destination; + if (o == m_view) { + destination = View; + } else if (o == m_view->viewport()) { + destination = ViewPort; + } else { + return false; + } + + switch (e->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: + addKeyEvent(destination, (QKeyEvent *)e); + return true; + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + case QEvent::MouseButtonDblClick: + addMouseEvent(destination, (QMouseEvent *)e); + return true; + default: + break; + } + return false; +} + +void QDeclarativeTester::executefailure() +{ + hasFailed = true; + + if (options & QDeclarativeViewer::ExitOnFailure) + exit(-1); +} + +void QDeclarativeTester::imagefailure() +{ + hasFailed = true; + + if (options & QDeclarativeViewer::ExitOnFailure) + exit(-1); +} + +void QDeclarativeTester::complete() +{ + if ((options & QDeclarativeViewer::TestErrorProperty) && !hasFailed) { + QString e = m_view->rootObject()->property("error").toString(); + if (!e.isEmpty()) { + qWarning() << "Test failed:" << e; + hasFailed = true; + } + } + if (options & QDeclarativeViewer::ExitOnComplete) + QApplication::exit(hasFailed?-1:0); + + if (hasCompleted) + return; + hasCompleted = true; + + if (options & QDeclarativeViewer::Play) + qWarning("Script playback complete"); +} + +void QDeclarativeTester::run() +{ + QDeclarativeComponent c(m_view->engine(), m_script + QLatin1String(".qml")); + + testscript = qobject_cast(c.create()); + if (testscript) testscript->setParent(this); + else { executefailure(); exit(-1); } + testscriptidx = 0; +} + +void QDeclarativeTester::save() +{ + QString filename = m_script + QLatin1String(".qml"); + QFileInfo filenameInfo(filename); + QDir saveDir = filenameInfo.absoluteDir(); + saveDir.mkpath("."); + + QFile file(filename); + file.open(QIODevice::WriteOnly); + QTextStream ts(&file); + + ts << "import Qt.VisualTest 4.6\n\n"; + ts << "VisualTest {\n"; + + int imgCount = 0; + QList keyevents = m_savedKeyEvents; + QList mouseevents = m_savedMouseEvents; + for (int ii = 0; ii < m_savedFrameEvents.count(); ++ii) { + const FrameEvent &fe = m_savedFrameEvents.at(ii); + ts << " Frame {\n"; + ts << " msec: " << fe.msec << "\n"; + if (!fe.hash.isEmpty()) { + ts << " hash: \"" << fe.hash.toHex() << "\"\n"; + } else if (!fe.image.isNull()) { + QString filename = filenameInfo.baseName() + "." + QString::number(imgCount) + ".png"; + fe.image.save(m_script + "." + QString::number(imgCount) + ".png"); + imgCount++; + ts << " image: \"" << filename << "\"\n"; + } + ts << " }\n"; + + while (!mouseevents.isEmpty() && + mouseevents.first().msec == fe.msec) { + MouseEvent me = mouseevents.takeFirst(); + + ts << " Mouse {\n"; + ts << " type: " << me.type << "\n"; + ts << " button: " << me.button << "\n"; + ts << " buttons: " << me.buttons << "\n"; + ts << " x: " << me.pos.x() << "; y: " << me.pos.y() << "\n"; + ts << " modifiers: " << me.modifiers << "\n"; + if (me.destination == ViewPort) + ts << " sendToViewport: true\n"; + ts << " }\n"; + } + + while (!keyevents.isEmpty() && + keyevents.first().msec == fe.msec) { + KeyEvent ke = keyevents.takeFirst(); + + ts << " Key {\n"; + ts << " type: " << ke.type << "\n"; + ts << " key: " << ke.key << "\n"; + ts << " modifiers: " << ke.modifiers << "\n"; + ts << " text: \"" << ke.text.toUtf8().toHex() << "\"\n"; + ts << " autorep: " << (ke.autorep?"true":"false") << "\n"; + ts << " count: " << ke.count << "\n"; + if (ke.destination == ViewPort) + ts << " sendToViewport: true\n"; + ts << " }\n"; + } + } + + ts << "}\n"; + file.close(); +} + +void QDeclarativeTester::updateCurrentTime(int msec) +{ + QDeclarativeItemPrivate::setConsistentTime(msec); + + QImage img(m_view->width(), m_view->height(), QImage::Format_RGB32); + + if (options & QDeclarativeViewer::TestImages) { + img.fill(qRgb(255,255,255)); + QPainter p(&img); + m_view->render(&p); + } + + FrameEvent fe; + fe.msec = msec; + if (msec == 0 || !(options & QDeclarativeViewer::TestImages)) { + // Skip first frame, skip if not doing images + } else if (0 == (m_savedFrameEvents.count() % 60)) { + fe.image = img; + } else { + QCryptographicHash hash(QCryptographicHash::Md5); + hash.addData((const char *)img.bits(), img.bytesPerLine() * img.height()); + fe.hash = hash.result(); + } + m_savedFrameEvents.append(fe); + + // Deliver mouse events + filterEvents = false; + + if (!testscript) { + for (int ii = 0; ii < m_mouseEvents.count(); ++ii) { + MouseEvent &me = m_mouseEvents[ii]; + me.msec = msec; + QMouseEvent event(me.type, me.pos, me.button, me.buttons, me.modifiers); + + if (me.destination == View) { + QCoreApplication::sendEvent(m_view, &event); + } else { + QCoreApplication::sendEvent(m_view->viewport(), &event); + } + } + + for (int ii = 0; ii < m_keyEvents.count(); ++ii) { + KeyEvent &ke = m_keyEvents[ii]; + ke.msec = msec; + QKeyEvent event(ke.type, ke.key, ke.modifiers, ke.text, ke.autorep, ke.count); + + if (ke.destination == View) { + QCoreApplication::sendEvent(m_view, &event); + } else { + QCoreApplication::sendEvent(m_view->viewport(), &event); + } + } + m_savedMouseEvents.append(m_mouseEvents); + m_savedKeyEvents.append(m_keyEvents); + } + + m_mouseEvents.clear(); + m_keyEvents.clear(); + + // Advance test script + while (testscript && testscript->count() > testscriptidx) { + + QObject *event = testscript->event(testscriptidx); + + if (QDeclarativeVisualTestFrame *frame = qobject_cast(event)) { + if (frame->msec() < msec) { + if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) { + qWarning() << "QDeclarativeTester: Extra frame. Seen:" + << msec << "Expected:" << frame->msec(); + imagefailure(); + } + } else if (frame->msec() == msec) { + if (!frame->hash().isEmpty() && frame->hash().toUtf8() != fe.hash.toHex()) { + if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) { + qWarning() << "QDeclarativeTester: Mismatched frame hash at" << msec + << ". Seen:" << fe.hash.toHex() + << "Expected:" << frame->hash().toUtf8(); + imagefailure(); + } + } + } else if (frame->msec() > msec) { + break; + } + + if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record) && !frame->image().isEmpty()) { + QImage goodImage(frame->image().toLocalFile()); + if (goodImage != img) { + QString reject(frame->image().toLocalFile() + ".reject.png"); + qWarning() << "QDeclarativeTester: Image mismatch. Reject saved to:" + << reject; + img.save(reject); + imagefailure(); + } + } + } else if (QDeclarativeVisualTestMouse *mouse = qobject_cast(event)) { + QPoint pos(mouse->x(), mouse->y()); + QPoint globalPos = m_view->mapToGlobal(QPoint(0, 0)) + pos; + QMouseEvent event((QEvent::Type)mouse->type(), pos, globalPos, (Qt::MouseButton)mouse->button(), (Qt::MouseButtons)mouse->buttons(), (Qt::KeyboardModifiers)mouse->modifiers()); + + MouseEvent me(&event); + me.msec = msec; + if (!mouse->sendToViewport()) { + QCoreApplication::sendEvent(m_view, &event); + me.destination = View; + } else { + QCoreApplication::sendEvent(m_view->viewport(), &event); + me.destination = ViewPort; + } + m_savedMouseEvents.append(me); + } else if (QDeclarativeVisualTestKey *key = qobject_cast(event)) { + + QKeyEvent event((QEvent::Type)key->type(), key->key(), (Qt::KeyboardModifiers)key->modifiers(), QString::fromUtf8(QByteArray::fromHex(key->text().toUtf8())), key->autorep(), key->count()); + + KeyEvent ke(&event); + ke.msec = msec; + if (!key->sendToViewport()) { + QCoreApplication::sendEvent(m_view, &event); + ke.destination = View; + } else { + QCoreApplication::sendEvent(m_view->viewport(), &event); + ke.destination = ViewPort; + } + m_savedKeyEvents.append(ke); + } + testscriptidx++; + } + + filterEvents = true; + + if (testscript && testscript->count() <= testscriptidx) + complete(); +} + +void QDeclarativeTester::registerTypes() +{ + qmlRegisterType("Qt.VisualTest", 4,6, "VisualTest"); + qmlRegisterType("Qt.VisualTest", 4,6, "Frame"); + qmlRegisterType("Qt.VisualTest", 4,6, "Mouse"); + qmlRegisterType("Qt.VisualTest", 4,6, "Key"); +} + +QT_END_NAMESPACE diff --git a/tools/qml/qdeclarativetester.h b/tools/qml/qdeclarativetester.h new file mode 100644 index 0000000..d49c9b8 --- /dev/null +++ b/tools/qml/qdeclarativetester.h @@ -0,0 +1,286 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVETESTER_H +#define QDECLARATIVETESTER_H + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QDeclarativeVisualTest : public QObject +{ + Q_OBJECT + Q_PROPERTY(QDeclarativeListProperty events READ events CONSTANT) + Q_CLASSINFO("DefaultProperty", "events") +public: + QDeclarativeVisualTest() {} + + QDeclarativeListProperty events() { return QDeclarativeListProperty(this, m_events); } + + int count() const { return m_events.count(); } + QObject *event(int idx) { return m_events.at(idx); } + +private: + QList m_events; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativeVisualTest) + +QT_BEGIN_NAMESPACE + +class QDeclarativeVisualTestFrame : public QObject +{ + Q_OBJECT + Q_PROPERTY(int msec READ msec WRITE setMsec) + Q_PROPERTY(QString hash READ hash WRITE setHash) + Q_PROPERTY(QUrl image READ image WRITE setImage) +public: + QDeclarativeVisualTestFrame() : m_msec(-1) {} + + int msec() const { return m_msec; } + void setMsec(int m) { m_msec = m; } + + QString hash() const { return m_hash; } + void setHash(const QString &hash) { m_hash = hash; } + + QUrl image() const { return m_image; } + void setImage(const QUrl &image) { m_image = image; } + +private: + int m_msec; + QString m_hash; + QUrl m_image; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativeVisualTestFrame) + +QT_BEGIN_NAMESPACE + +class QDeclarativeVisualTestMouse : public QObject +{ + Q_OBJECT + Q_PROPERTY(int type READ type WRITE setType) + Q_PROPERTY(int button READ button WRITE setButton) + Q_PROPERTY(int buttons READ buttons WRITE setButtons) + Q_PROPERTY(int x READ x WRITE setX) + Q_PROPERTY(int y READ y WRITE setY) + Q_PROPERTY(int modifiers READ modifiers WRITE setModifiers) + Q_PROPERTY(bool sendToViewport READ sendToViewport WRITE setSendToViewport) +public: + QDeclarativeVisualTestMouse() : m_type(0), m_button(0), m_buttons(0), m_x(0), m_y(0), m_modifiers(0), m_viewport(false) {} + + int type() const { return m_type; } + void setType(int t) { m_type = t; } + + int button() const { return m_button; } + void setButton(int b) { m_button = b; } + + int buttons() const { return m_buttons; } + void setButtons(int b) { m_buttons = b; } + + int x() const { return m_x; } + void setX(int x) { m_x = x; } + + int y() const { return m_y; } + void setY(int y) { m_y = y; } + + int modifiers() const { return m_modifiers; } + void setModifiers(int modifiers) { m_modifiers = modifiers; } + + bool sendToViewport() const { return m_viewport; } + void setSendToViewport(bool v) { m_viewport = v; } +private: + int m_type; + int m_button; + int m_buttons; + int m_x; + int m_y; + int m_modifiers; + bool m_viewport; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativeVisualTestMouse) + +QT_BEGIN_NAMESPACE + +class QDeclarativeVisualTestKey : public QObject +{ + Q_OBJECT + Q_PROPERTY(int type READ type WRITE setType) + Q_PROPERTY(int key READ key WRITE setKey) + Q_PROPERTY(int modifiers READ modifiers WRITE setModifiers) + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(bool autorep READ autorep WRITE setAutorep) + Q_PROPERTY(int count READ count WRITE setCount) + Q_PROPERTY(bool sendToViewport READ sendToViewport WRITE setSendToViewport) +public: + QDeclarativeVisualTestKey() : m_type(0), m_key(0), m_modifiers(0), m_autorep(false), m_count(0), m_viewport(false) {} + + int type() const { return m_type; } + void setType(int t) { m_type = t; } + + int key() const { return m_key; } + void setKey(int k) { m_key = k; } + + int modifiers() const { return m_modifiers; } + void setModifiers(int m) { m_modifiers = m; } + + QString text() const { return m_text; } + void setText(const QString &t) { m_text = t; } + + bool autorep() const { return m_autorep; } + void setAutorep(bool a) { m_autorep = a; } + + int count() const { return m_count; } + void setCount(int c) { m_count = c; } + + bool sendToViewport() const { return m_viewport; } + void setSendToViewport(bool v) { m_viewport = v; } +private: + int m_type; + int m_key; + int m_modifiers; + QString m_text; + bool m_autorep; + int m_count; + bool m_viewport; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativeVisualTestKey) + +QT_BEGIN_NAMESPACE + +class QDeclarativeTester : public QAbstractAnimation +{ +public: + QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions options, QDeclarativeView *parent); + ~QDeclarativeTester(); + + static void registerTypes(); + + virtual int duration() const; + + void run(); + void save(); + + void executefailure(); +protected: + virtual void updateCurrentTime(int msecs); + virtual bool eventFilter(QObject *, QEvent *); + +private: + QString m_script; + + void imagefailure(); + void complete(); + + enum Destination { View, ViewPort }; + void addKeyEvent(Destination, QKeyEvent *); + void addMouseEvent(Destination, QMouseEvent *); + QDeclarativeView *m_view; + + struct MouseEvent { + MouseEvent(QMouseEvent *e) + : type(e->type()), button(e->button()), buttons(e->buttons()), + pos(e->pos()), modifiers(e->modifiers()), destination(View) {} + + QEvent::Type type; + Qt::MouseButton button; + Qt::MouseButtons buttons; + QPoint pos; + Qt::KeyboardModifiers modifiers; + Destination destination; + + int msec; + }; + struct KeyEvent { + KeyEvent(QKeyEvent *e) + : type(e->type()), key(e->key()), modifiers(e->modifiers()), text(e->text()), + autorep(e->isAutoRepeat()), count(e->count()), destination(View) {} + QEvent::Type type; + int key; + Qt::KeyboardModifiers modifiers; + QString text; + bool autorep; + ushort count; + Destination destination; + + int msec; + }; + struct FrameEvent { + QImage image; + QByteArray hash; + int msec; + }; + QList m_mouseEvents; + QList m_keyEvents; + + QList m_savedMouseEvents; + QList m_savedKeyEvents; + QList m_savedFrameEvents; + bool filterEvents; + + QDeclarativeViewer::ScriptOptions options; + int testscriptidx; + QDeclarativeVisualTest *testscript; + + bool hasCompleted; + bool hasFailed; +}; + + +QT_END_NAMESPACE + +#endif // QDECLARATIVETESTER_H diff --git a/tools/qml/qfxtester.cpp b/tools/qml/qfxtester.cpp deleted file mode 100644 index 28bbf5e..0000000 --- a/tools/qml/qfxtester.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - - -QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions opts, - QDeclarativeView *parent) -: QAbstractAnimation(parent), m_script(script), m_view(parent), filterEvents(true), options(opts), - testscript(0), hasCompleted(false), hasFailed(false) -{ - parent->viewport()->installEventFilter(this); - parent->installEventFilter(this); - QUnifiedTimer::instance()->setConsistentTiming(true); - if (options & QDeclarativeViewer::Play) - this->run(); - start(); -} - -QDeclarativeTester::~QDeclarativeTester() -{ - if (!hasFailed && - options & QDeclarativeViewer::Record && - options & QDeclarativeViewer::SaveOnExit) - save(); -} - -int QDeclarativeTester::duration() const -{ - return -1; -} - -void QDeclarativeTester::addMouseEvent(Destination dest, QMouseEvent *me) -{ - MouseEvent e(me); - e.destination = dest; - m_mouseEvents << e; -} - -void QDeclarativeTester::addKeyEvent(Destination dest, QKeyEvent *ke) -{ - KeyEvent e(ke); - e.destination = dest; - m_keyEvents << e; -} - -bool QDeclarativeTester::eventFilter(QObject *o, QEvent *e) -{ - if (!filterEvents) - return false; - - Destination destination; - if (o == m_view) { - destination = View; - } else if (o == m_view->viewport()) { - destination = ViewPort; - } else { - return false; - } - - switch (e->type()) { - case QEvent::KeyPress: - case QEvent::KeyRelease: - addKeyEvent(destination, (QKeyEvent *)e); - return true; - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseMove: - case QEvent::MouseButtonDblClick: - addMouseEvent(destination, (QMouseEvent *)e); - return true; - default: - break; - } - return false; -} - -void QDeclarativeTester::executefailure() -{ - hasFailed = true; - - if (options & QDeclarativeViewer::ExitOnFailure) - exit(-1); -} - -void QDeclarativeTester::imagefailure() -{ - hasFailed = true; - - if (options & QDeclarativeViewer::ExitOnFailure) - exit(-1); -} - -void QDeclarativeTester::complete() -{ - if ((options & QDeclarativeViewer::TestErrorProperty) && !hasFailed) { - QString e = m_view->rootObject()->property("error").toString(); - if (!e.isEmpty()) { - qWarning() << "Test failed:" << e; - hasFailed = true; - } - } - if (options & QDeclarativeViewer::ExitOnComplete) - QApplication::exit(hasFailed?-1:0); - - if (hasCompleted) - return; - hasCompleted = true; - - if (options & QDeclarativeViewer::Play) - qWarning("Script playback complete"); -} - -void QDeclarativeTester::run() -{ - QDeclarativeComponent c(m_view->engine(), m_script + QLatin1String(".qml")); - - testscript = qobject_cast(c.create()); - if (testscript) testscript->setParent(this); - else { executefailure(); exit(-1); } - testscriptidx = 0; -} - -void QDeclarativeTester::save() -{ - QString filename = m_script + QLatin1String(".qml"); - QFileInfo filenameInfo(filename); - QDir saveDir = filenameInfo.absoluteDir(); - saveDir.mkpath("."); - - QFile file(filename); - file.open(QIODevice::WriteOnly); - QTextStream ts(&file); - - ts << "import Qt.VisualTest 4.6\n\n"; - ts << "VisualTest {\n"; - - int imgCount = 0; - QList keyevents = m_savedKeyEvents; - QList mouseevents = m_savedMouseEvents; - for (int ii = 0; ii < m_savedFrameEvents.count(); ++ii) { - const FrameEvent &fe = m_savedFrameEvents.at(ii); - ts << " Frame {\n"; - ts << " msec: " << fe.msec << "\n"; - if (!fe.hash.isEmpty()) { - ts << " hash: \"" << fe.hash.toHex() << "\"\n"; - } else if (!fe.image.isNull()) { - QString filename = filenameInfo.baseName() + "." + QString::number(imgCount) + ".png"; - fe.image.save(m_script + "." + QString::number(imgCount) + ".png"); - imgCount++; - ts << " image: \"" << filename << "\"\n"; - } - ts << " }\n"; - - while (!mouseevents.isEmpty() && - mouseevents.first().msec == fe.msec) { - MouseEvent me = mouseevents.takeFirst(); - - ts << " Mouse {\n"; - ts << " type: " << me.type << "\n"; - ts << " button: " << me.button << "\n"; - ts << " buttons: " << me.buttons << "\n"; - ts << " x: " << me.pos.x() << "; y: " << me.pos.y() << "\n"; - ts << " modifiers: " << me.modifiers << "\n"; - if (me.destination == ViewPort) - ts << " sendToViewport: true\n"; - ts << " }\n"; - } - - while (!keyevents.isEmpty() && - keyevents.first().msec == fe.msec) { - KeyEvent ke = keyevents.takeFirst(); - - ts << " Key {\n"; - ts << " type: " << ke.type << "\n"; - ts << " key: " << ke.key << "\n"; - ts << " modifiers: " << ke.modifiers << "\n"; - ts << " text: \"" << ke.text.toUtf8().toHex() << "\"\n"; - ts << " autorep: " << (ke.autorep?"true":"false") << "\n"; - ts << " count: " << ke.count << "\n"; - if (ke.destination == ViewPort) - ts << " sendToViewport: true\n"; - ts << " }\n"; - } - } - - ts << "}\n"; - file.close(); -} - -void QDeclarativeTester::updateCurrentTime(int msec) -{ - QDeclarativeItemPrivate::setConsistentTime(msec); - - QImage img(m_view->width(), m_view->height(), QImage::Format_RGB32); - - if (options & QDeclarativeViewer::TestImages) { - img.fill(qRgb(255,255,255)); - QPainter p(&img); - m_view->render(&p); - } - - FrameEvent fe; - fe.msec = msec; - if (msec == 0 || !(options & QDeclarativeViewer::TestImages)) { - // Skip first frame, skip if not doing images - } else if (0 == (m_savedFrameEvents.count() % 60)) { - fe.image = img; - } else { - QCryptographicHash hash(QCryptographicHash::Md5); - hash.addData((const char *)img.bits(), img.bytesPerLine() * img.height()); - fe.hash = hash.result(); - } - m_savedFrameEvents.append(fe); - - // Deliver mouse events - filterEvents = false; - - if (!testscript) { - for (int ii = 0; ii < m_mouseEvents.count(); ++ii) { - MouseEvent &me = m_mouseEvents[ii]; - me.msec = msec; - QMouseEvent event(me.type, me.pos, me.button, me.buttons, me.modifiers); - - if (me.destination == View) { - QCoreApplication::sendEvent(m_view, &event); - } else { - QCoreApplication::sendEvent(m_view->viewport(), &event); - } - } - - for (int ii = 0; ii < m_keyEvents.count(); ++ii) { - KeyEvent &ke = m_keyEvents[ii]; - ke.msec = msec; - QKeyEvent event(ke.type, ke.key, ke.modifiers, ke.text, ke.autorep, ke.count); - - if (ke.destination == View) { - QCoreApplication::sendEvent(m_view, &event); - } else { - QCoreApplication::sendEvent(m_view->viewport(), &event); - } - } - m_savedMouseEvents.append(m_mouseEvents); - m_savedKeyEvents.append(m_keyEvents); - } - - m_mouseEvents.clear(); - m_keyEvents.clear(); - - // Advance test script - while (testscript && testscript->count() > testscriptidx) { - - QObject *event = testscript->event(testscriptidx); - - if (QDeclarativeVisualTestFrame *frame = qobject_cast(event)) { - if (frame->msec() < msec) { - if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) { - qWarning() << "QDeclarativeTester: Extra frame. Seen:" - << msec << "Expected:" << frame->msec(); - imagefailure(); - } - } else if (frame->msec() == msec) { - if (!frame->hash().isEmpty() && frame->hash().toUtf8() != fe.hash.toHex()) { - if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) { - qWarning() << "QDeclarativeTester: Mismatched frame hash. Seen:" - << fe.hash.toHex() << "Expected:" - << frame->hash().toUtf8(); - imagefailure(); - } - } - } else if (frame->msec() > msec) { - break; - } - - if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record) && !frame->image().isEmpty()) { - QImage goodImage(frame->image().toLocalFile()); - if (goodImage != img) { - QString reject(frame->image().toLocalFile() + ".reject.png"); - qWarning() << "QDeclarativeTester: Image mismatch. Reject saved to:" - << reject; - img.save(reject); - imagefailure(); - } - } - } else if (QDeclarativeVisualTestMouse *mouse = qobject_cast(event)) { - QPoint pos(mouse->x(), mouse->y()); - QPoint globalPos = m_view->mapToGlobal(QPoint(0, 0)) + pos; - QMouseEvent event((QEvent::Type)mouse->type(), pos, globalPos, (Qt::MouseButton)mouse->button(), (Qt::MouseButtons)mouse->buttons(), (Qt::KeyboardModifiers)mouse->modifiers()); - - MouseEvent me(&event); - me.msec = msec; - if (!mouse->sendToViewport()) { - QCoreApplication::sendEvent(m_view, &event); - me.destination = View; - } else { - QCoreApplication::sendEvent(m_view->viewport(), &event); - me.destination = ViewPort; - } - m_savedMouseEvents.append(me); - } else if (QDeclarativeVisualTestKey *key = qobject_cast(event)) { - - QKeyEvent event((QEvent::Type)key->type(), key->key(), (Qt::KeyboardModifiers)key->modifiers(), QString::fromUtf8(QByteArray::fromHex(key->text().toUtf8())), key->autorep(), key->count()); - - KeyEvent ke(&event); - ke.msec = msec; - if (!key->sendToViewport()) { - QCoreApplication::sendEvent(m_view, &event); - ke.destination = View; - } else { - QCoreApplication::sendEvent(m_view->viewport(), &event); - ke.destination = ViewPort; - } - m_savedKeyEvents.append(ke); - } - testscriptidx++; - } - - filterEvents = true; - - if (testscript && testscript->count() <= testscriptidx) - complete(); -} - -void QDeclarativeTester::registerTypes() -{ - qmlRegisterType("Qt.VisualTest", 4,6, "VisualTest"); - qmlRegisterType("Qt.VisualTest", 4,6, "Frame"); - qmlRegisterType("Qt.VisualTest", 4,6, "Mouse"); - qmlRegisterType("Qt.VisualTest", 4,6, "Key"); -} - -QT_END_NAMESPACE diff --git a/tools/qml/qfxtester.h b/tools/qml/qfxtester.h deleted file mode 100644 index 6521409..0000000 --- a/tools/qml/qfxtester.h +++ /dev/null @@ -1,286 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QFXTESTER_H -#define QFXTESTER_H - -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QDeclarativeVisualTest : public QObject -{ - Q_OBJECT - Q_PROPERTY(QDeclarativeListProperty events READ events CONSTANT) - Q_CLASSINFO("DefaultProperty", "events") -public: - QDeclarativeVisualTest() {} - - QDeclarativeListProperty events() { return QDeclarativeListProperty(this, m_events); } - - int count() const { return m_events.count(); } - QObject *event(int idx) { return m_events.at(idx); } - -private: - QList m_events; -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QDeclarativeVisualTest) - -QT_BEGIN_NAMESPACE - -class QDeclarativeVisualTestFrame : public QObject -{ - Q_OBJECT - Q_PROPERTY(int msec READ msec WRITE setMsec) - Q_PROPERTY(QString hash READ hash WRITE setHash) - Q_PROPERTY(QUrl image READ image WRITE setImage) -public: - QDeclarativeVisualTestFrame() : m_msec(-1) {} - - int msec() const { return m_msec; } - void setMsec(int m) { m_msec = m; } - - QString hash() const { return m_hash; } - void setHash(const QString &hash) { m_hash = hash; } - - QUrl image() const { return m_image; } - void setImage(const QUrl &image) { m_image = image; } - -private: - int m_msec; - QString m_hash; - QUrl m_image; -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QDeclarativeVisualTestFrame) - -QT_BEGIN_NAMESPACE - -class QDeclarativeVisualTestMouse : public QObject -{ - Q_OBJECT - Q_PROPERTY(int type READ type WRITE setType) - Q_PROPERTY(int button READ button WRITE setButton) - Q_PROPERTY(int buttons READ buttons WRITE setButtons) - Q_PROPERTY(int x READ x WRITE setX) - Q_PROPERTY(int y READ y WRITE setY) - Q_PROPERTY(int modifiers READ modifiers WRITE setModifiers) - Q_PROPERTY(bool sendToViewport READ sendToViewport WRITE setSendToViewport) -public: - QDeclarativeVisualTestMouse() : m_type(0), m_button(0), m_buttons(0), m_x(0), m_y(0), m_modifiers(0), m_viewport(false) {} - - int type() const { return m_type; } - void setType(int t) { m_type = t; } - - int button() const { return m_button; } - void setButton(int b) { m_button = b; } - - int buttons() const { return m_buttons; } - void setButtons(int b) { m_buttons = b; } - - int x() const { return m_x; } - void setX(int x) { m_x = x; } - - int y() const { return m_y; } - void setY(int y) { m_y = y; } - - int modifiers() const { return m_modifiers; } - void setModifiers(int modifiers) { m_modifiers = modifiers; } - - bool sendToViewport() const { return m_viewport; } - void setSendToViewport(bool v) { m_viewport = v; } -private: - int m_type; - int m_button; - int m_buttons; - int m_x; - int m_y; - int m_modifiers; - bool m_viewport; -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QDeclarativeVisualTestMouse) - -QT_BEGIN_NAMESPACE - -class QDeclarativeVisualTestKey : public QObject -{ - Q_OBJECT - Q_PROPERTY(int type READ type WRITE setType) - Q_PROPERTY(int key READ key WRITE setKey) - Q_PROPERTY(int modifiers READ modifiers WRITE setModifiers) - Q_PROPERTY(QString text READ text WRITE setText) - Q_PROPERTY(bool autorep READ autorep WRITE setAutorep) - Q_PROPERTY(int count READ count WRITE setCount) - Q_PROPERTY(bool sendToViewport READ sendToViewport WRITE setSendToViewport) -public: - QDeclarativeVisualTestKey() : m_type(0), m_key(0), m_modifiers(0), m_autorep(false), m_count(0), m_viewport(false) {} - - int type() const { return m_type; } - void setType(int t) { m_type = t; } - - int key() const { return m_key; } - void setKey(int k) { m_key = k; } - - int modifiers() const { return m_modifiers; } - void setModifiers(int m) { m_modifiers = m; } - - QString text() const { return m_text; } - void setText(const QString &t) { m_text = t; } - - bool autorep() const { return m_autorep; } - void setAutorep(bool a) { m_autorep = a; } - - int count() const { return m_count; } - void setCount(int c) { m_count = c; } - - bool sendToViewport() const { return m_viewport; } - void setSendToViewport(bool v) { m_viewport = v; } -private: - int m_type; - int m_key; - int m_modifiers; - QString m_text; - bool m_autorep; - int m_count; - bool m_viewport; -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QDeclarativeVisualTestKey) - -QT_BEGIN_NAMESPACE - -class QDeclarativeTester : public QAbstractAnimation -{ -public: - QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions options, QDeclarativeView *parent); - ~QDeclarativeTester(); - - static void registerTypes(); - - virtual int duration() const; - - void run(); - void save(); - - void executefailure(); -protected: - virtual void updateCurrentTime(int msecs); - virtual bool eventFilter(QObject *, QEvent *); - -private: - QString m_script; - - void imagefailure(); - void complete(); - - enum Destination { View, ViewPort }; - void addKeyEvent(Destination, QKeyEvent *); - void addMouseEvent(Destination, QMouseEvent *); - QDeclarativeView *m_view; - - struct MouseEvent { - MouseEvent(QMouseEvent *e) - : type(e->type()), button(e->button()), buttons(e->buttons()), - pos(e->pos()), modifiers(e->modifiers()), destination(View) {} - - QEvent::Type type; - Qt::MouseButton button; - Qt::MouseButtons buttons; - QPoint pos; - Qt::KeyboardModifiers modifiers; - Destination destination; - - int msec; - }; - struct KeyEvent { - KeyEvent(QKeyEvent *e) - : type(e->type()), key(e->key()), modifiers(e->modifiers()), text(e->text()), - autorep(e->isAutoRepeat()), count(e->count()), destination(View) {} - QEvent::Type type; - int key; - Qt::KeyboardModifiers modifiers; - QString text; - bool autorep; - ushort count; - Destination destination; - - int msec; - }; - struct FrameEvent { - QImage image; - QByteArray hash; - int msec; - }; - QList m_mouseEvents; - QList m_keyEvents; - - QList m_savedMouseEvents; - QList m_savedKeyEvents; - QList m_savedFrameEvents; - bool filterEvents; - - QDeclarativeViewer::ScriptOptions options; - int testscriptidx; - QDeclarativeVisualTest *testscript; - - bool hasCompleted; - bool hasFailed; -}; - - -QT_END_NAMESPACE - -#endif // QFXTESTER_H diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index a7eb6f5..ba283b6 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -15,13 +15,13 @@ contains(QT_CONFIG, opengl) { # Input HEADERS += qmlruntime.h \ proxysettings.h \ - qfxtester.h \ + qdeclarativetester.h \ deviceorientation.h \ qdeclarativefolderlistmodel.h SOURCES += main.cpp \ qmlruntime.cpp \ proxysettings.cpp \ - qfxtester.cpp \ + qdeclarativetester.cpp \ qdeclarativefolderlistmodel.cpp RESOURCES = qmlruntime.qrc maemo5 { diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 44cab97..1ab528e 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -95,7 +95,7 @@ #include #endif -#include +#include #if defined (Q_OS_SYMBIAN) #define SYMBIAN_NETWORK_INIT -- cgit v0.12 From 6905c23c8363ce3f6698b0bc81dc81eef0f8de20 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 31 Mar 2010 14:25:23 +1000 Subject: Improve flipable example. --- doc/src/snippets/declarative/flipable.qml | 37 +++++++++++++++++++ examples/declarative/flipable/back.png | Bin 5048 -> 0 bytes examples/declarative/flipable/content/5_heart.png | Bin 0 -> 3872 bytes examples/declarative/flipable/content/9_club.png | Bin 0 -> 6135 bytes examples/declarative/flipable/content/Card.qml | 38 ++++++++++++++++++++ examples/declarative/flipable/content/back.png | Bin 0 -> 1418 bytes examples/declarative/flipable/flipable-example.qml | 40 +++++---------------- examples/declarative/flipable/front.png | Bin 6431 -> 0 bytes .../graphicsitems/qdeclarativeflipable.cpp | 2 +- 9 files changed, 84 insertions(+), 33 deletions(-) create mode 100644 doc/src/snippets/declarative/flipable.qml delete mode 100644 examples/declarative/flipable/back.png create mode 100644 examples/declarative/flipable/content/5_heart.png create mode 100644 examples/declarative/flipable/content/9_club.png create mode 100644 examples/declarative/flipable/content/Card.qml create mode 100644 examples/declarative/flipable/content/back.png delete mode 100644 examples/declarative/flipable/front.png diff --git a/doc/src/snippets/declarative/flipable.qml b/doc/src/snippets/declarative/flipable.qml new file mode 100644 index 0000000..c837ebc --- /dev/null +++ b/doc/src/snippets/declarative/flipable.qml @@ -0,0 +1,37 @@ +//! [0] +import Qt 4.6 + +Flipable { + id: flipable + width: 240 + height: 240 + + property int angle: 0 + property bool flipped: false + + front: Image { source: "front.png" } + back: Image { source: "back.png" } + + transform: Rotation { + origin.x: flipable.width/2; origin.y: flipable.height/2 + axis.x: 0; axis.y: 1; axis.z: 0 // rotate around y-axis + angle: flipable.angle + } + + states: State { + name: "back" + PropertyChanges { target: flipable; angle: 180 } + when: flipable.flipped + } + + transitions: Transition { + NumberAnimation { properties: "angle"; duration: 1000 } + } + + MouseArea { + anchors.fill: parent + onClicked: flipable.flipped = !flipable.flipped + } +} +//! [0] + diff --git a/examples/declarative/flipable/back.png b/examples/declarative/flipable/back.png deleted file mode 100644 index 0b4cafc..0000000 Binary files a/examples/declarative/flipable/back.png and /dev/null differ diff --git a/examples/declarative/flipable/content/5_heart.png b/examples/declarative/flipable/content/5_heart.png new file mode 100644 index 0000000..fb59d81 Binary files /dev/null and b/examples/declarative/flipable/content/5_heart.png differ diff --git a/examples/declarative/flipable/content/9_club.png b/examples/declarative/flipable/content/9_club.png new file mode 100644 index 0000000..2545001 Binary files /dev/null and b/examples/declarative/flipable/content/9_club.png differ diff --git a/examples/declarative/flipable/content/Card.qml b/examples/declarative/flipable/content/Card.qml new file mode 100644 index 0000000..6b8fa69 --- /dev/null +++ b/examples/declarative/flipable/content/Card.qml @@ -0,0 +1,38 @@ +import Qt 4.6 + +Flipable { + id: container + + property alias image: frontImage.source + property bool flipped: true + property int xAxis: 0 + property int yAxis: 0 + property int angle: 0 + + width: front.width; height: front.height; state: "back" + + front: Image { id: frontImage; smooth: true } + back: Image { source: "back.png"; smooth: true } + + MouseArea { anchors.fill: parent; onClicked: container.flipped = !container.flipped } + + transform: Rotation { + id: rotation; origin.x: container.width / 2; origin.y: container.height / 2 + axis.x: container.xAxis; axis.y: container.yAxis; axis.z: 0 + } + + states: State { + name: "back"; when: container.flipped + PropertyChanges { target: rotation; angle: container.angle } + } + + transitions: Transition { + ParallelAnimation { + NumberAnimation { target: rotation; properties: "angle"; duration: 600 } + SequentialAnimation { + NumberAnimation { target: container; property: "scale"; to: 0.75; duration: 300 } + NumberAnimation { target: container; property: "scale"; to: 1.0; duration: 300 } + } + } + } +} diff --git a/examples/declarative/flipable/content/back.png b/examples/declarative/flipable/content/back.png new file mode 100644 index 0000000..f715d74 Binary files /dev/null and b/examples/declarative/flipable/content/back.png differ diff --git a/examples/declarative/flipable/flipable-example.qml b/examples/declarative/flipable/flipable-example.qml index c837ebc..eebc721 100644 --- a/examples/declarative/flipable/flipable-example.qml +++ b/examples/declarative/flipable/flipable-example.qml @@ -1,37 +1,13 @@ -//! [0] import Qt 4.6 +import "content" -Flipable { - id: flipable - width: 240 - height: 240 +Rectangle { + id: window; width: 480; height: 320 + color: "darkgreen" - property int angle: 0 - property bool flipped: false - - front: Image { source: "front.png" } - back: Image { source: "back.png" } - - transform: Rotation { - origin.x: flipable.width/2; origin.y: flipable.height/2 - axis.x: 0; axis.y: 1; axis.z: 0 // rotate around y-axis - angle: flipable.angle - } - - states: State { - name: "back" - PropertyChanges { target: flipable; angle: 180 } - when: flipable.flipped - } - - transitions: Transition { - NumberAnimation { properties: "angle"; duration: 1000 } - } - - MouseArea { - anchors.fill: parent - onClicked: flipable.flipped = !flipable.flipped + Row { + anchors.centerIn: parent; spacing: 30 + Card { image: "content/9_club.png"; angle: 180; yAxis: 1 } + Card { image: "content/5_heart.png"; angle: 540; xAxis: 1 } } } -//! [0] - diff --git a/examples/declarative/flipable/front.png b/examples/declarative/flipable/front.png deleted file mode 100644 index 796b605..0000000 Binary files a/examples/declarative/flipable/front.png and /dev/null differ diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp index e670d3e..ccefc70 100644 --- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp @@ -75,7 +75,7 @@ public: Here is a Flipable that flips whenever it is clicked: - \snippet examples/declarative/flipable/flipable-example.qml 0 + \snippet doc/src/snippets/declarative/flipable.qml 0 \image flipable.gif -- cgit v0.12 From 8ee60825b4fa864ef0f826e6452a6340ed8ebb86 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 31 Mar 2010 14:26:52 +1000 Subject: Minor cleanup. --- examples/declarative/clocks/clocks.qml | 7 +++---- examples/declarative/clocks/content/Clock.qml | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/declarative/clocks/clocks.qml b/examples/declarative/clocks/clocks.qml index 624748a..c5aa1dc 100644 --- a/examples/declarative/clocks/clocks.qml +++ b/examples/declarative/clocks/clocks.qml @@ -2,12 +2,11 @@ import Qt 4.6 import "content" Rectangle { - width: childrenRect.width - height: childrenRect.height + width: 640; height: 240 color: "#646464" - Grid { - columns: 3 + Row { + anchors.centerIn: parent Clock { city: "New York"; shift: -4 } Clock { city: "Mumbai"; shift: 5.5 } Clock { city: "Tokyo"; shift: 9 } diff --git a/examples/declarative/clocks/content/Clock.qml b/examples/declarative/clocks/content/Clock.qml index 75a1cf5..90c6be8 100644 --- a/examples/declarative/clocks/content/Clock.qml +++ b/examples/declarative/clocks/content/Clock.qml @@ -74,7 +74,7 @@ Item { } Text { - id: cityLabel; font.bold: true; font.pixelSize: 14; y:200; color: "white" - anchors.horizontalCenter: parent.horizontalCenter + id: cityLabel; font.bold: true; font.pixelSize: 14; y: 200; color: "white" + anchors.horizontalCenter: parent.horizontalCenter; style: Text.Raised; styleColor: "black" } } -- cgit v0.12 From 1bb04f8c0675449a851cf636680951bd0a142507 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 31 Mar 2010 14:53:29 +1000 Subject: doc bug relationships more clearly --- .../auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp | 4 ++-- .../declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp | 2 +- .../declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp b/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp index 6b7d57f..16ae7fc 100644 --- a/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp +++ b/tests/auto/declarative/qdeclarativeanchors/tst_qdeclarativeanchors.cpp @@ -390,7 +390,7 @@ void tst_qdeclarativeanchors::fill() QCOMPARE(rect->y(), 0.0 + 30.0); QCOMPARE(rect->width(), 200.0 - 10.0 - 20.0); QCOMPARE(rect->height(), 200.0 - 30.0 - 40.0); - //Alter Offsets (QTBUG-6631) + //Alter Offsets (tests QTBUG-6631) rect->anchors()->setLeftMargin(20.0); rect->anchors()->setRightMargin(0.0); rect->anchors()->setBottomMargin(0.0); @@ -411,7 +411,7 @@ void tst_qdeclarativeanchors::centerIn() QDeclarativeRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); QCOMPARE(rect->x(), 75.0 + 10); QCOMPARE(rect->y(), 75.0 + 30); - //Alter Offsets (QTBUG-6631) + //Alter Offsets (tests QTBUG-6631) rect->anchors()->setHorizontalCenterOffset(-20.0); rect->anchors()->setVerticalCenterOffset(-10.0); QCOMPARE(rect->x(), 75.0 - 20.0); diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 84e7182..b6f55dd 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -523,7 +523,7 @@ void tst_qdeclarativetextinput::navigation() QVERIFY(input->hasFocus() == false); simulateKey(canvas, Qt::Key_Right); QVERIFY(input->hasFocus() == true); - //QT-2944: If text is selected, then we should deselect first. + //QT-2944: If text is selected, ensure we deselect upon cursor motion input->setCursorPosition(input->text().length()); input->setSelectionStart(0); input->setSelectionEnd(input->text().length()); diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp index a5cb16f..4e254eb 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp @@ -432,7 +432,6 @@ void tst_qdeclarativevaluetypes::autoBindingRemoval() object->setProperty("value", QVariant(92)); - //QEXPECT_FAIL("", "QT-2920", Continue); QCOMPARE(object->rect().x(), 42); delete object; -- cgit v0.12 From e178cf86ff5007d5af31181d064b1bf824ffbc33 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 31 Mar 2010 15:27:17 +1000 Subject: Fix snapping in listview. --- .../graphicsitems/qdeclarativegridview.cpp | 4 +- .../graphicsitems/qdeclarativelistview.cpp | 46 +++++++++++++++------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 12ede34..30f04f6 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -815,7 +815,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = maxExtent; } - if ((maxDistance > 0 || overShoot) && (snapMode != QDeclarativeGridView::NoSnap || highlightRange == QDeclarativeGridView::StrictlyEnforceRange)) { + if (maxDistance > 0 || overShoot) { // This mode requires the grid to stop exactly on a row boundary. qreal v = velocity; if (maxVelocity != -1 && maxVelocity < qAbs(v)) { @@ -1856,6 +1856,8 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) if (d->currentItem) d->currentItem->index = d->currentIndex; emit currentIndexChanged(); + } else if (d->currentIndex < 0) { + d->updateCurrent(0); } emit countChanged(); return; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index cbf8eac..308612f 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -305,7 +305,7 @@ public: if (item->index == -1) continue; qreal itemTop = item->position(); - if (item->index == model->count()-1 || (itemTop+item->size()/2 >= pos)) + if (itemTop+item->size()/2 >= pos && itemTop <= pos) return item->position(); } if (visibleItems.count()) { @@ -1153,7 +1153,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m maxDistance = qAbs(minExtent - data.move.value()); } } - if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) + if (snapMode == QDeclarativeListView::NoSnap && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = minExtent; } else { if (data.move.value() > maxExtent) { @@ -1164,10 +1164,10 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m maxDistance = qAbs(maxExtent - data.move.value()); } } - if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) + if (snapMode == QDeclarativeListView::NoSnap && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = maxExtent; } - if ((maxDistance > 0 || overShoot) && (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)) { + if (maxDistance > 0 || overShoot) { // These modes require the list to stop exactly on an item boundary. // The initial flick will estimate the boundary to stop on. // Since list items can have variable sizes, the boundary will be @@ -1183,18 +1183,35 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m // the initial flick - estimate boundary qreal accel = deceleration; qreal v2 = v * v; - if (maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) { - // + averageSize/4 to encourage moving at least one item in the flick direction - qreal dist = v2 / (accel * 2.0) + averageSize/4; - if (v > 0) - dist = -dist; + overshootDist = 0.0; + // + averageSize/4 to encourage moving at least one item in the flick direction + qreal dist = v2 / (accel * 2.0) + averageSize/4; + if (maxDistance > 0) + dist = qMin(dist, maxDistance); + if (v > 0) + dist = -dist; + if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeListView::SnapOneItem) { data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; + if (overShoot) { + if (data.flickTarget >= minExtent) { + overshootDist = overShootDistance(v, vSize); + data.flickTarget += overshootDist; + } else if (data.flickTarget <= maxExtent) { + overshootDist = overShootDistance(v, vSize); + data.flickTarget -= overshootDist; + } + } dist = -data.flickTarget + data.move.value(); accel = v2 / (2.0f * qAbs(dist)); - overshootDist = 0.0; - } else { - data.flickTarget = velocity > 0 ? minExtent : maxExtent; - overshootDist = overShoot ? overShootDistance(v, vSize) : 0; + } else if (overShoot) { + data.flickTarget = data.move.value() - dist; + if (data.flickTarget >= minExtent) { + overshootDist = overShootDistance(v, vSize); + data.flickTarget += overshootDist; + } else if (data.flickTarget <= maxExtent) { + overshootDist = overShootDistance(v, vSize); + data.flickTarget -= overshootDist; + } } timeline.reset(data.move); timeline.accel(data.move, v, accel, maxDistance + overshootDist); @@ -2381,6 +2398,8 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) if (d->currentItem) d->currentItem->index = d->currentIndex; emit currentIndexChanged(); + } else if (d->currentIndex < 0) { + d->updateCurrent(0); } emit countChanged(); return; @@ -2743,7 +2762,6 @@ void QDeclarativeListView::destroyingItem(QDeclarativeItem *item) void QDeclarativeListView::animStopped() { Q_D(QDeclarativeListView); - d->moveReason = QDeclarativeListViewPrivate::Other; d->bufferMode = QDeclarativeListViewPrivate::NoBuffer; } -- cgit v0.12 From a795a55cf2796a44cf30e002962ebad0588ef740 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 31 Mar 2010 08:36:16 +0200 Subject: QGraphicsEffect : Don't rely on the exposedArea when rendering the item into the cache. I forgot to change this line during fcb738161efc965e91c3d528c31ac77d3a05ac64 Task-number:QTBUG-9496 Reviewed-by:sroedal --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index e5471b0..20c9faa 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -11054,7 +11054,7 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP &newEffectTransform, false, true); } else if (deviceCoordinates) { // Device coordinates with info. - scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion, + scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0, info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform, info->drawItem); } else { -- cgit v0.12 From 93ae014d7ee06a6ebb701420fffef5895cd731c4 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 31 Mar 2010 06:28:59 +0200 Subject: Add a QGraphicsItem::updateMicroFocus() to QGraphicsItem. QGraphicsItem is no more lacking a way to notify the input method of a changed micro focus. Reviewed-by:denis Reviewed-by:simon hausmann --- src/gui/graphicsview/qgraphicsitem.cpp | 34 ++++++++++++ src/gui/graphicsview/qgraphicsitem.h | 4 ++ src/gui/kernel/qapplication.h | 1 + tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 71 ++++++++++++++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 02a1ecb..71f248d 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -731,6 +731,9 @@ #include #include #include +#ifndef QT_NO_ACCESSIBILITY +# include "qaccessible.h" +#endif #include #include @@ -738,6 +741,7 @@ #include #include #include +#include #ifdef Q_WS_X11 #include @@ -7305,6 +7309,31 @@ void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints) } /*! + Updates the item's micro focus. + + \since 4.7 + + \sa QInputContext +*/ +void QGraphicsItem::updateMicroFocus() +{ +#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) + if (QWidget *fw = qApp->focusWidget()) { + if (qt_widget_private(fw)->ic || qApp->d_func()->inputContext) { + if (QInputContext *ic = fw->inputContext()) { + if (ic) + ic->update(); + } + } +#ifndef QT_NO_ACCESSIBILITY + // ##### is this correct + QAccessible::updateAccessibility(fw, 0, QAccessible::StateChanged); +#endif + } +#endif +} + +/*! This virtual function is called by QGraphicsItem to notify custom items that some part of the item's state changes. By reimplementing this function, your can react to a change, and in some cases, (depending on \a @@ -7580,6 +7609,11 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) } } +void QGraphicsObject::updateMicroFocus() +{ + QGraphicsItem::updateMicroFocus(); +} + void QGraphicsItemPrivate::append(QDeclarativeListProperty *list, QGraphicsObject *item) { QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0); diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 2c45b62..9cc75af 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -424,6 +424,7 @@ public: void removeSceneEventFilter(QGraphicsItem *filterItem); protected: + void updateMicroFocus(); virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event); virtual bool sceneEvent(QEvent *event); virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); @@ -571,6 +572,9 @@ public: void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags()); void ungrabGesture(Qt::GestureType type); +protected Q_SLOTS: + void updateMicroFocus(); + Q_SIGNALS: void parentChanged(); void opacityChanged(); diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index ee74350..c21b982 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -376,6 +376,7 @@ private: Q_DECLARE_PRIVATE(QApplication) friend class QGraphicsWidget; + friend class QGraphicsItem; friend class QGraphicsScene; friend class QGraphicsScenePrivate; friend class QWidget; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index be50182..3d86c48 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include "../../shared/util.h" @@ -424,6 +425,7 @@ private slots: void modality_keyEvents(); void itemIsInFront(); void scenePosChange(); + void updateMicroFocus(); // task specific tests below me void task141694_textItemEnsureVisible(); @@ -9988,6 +9990,75 @@ void tst_QGraphicsItem::scenePosChange() QCOMPARE(child2->changes.count(QGraphicsItem::ItemScenePositionHasChanged), 0); } +class MyInputContext : public QInputContext +{ +public: + MyInputContext() : nbUpdates(0) {} + ~MyInputContext() {} + + QString identifierName() { return QString(); } + QString language() { return QString(); } + + void reset() {} + + bool isComposing() const { return false; } + + void update() { nbUpdates++; } + + bool nbUpdates; +}; + +class MyInputWidget : public QGraphicsWidget +{ +public: + MyInputWidget() + { + setFlag(QGraphicsItem::ItemIsFocusable, true); + setFlag(QGraphicsItem::ItemAcceptsInputMethod, true); + } + void mousePressEvent(QGraphicsSceneMouseEvent *event) + { + event->accept(); + } + + void doUpdateMicroFocus() + { + updateMicroFocus(); + } +}; + +void tst_QGraphicsItem::updateMicroFocus() +{ + QGraphicsScene scene; + QWidget parent; + QGridLayout layout; + parent.setLayout(&layout); + QGraphicsView view(&scene); + QGraphicsView view2(&scene); + layout.addWidget(&view, 0, 0); + layout.addWidget(&view2, 0, 1); + MyInputContext ic2; + view2.setInputContext(&ic2); + MyInputContext ic; + view.setInputContext(&ic); + MyInputWidget input; + input.setPos(0, 0); + input.resize(150, 150); + scene.addItem(&input); + input.setFocus(); + parent.show(); + view.setFocus(); + qApp->setAutoSipEnabled(true); + QApplication::setActiveWindow(&parent); + QTest::qWaitForWindowShown(&parent); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&parent)); + input.doUpdateMicroFocus(); + QApplication::processEvents(); + QCOMPARE(ic.nbUpdates, 1); + //No update since view2 does not have the focus. + QCOMPARE(ic2.nbUpdates, 0); +} + void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() { struct Item : public QGraphicsTextItem -- cgit v0.12 From 93135ba7f52e0ccbbcd8bda390a69d089da62b83 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 31 Mar 2010 12:12:43 +0200 Subject: Revert 4.6 commits that shouldn't be in 4.7. Commits reverted: 880e4935410769b8337d75f219bef70493c4bb2c 82a306e7dda06909801f576bbbbebb59dc41c563 6cb935dd89a391f792f8ad42012b5c7c38712f17 ebd1c45822aca087be994c898cfb01cd41599429 4e4c0055d59978850796ff8c1b5015e17459e8d2 --- src/gui/graphicsview/qgraphicsitem.cpp | 103 +++++++++++++++++++++ src/gui/graphicsview/qgraphicsitem.h | 7 ++ src/gui/graphicsview/qgraphicsitem_p.h | 68 ++++++++++++++ src/gui/graphicsview/qgraphicswidget.cpp | 15 ++- src/gui/graphicsview/qgraphicswidget.h | 2 + src/gui/graphicsview/qgraphicswidget_p.cpp | 51 ++++++++++ src/gui/graphicsview/qgraphicswidget_p.h | 9 ++ tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 35 ++++++- 8 files changed, 287 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 65ccf72..e5471b0 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -5248,6 +5248,8 @@ void QGraphicsItemPrivate::addChild(QGraphicsItem *child) needSortChildren = 1; // ### maybe 0 child->d_ptr->siblingIndex = children.size(); children.append(child); + if (isObject) + emit static_cast(q_ptr)->childrenChanged(); } /*! @@ -5270,6 +5272,8 @@ void QGraphicsItemPrivate::removeChild(QGraphicsItem *child) // the child is not guaranteed to be at the index after the list is sorted. // (see ensureSortedChildren()). child->d_ptr->siblingIndex = -1; + if (isObject) + emit static_cast(q_ptr)->childrenChanged(); } /*! @@ -7477,6 +7481,88 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) } } +void QGraphicsItemPrivate::append(QDeclarativeListProperty *list, QGraphicsObject *item) +{ + QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0); +} + +/*! + Returns a list of this item's children. + + The items are sorted by stacking order. This takes into account both the + items' insertion order and their Z-values. + +*/ +QDeclarativeListProperty QGraphicsItemPrivate::childrenList() +{ + Q_Q(QGraphicsItem); + if (isObject) { + QGraphicsObject *that = static_cast(q); + return QDeclarativeListProperty(that, &children, QGraphicsItemPrivate::append); + } else { + //QGraphicsItem is not supported for this property + return QDeclarativeListProperty(); + } +} + +/*! + \internal + Returns the width of the item + Reimplemented by QGraphicsWidget +*/ +qreal QGraphicsItemPrivate::width() const +{ + return 0; +} + +/*! + \internal + Set the width of the item + Reimplemented by QGraphicsWidget +*/ +void QGraphicsItemPrivate::setWidth(qreal w) +{ + Q_UNUSED(w); +} + +/*! + \internal + Reset the width of the item + Reimplemented by QGraphicsWidget +*/ +void QGraphicsItemPrivate::resetWidth() +{ +} + +/*! + \internal + Returns the height of the item + Reimplemented by QGraphicsWidget +*/ +qreal QGraphicsItemPrivate::height() const +{ + return 0; +} + +/*! + \internal + Set the height of the item + Reimplemented by QGraphicsWidget +*/ +void QGraphicsItemPrivate::setHeight(qreal h) +{ + Q_UNUSED(h); +} + +/*! + \internal + Reset the height of the item + Reimplemented by QGraphicsWidget +*/ +void QGraphicsItemPrivate::resetHeight() +{ +} + /*! \property QGraphicsObject::parent \brief the parent of the item @@ -7663,6 +7749,23 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) \sa scale, rotation, QGraphicsItem::transformOriginPoint() */ +/*! + \fn void QGraphicsObject::widthChanged() + \internal +*/ + +/*! + \fn void QGraphicsObject::heightChanged() + \internal +*/ + +/*! + + \fn QGraphicsObject::childrenChanged() + + This signal gets emitted whenever the children list changes + \internal +*/ /*! \class QAbstractGraphicsShapeItem diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 56f94a2..22be64c 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -547,6 +547,10 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint) + Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), QDeclarativeListProperty children READ childrenList DESIGNABLE false NOTIFY childrenChanged) + Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL) + Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL) + Q_CLASSINFO("DefaultProperty", "children") Q_INTERFACES(QGraphicsItem) public: QGraphicsObject(QGraphicsItem *parent = 0); @@ -571,6 +575,9 @@ Q_SIGNALS: void zChanged(); void rotationChanged(); void scaleChanged(); + void childrenChanged(); + void widthChanged(); + void heightChanged(); protected: QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index c256f63..73b8f04 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -71,6 +71,63 @@ QT_BEGIN_NAMESPACE class QGraphicsItemPrivate; +#ifndef QDECLARATIVELISTPROPERTY +#define QDECLARATIVELISTPROPERTY +template +class QDeclarativeListProperty { +public: + typedef void (*AppendFunction)(QDeclarativeListProperty *, T*); + typedef int (*CountFunction)(QDeclarativeListProperty *); + typedef T *(*AtFunction)(QDeclarativeListProperty *, int); + typedef void (*ClearFunction)(QDeclarativeListProperty *); + + QDeclarativeListProperty() + : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {} + QDeclarativeListProperty(QObject *o, QList &list) + : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at), + clear(qlist_clear), dummy1(0), dummy2(0) {} + QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0, + ClearFunction r = 0) + : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {} + + bool operator==(const QDeclarativeListProperty &o) const { + return object == o.object && + data == o.data && + append == o.append && + count == o.count && + at == o.at && + clear == o.clear; + } + + QObject *object; + void *data; + + AppendFunction append; + + CountFunction count; + AtFunction at; + + ClearFunction clear; + + void *dummy1; + void *dummy2; + +private: + static void qlist_append(QDeclarativeListProperty *p, T *v) { + ((QList *)p->data)->append(v); + } + static int qlist_count(QDeclarativeListProperty *p) { + return ((QList *)p->data)->count(); + } + static T *qlist_at(QDeclarativeListProperty *p, int idx) { + return ((QList *)p->data)->at(idx); + } + static void qlist_clear(QDeclarativeListProperty *p) { + return ((QList *)p->data)->clear(); + } +}; +#endif + class QGraphicsItemCache { public: @@ -238,6 +295,7 @@ public: void resolveDepth(); void addChild(QGraphicsItem *child); void removeChild(QGraphicsItem *child); + QDeclarativeListProperty childrenList(); void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, const QVariant *thisPointerVariant); void childrenBoundingRectHelper(QTransform *x, QRectF *rect); @@ -424,11 +482,21 @@ public: inline QTransform transformToParent() const; inline void ensureSortedChildren(); + static void append(QDeclarativeListProperty *list, QGraphicsObject *item); static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b); void ensureSequentialSiblingIndex(); inline void sendScenePosChange(); virtual void siblingOrderChange(); + // Private Properties + virtual qreal width() const; + virtual void setWidth(qreal); + virtual void resetWidth(); + + virtual qreal height() const; + virtual void setHeight(qreal); + virtual void resetHeight(); + QRectF childrenBoundingRect; QRectF needsRepaint; QMap paintedViewBoundingRects; diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index edb648b..8e439be 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -324,6 +324,14 @@ void QGraphicsWidget::resize(const QSizeF &size) */ /*! + + \fn QGraphicsWidget::geometryChanged() + + This signal gets emitted whenever the geometry of the item changes + \internal +*/ + +/*! \property QGraphicsWidget::geometry \brief the geometry of the widget @@ -384,13 +392,17 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) } QSizeF oldSize = size(); QGraphicsLayoutItem::setGeometry(newGeom); - + emit geometryChanged(); // Send resize event bool resized = newGeom.size() != oldSize; if (resized) { QGraphicsSceneResizeEvent re; re.setOldSize(oldSize); re.setNewSize(newGeom.size()); + if (oldSize.width() != newGeom.size().width()) + emit widthChanged(); + if (oldSize.height() != newGeom.size().height()) + emit heightChanged(); QApplication::sendEvent(this, &re); } } @@ -795,6 +807,7 @@ void QGraphicsWidget::setLayout(QGraphicsLayout *l) l->setParentLayoutItem(this); l->d_func()->reparentChildItems(this); l->invalidate(); + emit layoutChanged(); } /*! diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 87c669b..a22b642 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -83,6 +83,7 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle) Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground) + Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); @@ -180,6 +181,7 @@ public: Q_SIGNALS: void geometryChanged(); + void layoutChanged(); public Q_SLOTS: bool close(); diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 1835c74..6e397b6 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -44,6 +44,7 @@ #ifndef QT_NO_GRAPHICSVIEW #include +#include #include "qgraphicswidget_p.h" #include "qgraphicslayout.h" #include "qgraphicsscene_p.h" @@ -825,6 +826,56 @@ void QGraphicsWidgetPrivate::setLayout_helper(QGraphicsLayout *l) } } +qreal QGraphicsWidgetPrivate::width() const +{ + Q_Q(const QGraphicsWidget); + return q->geometry().width(); +} + +void QGraphicsWidgetPrivate::setWidth(qreal w) +{ + if (qIsNaN(w)) + return; + Q_Q(QGraphicsWidget); + if (q->geometry().width() == w) + return; + + QRectF oldGeom = q->geometry(); + + q->setGeometry(QRectF(q->x(), q->y(), w, height())); +} + +void QGraphicsWidgetPrivate::resetWidth() +{ + Q_Q(QGraphicsWidget); + q->setGeometry(QRectF(q->x(), q->y(), 0, height())); +} + +qreal QGraphicsWidgetPrivate::height() const +{ + Q_Q(const QGraphicsWidget); + return q->geometry().height(); +} + +void QGraphicsWidgetPrivate::setHeight(qreal h) +{ + if (qIsNaN(h)) + return; + Q_Q(QGraphicsWidget); + if (q->geometry().height() == h) + return; + + QRectF oldGeom = q->geometry(); + + q->setGeometry(QRectF(q->x(), q->y(), width(), h)); +} + +void QGraphicsWidgetPrivate::resetHeight() +{ + Q_Q(QGraphicsWidget); + q->setGeometry(QRectF(q->x(), q->y(), width(), 0)); +} + QT_END_NAMESPACE #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index 3ab8737..7116a23 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -131,6 +131,15 @@ public: void windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event); bool hasDecoration() const; + // Private Properties + qreal width() const; + void setWidth(qreal); + void resetWidth(); + + qreal height() const; + void setHeight(qreal); + void resetHeight(); + // State inline int attributeToBitIndex(Qt::WidgetAttribute att) const { diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 2a1c55a..3313240 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -111,6 +111,8 @@ private slots: void fontPropagationSceneChange(); void geometry_data(); void geometry(); + void width(); + void height(); void getContentsMargins_data(); void getContentsMargins(); void initStyleOption_data(); @@ -766,14 +768,42 @@ void tst_QGraphicsWidget::geometry() { SubQGraphicsWidget widget; QCOMPARE(widget.geometry(), QRectF(widget.pos(), widget.size())); - + QSignalSpy spy(&widget, SIGNAL(geometryChanged())); QFETCH(QPointF, pos); QFETCH(QSizeF, size); widget.setPos(pos); widget.resize(size); + if (!size.isNull()) + QCOMPARE(spy.count(), 1); QCOMPARE(widget.geometry(), QRectF(pos, size)); } +void tst_QGraphicsWidget::width() +{ + QGraphicsWidget w; + QCOMPARE(w.property("width").toReal(), qreal(0)); + QSignalSpy spy(&w, SIGNAL(widthChanged())); + w.setProperty("width", qreal(50)); + QCOMPARE(w.property("width").toReal(), qreal(50)); + QCOMPARE(spy.count(), 1); + //calling old school setGeometry should work too + w.setGeometry(0, 0, 200, 200); + QCOMPARE(spy.count(), 2); +} + +void tst_QGraphicsWidget::height() +{ + QGraphicsWidget w; + QCOMPARE(w.property("height").toReal(), qreal(0)); + QSignalSpy spy(&w, SIGNAL(heightChanged())); + w.setProperty("height", qreal(50)); + QCOMPARE(w.property("height").toReal(), qreal(50)); + QCOMPARE(spy.count(), 1); + //calling old school setGeometry should work too + w.setGeometry(0, 0, 200, 200); + QCOMPARE(spy.count(), 2); +} + void tst_QGraphicsWidget::getContentsMargins_data() { QTest::addColumn("left"); @@ -913,6 +943,7 @@ void tst_QGraphicsWidget::layout() layout->addItem(item); children.append(item); } + QSignalSpy spy(&widget, SIGNAL(layoutChanged())); widget.setLayout(layout); QTRY_COMPARE(widget.layout(), static_cast(layout)); @@ -921,7 +952,7 @@ void tst_QGraphicsWidget::layout() QCOMPARE(item->parentWidget(), (QGraphicsWidget *)&widget); QVERIFY(item->geometry() != QRectF(0, 0, -1, -1)); } - + QCOMPARE(spy.count(), 1); // don't crash widget.setLayout(0); } -- cgit v0.12 From 93ee746f5b63670af280dfe2e8acaebeb48723b8 Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 31 Mar 2010 12:27:55 +0200 Subject: Optimize QDeclarativeEngine::importExtension Avoid double initialization of QPluginLoader and assert that modules are imported with a stable uri --- src/declarative/qml/qdeclarativeengine.cpp | 51 ++++++++++++++++++------------ 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index bb742ee..5058d4d 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -81,6 +81,7 @@ #include #include #include +#include #include #include #include @@ -342,7 +343,8 @@ void QDeclarativeEnginePrivate::clear(SimpleList &pss) } Q_GLOBAL_STATIC(QDeclarativeEngineDebugServer, qmlEngineDebugServer); -Q_GLOBAL_STATIC(QSet, qmlEnginePluginsWithRegisteredTypes); +typedef QMap StringStringMap; +Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri void QDeclarativeEnginePrivate::init() { @@ -1838,34 +1840,43 @@ bool QDeclarativeEngine::importExtension(const QString &fileName, const QString qDebug() << "QDeclarativeEngine::importExtension" << uri << "from" << fileName; QFileInfo fileInfo(fileName); const QString absoluteFilePath = fileInfo.absoluteFilePath(); - QPluginLoader loader(absoluteFilePath); - if (QDeclarativeExtensionInterface *iface = qobject_cast(loader.instance())) { - const QByteArray bytes = uri.toUtf8(); - const char *moduleId = bytes.constData(); + QDeclarativeEnginePrivate *d = QDeclarativeEnginePrivate::get(this); + bool engineInitialized = d->initializedPlugins.contains(absoluteFilePath); + bool typesRegistered = qmlEnginePluginsWithRegisteredTypes()->contains(absoluteFilePath); - // ### this code should probably be protected with a mutex. - if (! qmlEnginePluginsWithRegisteredTypes()->contains(absoluteFilePath)) { - // types should only be registered once (they're global). + if (typesRegistered) { + Q_ASSERT_X(qmlEnginePluginsWithRegisteredTypes()->value(absoluteFilePath) == uri, + "QDeclarativeEngine::importExtension", + "Internal error: Plugin imported previously with different uri"); + } - qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath); - iface->registerTypes(moduleId); - } + if (!engineInitialized || !typesRegistered) { + QPluginLoader loader(absoluteFilePath); - QDeclarativeEnginePrivate *d = QDeclarativeEnginePrivate::get(this); + if (QDeclarativeExtensionInterface *iface = qobject_cast(loader.instance())) { - if (! d->initializedPlugins.contains(absoluteFilePath)) { - // things on the engine (eg. adding new global objects) have to be done for every engine. + const QByteArray bytes = uri.toUtf8(); + const char *moduleId = bytes.constData(); + if (!typesRegistered) { - // protect against double initialization - d->initializedPlugins.insert(absoluteFilePath); - iface->initializeEngine(this, moduleId); - } + // ### this code should probably be protected with a mutex. + qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, uri); + iface->registerTypes(moduleId); + } + if (!engineInitialized) { + // things on the engine (eg. adding new global objects) have to be done for every engine. - return true; + // protect against double initialization + d->initializedPlugins.insert(absoluteFilePath); + iface->initializeEngine(this, moduleId); + } + } else { + return false; + } } - return false; + return true; } /*! -- cgit v0.12 From 582cbf2d92addb34088830a3de97c08ddb147e30 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Mar 2010 16:54:26 +0200 Subject: Add QDateTime members that operate on 64-bit milliseconds. This complements QDateTime::currentMsecsSinceEpoch. Task-number: QTBUG-9017 Reviewed-by: Denis Dzyubenko --- src/corelib/tools/qdatetime.cpp | 117 ++++++++++++++++++++++++++++----- src/corelib/tools/qdatetime.h | 3 + tests/auto/qdatetime/tst_qdatetime.cpp | 69 +++++++++++++++++++ 3 files changed, 174 insertions(+), 15 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 54a4205..7628dd2 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2315,17 +2315,35 @@ void QDateTime::setTimeSpec(Qt::TimeSpec spec) } } -static uint toTime_tHelper(const QDate &utcDate, const QTime &utcTime) +qint64 toMsecsSinceEpoch_helper(qint64 jd, int msecs) { - int days = QDate(1970, 1, 1).daysTo(utcDate); - int secs = QTime().secsTo(utcTime); - if (days < 0 || (days == 0 && secs < 0)) - return uint(-1); + int days = jd - julianDayFromGregorianDate(1970, 1, 1); + qint64 retval = (qlonglong(days) * MSECS_PER_DAY) + msecs; + return retval; +} - qlonglong retval = (qlonglong(days) * SECS_PER_DAY) + secs; - if (retval >= Q_INT64_C(0xFFFFFFFF)) - return uint(-1); - return uint(retval); +/*! + \since 4.7 + + Returns the datetime as the number of milliseconds that have passed + since 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC). + + On systems that do not support time zones, this function will + behave as if local time were Qt::UTC. + + The behavior for this function is undefined if the datetime stored in + this object is not valid. However, for all valid dates, this function + returns a unique value. + + \sa toTime_t(), setMsecsSinceEpoch() +*/ +qint64 QDateTime::toMsecsSinceEpoch() const +{ + QDate utcDate; + QTime utcTime; + d->getUTC(utcDate, utcTime); + + return toMsecsSinceEpoch_helper(utcDate.jd, utcTime.ds()); } /*! @@ -2335,16 +2353,63 @@ static uint toTime_tHelper(const QDate &utcDate, const QTime &utcTime) On systems that do not support time zones, this function will behave as if local time were Qt::UTC. - \sa setTime_t() + \note This function returns a 32-bit unsigned integer, so it does not + support dates before 1970, but it does support dates after + 2038-01-19T03:14:06, which may not be valid time_t values. Be careful + when passing those time_t values to system functions, which could + interpret them as negative dates. + + If the date is outside the range 1970-01-01T00:00:00 to + 2106-02-07T06:28:14, this function returns -1 cast to an unsigned integer + (i.e., 0xFFFFFFFF). + + To get an extended range, use toMsecsSinceEpoch(). + + \sa toMsecsSinceEpoch(), setTime_t() */ uint QDateTime::toTime_t() const { - QDate utcDate; - QTime utcTime; - d->getUTC(utcDate, utcTime); + qint64 retval = toMsecsSinceEpoch() / 1000; + if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF)) + return uint(-1); + return uint(retval); +} - return toTime_tHelper(utcDate, utcTime); +/*! + \since 4.7 + + Sets the date and time given the number of \a mulliseconds that have + passed since 1970-01-01T00:00:00.000, Coordinated Universal Time + (Qt::UTC). On systems that do not support time zones this function + will behave as if local time were Qt::UTC. + + Note that there are possible values for \a msecs that lie outside the + valid range of QDateTime, both negative and positive. The behavior of + this function is undefined for those values. + + \sa toMsecsSinceEpoch(), setTime_t() +*/ +void QDateTime::setMsecsSinceEpoch(qint64 msecs) +{ + detach(); + + QDateTimePrivate::Spec oldSpec = d->spec; + + int ddays = msecs / MSECS_PER_DAY; + msecs %= MSECS_PER_DAY; + if (msecs < 0) { + // negative + --ddays; + msecs += MSECS_PER_DAY; + } + + d->date = QDate(1970, 1, 1).addDays(ddays); + d->time = QTime().addMSecs(msecs); + d->spec = QDateTimePrivate::UTC; + + if (oldSpec != QDateTimePrivate::UTC) + d->spec = d->getLocal(d->date, d->time); } /*! @@ -3088,6 +3153,27 @@ QDateTime QDateTime::fromTime_t(uint seconds) } /*! + \since 4.7 + + Returns a datetime whose date and time are the number of milliseconds \a msec + that have passed since 1970-01-01T00:00:00.000, Coordinated Universal + Time (Qt::UTC). On systems that do not support time zones, the time + will be set as if local time were Qt::UTC. + + Note that there are possible values for \a msecs that lie outside the valid + range of QDateTime, both negative and positive. The behavior of this + function is undefined for those values. + + \sa toTime_t(), setTime_t() +*/ +QDateTime QDateTime::fromMsecsSinceEpoch(qint64 msecs) +{ + QDateTime d; + d.setMsecsSinceEpoch(msecs); + return d; +} + +/*! \since 4.4 \internal @@ -3841,7 +3927,8 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) { QDate fakeDate = adjustDate(date); - time_t secsSince1Jan1970UTC = toTime_tHelper(fakeDate, time); + // won't overflow because of fakeDate + time_t secsSince1Jan1970UTC = toMsecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000; tm *brokenDown = 0; #if defined(Q_OS_WINCE) diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index ef5968e..248793b 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -230,10 +230,12 @@ public: QDate date() const; QTime time() const; Qt::TimeSpec timeSpec() const; + qint64 toMsecsSinceEpoch() const; uint toTime_t() const; void setDate(const QDate &date); void setTime(const QTime &time); void setTimeSpec(Qt::TimeSpec spec); + void setMsecsSinceEpoch(qint64 msecs); void setTime_t(uint secsSince1Jan1970UTC); #ifndef QT_NO_DATESTRING QString toString(Qt::DateFormat f = Qt::TextDate) const; @@ -267,6 +269,7 @@ public: static QDateTime fromString(const QString &s, const QString &format); #endif static QDateTime fromTime_t(uint secsSince1Jan1970UTC); + static QDateTime fromMsecsSinceEpoch(qint64 msecs); static qint64 currentMsecsSinceEpoch(); #ifdef QT3_SUPPORT diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index a6b9a5f..b04a1b5 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -83,6 +83,8 @@ private slots: void setTime(); void setTimeSpec(); void setTime_t(); + void setMsecsSinceEpoch_data(); + void setMsecsSinceEpoch(); void toString_enumformat(); void toString_strformat_data(); void toString_strformat(); @@ -437,6 +439,71 @@ void tst_QDateTime::setTime_t() } } +void tst_QDateTime::setMsecsSinceEpoch_data() +{ + QTest::addColumn("msecs"); + QTest::addColumn("utc"); + QTest::addColumn("european"); + + QTest::newRow("zero") + << Q_INT64_C(0) + << QDateTime(QDate(1970, 1, 1), QTime(), Qt::UTC) + << QDateTime(QDate(1970, 1, 1), QTime(1, 0)); + QTest::newRow("-1") + << Q_INT64_C(-1) + << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59, 999), Qt::UTC) + << QDateTime(QDate(1970, 1, 1), QTime(0, 59, 59, 999)); + QTest::newRow("123456789") + << Q_INT64_C(123456789) + << QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36, 789), Qt::UTC) + << QDateTime(QDate(1970, 1, 2), QTime(11, 17, 36, 789), Qt::LocalTime); + QTest::newRow("-123456789") + << Q_INT64_C(-123456789) + << QDateTime(QDate(1969, 12, 30), QTime(13, 42, 23, 211), Qt::UTC) + << QDateTime(QDate(1969, 12, 30), QTime(14, 42, 23, 211), Qt::LocalTime); + QTest::newRow("non-time_t") + << (Q_INT64_C(1000) << 32) + << QDateTime(QDate(2106, 2, 7), QTime(6, 28, 16), Qt::UTC) + << QDateTime(QDate(2106, 2, 7), QTime(7, 28, 16)); + QTest::newRow("very-large") + << (Q_INT64_C(123456) << 32) + << QDateTime(QDate(18772, 8, 15), QTime(1, 8, 14, 976), Qt::UTC) + << QDateTime(QDate(18772, 8, 15), QTime(3, 8, 14, 976)); + QTest::newRow("min_date") // julian day 0 is an invalid date for QDate + << Q_INT64_C(-210866716800000) + << QDateTime(QDate::fromJulianDay(1), QTime(), Qt::UTC) + << QDateTime(QDate::fromJulianDay(1), QTime(1, 0)); + QTest::newRow("max_date") // technically jd is unsigned, but fromJulianDay takes int + << Q_INT64_C(185331720376799999) + << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(21, 59, 59, 999), Qt::UTC) + << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(23, 59, 59, 999)); +} + +void tst_QDateTime::setMsecsSinceEpoch() +{ + QFETCH(qint64, msecs); + QFETCH(QDateTime, utc); + QFETCH(QDateTime, european); + + QDateTime dt; + dt.setTimeSpec(Qt::UTC); + dt.setMsecsSinceEpoch(msecs); + + QCOMPARE(dt, utc); + if (europeanTimeZone) { + QCOMPARE(dt.toLocalTime(), european); + } + + QCOMPARE(dt.toMsecsSinceEpoch(), msecs); + + if (quint64(msecs / 1000) < 0xFFFFFFFF) { + QCOMPARE(qint64(dt.toTime_t()), msecs / 1000); + } + + QDateTime reference(QDate(1970, 1, 1), QTime(), Qt::UTC); + QCOMPARE(dt, reference.addMSecs(msecs)); +} + void tst_QDateTime::toString_enumformat() { QDateTime dt1(QDate(1995, 5, 20), QTime(12, 34, 56)); @@ -953,6 +1020,8 @@ void tst_QDateTime::currentDateTimeUtc2() // and finally, the time_t should equal our number QCOMPARE(qint64(utc.toTime_t()), msec / 1000); QCOMPARE(qint64(local.toTime_t()), msec / 1000); + QCOMPARE(utc.toMsecsSinceEpoch(), msec); + QCOMPARE(local.toMsecsSinceEpoch(), msec); } void tst_QDateTime::toTime_t_data() -- cgit v0.12 From 32f002486941c0cba246e08491e9a0800942cded Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Mar 2010 10:40:25 +0200 Subject: Rename the xxxMsecsSinceEpoch functions to xxxMSecsSinceEpoch. Matches the addMSecs existing functions in QTime and QDateTime. Reviewed-by: Marius Storm-Olsen --- src/corelib/tools/qdatetime.cpp | 32 ++++++++++++++--------------- src/corelib/tools/qdatetime.h | 8 ++++---- src/corelib/tools/qelapsedtimer_generic.cpp | 4 ++-- tests/auto/qdatetime/tst_qdatetime.cpp | 18 ++++++++-------- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 7628dd2..69b232d 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2315,7 +2315,7 @@ void QDateTime::setTimeSpec(Qt::TimeSpec spec) } } -qint64 toMsecsSinceEpoch_helper(qint64 jd, int msecs) +qint64 toMSecsSinceEpoch_helper(qint64 jd, int msecs) { int days = jd - julianDayFromGregorianDate(1970, 1, 1); qint64 retval = (qlonglong(days) * MSECS_PER_DAY) + msecs; @@ -2335,15 +2335,15 @@ qint64 toMsecsSinceEpoch_helper(qint64 jd, int msecs) this object is not valid. However, for all valid dates, this function returns a unique value. - \sa toTime_t(), setMsecsSinceEpoch() + \sa toTime_t(), setMSecsSinceEpoch() */ -qint64 QDateTime::toMsecsSinceEpoch() const +qint64 QDateTime::toMSecsSinceEpoch() const { QDate utcDate; QTime utcTime; d->getUTC(utcDate, utcTime); - return toMsecsSinceEpoch_helper(utcDate.jd, utcTime.ds()); + return toMSecsSinceEpoch_helper(utcDate.jd, utcTime.ds()); } /*! @@ -2363,14 +2363,14 @@ qint64 QDateTime::toMsecsSinceEpoch() const 2106-02-07T06:28:14, this function returns -1 cast to an unsigned integer (i.e., 0xFFFFFFFF). - To get an extended range, use toMsecsSinceEpoch(). + To get an extended range, use toMSecsSinceEpoch(). - \sa toMsecsSinceEpoch(), setTime_t() + \sa toMSecsSinceEpoch(), setTime_t() */ uint QDateTime::toTime_t() const { - qint64 retval = toMsecsSinceEpoch() / 1000; + qint64 retval = toMSecsSinceEpoch() / 1000; if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF)) return uint(-1); return uint(retval); @@ -2388,9 +2388,9 @@ uint QDateTime::toTime_t() const valid range of QDateTime, both negative and positive. The behavior of this function is undefined for those values. - \sa toMsecsSinceEpoch(), setTime_t() + \sa toMSecsSinceEpoch(), setTime_t() */ -void QDateTime::setMsecsSinceEpoch(qint64 msecs) +void QDateTime::setMSecsSinceEpoch(qint64 msecs) { detach(); @@ -2878,7 +2878,7 @@ bool QDateTime::operator<(const QDateTime &other) const */ /*! - \fn qint64 QDateTime::currentMsecsSinceEpoch() + \fn qint64 QDateTime::currentMSecsSinceEpoch() \since 4.7 Returns the number of milliseconds since 1970-01-01T00:00:00 Universal @@ -2941,7 +2941,7 @@ QDateTime QDateTime::currentDateTimeUtc() return QDateTime(d, t, Qt::UTC); } -qint64 QDateTime::currentMsecsSinceEpoch() +qint64 QDateTime::currentMSecsSinceEpoch() { QDate d; QTime t; @@ -3005,7 +3005,7 @@ QDateTime QDateTime::currentDateTimeUtc() return QDateTime(d, ct, Qt::UTC); } -qint64 QDateTime::currentMsecsSinceEpoch() +qint64 QDateTime::currentMSecsSinceEpoch() { QDate d; QTime ct; @@ -3122,7 +3122,7 @@ QDateTime QDateTime::currentDateTimeUtc() return dt; } -qint64 QDateTime::currentMsecsSinceEpoch() +qint64 QDateTime::currentMSecsSinceEpoch() { // posix compliant system // we have milliseconds @@ -3166,10 +3166,10 @@ QDateTime QDateTime::fromTime_t(uint seconds) \sa toTime_t(), setTime_t() */ -QDateTime QDateTime::fromMsecsSinceEpoch(qint64 msecs) +QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs) { QDateTime d; - d.setMsecsSinceEpoch(msecs); + d.setMSecsSinceEpoch(msecs); return d; } @@ -3928,7 +3928,7 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) QDate fakeDate = adjustDate(date); // won't overflow because of fakeDate - time_t secsSince1Jan1970UTC = toMsecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000; + time_t secsSince1Jan1970UTC = toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000; tm *brokenDown = 0; #if defined(Q_OS_WINCE) diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index 248793b..f445f1c 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -230,12 +230,12 @@ public: QDate date() const; QTime time() const; Qt::TimeSpec timeSpec() const; - qint64 toMsecsSinceEpoch() const; + qint64 toMSecsSinceEpoch() const; uint toTime_t() const; void setDate(const QDate &date); void setTime(const QTime &time); void setTimeSpec(Qt::TimeSpec spec); - void setMsecsSinceEpoch(qint64 msecs); + void setMSecsSinceEpoch(qint64 msecs); void setTime_t(uint secsSince1Jan1970UTC); #ifndef QT_NO_DATESTRING QString toString(Qt::DateFormat f = Qt::TextDate) const; @@ -269,8 +269,8 @@ public: static QDateTime fromString(const QString &s, const QString &format); #endif static QDateTime fromTime_t(uint secsSince1Jan1970UTC); - static QDateTime fromMsecsSinceEpoch(qint64 msecs); - static qint64 currentMsecsSinceEpoch(); + static QDateTime fromMSecsSinceEpoch(qint64 msecs); + static qint64 currentMSecsSinceEpoch(); #ifdef QT3_SUPPORT inline QT3_SUPPORT void setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec) { diff --git a/src/corelib/tools/qelapsedtimer_generic.cpp b/src/corelib/tools/qelapsedtimer_generic.cpp index 9b589c1..85986e6 100644 --- a/src/corelib/tools/qelapsedtimer_generic.cpp +++ b/src/corelib/tools/qelapsedtimer_generic.cpp @@ -98,7 +98,7 @@ void QElapsedTimer::start() qint64 QElapsedTimer::restart() { qint64 old = t1; - t1 = QDateTime::currentMsecsSinceEpoch(); + t1 = QDateTime::currentMSecsSinceEpoch(); t2 = 0; return t1 - old; } @@ -112,7 +112,7 @@ qint64 QElapsedTimer::restart() */ qint64 QElapsedTimer::elapsed() const { - return QDateTime::currentMsecsSinceEpoch() - t1; + return QDateTime::currentMSecsSinceEpoch() - t1; } /*! diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index b04a1b5..6aca996 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -83,8 +83,8 @@ private slots: void setTime(); void setTimeSpec(); void setTime_t(); - void setMsecsSinceEpoch_data(); - void setMsecsSinceEpoch(); + void setMSecsSinceEpoch_data(); + void setMSecsSinceEpoch(); void toString_enumformat(); void toString_strformat_data(); void toString_strformat(); @@ -439,7 +439,7 @@ void tst_QDateTime::setTime_t() } } -void tst_QDateTime::setMsecsSinceEpoch_data() +void tst_QDateTime::setMSecsSinceEpoch_data() { QTest::addColumn("msecs"); QTest::addColumn("utc"); @@ -479,7 +479,7 @@ void tst_QDateTime::setMsecsSinceEpoch_data() << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(23, 59, 59, 999)); } -void tst_QDateTime::setMsecsSinceEpoch() +void tst_QDateTime::setMSecsSinceEpoch() { QFETCH(qint64, msecs); QFETCH(QDateTime, utc); @@ -487,14 +487,14 @@ void tst_QDateTime::setMsecsSinceEpoch() QDateTime dt; dt.setTimeSpec(Qt::UTC); - dt.setMsecsSinceEpoch(msecs); + dt.setMSecsSinceEpoch(msecs); QCOMPARE(dt, utc); if (europeanTimeZone) { QCOMPARE(dt.toLocalTime(), european); } - QCOMPARE(dt.toMsecsSinceEpoch(), msecs); + QCOMPARE(dt.toMSecsSinceEpoch(), msecs); if (quint64(msecs / 1000) < 0xFFFFFFFF) { QCOMPARE(qint64(dt.toTime_t()), msecs / 1000); @@ -999,7 +999,7 @@ void tst_QDateTime::currentDateTimeUtc2() do { local = QDateTime::currentDateTime(); utc = QDateTime::currentDateTimeUtc(); - msec = QDateTime::currentMsecsSinceEpoch(); + msec = QDateTime::currentMSecsSinceEpoch(); ok = local.time().msec() == utc.time().msec() && utc.time().msec() == (msec % 1000); } while (--i && !ok); @@ -1020,8 +1020,8 @@ void tst_QDateTime::currentDateTimeUtc2() // and finally, the time_t should equal our number QCOMPARE(qint64(utc.toTime_t()), msec / 1000); QCOMPARE(qint64(local.toTime_t()), msec / 1000); - QCOMPARE(utc.toMsecsSinceEpoch(), msec); - QCOMPARE(local.toMsecsSinceEpoch(), msec); + QCOMPARE(utc.toMSecsSinceEpoch(), msec); + QCOMPARE(local.toMSecsSinceEpoch(), msec); } void tst_QDateTime::toTime_t_data() -- cgit v0.12 From 524ee26ed5202aa45d337a0a852a2eb2896ac205 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 31 Mar 2010 12:38:21 +0200 Subject: Remove leading whitespace from Qt header macros. The tst_headers::macros test doesn't like it. It's easier to remove the spaces than to fix the test. Reviewed-by: Markus Goetz --- src/network/bearer/qnetworkconfigmanager.h | 14 +++++++------- src/network/bearer/qnetworkconfiguration.h | 14 +++++++------- src/network/bearer/qnetworksession.h | 18 +++++++++--------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h index 19951f8..79bb27c 100644 --- a/src/network/bearer/qnetworkconfigmanager.h +++ b/src/network/bearer/qnetworkconfigmanager.h @@ -52,12 +52,12 @@ QT_BEGIN_HEADER #ifndef QT_MOBILITY_BEARER - QT_BEGIN_NAMESPACE - #define QNetworkConfigurationManagerExport Q_NETWORK_EXPORT - QT_MODULE(Network) +QT_BEGIN_NAMESPACE +#define QNetworkConfigurationManagerExport Q_NETWORK_EXPORT +QT_MODULE(Network) #else - QTM_BEGIN_NAMESPACE - #define QNetworkConfigurationManagerExport Q_BEARER_EXPORT +QTM_BEGIN_NAMESPACE +#define QNetworkConfigurationManagerExport Q_BEARER_EXPORT #endif class QNetworkConfigurationManagerPrivate; @@ -104,9 +104,9 @@ Q_SIGNALS: Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkConfigurationManager::Capabilities) #ifndef QT_MOBILITY_BEARER - QT_END_NAMESPACE +QT_END_NAMESPACE #else - QTM_END_NAMESPACE +QTM_END_NAMESPACE #endif QT_END_HEADER diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h index 3b49d0a..dce39eb 100644 --- a/src/network/bearer/qnetworkconfiguration.h +++ b/src/network/bearer/qnetworkconfiguration.h @@ -59,12 +59,12 @@ QT_BEGIN_HEADER #ifndef QT_MOBILITY_BEARER - QT_BEGIN_NAMESPACE - QT_MODULE(Network) - #define QNetworkConfigurationExport Q_NETWORK_EXPORT +QT_BEGIN_NAMESPACE +QT_MODULE(Network) +#define QNetworkConfigurationExport Q_NETWORK_EXPORT #else - QTM_BEGIN_NAMESPACE - #define QNetworkConfigurationExport Q_BEARER_EXPORT +QTM_BEGIN_NAMESPACE +#define QNetworkConfigurationExport Q_BEARER_EXPORT #endif class QNetworkConfigurationPrivate; @@ -123,9 +123,9 @@ private: }; #ifndef QT_MOBILITY_BEARER - QT_END_NAMESPACE +QT_END_NAMESPACE #else - QTM_END_NAMESPACE +QTM_END_NAMESPACE #endif QT_END_HEADER diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h index 2681d1f..2911d0a 100644 --- a/src/network/bearer/qnetworksession.h +++ b/src/network/bearer/qnetworksession.h @@ -55,14 +55,14 @@ QT_BEGIN_HEADER #ifndef QT_MOBILITY_BEARER - #include - QT_BEGIN_NAMESPACE - QT_MODULE(Network) - #define QNetworkSessionExport Q_NETWORK_EXPORT +#include +QT_BEGIN_NAMESPACE +QT_MODULE(Network) +#define QNetworkSessionExport Q_NETWORK_EXPORT #else - #include "qmobilityglobal.h" - QTM_BEGIN_NAMESPACE - #define QNetworkSessionExport Q_BEARER_EXPORT +#include "qmobilityglobal.h" +QTM_BEGIN_NAMESPACE +#define QNetworkSessionExport Q_BEARER_EXPORT #endif class QNetworkSessionPrivate; @@ -142,9 +142,9 @@ private: }; #ifndef QT_MOBILITY_BEARER - QT_END_NAMESPACE +QT_END_NAMESPACE #else - QTM_END_NAMESPACE +QTM_END_NAMESPACE #endif QT_END_HEADER -- cgit v0.12 From f858af947c92ad77d0aa14bbf80171b9b822bd75 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 31 Mar 2010 12:53:12 +0200 Subject: Update Comment --- tests/auto/declarative/qdeclarativelayouts/tst_qdeclarativelayouts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/declarative/qdeclarativelayouts/tst_qdeclarativelayouts.cpp b/tests/auto/declarative/qdeclarativelayouts/tst_qdeclarativelayouts.cpp index 879047e..412c3b7 100644 --- a/tests/auto/declarative/qdeclarativelayouts/tst_qdeclarativelayouts.cpp +++ b/tests/auto/declarative/qdeclarativelayouts/tst_qdeclarativelayouts.cpp @@ -130,7 +130,7 @@ void tst_QDeclarativeLayouts::test_qml() void tst_QDeclarativeLayouts::test_cpp() { - //TODO: Waiting on QT-2407 to write this test + //TODO: This test! } QDeclarativeView *tst_QDeclarativeLayouts::createView(const QString &filename) -- cgit v0.12 From 5323b5df1587d05de29857305ec0726e2f87610d Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 31 Mar 2010 12:54:44 +0200 Subject: Fix bug when adding import paths manually Paths were being added relatively even though they should be converted to a canoncial form. Patch originally by tmikola Reviewed-by: mae --- src/declarative/qml/qdeclarativeengine.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index bb742ee..2cae632 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1788,7 +1788,13 @@ void QDeclarativeEngine::addImportPath(const QString& path) if (qmlImportTrace()) qDebug() << "QDeclarativeEngine::addImportPath" << path; Q_D(QDeclarativeEngine); - d->fileImportPath.prepend(path); + QUrl url = QUrl(path); + if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { + QDir dir = QDir(path); + d->fileImportPath.prepend(dir.canonicalPath()); + } else { + d->fileImportPath.prepend(path); + } } -- cgit v0.12 From 2fe059c863377befdcf65084a07a7f4841beef0d Mon Sep 17 00:00:00 2001 From: aavit Date: Tue, 30 Mar 2010 13:41:18 +0200 Subject: Total makeover of SVG image reader Improved/fixed canRead(). Added svgz support. Implemented ClipRect, ScaledClipRect and BackgroundColor support. Avoid data copy when reading from memory. Improved support reading from sequential devices. Added svg and svgz files to the qimagereader autotests. Task-number: QTBUG-8227 and QTBUG-9053 Reviewed-by: Kim --- src/plugins/imageformats/svg/main.cpp | 16 +- src/plugins/imageformats/svg/qsvgiohandler.cpp | 157 ++++++--- tests/auto/qimagereader/images/corrupt.svg | 32 ++ tests/auto/qimagereader/images/corrupt.svgz | Bin 0 -> 407 bytes tests/auto/qimagereader/images/rect.svg | 462 +++++++++++++++++++++++++ tests/auto/qimagereader/images/rect.svgz | Bin 0 -> 5082 bytes tests/auto/qimagereader/qimagereader.pro | 1 + tests/auto/qimagereader/qimagereader.qrc | 4 + tests/auto/qimagereader/tst_qimagereader.cpp | 64 +++- 9 files changed, 667 insertions(+), 69 deletions(-) create mode 100644 tests/auto/qimagereader/images/corrupt.svg create mode 100644 tests/auto/qimagereader/images/corrupt.svgz create mode 100644 tests/auto/qimagereader/images/rect.svg create mode 100644 tests/auto/qimagereader/images/rect.svgz diff --git a/src/plugins/imageformats/svg/main.cpp b/src/plugins/imageformats/svg/main.cpp index dbbd3b7..329e9d4 100644 --- a/src/plugins/imageformats/svg/main.cpp +++ b/src/plugins/imageformats/svg/main.cpp @@ -62,26 +62,18 @@ public: QStringList QSvgPlugin::keys() const { - return QStringList() << QLatin1String("svg"); + return QStringList() << QLatin1String("svg") << QLatin1String("svgz"); } QImageIOPlugin::Capabilities QSvgPlugin::capabilities(QIODevice *device, const QByteArray &format) const { - //### canRead disabled for now because it's hard to detect - // whether the file is actually svg without parsing it - //if (device->isReadable() && QSvgIOHandler::canRead(device)) - - if (format == "svg") + if (format == "svg" || format == "svgz") return Capabilities(CanRead); - else - return 0; - - - if (!device->isOpen()) + if (!format.isEmpty()) return 0; Capabilities cap; - if (device->isReadable()) + if (device->isReadable() && QSvgIOHandler::canRead(device)) cap |= CanRead; return cap; } diff --git a/src/plugins/imageformats/svg/qsvgiohandler.cpp b/src/plugins/imageformats/svg/qsvgiohandler.cpp index f3670c6..8155569 100644 --- a/src/plugins/imageformats/svg/qsvgiohandler.cpp +++ b/src/plugins/imageformats/svg/qsvgiohandler.cpp @@ -48,6 +48,7 @@ #include "qpixmap.h" #include "qpainter.h" #include "qvariant.h" +#include "qbuffer.h" #include "qdebug.h" QT_BEGIN_NAMESPACE @@ -55,67 +56,54 @@ QT_BEGIN_NAMESPACE class QSvgIOHandlerPrivate { public: - QSvgIOHandlerPrivate() - : r(new QSvgRenderer()), loaded(false) + QSvgIOHandlerPrivate(QSvgIOHandler *qq) + : q(qq), loaded(false), readDone(false), backColor(Qt::transparent) {} - ~QSvgIOHandlerPrivate() - { - delete r; - } bool load(QIODevice *device); - static bool findSvgTag(QIODevice *device); - QSvgRenderer *r; - QSize defaultSize; - QSize currentSize; - bool loaded; + QSvgIOHandler *q; + QSvgRenderer r; + QXmlStreamReader xmlReader; + QSize defaultSize; + QRect clipRect; + QSize scaledSize; + QRect scaledClipRect; + bool loaded; + bool readDone; + QColor backColor; }; + bool QSvgIOHandlerPrivate::load(QIODevice *device) { if (loaded) return true; + if (q->format().isEmpty()) + q->canRead(); + + bool res = false; + QBuffer *buf = qobject_cast(device); + if (buf) { + res = r.load(buf->data()); + } else if (q->format() == "svgz") { + res = r.load(device->readAll()); // ### can't stream svgz + } else { + xmlReader.setDevice(device); + res = r.load(&xmlReader); //### doesn't leave pos() correctly + } - if (r->load(device->readAll())) { - defaultSize = QSize(r->viewBox().width(), r->viewBox().height()); - if (currentSize.isEmpty()) - currentSize = defaultSize; + if (res) { + defaultSize = QSize(r.viewBox().width(), r.viewBox().height()); + loaded = true; } - loaded = r->isValid(); return loaded; } -bool QSvgIOHandlerPrivate::findSvgTag(QIODevice *device) -{ - qint64 pos = device->pos(); - device->seek(0); - char buffer[256]; - const char svg_tag[] = "read(buffer, 256); - for (int i=0; iseek(pos); - return true; - } - } - } - if (device->atEnd()) - break; - device->seek(device->pos()-4); - } - device->seek(pos); - return false; -} QSvgIOHandler::QSvgIOHandler() - : d(new QSvgIOHandlerPrivate()) + : d(new QSvgIOHandlerPrivate(this)) { } @@ -129,7 +117,20 @@ QSvgIOHandler::~QSvgIOHandler() bool QSvgIOHandler::canRead() const { - return QSvgIOHandlerPrivate::findSvgTag(device()); + if (!device()) + return false; + if (d->loaded && !d->readDone) + return true; // Will happen if we have been asked for the size + + QByteArray buf = device()->peek(8); + if (buf.startsWith("\x1f\x8b")) { + setFormat("svgz"); + return true; + } else if (buf.contains("load(device())) { - *image = QImage(d->currentSize, QImage::Format_ARGB32_Premultiplied); - if (!d->currentSize.isEmpty()) { - image->fill(0x00000000); + if (!d->readDone && d->load(device())) { + bool xform = (d->clipRect.isValid() || d->scaledSize.isValid() || d->scaledClipRect.isValid()); + QSize finalSize = d->defaultSize; + QRectF bounds; + if (xform && !d->defaultSize.isEmpty()) { + bounds = QRectF(QPointF(0,0), QSizeF(d->defaultSize)); + QPoint tr1, tr2; + QSizeF sc(1, 1); + if (d->clipRect.isValid()) { + tr1 = -d->clipRect.topLeft(); + finalSize = d->clipRect.size(); + } + if (d->scaledSize.isValid()) { + sc = QSizeF(qreal(d->scaledSize.width()) / finalSize.width(), + qreal(d->scaledSize.height()) / finalSize.height()); + finalSize = d->scaledSize; + } + if (d->scaledClipRect.isValid()) { + tr2 = -d->scaledClipRect.topLeft(); + finalSize = d->scaledClipRect.size(); + } + QTransform t; + t.translate(tr2.x(), tr2.y()); + t.scale(sc.width(), sc.height()); + t.translate(tr1.x(), tr1.y()); + bounds = t.mapRect(bounds); + } + *image = QImage(finalSize, QImage::Format_ARGB32_Premultiplied); + if (!finalSize.isEmpty()) { + image->fill(d->backColor.rgba()); QPainter p(image); - d->r->render(&p); + d->r.render(&p, bounds); p.end(); } + d->readDone = true; return true; } @@ -166,8 +194,17 @@ QVariant QSvgIOHandler::option(ImageOption option) const d->load(device()); return d->defaultSize; break; + case ClipRect: + return d->clipRect; + break; case ScaledSize: - return d->currentSize; + return d->scaledSize; + break; + case ScaledClipRect: + return d->scaledClipRect; + break; + case BackgroundColor: + return d->backColor; break; default: break; @@ -179,12 +216,17 @@ QVariant QSvgIOHandler::option(ImageOption option) const void QSvgIOHandler::setOption(ImageOption option, const QVariant & value) { switch(option) { - case Size: - d->defaultSize = value.toSize(); - d->currentSize = value.toSize(); + case ClipRect: + d->clipRect = value.toRect(); break; case ScaledSize: - d->currentSize = value.toSize(); + d->scaledSize = value.toSize(); + break; + case ScaledClipRect: + d->scaledClipRect = value.toRect(); + break; + case BackgroundColor: + d->backColor = value.value(); break; default: break; @@ -198,7 +240,10 @@ bool QSvgIOHandler::supportsOption(ImageOption option) const { case ImageFormat: case Size: + case ClipRect: case ScaledSize: + case ScaledClipRect: + case BackgroundColor: return true; default: break; @@ -206,9 +251,11 @@ bool QSvgIOHandler::supportsOption(ImageOption option) const return false; } + bool QSvgIOHandler::canRead(QIODevice *device) { - return QSvgIOHandlerPrivate::findSvgTag(device); + QByteArray buf = device->peek(8); + return buf.startsWith("\x1f\x8b") || buf.contains(" + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/auto/qimagereader/images/rect.svgz b/tests/auto/qimagereader/images/rect.svgz new file mode 100644 index 0000000..c2e193b Binary files /dev/null and b/tests/auto/qimagereader/images/rect.svgz differ diff --git a/tests/auto/qimagereader/qimagereader.pro b/tests/auto/qimagereader/qimagereader.pro index 5b061b0..402e94b 100644 --- a/tests/auto/qimagereader/qimagereader.pro +++ b/tests/auto/qimagereader/qimagereader.pro @@ -9,6 +9,7 @@ RESOURCES += qimagereader.qrc !contains(QT_CONFIG, no-jpeg):DEFINES += QTEST_HAVE_JPEG !contains(QT_CONFIG, no-mng):DEFINES += QTEST_HAVE_MNG !contains(QT_CONFIG, no-tiff):DEFINES += QTEST_HAVE_TIFF +!contains(QT_CONFIG, no-svg):DEFINES += QTEST_HAVE_SVG win32-msvc:QMAKE_CXXFLAGS -= -Zm200 win32-msvc:QMAKE_CXXFLAGS += -Zm800 diff --git a/tests/auto/qimagereader/qimagereader.qrc b/tests/auto/qimagereader/qimagereader.qrc index bc48244..278427b 100644 --- a/tests/auto/qimagereader/qimagereader.qrc +++ b/tests/auto/qimagereader/qimagereader.qrc @@ -61,5 +61,9 @@ images/four-frames.gif images/qt-gif-anim.gif images/qt-gif-noanim.gif + images/rect.svg + images/rect.svgz + images/corrupt.svg + images/corrupt.svgz diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index 99244c2..1b4c502 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -245,6 +245,10 @@ void tst_QImageReader::readImage_data() QTest::newRow("MNG: ball") << QString("ball.mng") << true << QByteArray("mng"); QTest::newRow("MNG: fire") << QString("fire.mng") << true << QByteArray("mng"); #endif +#if defined QTEST_HAVE_SVG + QTest::newRow("SVG: rect") << QString("rect.svg") << true << QByteArray("svg"); + QTest::newRow("SVGZ: rect") << QString("rect.svgz") << true << QByteArray("svgz"); +#endif } void tst_QImageReader::readImage() @@ -294,7 +298,6 @@ void tst_QImageReader::readImage() QVERIFY(!image2Reader.format().isEmpty()); } QCOMPARE(image, image2); - do { QVERIFY2(!image.isNull(), io.errorString().toLatin1().constData()); } while (!(image = io.read()).isNull()); @@ -342,6 +345,10 @@ void tst_QImageReader::setScaledSize_data() QTest::newRow("MNG: ball") << "ball" << QSize(200, 200) << QByteArray("mng"); QTest::newRow("MNG: fire") << "fire" << QSize(200, 200) << QByteArray("mng"); #endif // QTEST_HAVE_MNG +#if defined QTEST_HAVE_SVG + QTest::newRow("SVG: rect") << "rect" << QSize(200, 200) << QByteArray("svg"); + QTest::newRow("SVGZ: rect") << "rect" << QSize(200, 200) << QByteArray("svgz"); +#endif } void tst_QImageReader::setScaledSize() @@ -409,6 +416,10 @@ void tst_QImageReader::setClipRect_data() QTest::newRow("MNG: ball") << "ball" << QRect(0, 0, 50, 50) << QByteArray("mng"); QTest::newRow("MNG: fire") << "fire" << QRect(0, 0, 50, 50) << QByteArray("mng"); #endif // QTEST_HAVE_MNG +#if defined QTEST_HAVE_SVG + QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg"); + QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz"); +#endif } void tst_QImageReader::setClipRect() @@ -456,6 +467,10 @@ void tst_QImageReader::setScaledClipRect_data() QTest::newRow("MNG: ball") << "ball" << QRect(0, 0, 50, 50) << QByteArray("mng"); QTest::newRow("MNG: fire") << "fire" << QRect(0, 0, 50, 50) << QByteArray("mng"); #endif // QTEST_HAVE_MNG +#if defined QTEST_HAVE_SVG + QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg"); + QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz"); +#endif } void tst_QImageReader::setScaledClipRect() @@ -509,6 +524,8 @@ void tst_QImageReader::imageFormat_data() QTest::newRow("png-2") << QString("YCbCr_cmyk.png") << QByteArray("png") << QImage::Format_RGB32; QTest::newRow("mng-1") << QString("ball.mng") << QByteArray("mng") << QImage::Format_Invalid; QTest::newRow("mng-2") << QString("fire.mng") << QByteArray("mng") << QImage::Format_Invalid; + QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg") << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz") << QImage::Format_ARGB32_Premultiplied; } void tst_QImageReader::imageFormat() @@ -530,6 +547,10 @@ void tst_QImageReader::imageFormat() #ifndef QTEST_HAVE_MNG return; #endif // !QTEST_HAVE_MNG + if (QByteArray("svg") == format || QByteArray("svgz") == format) +#ifndef QTEST_HAVE_SVG + return; +#endif // !QTEST_HAVE_SVG QSKIP(("Qt does not support the " + format + " format.").constData(), SkipSingle); } else { QCOMPARE(QImageReader::imageFormat(prefix + fileName), format); @@ -604,6 +625,10 @@ void tst_QImageReader::setBackgroundColor_data() QTest::newRow("MNG: ball") << QString("ball.mng") << QColor(Qt::yellow); QTest::newRow("MNG: fire") << QString("fire.mng") << QColor(Qt::gray); #endif +#if defined QTEST_HAVE_SVG + QTest::newRow("SVG: rect") << QString("rect.svg") << QColor(Qt::darkGreen); + QTest::newRow("SVGZ: rect") << QString("rect.svgz") << QColor(Qt::darkGreen); +#endif } void tst_QImageReader::setBackgroundColor() @@ -641,6 +666,10 @@ void tst_QImageReader::supportsAnimation_data() QTest::newRow("MNG: ball") << QString("ball.mng") << true; QTest::newRow("MNG: fire") << QString("fire.mng") << true; #endif +#if defined QTEST_HAVE_SVG + QTest::newRow("SVG: rect") << QString("rect.svg") << false; + QTest::newRow("SVGZ: rect") << QString("rect.svgz") << false; +#endif } void tst_QImageReader::supportsAnimation() @@ -979,6 +1008,10 @@ void tst_QImageReader::readFromDevice_data() QTest::newRow("mng-1") << QString("ball.mng") << QByteArray("mng"); QTest::newRow("mng-2") << QString("fire.mng") << QByteArray("mng"); #endif // QTEST_HAVE_MNG +#if defined QTEST_HAVE_SVG + QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg"); + QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz"); +#endif } void tst_QImageReader::readFromDevice() @@ -1059,6 +1092,10 @@ void tst_QImageReader::readFromFileAfterJunk_data() QTest::newRow("png") << QString("kollada.png") << QByteArray("png"); // QTest::newRow("mng-1") << QString("images/ball.mng") << QByteArray("mng"); // QTest::newRow("mng-2") << QString("images/fire.mng") << QByteArray("mng"); +#if defined QTEST_HAVE_SVG + QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg"); + QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz"); +#endif } void tst_QImageReader::readFromFileAfterJunk() @@ -1081,7 +1118,7 @@ void tst_QImageReader::readFromFileAfterJunk() QVERIFY(!imageData.isNull()); int iterations = 10; - if (format == "ppm" || format == "pbm" || format == "pgm") + if (format == "ppm" || format == "pbm" || format == "pgm" || format == "svg" || format == "svgz") iterations = 1; if (format == "mng" || !QImageWriter::supportedImageFormats().contains(format)) { @@ -1233,6 +1270,20 @@ void tst_QImageReader::readFromResources_data() << QByteArray("mng") << QSize(32, 32) << QString(""); #endif +#ifdef QTEST_HAVE_SVG + QTest::newRow("rect.svg") << QString("rect.svg") + << QByteArray("svg") << QSize(105, 137) + << QString(""); + QTest::newRow("rect.svgz") << QString("rect.svgz") + << QByteArray("svgz") << QSize(105, 137) + << QString(""); + QTest::newRow("corrupt.svg") << QString("corrupt.svg") + << QByteArray("svg") << QSize(0, 0) + << QString(""); + QTest::newRow("corrupt.svgz") << QString("corrupt.svgz") + << QByteArray("svgz") << QSize(0, 0) + << QString(""); +#endif QTest::newRow("image.pbm") << QString("image.pbm") << QByteArray("pbm") << QSize(16, 6) << QString(""); @@ -1405,6 +1456,10 @@ void tst_QImageReader::readCorruptImage_data() #if defined QTEST_HAVE_TIFF QTest::newRow("corrupt tiff") << QString("corrupt-data.tif") << true << QString(""); #endif +#if defined QTEST_HAVE_SVG + QTest::newRow("corrupt svg") << QString("corrupt.svg") << true << QString(""); + QTest::newRow("corrupt svgz") << QString("corrupt.svgz") << true << QString(""); +#endif } void tst_QImageReader::readCorruptImage() @@ -1753,6 +1808,11 @@ void tst_QImageReader::testIgnoresFormatAndExtension_data() #if defined QTEST_HAVE_TIFF QTest::newRow("image_100dpi.tif") << "image_100dpi" << "tif" << "tiff"; #endif + +#if defined QTEST_HAVE_SVG + QTest::newRow("rect.svg") << "rect" << "svg" << "svg"; + QTest::newRow("rect.svgz") << "rect" << "svgz" << "svgz"; +#endif } -- cgit v0.12 From b75ebb19032ab2b739c848ed1e8cc1fa74f3cd21 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 31 Mar 2010 14:06:47 +0200 Subject: Fix 'make sis' finding the dll on symbian --- src/imports/multimedia/multimedia.pro | 2 +- src/imports/particles/particles.pro | 2 +- src/imports/webkit/webkit.pro | 2 +- src/imports/widgets/widgets.pro | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/imports/multimedia/multimedia.pro b/src/imports/multimedia/multimedia.pro index 78618fc..92f7ec4 100644 --- a/src/imports/multimedia/multimedia.pro +++ b/src/imports/multimedia/multimedia.pro @@ -27,7 +27,7 @@ symbian:{ load(data_caging_paths) include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - importFiles.sources = multimedia.dll \ + importFiles.sources = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH/multimedia.dll \ qmldir importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro index a46db8c..58bfe05 100644 --- a/src/imports/particles/particles.pro +++ b/src/imports/particles/particles.pro @@ -21,7 +21,7 @@ symbian:{ load(data_caging_paths) include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - importFiles.sources = particles.dll \ + importFiles.sources = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH/particles.dll \ qmldir importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH diff --git a/src/imports/webkit/webkit.pro b/src/imports/webkit/webkit.pro index 7463a7f..62db9ac 100644 --- a/src/imports/webkit/webkit.pro +++ b/src/imports/webkit/webkit.pro @@ -18,7 +18,7 @@ symbian:{ load(data_caging_paths) include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - importFiles.sources = webkitqmlplugin.dll \ + importFiles.sources = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH/webkitqmlplugin.dll \ qmldir importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro index cccd8b4..408f878 100644 --- a/src/imports/widgets/widgets.pro +++ b/src/imports/widgets/widgets.pro @@ -22,7 +22,7 @@ symbian:{ load(data_caging_paths) include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - importFiles.sources = widgets.dll \ + importFiles.sources = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH/widgets.dll \ qmldir importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH -- cgit v0.12 From 56949fc36c30a84e716b66ac74f3a0a8de74cc8e Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 31 Mar 2010 14:08:09 +0200 Subject: Cleanup the deployment code Remove local defines and passing of a list while its never used, only define it where its actually used. --- qmake/generators/symbian/symbian_makefile.h | 3 +-- qmake/generators/symbian/symbiancommon.cpp | 3 ++- qmake/generators/symbian/symbiancommon.h | 2 +- qmake/generators/symbian/symmake.cpp | 7 +++---- qmake/generators/symbian/symmake.h | 3 +-- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/qmake/generators/symbian/symbian_makefile.h b/qmake/generators/symbian/symbian_makefile.h index f9d3c24..797a602 100644 --- a/qmake/generators/symbian/symbian_makefile.h +++ b/qmake/generators/symbian/symbian_makefile.h @@ -66,7 +66,6 @@ public: // Generate pkg files if there are any actual files to deploy bool generatePkg = false; - DeploymentList depList; if (targetType == TypeExe) { generatePkg = true; @@ -80,7 +79,7 @@ public: } if (generatePkg) { - generatePkgFile(iconFile, depList, false); + generatePkgFile(iconFile, false); } // Get the application translations and convert to symbian OS lang code, i.e. decical number diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 54b60be..10889c4 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -142,7 +142,7 @@ void SymbianCommonGenerator::removeEpocSpecialCharacters(QString& str) removeSpecialCharacters(str); } -void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, DeploymentList &depList, bool epocBuild) +void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocBuild) { QMakeProject *project = generator->project; QString pkgTarget = project->first("QMAKE_ORIG_TARGET"); @@ -361,6 +361,7 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, Deployment QString remoteTestPath; remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid); + DeploymentList depList; initProjectDeploySymbian(project, depList, remoteTestPath, true, epocBuild, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles); if (depList.size()) t << "; DEPLOYMENT" << endl; diff --git a/qmake/generators/symbian/symbiancommon.h b/qmake/generators/symbian/symbiancommon.h index e2b1173..3efe5a4 100644 --- a/qmake/generators/symbian/symbiancommon.h +++ b/qmake/generators/symbian/symbiancommon.h @@ -68,7 +68,7 @@ protected: QString removePathSeparators(QString &file); void removeSpecialCharacters(QString& str); void removeEpocSpecialCharacters(QString& str); - void generatePkgFile(const QString &iconFile, DeploymentList &depList, bool epocBuild); + void generatePkgFile(const QString &iconFile, bool epocBuild); bool containsStartWithItem(const QChar &c, const QStringList& src); void writeRegRssFile(QMap &useritems); diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 0fcd26d..e05ced2 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -187,7 +187,6 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) // Generate pkg files if there are any actual files to deploy bool generatePkg = false; - DeploymentList depList; if (targetType == TypeExe) { generatePkg = true; @@ -201,10 +200,10 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) } if (generatePkg) { - generatePkgFile(iconFile, depList, true); + generatePkgFile(iconFile, true); } - writeBldInfContent(t, generatePkg, iconFile, depList); + writeBldInfContent(t, generatePkg, iconFile); // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile, // but all required data is not yet available. @@ -948,7 +947,7 @@ void SymbianMakefileGenerator::writeMmpFileRulesPart(QTextStream& t) } } -void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile, DeploymentList &depList) +void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile) { // Read user defined bld inf rules diff --git a/qmake/generators/symbian/symmake.h b/qmake/generators/symbian/symmake.h index d9ca390..b06ff5b 100644 --- a/qmake/generators/symbian/symmake.h +++ b/qmake/generators/symbian/symmake.h @@ -90,8 +90,7 @@ protected: void writeHeader(QTextStream &t); void writeBldInfContent(QTextStream& t, bool addDeploymentExtension, - const QString &iconFile, - DeploymentList &depList); + const QString &iconFile); static bool removeDuplicatedStrings(QStringList& stringList); -- cgit v0.12 From 5746327c5566223f01f10f62baf8d7c3e47a6c9f Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Wed, 31 Mar 2010 15:23:39 +0200 Subject: Fixed: Declared properties cannot be assigned in declaration Task-number: QTBUG-7860 --- src/declarative/qml/parser/qdeclarativejs.g | 50 + src/declarative/qml/parser/qdeclarativejsast.cpp | 1 + src/declarative/qml/parser/qdeclarativejsast_p.h | 10 +- .../qml/parser/qdeclarativejsgrammar.cpp | 1665 ++++++++++---------- .../qml/parser/qdeclarativejsgrammar_p.h | 12 +- .../qml/parser/qdeclarativejsparser.cpp | 422 ++--- .../qml/parser/qdeclarativejsparser_p.h | 4 +- src/declarative/qml/qdeclarativescriptparser.cpp | 13 +- .../tst_qdeclarativelanguage.cpp | 1 - 9 files changed, 1138 insertions(+), 1040 deletions(-) diff --git a/src/declarative/qml/parser/qdeclarativejs.g b/src/declarative/qml/parser/qdeclarativejs.g index 6434d10..536989f 100644 --- a/src/declarative/qml/parser/qdeclarativejs.g +++ b/src/declarative/qml/parser/qdeclarativejs.g @@ -971,6 +971,56 @@ case $rule_number: { } break; ./ +UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ; +/. +case $rule_number: { + AST::UiPublicMember *node = makeAstNode (driver->nodePool(), sym(4).sval, sym(6).sval); + node->typeModifier = sym(2).sval; + node->propertyToken = loc(1); + node->typeModifierToken = loc(2); + node->typeToken = loc(4); + node->identifierToken = loc(6); + node->semicolonToken = loc(7); // insert a fake ';' before ':' + + AST::UiQualifiedId *propertyName = makeAstNode(driver->nodePool(), sym(6).sval); + propertyName->identifierToken = loc(6); + propertyName->next = 0; + + AST::UiArrayBinding *binding = makeAstNode (driver->nodePool(), + propertyName, sym(9).UiArrayMemberList->finish()); + binding->colonToken = loc(7); + binding->lbracketToken = loc(8); + binding->rbracketToken = loc(10); + + node->binding = binding; + + sym(1).Node = node; +} break; +./ + +UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ; +/. +case $rule_number: { + AST::UiPublicMember *node = makeAstNode (driver->nodePool(), sym(2).sval, sym(3).sval); + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(3); + node->semicolonToken = loc(4); // insert a fake ';' before ':' + + AST::UiQualifiedId *propertyName = makeAstNode(driver->nodePool(), sym(3).sval); + propertyName->identifierToken = loc(3); + propertyName->next = 0; + + AST::UiObjectBinding *binding = makeAstNode (driver->nodePool(), + propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer); + binding->colonToken = loc(4); + + node->binding = binding; + + sym(1).Node = node; +} break; +./ + UiObjectMember: FunctionDeclaration ; /. case $rule_number: { diff --git a/src/declarative/qml/parser/qdeclarativejsast.cpp b/src/declarative/qml/parser/qdeclarativejsast.cpp index 3b569a7..e3d3a66 100644 --- a/src/declarative/qml/parser/qdeclarativejsast.cpp +++ b/src/declarative/qml/parser/qdeclarativejsast.cpp @@ -837,6 +837,7 @@ void UiPublicMember::accept0(Visitor *visitor) { if (visitor->visit(this)) { accept(expression, visitor); + accept(binding, visitor); } visitor->endVisit(this); diff --git a/src/declarative/qml/parser/qdeclarativejsast_p.h b/src/declarative/qml/parser/qdeclarativejsast_p.h index c1945ce..b839413 100644 --- a/src/declarative/qml/parser/qdeclarativejsast_p.h +++ b/src/declarative/qml/parser/qdeclarativejsast_p.h @@ -2485,13 +2485,13 @@ public: UiPublicMember(NameId *memberType, NameId *name) - : type(Property), typeModifier(0), memberType(memberType), name(name), expression(0), isDefaultMember(false), isReadonlyMember(false), parameters(0) + : type(Property), typeModifier(0), memberType(memberType), name(name), expression(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0) { kind = K; } UiPublicMember(NameId *memberType, NameId *name, ExpressionNode *expression) - : type(Property), typeModifier(0), memberType(memberType), name(name), expression(expression), isDefaultMember(false), isReadonlyMember(false), parameters(0) + : type(Property), typeModifier(0), memberType(memberType), name(name), expression(expression), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0) { kind = K; } virtual SourceLocation firstSourceLocation() const @@ -2506,6 +2506,9 @@ public: virtual SourceLocation lastSourceLocation() const { + if (binding) + return binding->lastSourceLocation(); + return semicolonToken; } @@ -2516,7 +2519,8 @@ public: NameId *typeModifier; NameId *memberType; NameId *name; - ExpressionNode *expression; + ExpressionNode *expression; // initialized with a JS expression + UiObjectMember *binding; // initialized with a QML object or array. bool isDefaultMember; bool isReadonlyMember; UiParameterList *parameters; diff --git a/src/declarative/qml/parser/qdeclarativejsgrammar.cpp b/src/declarative/qml/parser/qdeclarativejsgrammar.cpp index 89493ff..39a2d3f 100644 --- a/src/declarative/qml/parser/qdeclarativejsgrammar.cpp +++ b/src/declarative/qml/parser/qdeclarativejsgrammar.cpp @@ -64,35 +64,35 @@ const short QDeclarativeJSGrammar::lhs [] = { 106, 106, 106, 106, 106, 106, 106, 106, 126, 126, 126, 127, 127, 128, 128, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 116, 116, 116, 116, 116, 131, 131, + 106, 106, 106, 106, 106, 116, 116, 116, 116, 116, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 121, 133, 133, 133, - 133, 132, 132, 135, 135, 137, 137, 137, 137, 137, - 137, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 131, 131, 131, 131, 131, 131, 131, 131, 121, 133, + 133, 133, 133, 132, 132, 135, 135, 137, 137, 137, + 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 139, 139, 114, 114, 114, 114, 114, 142, - 142, 143, 143, 143, 143, 141, 141, 144, 144, 145, - 145, 146, 146, 146, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 148, 148, 148, 148, 149, 149, - 149, 150, 150, 150, 150, 151, 151, 151, 151, 151, - 151, 151, 152, 152, 152, 152, 152, 152, 153, 153, - 153, 153, 153, 154, 154, 154, 154, 154, 155, 155, - 156, 156, 157, 157, 158, 158, 159, 159, 160, 160, - 161, 161, 162, 162, 163, 163, 164, 164, 165, 165, - 166, 166, 136, 136, 167, 167, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 104, 104, - 169, 169, 170, 170, 171, 171, 103, 103, 103, 103, + 138, 138, 138, 138, 139, 139, 114, 114, 114, 114, + 114, 142, 142, 143, 143, 143, 143, 141, 141, 144, + 144, 145, 145, 146, 146, 146, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 148, 148, 148, 148, + 149, 149, 149, 150, 150, 150, 150, 151, 151, 151, + 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, + 153, 153, 153, 153, 153, 154, 154, 154, 154, 154, + 155, 155, 156, 156, 157, 157, 158, 158, 159, 159, + 160, 160, 161, 161, 162, 162, 163, 163, 164, 164, + 165, 165, 166, 166, 136, 136, 167, 167, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 104, 104, 169, 169, 170, 170, 171, 171, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 122, 183, 183, 182, 182, 130, 130, 184, 184, - 185, 185, 187, 187, 186, 188, 191, 189, 189, 192, - 190, 190, 123, 124, 124, 125, 125, 172, 172, 172, - 172, 172, 172, 172, 173, 173, 173, 173, 174, 174, - 174, 174, 175, 175, 176, 178, 193, 193, 196, 196, - 194, 194, 197, 195, 177, 177, 177, 179, 179, 180, - 180, 180, 198, 199, 181, 181, 129, 140, 203, 203, - 200, 200, 201, 201, 204, 107, 205, 205, 105, 105, - 202, 202, 134, 134, 206}; + 103, 103, 103, 122, 183, 183, 182, 182, 130, 130, + 184, 184, 185, 185, 187, 187, 186, 188, 191, 189, + 189, 192, 190, 190, 123, 124, 124, 125, 125, 172, + 172, 172, 172, 172, 172, 172, 173, 173, 173, 173, + 174, 174, 174, 174, 175, 175, 176, 178, 193, 193, + 196, 196, 194, 194, 197, 195, 177, 177, 177, 179, + 179, 180, 180, 180, 198, 199, 181, 181, 129, 140, + 203, 203, 200, 200, 201, 201, 204, 107, 205, 205, + 105, 105, 202, 202, 134, 134, 206}; const short QDeclarativeJSGrammar::rhs [] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, @@ -101,106 +101,107 @@ const short QDeclarativeJSGrammar::rhs [] = { 1, 5, 4, 4, 3, 3, 3, 3, 1, 1, 1, 0, 1, 2, 4, 6, 6, 3, 3, 7, 7, 4, 4, 5, 5, 6, 6, 7, 7, 7, - 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 3, 4, 5, 3, 4, 3, 1, 1, 2, 3, - 4, 1, 2, 3, 5, 1, 1, 1, 1, 1, + 7, 10, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 3, 4, 5, 3, 4, 3, 1, 1, + 2, 3, 4, 1, 2, 3, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 4, 3, 5, 1, - 2, 4, 4, 4, 3, 0, 1, 1, 3, 1, - 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 1, 3, 3, 3, 1, 3, - 3, 1, 3, 3, 3, 1, 3, 3, 3, 3, - 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, - 3, 3, 3, 1, 3, 3, 3, 3, 1, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 4, 3, + 5, 1, 2, 4, 4, 4, 3, 0, 1, 1, + 3, 1, 1, 1, 2, 2, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 3, 3, 3, + 1, 3, 3, 1, 3, 3, 3, 1, 3, 3, + 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, + 1, 3, 3, 3, 3, 1, 3, 3, 3, 3, + 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 3, 1, 3, 1, 5, - 1, 5, 1, 3, 1, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 0, 1, 1, 3, 0, 1, 1, 1, 1, 1, + 1, 5, 1, 5, 1, 3, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 0, 1, 1, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 1, 2, 0, 1, 3, 3, 1, 1, - 1, 3, 1, 3, 2, 2, 2, 0, 1, 2, - 0, 1, 1, 2, 2, 7, 5, 7, 7, 5, - 9, 10, 7, 8, 2, 2, 3, 3, 2, 2, - 3, 3, 3, 3, 5, 5, 3, 5, 1, 2, - 0, 1, 4, 3, 3, 3, 3, 3, 3, 3, - 3, 4, 5, 2, 2, 2, 8, 8, 1, 3, - 0, 1, 0, 1, 1, 1, 1, 2, 1, 1, - 0, 1, 0, 1, 2}; + 1, 1, 1, 3, 1, 2, 0, 1, 3, 3, + 1, 1, 1, 3, 1, 3, 2, 2, 2, 0, + 1, 2, 0, 1, 1, 2, 2, 7, 5, 7, + 7, 5, 9, 10, 7, 8, 2, 2, 3, 3, + 2, 2, 3, 3, 3, 3, 5, 5, 3, 5, + 1, 2, 0, 1, 4, 3, 3, 3, 3, 3, + 3, 3, 3, 4, 5, 2, 2, 2, 8, 8, + 1, 3, 0, 1, 0, 1, 1, 1, 1, 2, + 1, 1, 0, 1, 0, 1, 2}; const short QDeclarativeJSGrammar::action_default [] = { - 0, 0, 0, 0, 0, 0, 22, 0, 172, 239, - 203, 211, 207, 151, 223, 199, 3, 136, 70, 152, - 215, 219, 140, 169, 150, 155, 135, 189, 176, 0, - 77, 78, 73, 341, 64, 343, 0, 0, 0, 0, - 75, 0, 0, 71, 74, 68, 0, 0, 65, 67, - 66, 76, 69, 0, 72, 0, 0, 165, 0, 0, - 152, 171, 154, 153, 0, 0, 0, 167, 168, 166, - 170, 0, 200, 0, 0, 0, 0, 190, 0, 0, - 0, 0, 0, 0, 180, 0, 0, 0, 174, 175, - 173, 178, 182, 181, 179, 177, 192, 191, 193, 0, - 208, 0, 204, 0, 0, 146, 133, 145, 134, 102, - 103, 104, 129, 105, 130, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 131, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, - 0, 0, 144, 240, 147, 0, 148, 0, 149, 143, - 0, 236, 229, 227, 234, 235, 233, 232, 238, 231, - 230, 228, 237, 224, 0, 212, 0, 0, 216, 0, - 0, 220, 0, 0, 146, 138, 0, 137, 0, 142, - 156, 0, 342, 331, 332, 0, 329, 0, 330, 0, - 333, 247, 254, 253, 261, 249, 0, 250, 334, 0, - 340, 251, 252, 257, 255, 337, 335, 339, 258, 0, - 269, 0, 0, 0, 0, 341, 64, 0, 343, 65, - 241, 283, 66, 0, 0, 0, 270, 0, 0, 259, - 260, 0, 248, 256, 284, 285, 328, 338, 0, 299, - 300, 301, 302, 0, 295, 296, 297, 298, 325, 326, - 0, 0, 0, 0, 0, 288, 289, 245, 243, 205, - 213, 209, 225, 201, 246, 0, 152, 217, 221, 194, - 183, 0, 0, 202, 0, 0, 0, 0, 195, 0, - 0, 0, 0, 0, 187, 185, 188, 186, 184, 197, - 196, 198, 0, 210, 0, 206, 0, 244, 152, 0, - 226, 241, 242, 0, 241, 0, 0, 291, 0, 0, - 0, 293, 0, 214, 0, 0, 218, 0, 0, 222, - 281, 0, 273, 282, 276, 0, 280, 0, 241, 274, - 0, 241, 0, 0, 292, 0, 0, 0, 294, 342, - 331, 0, 0, 333, 0, 327, 0, 317, 0, 0, - 0, 287, 0, 286, 0, 344, 0, 101, 263, 266, - 0, 102, 269, 105, 130, 107, 108, 73, 112, 113, - 64, 114, 117, 71, 74, 65, 241, 66, 76, 120, - 69, 122, 72, 124, 125, 270, 127, 128, 132, 0, - 94, 0, 0, 96, 100, 98, 85, 97, 99, 0, - 95, 84, 264, 262, 140, 141, 146, 0, 139, 0, - 316, 0, 303, 304, 0, 315, 0, 0, 0, 306, - 311, 309, 312, 0, 0, 310, 311, 0, 307, 0, - 308, 265, 314, 0, 265, 313, 0, 318, 319, 0, - 265, 320, 321, 0, 0, 322, 0, 0, 0, 323, - 324, 158, 157, 0, 0, 0, 290, 0, 0, 0, - 305, 278, 271, 0, 279, 275, 0, 277, 267, 0, - 268, 272, 88, 0, 0, 92, 79, 0, 81, 90, - 0, 82, 91, 93, 83, 89, 80, 0, 86, 162, - 160, 164, 161, 159, 163, 6, 336, 4, 2, 62, - 87, 0, 0, 65, 67, 66, 31, 5, 0, 63, + 0, 0, 0, 0, 0, 0, 22, 0, 174, 241, + 205, 213, 209, 153, 225, 201, 3, 138, 72, 154, + 217, 221, 142, 171, 152, 157, 137, 191, 178, 0, + 79, 80, 75, 343, 66, 345, 0, 0, 0, 0, + 77, 0, 0, 73, 76, 70, 0, 0, 67, 69, + 68, 78, 71, 0, 74, 0, 0, 167, 0, 0, + 154, 173, 156, 155, 0, 0, 0, 169, 170, 168, + 172, 0, 202, 0, 0, 0, 0, 192, 0, 0, + 0, 0, 0, 0, 182, 0, 0, 0, 176, 177, + 175, 180, 184, 183, 181, 179, 194, 193, 195, 0, + 210, 0, 206, 0, 0, 148, 135, 147, 136, 104, + 105, 106, 131, 107, 132, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 133, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 134, + 0, 0, 146, 242, 149, 0, 150, 0, 151, 145, + 0, 238, 231, 229, 236, 237, 235, 234, 240, 233, + 232, 230, 239, 226, 0, 214, 0, 0, 218, 0, + 0, 222, 0, 0, 148, 140, 0, 139, 0, 144, + 158, 0, 344, 333, 334, 0, 331, 0, 332, 0, + 335, 249, 256, 255, 263, 251, 0, 252, 336, 0, + 342, 253, 254, 259, 257, 339, 337, 341, 260, 0, + 271, 0, 0, 0, 0, 343, 66, 0, 345, 67, + 243, 285, 68, 0, 0, 0, 272, 0, 0, 261, + 262, 0, 250, 258, 286, 287, 330, 340, 0, 301, + 302, 303, 304, 0, 297, 298, 299, 300, 327, 328, + 0, 0, 0, 0, 0, 290, 291, 247, 245, 207, + 215, 211, 227, 203, 248, 0, 154, 219, 223, 196, + 185, 0, 0, 204, 0, 0, 0, 0, 197, 0, + 0, 0, 0, 0, 189, 187, 190, 188, 186, 199, + 198, 200, 0, 212, 0, 208, 0, 246, 154, 0, + 228, 243, 244, 0, 243, 0, 0, 293, 0, 0, + 0, 295, 0, 216, 0, 0, 220, 0, 0, 224, + 283, 0, 275, 284, 278, 0, 282, 0, 243, 276, + 0, 243, 0, 0, 294, 0, 0, 0, 296, 344, + 333, 0, 0, 335, 0, 329, 0, 319, 0, 0, + 0, 289, 0, 288, 0, 346, 0, 103, 265, 268, + 0, 104, 271, 107, 132, 109, 110, 75, 114, 115, + 66, 116, 119, 73, 76, 67, 243, 68, 78, 122, + 71, 124, 74, 126, 127, 272, 129, 130, 134, 0, + 96, 0, 0, 98, 102, 100, 87, 99, 101, 0, + 97, 86, 266, 264, 142, 143, 148, 0, 141, 0, + 318, 0, 305, 306, 0, 317, 0, 0, 0, 308, + 313, 311, 314, 0, 0, 312, 313, 0, 309, 0, + 310, 267, 316, 0, 267, 315, 0, 320, 321, 0, + 267, 322, 323, 0, 0, 324, 0, 0, 0, 325, + 326, 160, 159, 0, 0, 0, 292, 0, 0, 0, + 307, 280, 273, 0, 281, 277, 0, 279, 269, 0, + 270, 274, 90, 0, 0, 94, 81, 0, 83, 92, + 0, 84, 93, 95, 85, 91, 82, 0, 88, 164, + 162, 166, 163, 161, 165, 6, 338, 4, 2, 64, + 89, 0, 0, 67, 69, 68, 31, 5, 0, 65, 0, 41, 40, 39, 0, 0, 54, 0, 55, 0, 60, 61, 0, 41, 0, 0, 0, 0, 0, 50, - 51, 0, 52, 0, 53, 0, 56, 57, 0, 0, - 0, 0, 0, 58, 59, 0, 48, 42, 49, 43, - 0, 0, 0, 0, 45, 0, 46, 47, 44, 0, - 0, 0, 30, 35, 36, 37, 38, 140, 265, 0, - 0, 102, 269, 105, 130, 107, 108, 73, 112, 113, - 64, 114, 117, 71, 74, 65, 241, 66, 76, 120, - 69, 122, 72, 124, 125, 270, 127, 128, 132, 140, - 0, 26, 0, 0, 32, 27, 33, 28, 24, 0, - 29, 25, 0, 34, 8, 0, 10, 0, 9, 0, - 1, 21, 12, 0, 13, 0, 14, 0, 19, 20, - 0, 15, 16, 0, 17, 18, 11, 23, 7, 345}; + 0, 51, 0, 0, 26, 0, 0, 62, 27, 0, + 30, 28, 24, 0, 29, 25, 0, 52, 0, 53, + 0, 142, 0, 56, 57, 63, 0, 0, 0, 0, + 0, 58, 59, 0, 48, 42, 49, 43, 0, 0, + 0, 0, 45, 0, 46, 47, 44, 0, 0, 35, + 36, 37, 38, 142, 267, 0, 0, 104, 271, 107, + 132, 109, 110, 75, 114, 115, 66, 116, 119, 73, + 76, 67, 243, 68, 78, 122, 71, 124, 74, 126, + 127, 272, 129, 130, 134, 0, 32, 33, 0, 34, + 8, 0, 10, 0, 9, 0, 1, 21, 12, 0, + 13, 0, 14, 0, 19, 20, 0, 15, 16, 0, + 17, 18, 11, 23, 7, 347}; const short QDeclarativeJSGrammar::goto_default [] = { - 7, 620, 207, 196, 205, 507, 495, 619, 638, 614, - 618, 616, 621, 22, 617, 18, 506, 609, 600, 562, - 508, 191, 195, 197, 201, 524, 550, 549, 200, 232, + 7, 626, 207, 196, 205, 507, 495, 625, 644, 620, + 624, 622, 627, 22, 623, 18, 506, 543, 533, 540, + 535, 191, 195, 197, 201, 524, 568, 567, 200, 232, 26, 474, 473, 356, 355, 9, 354, 357, 107, 17, 145, 24, 13, 144, 19, 25, 57, 23, 8, 28, 27, 269, 15, 263, 10, 259, 12, 261, 11, 260, @@ -211,775 +212,771 @@ const short QDeclarativeJSGrammar::goto_default [] = { 199, 181, 184, 198, 206, 0}; const short QDeclarativeJSGrammar::action_index [] = { - 314, 1273, 2404, 2404, 2307, 1001, 58, 98, 78, -101, - 95, 56, 4, 236, -101, 296, 86, -101, -101, 545, - 97, 115, 162, 197, -101, -101, -101, 447, 192, 1273, - -101, -101, -101, 369, -101, 2113, 1919, 1273, 1273, 1273, - -101, 732, 1273, -101, -101, -101, 1273, 1273, -101, -101, - -101, -101, -101, 1273, -101, 1273, 1273, -101, 1273, 1273, - 81, 195, -101, -101, 1273, 1273, 1273, -101, -101, -101, - 185, 1273, 283, 1273, 1273, 1273, 1273, 447, 1273, 1273, - 1273, 1273, 1273, 1273, 297, 1273, 1273, 1273, 107, 85, - 116, 297, 297, 297, 297, 191, 447, 447, 447, 1273, - 74, 1273, 102, 2016, 1273, 1273, -101, -101, -101, -101, + 421, 1288, 2322, 2322, 2419, 1016, -52, 37, 140, -101, + 35, -13, -40, 190, -101, 272, 34, -101, -101, 658, + 42, 103, 194, 201, -101, -101, -101, 439, 256, 1288, + -101, -101, -101, 282, -101, 2128, 1751, 1288, 1288, 1288, + -101, 917, 1288, -101, -101, -101, 1288, 1288, -101, -101, + -101, -101, -101, 1288, -101, 1288, 1288, -101, 1288, 1288, + 109, 245, -101, -101, 1288, 1288, 1288, -101, -101, -101, + 185, 1288, 295, 1288, 1288, 1288, 1288, 461, 1288, 1288, + 1288, 1288, 1288, 1288, 256, 1288, 1288, 1288, 155, 119, + 114, 176, 256, 332, 202, 332, 560, 560, 471, 1288, + -23, 1288, 53, 2031, 1288, 1288, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, -101, - 112, 1273, -101, -101, 92, 61, -101, 1273, -101, -101, - 1273, -101, -101, -101, -101, -101, -101, -101, -101, -101, - -101, -101, -101, -101, 1273, 36, 1273, 1273, 65, 62, - 1273, -101, 2016, 1273, 1273, -101, 127, -101, 42, -101, - -101, 57, -101, 294, 60, 35, -101, 259, -101, 32, - 2404, -101, -101, -101, -101, -101, 200, -101, -101, 33, - -101, -101, -101, -101, -101, -101, 2404, -101, -101, 436, - -101, 433, 100, 2307, 34, 369, 67, 45, 2598, 71, - 1273, -101, 72, 51, 1273, 59, -101, 54, 55, -101, - -101, 324, -101, -101, -101, -101, -101, -101, 88, -101, - -101, -101, -101, 76, -101, -101, -101, -101, -101, -101, - 5, 49, 1273, 104, 84, -101, -101, 1457, -101, 70, - 41, 1, -101, 287, 68, 46, 643, 73, 77, 364, - 297, 369, 1273, 238, 1273, 1273, 1273, 1273, 341, 1273, - 1273, 1273, 1273, 1273, 297, 175, 167, 161, 176, 348, - 315, 331, 1273, -13, 1273, 63, 1273, -101, 545, 1273, - -101, 1273, 64, 40, 1273, 2, 2307, -101, 1273, 152, - 2307, -101, 1273, 69, 1273, 1273, 75, 79, 1273, -101, - 44, 149, 66, -101, -101, 1273, -101, 369, 1273, -101, - 52, 1273, -54, 2307, -101, 1273, 151, 2307, -101, -29, - 369, -41, -11, 2404, -46, -101, 2307, -101, 1273, 131, - 2307, -5, 2307, -101, 8, 13, -55, -101, -101, 2307, - -51, 360, -2, 352, 119, 1273, 2307, 39, -19, 366, - 3, -24, 910, 6, 7, -101, 1367, -101, 11, -16, - -4, 1273, -6, -31, 1273, 9, 1273, -12, 17, 1273, - -101, 2210, 37, -101, -101, -101, -101, -101, -101, 1273, - -101, -101, -101, -101, 258, -101, 1273, -15, -101, 2307, - -101, 117, -101, -101, 2307, -101, 1273, 106, 16, -101, - 38, -101, 135, 96, 1273, -101, 135, 43, -101, 18, - -101, 2307, -101, 101, 2307, -101, 179, -101, -101, 99, - 2307, 31, -101, -7, -8, -101, 369, -34, -1, -101, - -101, -101, -101, 1273, 124, 2307, -101, 1273, 122, 2307, - -101, 25, -101, 207, -101, -101, 1273, -101, -101, 290, - -101, -101, -101, 114, 1733, -101, -101, 1826, -101, -101, - 1550, -101, -101, -101, -101, -101, -101, 103, -101, -101, - -101, -101, -101, -101, -101, -101, 2404, -101, -101, -101, - 221, -43, 704, 164, -26, 12, -101, -101, 188, -101, - 196, -101, -101, -101, 369, 183, -101, 1273, -101, 165, - -101, -101, 170, 0, 369, 160, 10, 369, 113, -101, - -101, 215, -101, 1273, -101, 225, -101, -101, 203, 369, - 28, 1273, 229, -101, -101, 202, -101, 218, -101, 30, - -21, 369, 199, 278, -101, 110, -101, -101, -101, 1640, - 1092, 583, -101, -101, -101, -101, -101, 284, 2501, 1919, - 14, 388, 29, 424, 93, 1273, 2307, 39, -9, 338, - 21, -3, 821, 24, 23, -101, 1367, -101, 48, 20, - 47, 1273, 50, 26, 1273, 53, 1273, 27, 22, 264, - 120, -101, 15, 813, -101, -101, -101, -101, -101, 1183, - -101, -101, 19, -101, -101, 498, -101, 249, -82, 902, - -101, -101, 118, 369, -101, 204, -101, 80, -101, -101, - 369, -101, -101, 82, -101, -101, -101, -101, -101, -101, + 100, 1288, -101, -101, 70, 59, -101, 1288, -101, -101, + 1288, -101, -101, -101, -101, -101, -101, -101, -101, -101, + -101, -101, -101, -101, 1288, 41, 1288, 1288, 98, 91, + 1288, -101, 2031, 1288, 1288, -101, 121, -101, 73, -101, + -101, 39, -101, 385, 180, 78, -101, 391, -101, 64, + 2322, -101, -101, -101, -101, -101, 208, -101, -101, 82, + -101, -101, -101, -101, -101, -101, 2322, -101, -101, 538, + -101, 495, 128, 2419, 54, 358, 62, 44, 2613, 67, + 1288, -101, 76, 63, 1288, 58, -101, 60, 46, -101, + -101, 309, -101, -101, -101, -101, -101, -101, 86, -101, + -101, -101, -101, 107, -101, -101, -101, -101, -101, -101, + 28, 52, 1288, 101, 102, -101, -101, 1472, -101, 83, + 75, 79, -101, 287, 84, 80, 585, 69, 89, 321, + 177, 482, 1288, 297, 1288, 1288, 1288, 1288, 331, 1288, + 1288, 1288, 1288, 1288, 332, 222, 332, 332, 332, 410, + 410, 410, 1288, 57, 1288, 72, 1288, -101, 658, 1288, + -101, 1288, 71, 45, 1288, 61, 2419, -101, 1288, 132, + 2419, -101, 1288, 47, 1288, 1288, 66, 65, 1288, -101, + 68, 112, 81, -101, -101, 1288, -101, 369, 1288, -101, + 85, 1288, 74, 2419, -101, 1288, 122, 2419, -101, 77, + 294, 16, -29, 2322, -53, -101, 2419, -101, 1288, 127, + 2419, -15, 2419, -101, 10, 11, -34, -101, -101, 2419, + -48, 504, 4, 476, 113, 1288, 2419, 2, -28, 420, + 6, -21, 719, 7, 87, -101, 1382, -101, -4, -16, + 5, 1288, 3, -27, 1288, 9, 1288, -18, -31, 1288, + -101, 2225, -7, -101, -101, -101, -101, -101, -101, 1288, + -101, -101, -101, -101, 246, -101, 1288, -38, -101, 2419, + -101, 88, -101, -101, 2419, -101, 1288, 106, 26, -101, + 55, -101, 50, 105, 1288, -101, 48, 38, -101, -8, + -101, 2419, -101, 94, 2419, -101, 238, -101, -101, 104, + 2419, 31, -101, 21, 19, -101, 305, 1, 30, -101, + -101, -101, -101, 1288, 136, 2419, -101, 1288, 134, 2419, + -101, 49, -101, 173, -101, -101, 1288, -101, -101, 363, + -101, -101, -101, 137, 1565, -101, -101, 1658, -101, -101, + 1844, -101, -101, -101, -101, -101, -101, 95, -101, -101, + -101, -101, -101, -101, -101, -101, 2322, -101, -101, -101, + 92, 15, 925, 169, 27, -6, -101, -101, 212, -101, + 191, -101, -101, -101, 323, 211, -101, 1288, -101, 214, + -101, -101, 216, 40, 317, 210, 43, 259, 236, -101, + 36, -101, 747, 96, -101, 29, 747, -101, -101, 1198, + -101, -101, -101, 1107, -101, -101, 231, -101, 1288, -101, + 217, 286, 32, -101, -101, -101, 188, 340, 51, 1288, + 175, -101, -101, 171, -101, 179, -101, 56, -11, 351, + 181, 336, -101, 110, -101, -101, -101, 1934, 647, -101, + -101, -101, -101, 253, 2516, 1751, -5, 460, 22, 468, + 138, 1288, 2419, 24, -2, 412, 23, -3, 836, 20, + 87, -101, 1382, -101, 17, -10, 18, 1288, 25, 8, + 1288, 33, 1288, 12, 14, 120, -101, -101, 13, -101, + -101, 747, -101, 248, -47, 828, -101, -101, 152, 482, + -101, 150, -101, 123, -101, -101, 398, -101, -101, 117, + -101, -101, -101, -101, -101, -101, - -106, 17, -83, 19, 24, 228, -106, -106, -106, -106, - -106, -106, -106, -106, -106, -106, -106, -106, -106, -49, - -106, -106, -106, -106, -106, -106, -106, -106, -106, 101, - -106, -106, -106, 2, -106, -106, -2, 29, 107, 166, - -106, 204, 183, -106, -106, -106, 174, 169, -106, -106, - -106, -106, -106, 145, -106, 141, 137, -106, 152, 161, - -106, -106, -106, -106, 163, 158, 157, -106, -106, -106, - -106, 132, -106, 142, 138, 187, 178, -106, 167, 181, - 81, 82, 85, 83, -106, 93, 114, 96, -106, -106, - -106, -106, -106, -106, -106, -106, -106, -106, -106, 170, - -106, 74, -106, 109, 80, 51, -106, -106, -106, -106, + -106, 6, -92, 10, 5, 278, -106, -106, -106, -106, + -106, -106, -106, -106, -106, -106, -106, -106, -106, -42, + -106, -106, -106, -106, -106, -106, -106, -106, -106, 109, + -106, -106, -106, -10, -106, -106, -35, 24, 73, 90, + -106, 219, 181, -106, -106, -106, 171, 120, -106, -106, + -106, -106, -106, 174, -106, 170, 167, -106, 175, 163, + -106, -106, -106, -106, 184, 177, 180, -106, -106, -106, + -106, 125, -106, 132, 134, 162, 130, -106, 121, 124, + 123, 141, 142, 152, -106, 154, 161, 160, -106, -106, + -106, -106, -106, -106, -106, -106, -106, -106, -106, 139, + -106, 143, -106, 156, 91, 55, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, - -106, 25, -106, -106, -106, -106, -106, 41, -106, -106, - 50, -106, -106, -106, -106, -106, -106, -106, -106, -106, - -106, -106, -106, -106, 98, -106, 104, 43, -106, -106, - 42, -106, 221, 64, 117, -106, -106, -106, -106, -106, - -106, -106, -106, 54, -106, -106, -106, 55, -106, -106, + -106, 32, -106, -106, -106, -106, -106, 33, -106, -106, + 26, -106, -106, -106, -106, -106, -106, -106, -106, -106, + -106, -106, -106, -106, 96, -106, 119, 52, -106, -106, + 66, -106, 220, 69, 71, -106, -106, -106, -106, -106, + -106, -106, -106, 25, -106, -106, -106, 64, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, - -106, -106, -106, -106, -106, -106, 47, -106, -106, 38, - -106, 33, -106, 92, -106, 73, -106, -106, 88, -106, - 86, -106, -106, -106, 94, 23, -106, -106, -106, -106, - -106, -11, -106, -106, -106, -106, -106, -106, -106, -106, + -106, -106, -106, -106, -106, -106, 70, -106, -106, 61, + -106, 41, -106, 39, -106, 37, -106, -106, 42, -106, + 79, -106, -106, -106, 81, 72, -106, -106, -106, -106, + -106, -5, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, - -106, -106, 22, -106, -106, -106, -106, 105, -106, -106, + -106, -106, 21, -106, -106, -106, -106, 112, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, -106, - -106, 7, 235, -106, 249, 219, 216, 222, -106, 124, - 125, 123, 122, 116, -106, -106, -106, -106, -106, -106, - -106, -106, 191, -106, 232, -106, 225, -106, -106, 231, - -106, 156, -106, -106, 130, -106, 91, -106, 5, -106, - 8, -106, 233, -106, 200, 189, -106, -106, 198, -106, - -106, -106, -106, -106, -106, 245, -106, 108, 95, -106, - -106, 298, -106, 195, -106, 89, -106, 71, -106, -106, - 120, -106, -106, -5, -106, -106, 52, -106, 53, -106, - 56, -106, 60, -106, -106, -106, -106, -106, -106, 39, - -106, 37, -106, 49, -106, 133, 69, -106, -106, 59, - -106, -106, 102, -106, -106, -106, 79, -106, -106, -106, - -106, 62, -106, 45, 67, -106, 75, -106, -106, 44, - -106, 1, -106, -106, -106, -106, -106, -106, -106, 46, - -106, -106, -106, -106, -106, -106, 115, -106, -106, 66, - -106, -106, -106, -106, 70, -106, 77, -106, -106, -106, - -106, -106, -9, -106, 72, -106, -38, -106, -106, -106, - -106, 97, -106, -106, 99, -106, -106, -106, -106, -106, - 40, -51, -106, -106, 36, -106, 34, -106, 63, -106, - -106, -106, -106, 35, -106, 48, -106, 58, -106, 57, - -106, -106, -106, -106, -106, -106, 28, -106, -106, 90, - -106, -106, -106, -106, 65, -106, -106, 159, -106, -106, - 61, -106, -106, -106, -106, -106, -106, -106, -106, -106, - -106, -106, -106, -106, -106, -106, 87, -106, -106, -106, - -106, -106, -13, -106, -106, -106, -106, -106, -106, -106, - -18, -106, -106, -106, -10, -106, -106, 0, -106, -106, - -106, -106, -106, -106, -4, -12, -106, -6, -106, -106, - -106, -106, -106, 3, -106, -106, -106, -106, -23, -14, - -106, 11, -106, -106, -106, -106, -106, 15, -106, -106, - -106, 16, 18, 14, -106, -106, -106, -106, -106, 292, - 399, 180, -106, -106, -106, -106, -106, -106, 26, 286, - 20, 21, -106, 30, -106, 177, 10, -106, -106, 31, - -106, -106, 193, -106, -106, -106, 32, -106, -106, -106, - -106, 27, -106, 13, 76, -106, 68, -106, -106, -106, - -106, -106, -106, 230, -106, -106, -106, -106, -106, 290, - -106, -106, -3, -106, -106, 6, -106, -106, 4, 270, - -106, -106, -106, 9, -106, -106, -106, -106, -106, -106, - 12, -106, -106, -106, -106, -106, -106, -106, -106, -106}; + -106, 17, 237, -106, 192, 236, 224, 225, -106, 97, + 98, 101, 99, 113, -106, -106, -106, -106, -106, -106, + -106, -106, 204, -106, 223, -106, 235, -106, -106, 239, + -106, 197, -106, -106, 228, -106, 27, -106, 13, -106, + 2, -106, 233, -106, 190, 198, -106, -106, 196, -106, + -106, -106, -106, -106, -106, 200, -106, 107, 135, -106, + -106, 186, -106, 84, -106, 80, -106, 76, -106, -106, + 89, -106, -106, -49, -106, -106, 47, -106, 40, -106, + 44, -106, 68, -106, -106, -106, -106, -106, -106, 53, + -106, 35, -106, 49, -106, 87, 63, -106, -106, 30, + -106, -106, 103, -106, -106, -106, 51, -106, -106, -106, + -106, 86, -106, 67, 114, -106, 74, -106, -106, 65, + -106, 56, -106, -106, -106, -106, -106, -106, -106, 62, + -106, -106, -106, -106, -106, -106, 95, -106, -106, 78, + -106, -106, -106, -106, 75, -106, 88, -106, -106, -106, + -106, -106, -54, -106, 45, -106, -40, -106, -106, -106, + -106, 94, -106, -106, 100, -106, -106, -106, -106, -106, + 150, -41, -106, -106, 54, -106, 43, -106, 48, -106, + -106, -106, -106, 59, -106, 57, -106, 60, -106, 58, + -106, -106, -106, -106, -106, -106, 38, -106, -106, 144, + -106, -106, -106, -106, 31, -106, -106, 202, -106, -106, + 50, -106, -106, -106, -106, -106, -106, -106, -106, -106, + -106, -106, -106, -106, -106, -106, 77, -106, -106, -106, + -106, -106, 82, -106, -106, -106, -106, -106, -106, -106, + -17, -106, -106, -106, -4, -106, -106, 12, -106, -106, + -106, -106, -106, -106, -14, 46, -106, -13, -106, -106, + -106, -106, 108, -106, -106, -106, 243, -106, -106, 295, + -106, -106, -106, 290, -106, -106, -106, -106, 346, -106, + -106, -106, 16, -106, -106, -106, 22, 23, -106, 34, + -106, -106, -106, -106, -106, 11, -106, -106, -106, 7, + 1, 8, -106, -106, -106, -106, -106, 307, 179, -106, + -106, -106, -106, -106, 18, 281, 9, 15, -106, 4, + -106, 83, 29, -106, -106, -2, -106, -106, 85, -106, + -106, -106, 3, -106, -106, -106, -106, 14, -106, 0, + 105, -106, 93, -106, -106, -106, -106, -106, -1, -106, + -106, 20, -106, -106, 28, 92, -106, -106, -106, 19, + -106, -106, -106, -106, -106, -106, -12, -106, -106, -106, + -106, -106, -106, -106, -106, -106}; const short QDeclarativeJSGrammar::action_info [] = { - 401, -123, 440, -121, 403, -129, 333, 340, 615, 345, - -96, 352, 348, -118, -100, 389, -126, 257, -99, 342, - 416, 391, 343, 510, 453, 440, 448, 257, -96, 446, - -100, -118, 440, 348, 527, 541, -129, 525, 552, 555, - 538, 545, 466, 424, 399, 408, -110, 560, 560, 420, - 431, 444, 560, 457, -121, -99, 416, -123, 457, 440, - -126, 325, 306, 453, 272, 190, 294, 164, 187, 170, - 257, 272, 141, 430, 346, 312, 296, 312, 409, 414, - 294, 348, 251, 101, 99, 252, 318, 416, 236, 292, - 453, 457, 440, 183, 141, 189, 71, 335, 639, 164, - 147, 304, 179, 71, 99, 443, 427, 301, 434, 141, - 0, 141, 141, 331, 141, 0, 0, 292, 58, 444, - 141, 149, 477, 62, 0, 58, 0, 314, 603, 59, - 141, 315, 141, 172, 63, 141, 59, 247, 246, 141, - 424, 629, 628, 635, 634, 256, 255, 58, 615, 242, - 241, 428, 173, 101, 249, 248, 58, 327, 59, 141, - 141, 249, 248, 488, 254, 166, 418, 59, 142, 167, - 478, 557, 556, 141, 530, 529, 604, 172, 413, 412, - 249, 248, 459, 177, 455, 172, 85, 141, 86, 511, - 517, 350, 85, 523, 86, 559, 173, 64, 174, 87, - 85, 85, 86, 86, 173, 87, 406, 64, 141, 64, - 328, 337, 310, 87, 87, 469, 85, 85, 86, 86, - 0, 560, 533, 0, 0, 511, 521, 520, 511, 87, - 87, 0, 511, 141, 0, 513, 172, 141, 547, 513, - 438, 437, 65, 0, 518, 516, 512, 511, 66, 0, - 512, 103, 65, 0, 65, 173, 274, 275, 66, 0, - 66, 235, 234, 548, 546, 632, 631, 0, 470, 468, - 104, 513, 105, 172, 513, 0, 534, 532, 513, 172, - 561, 0, 512, 276, 277, 512, 537, 536, 34, 512, - 544, 543, 173, 513, 406, 630, 625, -87, 173, 172, - 174, 73, 74, 0, 512, 274, 275, 34, 0, 0, - 626, 624, 0, 0, 73, 74, 0, -87, 173, 34, - 174, 0, 85, 34, 86, 48, 50, 49, 75, 76, - 0, 0, 276, 277, 0, 87, 0, 0, 279, 280, - 623, 75, 76, 0, 48, 50, 49, 281, 0, 0, - 282, 45, 283, 34, 279, 280, 48, 50, 49, 0, - 48, 50, 49, 281, 279, 280, 282, 34, 283, 0, - 45, 279, 280, 281, -341, 0, 282, 0, 283, 0, - 281, 34, 45, 282, 0, 283, 45, 279, 280, 34, - 48, 50, 49, 0, 0, 34, 281, 0, 34, 282, - 0, 283, -341, 0, 48, 50, 49, 6, 5, 4, - 1, 3, 2, 245, 244, 0, 45, 34, 48, 50, - 49, 240, 239, 0, 0, 0, 48, 50, 49, 0, - 45, 0, 48, 50, 49, 48, 50, 49, 0, 0, - 0, 0, 0, 0, 45, 0, 0, 0, 0, 240, - 239, 0, 45, 34, 48, 50, 49, 0, 45, 0, - 0, 45, 34, 0, 0, 34, 0, 0, 0, 0, - 78, 79, 0, 0, 0, 0, 0, 0, 80, 81, - 45, 0, 82, 0, 83, 245, 244, 0, 0, 0, - 48, 50, 49, 0, 245, 244, 0, 240, 239, 48, - 50, 49, 48, 50, 49, 0, 0, 0, 0, 0, - 30, 31, 0, 0, 0, 0, 45, 0, 0, 0, - 33, 0, 0, 0, 0, 45, 0, 34, 45, 0, + 399, 352, 345, -101, 343, 457, 440, 403, 257, -112, + -125, -131, -123, -98, -120, 348, -128, 389, 453, 391, + 416, 401, 408, 563, -101, -123, 416, -120, 539, -131, + -98, -112, -125, 348, 257, 99, 71, 645, 621, 101, + -128, 440, 141, 621, 164, 431, 539, 430, 453, 573, + 457, 444, 440, 424, 71, 424, 101, 446, 559, 420, + 424, 448, 539, 440, 570, 539, 466, 527, 312, 346, + 532, 312, 318, 272, 409, 183, 342, 525, 147, 141, + 348, 510, 457, 414, 272, 325, 0, 0, 252, 99, + 257, 440, 296, 556, -102, 292, 453, 190, 170, 416, + 164, 434, 141, 141, 536, 251, 304, 172, 141, 141, + 443, 0, 335, 340, 141, 427, 0, 0, 0, 149, + 327, 306, 0, 292, 444, 0, 173, 0, 536, 141, + 141, 0, 0, 179, 333, 141, 294, 236, 189, 314, + 141, 301, 141, 315, 141, 477, 331, 242, 241, 413, + 412, 62, 537, 166, 58, 488, 142, 167, 294, 58, + 428, 254, 63, 256, 255, 59, 418, 172, 247, 246, + 59, 575, 574, 328, 249, 248, 616, 177, 641, 640, + 58, 469, 337, 141, 635, 634, 173, 350, 187, 249, + 248, 59, 310, 478, 459, 58, 455, 64, 523, 249, + 248, 85, 85, 86, 86, 103, 59, 565, 511, 172, + 511, 638, 637, 64, 87, 87, 141, 511, 517, 577, + 511, 0, 141, 0, 104, 141, 105, 85, 173, 86, + 174, 172, 566, 564, 470, 468, 562, 561, 548, 511, + 87, 636, 65, 530, 513, 539, 141, 85, 66, 86, + 173, 0, 406, 0, 513, 512, 513, 64, 65, 0, + 87, 172, 0, 513, 66, 512, 513, 512, 172, 235, + 234, 0, 518, 516, 512, 521, 520, 512, 554, 553, + 173, 85, 406, 86, 0, 513, -89, 173, 34, 174, + 73, 74, 549, 547, 87, 631, 512, 531, 529, 438, + 437, 172, 65, 0, 578, 274, 275, 0, 66, 632, + 630, 34, 0, 73, 74, 274, 275, 75, 76, -89, + 173, 0, 174, 34, 0, 48, 50, 49, 0, 0, + 0, 0, 276, 277, 34, 0, 0, 0, 34, 629, + 75, 76, 276, 277, 279, 280, 34, 0, 48, 50, + 49, 45, 34, 281, 279, 280, 282, 85, 283, 86, + 48, 50, 49, 281, 0, 34, 282, 0, 283, 34, + 87, 48, 50, 49, 45, 48, 50, 49, 0, 0, + 34, 0, 0, 48, 50, 49, 45, 34, 0, 48, + 50, 49, 34, 0, 0, 0, 0, 45, 34, 0, + 0, 45, 48, 50, 49, 0, 48, 50, 49, 45, + 0, 0, 0, 0, 34, 45, 0, 48, 50, 49, + 34, 0, 0, 0, 48, 50, 49, 34, 45, 48, + 50, 49, 45, 279, 280, 48, 50, 49, 0, 0, + 0, 34, 281, 45, 0, 282, 0, 283, -343, 34, + 45, 48, 50, 49, 0, 45, -343, 48, 50, 49, + 0, 45, 78, 79, 48, 50, 49, 0, 0, 0, + 80, 81, 0, 0, 82, 0, 83, 45, 48, 50, + 49, 0, 0, 45, 78, 79, 48, 50, 49, 34, + 45, 0, 80, 81, 78, 79, 82, 34, 83, 0, + 0, 0, 80, 81, 45, 34, 82, 0, 83, 0, + 0, 34, 45, 0, 6, 5, 4, 1, 3, 2, + 0, 240, 239, 0, 34, 0, 48, 50, 49, 245, + 244, 0, 0, 34, 48, 50, 49, 245, 244, 0, + 0, 0, 48, 50, 49, 0, 0, 0, 48, 50, + 49, 0, 45, 0, 0, 0, 245, 244, 0, 0, + 45, 48, 50, 49, 0, 240, 239, 34, 45, 0, + 48, 50, 49, 0, 45, 0, 0, 0, 0, 0, + 0, 0, 0, 78, 79, 0, 0, 45, 151, 0, + 0, 80, 81, 0, 0, 82, 45, 83, 152, 240, + 239, 0, 153, 0, 48, 50, 49, 0, 0, 0, + 0, 154, 0, 155, 0, 0, 308, 0, 0, 0, + 0, 0, 0, 0, 156, 0, 157, 62, 0, 0, + 45, 0, 0, 0, 158, 0, 0, 159, 63, 0, + 0, 0, 0, 160, 0, 0, 0, 0, 0, 161, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 31, 151, 0, 0, 0, 162, 0, 0, 0, 33, + 0, 152, 0, 0, 0, 153, 34, 0, 0, 0, + 35, 36, 0, 37, 154, 0, 155, 0, 0, 0, + 502, 0, 0, 0, 44, 0, 0, 156, 0, 157, + 62, 0, 0, 0, 0, 0, 0, 158, 0, 0, + 159, 63, 51, 48, 50, 49, 160, 52, 0, 0, + 0, 0, 161, 0, 0, 0, 0, 0, 43, 54, + 32, 30, 31, 0, 40, 0, 0, 0, 162, 45, + 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, + 0, 0, 35, 36, 0, 37, 0, 0, 0, 30, + 31, 0, 41, 0, 0, 0, 44, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, + 35, 36, 0, 37, 51, 48, 50, 49, 0, 52, + 502, 0, 0, 0, 44, 0, 0, 0, 0, 0, + 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, + 0, 45, 51, 48, 50, 49, 0, 52, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 43, 54, + 32, 0, 0, 0, 40, 0, 0, 0, 0, 45, + 30, 31, 0, 0, 0, 0, 0, 0, 30, 31, + 33, 0, 0, 0, 0, 0, 0, 34, 33, 0, + 0, 35, 36, 0, 37, 34, 0, 0, 0, 35, + 36, 502, 37, 0, 0, 44, 0, 0, 0, 41, + 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 51, 48, 50, 49, 0, 52, 0, + 0, 51, 48, 50, 49, 0, 52, 0, 0, 43, + 54, 32, 0, 0, 0, 40, 0, 43, 54, 32, + 45, 0, 0, 40, 0, 0, 0, 0, 45, 30, + 31, 0, 0, 0, 0, 0, 0, 30, 31, 33, + 0, 0, 0, 0, 0, 0, 34, 33, 0, 0, + 35, 36, 0, 37, 34, 0, 0, 0, 35, 36, + 41, 37, 0, 0, 44, 0, 0, 0, 502, 0, + 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 51, 48, 50, 49, 0, 52, 0, 0, + 51, 48, 50, 49, 0, 52, 0, 0, 43, 54, + 32, 0, 0, 0, 40, 0, 43, 54, 32, 45, + 0, 0, 40, 0, 0, 0, 0, 45, 0, 0, + 0, 0, 0, 0, 0, 0, 501, 0, 30, 31, + 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, + 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, + 36, 0, 37, 0, 0, 0, 0, 0, 0, 502, + 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 51, 503, 505, 504, 0, 52, 0, 0, 0, + 0, 226, 0, 0, 0, 0, 0, 43, 54, 32, + 210, 0, 0, 40, 0, 0, 0, 0, 45, 0, + 0, 0, 0, 0, 0, 0, 0, 501, 0, 30, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 215, + 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, + 35, 36, 0, 37, 0, 0, 0, 0, 0, 0, + 502, 0, 0, 0, 44, 0, 0, 0, 0, 0, + 0, 0, 544, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 51, 503, 505, 504, 0, 52, 0, 0, + 0, 0, 226, 0, 0, 0, 0, 0, 43, 54, + 32, 210, 0, 0, 40, 0, 0, 0, 0, 45, + 0, 0, 0, 0, 0, 0, 0, 0, 501, 0, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 215, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, 0, 0, 0, 0, 0, - 0, 502, 0, 0, 0, 44, 0, 0, 151, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 152, 0, - 0, 0, 153, 51, 48, 50, 49, 0, 52, 0, - 0, 154, 0, 155, 0, 0, 0, 0, 0, 43, - 54, 32, 0, 0, 156, 40, 157, 62, 0, 0, - 45, 0, 0, 0, 158, 30, 31, 159, 63, 0, - 0, 0, 0, 160, 0, 33, 0, 0, 0, 161, - 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, - 0, 0, 0, 0, 0, 162, 502, 0, 0, 0, - 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 151, 0, 51, 48, - 50, 49, 0, 52, 0, 0, 152, 0, 0, 0, - 153, 0, 0, 0, 43, 54, 32, 0, 0, 154, - 40, 155, 0, 0, 308, 45, 0, 0, 0, 0, - 0, 0, 156, 0, 157, 62, 0, 0, 0, 0, - 0, 0, 158, 0, 0, 159, 63, 0, 0, 0, - 0, 160, 0, 0, 0, 0, 0, 161, 0, 0, - 0, 0, 0, 0, 0, 0, 30, 31, 0, 0, - 0, 0, 0, 162, 0, 0, 33, 0, 0, 0, - 0, 0, 0, 34, 0, 0, 0, 35, 36, 0, - 37, 0, 0, 0, 30, 31, 0, 502, 0, 0, - 0, 44, 0, 0, 33, 0, 0, 0, 0, 0, - 0, 34, 0, 0, 0, 35, 36, 0, 37, 51, - 48, 50, 49, 0, 52, 41, 0, 0, 0, 44, - 0, 0, 0, 0, 0, 43, 54, 32, 0, 0, - 0, 40, 0, 0, 0, 0, 45, 51, 48, 50, - 49, 0, 52, 0, 0, 0, 0, 0, 0, 0, + 0, 502, 0, 0, 0, 44, 0, 0, 0, 0, + 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 51, 503, 505, 504, 0, 52, 0, + 0, 0, 0, 226, 0, 0, 0, 0, 0, 43, + 54, 32, 210, 0, 0, 40, 0, 0, 0, 0, + 45, 0, 0, 0, 0, 0, 0, 0, 0, 29, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, + 0, 35, 36, 0, 37, 0, 0, 0, 38, 0, + 39, 41, 42, 0, 0, 44, 0, 0, 0, 46, + 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 51, 48, 50, 49, 0, 52, 0, + 53, 0, 55, 0, 56, 0, 0, 0, 0, 43, + 54, 32, 0, 0, 0, 40, 0, 0, 0, 0, + 45, 0, 0, 0, 0, 0, 0, 0, 0, -121, + 0, 0, 0, 29, 30, 31, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, + 0, 34, 0, 0, 0, 35, 36, 0, 37, 0, + 0, 0, 38, 0, 39, 41, 42, 0, 0, 44, + 0, 0, 0, 46, 0, 47, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 51, 48, 50, + 49, 0, 52, 0, 53, 0, 55, 0, 56, 0, 0, 0, 0, 43, 54, 32, 0, 0, 0, 40, - 0, 0, 0, 0, 45, 30, 31, 0, 0, 0, - 0, 0, 0, 30, 31, 33, 0, 0, 0, 0, - 0, 0, 34, 33, 0, 0, 35, 36, 0, 37, - 34, 0, 0, 0, 35, 36, 502, 37, 0, 0, - 44, 0, 0, 0, 41, 0, 0, 0, 44, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 48, - 50, 49, 0, 52, 0, 0, 51, 48, 50, 49, - 0, 52, 0, 0, 43, 54, 32, 0, 0, 0, - 40, 0, 43, 54, 32, 45, 0, 0, 40, 0, - 0, 0, 0, 45, 30, 31, 0, 0, 0, 0, - 0, 0, 30, 31, 33, 0, 0, 0, 0, 0, - 0, 34, 33, 0, 0, 35, 36, 0, 37, 34, - 0, 0, 0, 35, 36, 502, 37, 0, 0, 44, - 0, 0, 0, 41, 0, 0, 0, 44, 0, 0, + 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, + 0, 0, 0, 29, 30, 31, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, + 0, 34, 0, 0, 0, 35, 36, 0, 37, 0, + 0, 0, 38, 0, 39, 41, 42, 0, 0, 44, + 0, 0, 0, 46, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 48, 50, - 49, 0, 52, 0, 0, 51, 48, 50, 49, 0, - 52, 0, 0, 43, 54, 32, 0, 0, 0, 40, - 0, 43, 54, 32, 45, 0, 0, 40, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 501, 0, 30, 31, 0, 0, 0, 0, 0, - 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, + 49, 0, 52, 0, 53, 0, 55, 271, 56, 0, + 0, 0, 0, 43, 54, 32, 0, 0, 0, 40, + 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, + 0, 0, 0, 483, 0, 0, 29, 30, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 0, 34, 0, 0, 0, 35, 36, + 0, 37, 0, 0, 0, 38, 0, 39, 41, 42, + 0, 0, 44, 0, 0, 0, 46, 0, 47, 0, + 0, 486, 0, 0, 0, 0, 0, 0, 0, 0, + 51, 48, 50, 49, 0, 52, 0, 53, 0, 55, + 0, 56, 0, 0, 0, 0, 43, 54, 32, 0, + 0, 0, 40, 0, 0, 0, 0, 45, 0, 0, + 0, 0, 0, 0, 0, 0, 475, 0, 0, 29, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, + 0, 35, 36, 0, 37, 0, 0, 0, 38, 0, + 39, 41, 42, 0, 0, 44, 0, 0, 0, 46, + 0, 47, 0, 0, 481, 0, 0, 0, 0, 0, + 0, 0, 0, 51, 48, 50, 49, 0, 52, 0, + 53, 0, 55, 0, 56, 0, 0, 0, 0, 43, + 54, 32, 0, 0, 0, 40, 0, 0, 0, 0, + 45, 0, 0, 0, 0, 0, 0, 0, 0, 475, + 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, 0, 0, - 0, 0, 0, 0, 502, 0, 0, 0, 44, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 51, 503, 505, 504, - 0, 52, 0, 0, 0, 0, 226, 0, 0, 0, - 0, 0, 43, 54, 32, 210, 0, 0, 40, 0, + 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, + 0, 0, 46, 0, 47, 0, 0, 476, 0, 0, + 0, 0, 0, 0, 0, 0, 51, 48, 50, 49, + 0, 52, 0, 53, 0, 55, 0, 56, 0, 0, + 0, 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, - 0, 0, 501, 0, 30, 31, 0, 0, 0, 0, - 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, - 0, 34, 0, 0, 0, 35, 36, 0, 37, 0, - 0, 0, 0, 0, 0, 502, 0, 0, 0, 44, - 0, 0, 0, 0, 0, 0, 0, 607, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 51, 503, 505, - 504, 0, 52, 0, 0, 0, 0, 226, 0, 0, - 0, 0, 0, 43, 54, 32, 210, 0, 0, 40, - 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, - 0, 0, 0, 501, 0, 30, 31, 0, 0, 0, - 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, - 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, - 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, - 44, 0, 0, 0, 0, 0, 0, 0, 610, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 503, - 505, 504, 0, 52, 0, 0, 0, 0, 226, 0, - 0, 0, 0, 0, 43, 54, 32, 210, 0, 0, - 40, 0, 0, 0, 0, 45, 0, 0, 0, 0, - 0, 0, 0, 0, 29, 30, 31, 0, 0, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, - 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, - 0, 0, 0, 38, 0, 39, 41, 42, 0, 0, - 44, 0, 0, 0, 46, 0, 47, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 48, - 50, 49, 0, 52, 0, 53, 0, 55, 0, 56, - 0, 0, 0, 0, 43, 54, 32, 0, 0, 0, - 40, 0, 0, 0, 0, 45, 0, 0, 0, 0, - 0, 0, 0, 0, -119, 0, 0, 0, 29, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, - 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, - 35, 36, 0, 37, 0, 0, 0, 38, 0, 39, - 41, 42, 0, 0, 44, 0, 0, 0, 46, 0, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 51, 48, 50, 49, 0, 52, 0, 53, - 0, 55, 0, 56, 0, 0, 0, 0, 43, 54, - 32, 0, 0, 0, 40, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, - 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, - 35, 36, 0, 37, 0, 0, 0, 38, 0, 39, - 41, 42, 0, 0, 44, 0, 0, 0, 46, 0, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 51, 48, 50, 49, 0, 52, 0, 53, - 0, 55, 271, 56, 0, 0, 0, 0, 43, 54, - 32, 0, 0, 0, 40, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 483, 0, - 0, 29, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, - 0, 0, 0, 35, 36, 0, 37, 0, 0, 0, - 38, 0, 39, 41, 42, 0, 0, 44, 0, 0, - 0, 46, 0, 47, 0, 0, 484, 0, 0, 0, - 0, 0, 0, 0, 0, 51, 48, 50, 49, 0, - 52, 0, 53, 0, 55, 0, 56, 0, 0, 0, - 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 29, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, - 217, 0, 0, 568, 569, 0, 37, 0, 0, 0, - 38, 0, 39, 41, 42, 0, 0, 44, 0, 0, - 0, 46, 0, 47, 0, 0, 0, 0, 0, 0, - 0, 221, 0, 0, 0, 51, 48, 50, 49, 0, - 52, 0, 53, 0, 55, 0, 56, 0, 0, 0, - 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 483, 0, 0, 29, 30, 31, 0, 0, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, - 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, - 0, 0, 0, 38, 0, 39, 41, 42, 0, 0, - 44, 0, 0, 0, 46, 0, 47, 0, 0, 486, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 48, - 50, 49, 0, 52, 0, 53, 0, 55, 0, 56, - 0, 0, 0, 0, 43, 54, 32, 0, 0, 0, - 40, 0, 0, 0, 0, 45, 0, 0, 0, 0, - 0, 0, 0, 0, 475, 0, 0, 29, 30, 31, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, - 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, - 36, 0, 37, 0, 0, 0, 38, 0, 39, 41, - 42, 0, 0, 44, 0, 0, 0, 46, 0, 47, - 0, 0, 481, 0, 0, 0, 0, 0, 0, 0, - 0, 51, 48, 50, 49, 0, 52, 0, 53, 0, - 55, 0, 56, 0, 0, 0, 0, 43, 54, 32, - 0, 0, 0, 40, 0, 0, 0, 0, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, - 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 0, 35, 36, 0, 37, 0, 0, 0, 38, - 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, - 46, 0, 47, 0, 0, 476, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 48, 50, 49, 0, 52, - 0, 53, 0, 55, 0, 56, 0, 0, 0, 0, - 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, - 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, - 109, 110, 111, 0, 0, 113, 115, 116, 0, 0, - 117, 0, 118, 0, 0, 0, 120, 121, 122, 0, - 0, 0, 0, 0, 0, 34, 123, 124, 125, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 129, 0, 0, 0, 0, - 0, 0, 48, 50, 49, 130, 131, 132, 0, 134, - 135, 136, 137, 138, 139, 0, 0, 127, 133, 119, - 112, 114, 128, 0, 0, 0, 0, 0, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 109, 110, 111, - 0, 0, 113, 115, 116, 0, 0, 117, 0, 118, - 0, 0, 0, 120, 121, 122, 0, 0, 0, 0, - 0, 0, 393, 123, 124, 125, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, - 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 129, 0, 0, 0, 0, 0, 398, 395, - 397, 0, 130, 131, 132, 0, 134, 135, 136, 137, - 138, 139, 0, 0, 127, 133, 119, 112, 114, 128, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 110, 111, 0, 0, 113, - 115, 116, 0, 0, 117, 0, 118, 0, 0, 0, - 120, 121, 122, 0, 0, 0, 0, 0, 0, 393, - 123, 124, 125, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 126, 0, 0, 0, 394, 0, 0, - 0, 0, 0, 0, 0, 396, 0, 0, 0, 129, - 0, 0, 0, 0, 0, 398, 395, 397, 0, 130, - 131, 132, 0, 134, 135, 136, 137, 138, 139, 0, - 0, 127, 133, 119, 112, 114, 128, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 209, 0, 0, 0, 0, 211, 0, 29, 30, - 31, 213, 0, 0, 0, 0, 0, 0, 214, 33, - 0, 0, 0, 0, 0, 0, 216, 217, 0, 0, - 218, 36, 0, 37, 0, 0, 0, 38, 0, 39, - 41, 42, 0, 0, 44, 0, 0, 0, 46, 0, - 47, 0, 0, 0, 0, 0, 220, 0, 221, 0, - 0, 0, 51, 219, 222, 49, 223, 52, 224, 53, - 225, 55, 226, 56, 227, 228, 0, 0, 43, 54, - 32, 210, 212, 0, 40, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 209, 0, - 0, 0, 0, 211, 0, 29, 30, 31, 213, 0, - 0, 0, 0, 0, 0, 214, 215, 0, 0, 0, - 0, 0, 0, 216, 217, 0, 0, 218, 36, 0, + 0, 0, 483, 0, 0, 29, 30, 31, 0, 0, + 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, + 0, 0, 0, 34, 0, 0, 0, 35, 36, 0, + 37, 0, 0, 0, 38, 0, 39, 41, 42, 0, + 0, 44, 0, 0, 0, 46, 0, 47, 0, 0, + 484, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 48, 50, 49, 0, 52, 0, 53, 0, 55, 0, + 56, 0, 0, 0, 0, 43, 54, 32, 0, 0, + 0, 40, 0, 0, 0, 0, 45, 0, 0, 0, + 0, 0, 0, 0, 0, 29, 30, 31, 0, 0, + 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, + 0, 0, 0, 34, 217, 0, 0, 584, 585, 0, 37, 0, 0, 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, 46, 0, 47, 0, 0, - 0, 0, 0, 220, 0, 221, 0, 0, 0, 51, - 219, 222, 49, 223, 52, 224, 53, 225, 55, 226, - 56, 227, 228, 0, 0, 43, 54, 32, 210, 212, + 0, 0, 0, 0, 0, 221, 0, 0, 0, 51, + 48, 50, 49, 0, 52, 0, 53, 0, 55, 0, + 56, 0, 0, 0, 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, 0, 45, 0, 0, 0, - 0, 0, 0, 0, 0, 571, 110, 111, 0, 0, - 573, 115, 575, 30, 31, 576, 0, 118, 0, 0, - 0, 120, 578, 579, 0, 0, 0, 0, 0, 0, - 580, 581, 124, 125, 218, 36, 0, 37, 0, 0, - 0, 38, 0, 39, 582, 42, 0, 0, 584, 0, - 0, 0, 46, 0, 47, 0, 0, 0, 0, 0, - 586, 0, 221, 0, 0, 0, 588, 585, 587, 49, - 589, 590, 591, 53, 593, 594, 595, 596, 597, 598, - 0, 0, 583, 592, 577, 572, 574, 128, 40, 0, + 0, 0, 0, 0, 0, 109, 110, 111, 0, 0, + 113, 115, 116, 0, 0, 117, 0, 118, 0, 0, + 0, 120, 121, 122, 0, 0, 0, 0, 0, 0, + 34, 123, 124, 125, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 129, 0, 0, 0, 0, 0, 0, 48, 50, 49, + 130, 131, 132, 0, 134, 135, 136, 137, 138, 139, + 0, 0, 127, 133, 119, 112, 114, 128, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, - 0, 0, 361, 110, 111, 0, 0, 363, 115, 365, - 30, 31, 366, 0, 118, 0, 0, 0, 120, 368, - 369, 0, 0, 0, 0, 0, 0, 370, 371, 124, - 125, 218, 36, 0, 37, 0, 0, 0, 38, 0, - 39, 372, 42, 0, 0, 374, 0, 0, 0, 46, - 0, 47, 0, -265, 0, 0, 0, 376, 0, 221, - 0, 0, 0, 378, 375, 377, 49, 379, 380, 381, - 53, 383, 384, 385, 386, 387, 388, 0, 0, 373, - 382, 367, 362, 364, 128, 40, 0, 0, 0, 0, - 45, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 109, 110, 111, 0, 0, 113, 115, 116, + 0, 0, 117, 0, 118, 0, 0, 0, 120, 121, + 122, 0, 0, 0, 0, 0, 0, 393, 123, 124, + 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 126, 0, 0, 0, 394, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, + 0, 0, 0, 398, 395, 397, 0, 130, 131, 132, + 0, 134, 135, 136, 137, 138, 139, 0, 0, 127, + 133, 119, 112, 114, 128, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, + 110, 111, 0, 0, 113, 115, 116, 0, 0, 117, + 0, 118, 0, 0, 0, 120, 121, 122, 0, 0, + 0, 0, 0, 0, 393, 123, 124, 125, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 126, 0, + 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, + 396, 0, 0, 0, 129, 0, 0, 0, 0, 0, + 398, 395, 397, 0, 130, 131, 132, 0, 134, 135, + 136, 137, 138, 139, 0, 0, 127, 133, 119, 112, + 114, 128, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, + 0, 211, 0, 29, 30, 31, 213, 0, 0, 0, + 0, 0, 0, 214, 215, 0, 0, 0, 0, 0, + 0, 216, 217, 0, 0, 218, 36, 0, 37, 0, + 0, 0, 38, 0, 39, 41, 42, 0, 0, 44, + 0, 0, 0, 46, 0, 47, 0, 0, 0, 0, + 0, 220, 0, 221, 0, 0, 0, 51, 219, 222, + 49, 223, 52, 224, 53, 225, 55, 226, 56, 227, + 228, 0, 0, 43, 54, 32, 210, 212, 0, 40, + 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, + 0, 0, 0, 209, 0, 0, 0, 0, 211, 0, + 29, 30, 31, 213, 0, 0, 0, 0, 0, 0, + 214, 33, 0, 0, 0, 0, 0, 0, 216, 217, + 0, 0, 218, 36, 0, 37, 0, 0, 0, 38, + 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, + 46, 0, 47, 0, 0, 0, 0, 0, 220, 0, + 221, 0, 0, 0, 51, 219, 222, 49, 223, 52, + 224, 53, 225, 55, 226, 56, 227, 228, 0, 0, + 43, 54, 32, 210, 212, 0, 40, 0, 0, 0, + 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, + 587, 110, 111, 0, 0, 589, 115, 591, 30, 31, + 592, 0, 118, 0, 0, 0, 120, 594, 595, 0, + 0, 0, 0, 0, 0, 596, 597, 124, 125, 218, + 36, 0, 37, 0, 0, 0, 38, 0, 39, 598, + 42, 0, 0, 600, 0, 0, 0, 46, 0, 47, + 0, 0, 0, 0, 0, 602, 0, 221, 0, 0, + 0, 604, 601, 603, 49, 605, 606, 607, 53, 609, + 610, 611, 612, 613, 614, 0, 0, 599, 608, 593, + 588, 590, 128, 40, 0, 0, 0, 0, 45, 0, + 0, 0, 0, 0, 0, 0, 0, 361, 110, 111, + 0, 0, 363, 115, 365, 30, 31, 366, 0, 118, + 0, 0, 0, 120, 368, 369, 0, 0, 0, 0, + 0, 0, 370, 371, 124, 125, 218, 36, 0, 37, + 0, 0, 0, 38, 0, 39, 372, 42, 0, 0, + 374, 0, 0, 0, 46, 0, 47, 0, -267, 0, + 0, 0, 376, 0, 221, 0, 0, 0, 378, 375, + 377, 49, 379, 380, 381, 53, 383, 384, 385, 386, + 387, 388, 0, 0, 373, 382, 367, 362, 364, 128, + 40, 0, 0, 0, 0, 45, 0, 0, 0, 0, + 0, 0, 0, 0, - 522, 540, 539, 519, 461, 515, 535, 514, 309, 528, - 311, 531, 250, 526, 542, 636, 613, 182, 150, 622, - 16, 496, 320, 497, 627, 253, 498, 633, 358, 554, - 436, 558, 487, 472, 439, 302, 238, 392, 454, 606, - 551, 402, 358, 553, 439, 243, 182, 445, 243, 447, - 456, 237, 238, 238, 347, 429, 349, 450, 351, 460, - 143, 458, 353, 467, 243, 436, 439, 176, 410, 186, - 188, 250, 415, 338, 182, 433, 148, 171, 169, 390, - 417, 400, 302, 140, 449, 163, 146, 425, 339, 302, - 358, 237, 336, 307, 250, 344, 482, 436, 302, 358, - 485, 358, 0, 0, 0, 461, 0, 0, 0, 0, - 0, 60, 60, 451, 452, 404, 0, 0, 60, 60, - 60, 452, 451, 320, 106, 60, 60, 60, 102, 60, - 92, 93, 95, 302, 94, 186, 0, 60, 0, 0, - 60, 88, 60, 405, 90, 60, 108, 180, 60, 266, - 146, 60, 146, 489, 270, 407, 165, 178, 60, 302, - 60, 0, 89, 330, 168, 288, 60, 60, 60, 60, - 0, 287, 286, 284, 285, 471, 60, 60, 432, 180, - 435, 60, 60, 452, 72, 60, 60, 451, 96, 60, - 480, 494, 77, 500, 479, 329, 60, 334, 305, 61, - 612, 60, 60, 69, 68, 60, 404, 60, 70, 67, - 60, 60, 490, 60, 60, 493, 84, 404, 60, 341, - 492, 60, 60, 180, 303, 60, 100, 60, 98, 491, - 91, 60, 0, 298, 405, 60, 106, 97, 270, 0, - 270, 500, 298, 500, 60, 405, 605, 270, 293, 270, - 602, 0, 0, 0, 0, 317, 499, 509, 108, 175, - 60, 316, 0, 60, 319, 270, 60, 290, 270, 298, - 289, 270, 0, 291, 270, 298, 60, 60, 0, 60, - 270, 270, 270, 500, 270, 0, 637, 295, 273, 298, - 602, 297, 313, 60, 270, 611, 0, 300, 270, 599, - 278, 302, 601, 500, 0, 567, 602, 0, 0, 0, - 0, 326, 570, 563, 564, 565, 566, 0, 499, 509, - 0, 472, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 332, 0, 0, 0, + 472, 546, 528, 639, 311, 182, 302, 498, 514, 16, + 461, 515, 496, 182, 497, 519, 309, 436, 619, 243, + 358, 439, 576, 572, 253, 150, 571, 487, 617, 307, + 238, 250, 320, 628, 633, 555, 569, 560, 558, 642, + 186, 250, 425, 349, 358, 182, 351, 557, 433, 347, + 238, 344, 339, 429, 302, 402, 243, 445, 447, 456, + 460, 163, 454, 458, 243, 250, 485, 143, 148, 449, + 353, 526, 176, 467, 237, 450, 238, 415, 338, 188, + 410, 237, 302, 336, 436, 482, 334, 169, 439, 436, + 146, 417, 392, 439, 140, 522, 358, 400, 404, 0, + 390, 171, 358, 0, 186, 500, 146, 0, 643, 0, + 0, 178, 0, 0, 0, 0, 404, 60, 60, 489, + 452, 500, 320, 0, 534, 0, 405, 60, 0, 180, + 146, 60, 0, 180, 60, 407, 490, 60, 302, 452, + 60, 60, 60, 60, 405, 60, 284, 285, 287, 60, + 286, 451, 358, 60, 165, 180, 266, 60, 60, 461, + 451, 270, 288, 60, 60, 60, 493, 60, 60, 60, + 84, 106, 92, 91, 60, 432, 60, 72, 60, 168, + 98, 435, 77, 60, 96, 60, 60, 60, 341, 302, + 93, 94, 500, 108, 329, 100, 60, 102, 60, 618, + 302, 95, 88, 330, 60, 60, 60, 60, 90, 89, + 70, 60, 97, 452, 60, 60, 451, 492, 60, 60, + 494, 60, 61, 68, 60, 60, 69, 491, 60, 471, + 67, 302, 404, 480, 60, 106, 60, 479, 0, 270, + 298, 270, 298, 278, 298, 270, 0, 270, 60, 270, + 0, 316, 0, 270, 332, 0, 500, 108, 175, 538, + 405, 293, 319, 0, 317, 303, 326, 60, 60, 60, + 0, 0, 270, 270, 270, 290, 291, 60, 295, 298, + 60, 60, 270, 298, 270, 270, 270, 289, 270, 0, + 273, 500, 313, 0, 551, 545, 305, 534, 508, 615, + 542, 297, 0, 500, 0, 300, 499, 509, 500, 0, + 508, 0, 0, 0, 0, 508, 472, 0, 499, 509, + 583, 0, 0, 499, 509, 0, 0, 586, 579, 580, + 581, 582, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 550, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, + 0, 0, 0, 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 608, 0, 0, 0, 0, 0, - 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 499, 509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0}; + 0, 0}; const short QDeclarativeJSGrammar::action_check [] = { - 55, 7, 33, 7, 55, 7, 60, 36, 90, 55, - 7, 16, 36, 7, 7, 7, 7, 36, 7, 60, - 36, 8, 33, 66, 36, 33, 60, 36, 7, 36, - 7, 7, 33, 36, 24, 7, 7, 37, 8, 60, - 66, 29, 17, 5, 7, 60, 7, 33, 33, 33, - 7, 20, 33, 36, 7, 7, 36, 7, 36, 33, - 7, 17, 60, 36, 1, 33, 79, 2, 8, 7, - 36, 1, 8, 55, 7, 2, 8, 2, 7, 7, - 79, 36, 77, 79, 48, 36, 7, 36, 55, 48, - 36, 36, 33, 36, 8, 60, 1, 31, 0, 2, - 8, 61, 60, 1, 48, 6, 10, 61, 7, 8, - -1, 8, 8, 61, 8, -1, -1, 48, 40, 20, - 8, 60, 8, 42, -1, 40, -1, 50, 8, 51, - 8, 54, 8, 15, 53, 8, 51, 61, 62, 8, - 5, 61, 62, 61, 62, 61, 62, 40, 90, 61, - 62, 55, 34, 79, 61, 62, 40, 8, 51, 8, - 8, 61, 62, 60, 60, 50, 60, 51, 56, 54, - 56, 61, 62, 8, 61, 62, 56, 15, 61, 62, - 61, 62, 60, 56, 60, 15, 25, 8, 27, 29, - 7, 60, 25, 29, 27, 7, 34, 12, 36, 38, - 25, 25, 27, 27, 34, 38, 36, 12, 8, 12, - 61, 60, 60, 38, 38, 8, 25, 25, 27, 27, - -1, 33, 7, -1, -1, 29, 61, 62, 29, 38, - 38, -1, 29, 8, -1, 75, 15, 8, 36, 75, - 61, 62, 57, -1, 61, 62, 86, 29, 63, -1, - 86, 15, 57, -1, 57, 34, 18, 19, 63, -1, - 63, 61, 62, 61, 62, 61, 62, -1, 61, 62, - 34, 75, 36, 15, 75, -1, 61, 62, 75, 15, - 92, -1, 86, 45, 46, 86, 61, 62, 29, 86, - 61, 62, 34, 75, 36, 91, 47, 33, 34, 15, - 36, 18, 19, -1, 86, 18, 19, 29, -1, -1, - 61, 62, -1, -1, 18, 19, -1, 33, 34, 29, - 36, -1, 25, 29, 27, 66, 67, 68, 45, 46, - -1, -1, 45, 46, -1, 38, -1, -1, 23, 24, - 91, 45, 46, -1, 66, 67, 68, 32, -1, -1, - 35, 92, 37, 29, 23, 24, 66, 67, 68, -1, - 66, 67, 68, 32, 23, 24, 35, 29, 37, -1, - 92, 23, 24, 32, 36, -1, 35, -1, 37, -1, - 32, 29, 92, 35, -1, 37, 92, 23, 24, 29, - 66, 67, 68, -1, -1, 29, 32, -1, 29, 35, - -1, 37, 36, -1, 66, 67, 68, 93, 94, 95, - 96, 97, 98, 61, 62, -1, 92, 29, 66, 67, - 68, 61, 62, -1, -1, -1, 66, 67, 68, -1, - 92, -1, 66, 67, 68, 66, 67, 68, -1, -1, - -1, -1, -1, -1, 92, -1, -1, -1, -1, 61, - 62, -1, 92, 29, 66, 67, 68, -1, 92, -1, - -1, 92, 29, -1, -1, 29, -1, -1, -1, -1, - 23, 24, -1, -1, -1, -1, -1, -1, 31, 32, - 92, -1, 35, -1, 37, 61, 62, -1, -1, -1, - 66, 67, 68, -1, 61, 62, -1, 61, 62, 66, - 67, 68, 66, 67, 68, -1, -1, -1, -1, -1, - 12, 13, -1, -1, -1, -1, 92, -1, -1, -1, - 22, -1, -1, -1, -1, 92, -1, 29, 92, -1, + 7, 16, 55, 7, 33, 36, 33, 55, 36, 7, + 7, 7, 7, 7, 7, 36, 7, 7, 36, 8, + 36, 55, 60, 29, 7, 7, 36, 7, 33, 7, + 7, 7, 7, 36, 36, 48, 1, 0, 90, 79, + 7, 33, 8, 90, 2, 7, 33, 55, 36, 60, + 36, 20, 33, 5, 1, 5, 79, 36, 7, 33, + 5, 60, 33, 33, 8, 33, 17, 24, 2, 7, + 34, 2, 7, 1, 7, 36, 60, 37, 8, 8, + 36, 66, 36, 7, 1, 17, -1, -1, 36, 48, + 36, 33, 8, 66, 7, 48, 36, 33, 7, 36, + 2, 7, 8, 8, 8, 77, 61, 15, 8, 8, + 6, -1, 31, 36, 8, 10, -1, -1, -1, 60, + 8, 60, -1, 48, 20, -1, 34, -1, 8, 8, + 8, -1, -1, 60, 60, 8, 79, 55, 60, 50, + 8, 61, 8, 54, 8, 8, 61, 61, 62, 61, + 62, 42, 56, 50, 40, 60, 56, 54, 79, 40, + 55, 60, 53, 61, 62, 51, 60, 15, 61, 62, + 51, 61, 62, 61, 61, 62, 56, 56, 61, 62, + 40, 8, 60, 8, 61, 62, 34, 60, 8, 61, + 62, 51, 60, 56, 60, 40, 60, 12, 29, 61, + 62, 25, 25, 27, 27, 15, 51, 36, 29, 15, + 29, 61, 62, 12, 38, 38, 8, 29, 7, 7, + 29, -1, 8, -1, 34, 8, 36, 25, 34, 27, + 36, 15, 61, 62, 61, 62, 61, 62, 7, 29, + 38, 91, 57, 7, 75, 33, 8, 25, 63, 27, + 34, -1, 36, -1, 75, 86, 75, 12, 57, -1, + 38, 15, -1, 75, 63, 86, 75, 86, 15, 61, + 62, -1, 61, 62, 86, 61, 62, 86, 61, 62, + 34, 25, 36, 27, -1, 75, 33, 34, 29, 36, + 18, 19, 61, 62, 38, 47, 86, 61, 62, 61, + 62, 15, 57, -1, 92, 18, 19, -1, 63, 61, + 62, 29, -1, 18, 19, 18, 19, 45, 46, 33, + 34, -1, 36, 29, -1, 66, 67, 68, -1, -1, + -1, -1, 45, 46, 29, -1, -1, -1, 29, 91, + 45, 46, 45, 46, 23, 24, 29, -1, 66, 67, + 68, 92, 29, 32, 23, 24, 35, 25, 37, 27, + 66, 67, 68, 32, -1, 29, 35, -1, 37, 29, + 38, 66, 67, 68, 92, 66, 67, 68, -1, -1, + 29, -1, -1, 66, 67, 68, 92, 29, -1, 66, + 67, 68, 29, -1, -1, -1, -1, 92, 29, -1, + -1, 92, 66, 67, 68, -1, 66, 67, 68, 92, + -1, -1, -1, -1, 29, 92, -1, 66, 67, 68, + 29, -1, -1, -1, 66, 67, 68, 29, 92, 66, + 67, 68, 92, 23, 24, 66, 67, 68, -1, -1, + -1, 29, 32, 92, -1, 35, -1, 37, 36, 29, + 92, 66, 67, 68, -1, 92, 36, 66, 67, 68, + -1, 92, 23, 24, 66, 67, 68, -1, -1, -1, + 31, 32, -1, -1, 35, -1, 37, 92, 66, 67, + 68, -1, -1, 92, 23, 24, 66, 67, 68, 29, + 92, -1, 31, 32, 23, 24, 35, 29, 37, -1, + -1, -1, 31, 32, 92, 29, 35, -1, 37, -1, + -1, 29, 92, -1, 93, 94, 95, 96, 97, 98, + -1, 61, 62, -1, 29, -1, 66, 67, 68, 61, + 62, -1, -1, 29, 66, 67, 68, 61, 62, -1, + -1, -1, 66, 67, 68, -1, -1, -1, 66, 67, + 68, -1, 92, -1, -1, -1, 61, 62, -1, -1, + 92, 66, 67, 68, -1, 61, 62, 29, 92, -1, + 66, 67, 68, -1, 92, -1, -1, -1, -1, -1, + -1, -1, -1, 23, 24, -1, -1, 92, 3, -1, + -1, 31, 32, -1, -1, 35, 92, 37, 13, 61, + 62, -1, 17, -1, 66, 67, 68, -1, -1, -1, + -1, 26, -1, 28, -1, -1, 31, -1, -1, -1, + -1, -1, -1, -1, 39, -1, 41, 42, -1, -1, + 92, -1, -1, -1, 49, -1, -1, 52, 53, -1, + -1, -1, -1, 58, -1, -1, -1, -1, -1, 64, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, + 13, 3, -1, -1, -1, 80, -1, -1, -1, 22, + -1, 13, -1, -1, -1, 17, 29, -1, -1, -1, + 33, 34, -1, 36, 26, -1, 28, -1, -1, -1, + 43, -1, -1, -1, 47, -1, -1, 39, -1, 41, + 42, -1, -1, -1, -1, -1, -1, 49, -1, -1, + 52, 53, 65, 66, 67, 68, 58, 70, -1, -1, + -1, -1, 64, -1, -1, -1, -1, -1, 81, 82, + 83, 12, 13, -1, 87, -1, -1, -1, 80, 92, + -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, + -1, -1, 33, 34, -1, 36, -1, -1, -1, 12, + 13, -1, 43, -1, -1, -1, 47, -1, -1, 22, + -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, + 33, 34, -1, 36, 65, 66, 67, 68, -1, 70, + 43, -1, -1, -1, 47, -1, -1, -1, -1, -1, + 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, + -1, 92, 65, 66, 67, 68, -1, 70, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 81, 82, + 83, -1, -1, -1, 87, -1, -1, -1, -1, 92, + 12, 13, -1, -1, -1, -1, -1, -1, 12, 13, + 22, -1, -1, -1, -1, -1, -1, 29, 22, -1, + -1, 33, 34, -1, 36, 29, -1, -1, -1, 33, + 34, 43, 36, -1, -1, 47, -1, -1, -1, 43, + -1, -1, -1, 47, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, + -1, 65, 66, 67, 68, -1, 70, -1, -1, 81, + 82, 83, -1, -1, -1, 87, -1, 81, 82, 83, + 92, -1, -1, 87, -1, -1, -1, -1, 92, 12, + 13, -1, -1, -1, -1, -1, -1, 12, 13, 22, + -1, -1, -1, -1, -1, -1, 29, 22, -1, -1, + 33, 34, -1, 36, 29, -1, -1, -1, 33, 34, + 43, 36, -1, -1, 47, -1, -1, -1, 43, -1, + -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 65, 66, 67, 68, -1, 70, -1, -1, + 65, 66, 67, 68, -1, 70, -1, -1, 81, 82, + 83, -1, -1, -1, 87, -1, 81, 82, 83, 92, + -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, + -1, -1, -1, -1, -1, -1, 10, -1, 12, 13, + -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, + -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, + 34, -1, 36, -1, -1, -1, -1, -1, -1, 43, + -1, -1, -1, 47, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 65, 66, 67, 68, -1, 70, -1, -1, -1, + -1, 75, -1, -1, -1, -1, -1, 81, 82, 83, + 84, -1, -1, 87, -1, -1, -1, -1, 92, -1, + -1, -1, -1, -1, -1, -1, -1, 10, -1, 12, + 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, + -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, + 33, 34, -1, 36, -1, -1, -1, -1, -1, -1, + 43, -1, -1, -1, 47, -1, -1, -1, -1, -1, + -1, -1, 55, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 65, 66, 67, 68, -1, 70, -1, -1, + -1, -1, 75, -1, -1, -1, -1, -1, 81, 82, + 83, 84, -1, -1, 87, -1, -1, -1, -1, 92, + -1, -1, -1, -1, -1, -1, -1, -1, 10, -1, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, -1, -1, - -1, 43, -1, -1, -1, 47, -1, -1, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 13, -1, - -1, -1, 17, 65, 66, 67, 68, -1, 70, -1, - -1, 26, -1, 28, -1, -1, -1, -1, -1, 81, - 82, 83, -1, -1, 39, 87, 41, 42, -1, -1, - 92, -1, -1, -1, 49, 12, 13, 52, 53, -1, - -1, -1, -1, 58, -1, 22, -1, -1, -1, 64, - -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, - -1, -1, -1, -1, -1, 80, 43, -1, -1, -1, - 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3, -1, 65, 66, - 67, 68, -1, 70, -1, -1, 13, -1, -1, -1, - 17, -1, -1, -1, 81, 82, 83, -1, -1, 26, - 87, 28, -1, -1, 31, 92, -1, -1, -1, -1, - -1, -1, 39, -1, 41, 42, -1, -1, -1, -1, - -1, -1, 49, -1, -1, 52, 53, -1, -1, -1, - -1, 58, -1, -1, -1, -1, -1, 64, -1, -1, - -1, -1, -1, -1, -1, -1, 12, 13, -1, -1, - -1, -1, -1, 80, -1, -1, 22, -1, -1, -1, - -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, - 36, -1, -1, -1, 12, 13, -1, 43, -1, -1, - -1, 47, -1, -1, 22, -1, -1, -1, -1, -1, - -1, 29, -1, -1, -1, 33, 34, -1, 36, 65, - 66, 67, 68, -1, 70, 43, -1, -1, -1, 47, - -1, -1, -1, -1, -1, 81, 82, 83, -1, -1, - -1, 87, -1, -1, -1, -1, 92, 65, 66, 67, - 68, -1, 70, -1, -1, -1, -1, -1, -1, -1, + -1, 43, -1, -1, -1, 47, -1, -1, -1, -1, + -1, -1, -1, 55, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, + -1, -1, -1, 75, -1, -1, -1, -1, -1, 81, + 82, 83, 84, -1, -1, 87, -1, -1, -1, -1, + 92, -1, -1, -1, -1, -1, -1, -1, -1, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, + -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, + 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, + -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, + 72, -1, 74, -1, 76, -1, -1, -1, -1, 81, + 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, + 92, -1, -1, -1, -1, -1, -1, -1, -1, 7, + -1, -1, -1, 11, 12, 13, -1, -1, -1, -1, + -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, + -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, + -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, + -1, -1, -1, 51, -1, 53, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, + 68, -1, 70, -1, 72, -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, - -1, -1, -1, -1, 92, 12, 13, -1, -1, -1, - -1, -1, -1, 12, 13, 22, -1, -1, -1, -1, - -1, -1, 29, 22, -1, -1, 33, 34, -1, 36, - 29, -1, -1, -1, 33, 34, 43, 36, -1, -1, - 47, -1, -1, -1, 43, -1, -1, -1, 47, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, - 67, 68, -1, 70, -1, -1, 65, 66, 67, 68, - -1, 70, -1, -1, 81, 82, 83, -1, -1, -1, - 87, -1, 81, 82, 83, 92, -1, -1, 87, -1, - -1, -1, -1, 92, 12, 13, -1, -1, -1, -1, - -1, -1, 12, 13, 22, -1, -1, -1, -1, -1, - -1, 29, 22, -1, -1, 33, 34, -1, 36, 29, - -1, -1, -1, 33, 34, 43, 36, -1, -1, 47, - -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, + -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, + -1, -1, -1, 11, 12, 13, -1, -1, -1, -1, + -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, + -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, + -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, + -1, -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, - 68, -1, 70, -1, -1, 65, 66, 67, 68, -1, - 70, -1, -1, 81, 82, 83, -1, -1, -1, 87, - -1, 81, 82, 83, 92, -1, -1, 87, -1, -1, - -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, - -1, 10, -1, 12, 13, -1, -1, -1, -1, -1, + 68, -1, 70, -1, 72, -1, 74, 75, 76, -1, + -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, + -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, + -1, -1, -1, 8, -1, -1, 11, 12, 13, -1, + -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, + -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, + -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, + -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, + -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, + 65, 66, 67, 68, -1, 70, -1, 72, -1, 74, + -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, + -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, + -1, -1, -1, -1, -1, -1, 8, -1, -1, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, + -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, + 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, + -1, 53, -1, -1, 56, -1, -1, -1, -1, -1, + -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, + 72, -1, 74, -1, 76, -1, -1, -1, -1, 81, + 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, + 92, -1, -1, -1, -1, -1, -1, -1, -1, 8, + -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, -1, - -1, -1, -1, -1, 43, -1, -1, -1, 47, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, + -1, -1, 51, -1, 53, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, - -1, 70, -1, -1, -1, -1, 75, -1, -1, -1, - -1, -1, 81, 82, 83, 84, -1, -1, 87, -1, + -1, 70, -1, 72, -1, 74, -1, 76, -1, -1, + -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, - -1, -1, 10, -1, 12, 13, -1, -1, -1, -1, - -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, - -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, - -1, -1, -1, -1, -1, 43, -1, -1, -1, 47, - -1, -1, -1, -1, -1, -1, -1, 55, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, - 68, -1, 70, -1, -1, -1, -1, 75, -1, -1, - -1, -1, -1, 81, 82, 83, 84, -1, -1, 87, - -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, - -1, -1, -1, 10, -1, 12, 13, -1, -1, -1, - -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, - -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, - -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, - 47, -1, -1, -1, -1, -1, -1, -1, 55, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, - 67, 68, -1, 70, -1, -1, -1, -1, 75, -1, - -1, -1, -1, -1, 81, 82, 83, 84, -1, -1, - 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, - -1, -1, -1, -1, 11, 12, 13, -1, -1, -1, - -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, - -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, - -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, - 47, -1, -1, -1, 51, -1, 53, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, - 67, 68, -1, 70, -1, 72, -1, 74, -1, 76, - -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, - 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, - -1, -1, -1, -1, 7, -1, -1, -1, 11, 12, - 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, - -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, - 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, - 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, - 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, - -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, - 83, -1, -1, -1, 87, -1, -1, -1, -1, 92, - -1, -1, -1, -1, -1, -1, -1, -1, 11, 12, - 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, - -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, - 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, - 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, - 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, - -1, 74, 75, 76, -1, -1, -1, -1, 81, 82, - 83, -1, -1, -1, 87, -1, -1, -1, -1, 92, - -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, - -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, - -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, - 40, -1, 42, 43, 44, -1, -1, 47, -1, -1, - -1, 51, -1, 53, -1, -1, 56, -1, -1, -1, - -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, - 70, -1, 72, -1, 74, -1, 76, -1, -1, -1, - -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, - -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, - -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, - 30, -1, -1, 33, 34, -1, 36, -1, -1, -1, - 40, -1, 42, 43, 44, -1, -1, 47, -1, -1, - -1, 51, -1, 53, -1, -1, -1, -1, -1, -1, - -1, 61, -1, -1, -1, 65, 66, 67, 68, -1, - 70, -1, 72, -1, 74, -1, 76, -1, -1, -1, - -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, - -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, - -1, 8, -1, -1, 11, 12, 13, -1, -1, -1, - -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, - -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, - -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, - 47, -1, -1, -1, 51, -1, 53, -1, -1, 56, - -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, - 67, 68, -1, 70, -1, 72, -1, 74, -1, 76, - -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, - 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, - -1, -1, -1, -1, 8, -1, -1, 11, 12, 13, - -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, - -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, - 34, -1, 36, -1, -1, -1, 40, -1, 42, 43, - 44, -1, -1, 47, -1, -1, -1, 51, -1, 53, - -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, - -1, 65, 66, 67, 68, -1, 70, -1, 72, -1, - 74, -1, 76, -1, -1, -1, -1, 81, 82, 83, - -1, -1, -1, 87, -1, -1, -1, -1, 92, -1, - -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, - 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, - -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, - -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, - -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, - 51, -1, 53, -1, -1, 56, -1, -1, -1, -1, - -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, - -1, 72, -1, 74, -1, 76, -1, -1, -1, -1, - 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, - -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, - 4, 5, 6, -1, -1, 9, 10, 11, -1, -1, - 14, -1, 16, -1, -1, -1, 20, 21, 22, -1, - -1, -1, -1, -1, -1, 29, 30, 31, 32, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 43, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 59, -1, -1, -1, -1, - -1, -1, 66, 67, 68, 69, 70, 71, -1, 73, - 74, 75, 76, 77, 78, -1, -1, 81, 82, 83, - 84, 85, 86, -1, -1, -1, -1, -1, 92, -1, - -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, - -1, -1, 9, 10, 11, -1, -1, 14, -1, 16, - -1, -1, -1, 20, 21, 22, -1, -1, -1, -1, - -1, -1, 29, 30, 31, 32, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, - 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 59, -1, -1, -1, -1, -1, 65, 66, - 67, -1, 69, 70, 71, -1, 73, 74, 75, 76, - 77, 78, -1, -1, 81, 82, 83, 84, 85, 86, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4, 5, 6, -1, -1, 9, - 10, 11, -1, -1, 14, -1, 16, -1, -1, -1, - 20, 21, 22, -1, -1, -1, -1, -1, -1, 29, - 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, - -1, -1, -1, -1, -1, 55, -1, -1, -1, 59, - -1, -1, -1, -1, -1, 65, 66, 67, -1, 69, - 70, 71, -1, 73, 74, 75, 76, 77, 78, -1, - -1, 81, 82, 83, 84, 85, 86, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4, -1, -1, -1, -1, 9, -1, 11, 12, - 13, 14, -1, -1, -1, -1, -1, -1, 21, 22, - -1, -1, -1, -1, -1, -1, 29, 30, -1, -1, - 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, - 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, - 53, -1, -1, -1, -1, -1, 59, -1, 61, -1, - -1, -1, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, -1, -1, 81, 82, - 83, 84, 85, -1, 87, -1, -1, -1, -1, 92, - -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, - -1, -1, -1, 9, -1, 11, 12, 13, 14, -1, - -1, -1, -1, -1, -1, 21, 22, -1, -1, -1, + -1, -1, 8, -1, -1, 11, 12, 13, -1, -1, + -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, + -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, + 36, -1, -1, -1, 40, -1, 42, 43, 44, -1, + -1, 47, -1, -1, -1, 51, -1, 53, -1, -1, + 56, -1, -1, -1, -1, -1, -1, -1, -1, 65, + 66, 67, 68, -1, 70, -1, 72, -1, 74, -1, + 76, -1, -1, -1, -1, 81, 82, 83, -1, -1, + -1, 87, -1, -1, -1, -1, 92, -1, -1, -1, + -1, -1, -1, -1, -1, 11, 12, 13, -1, -1, + -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, 30, -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, -1, - -1, -1, -1, 59, -1, 61, -1, -1, -1, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, -1, -1, 81, 82, 83, 84, 85, + -1, -1, -1, -1, -1, 61, -1, -1, -1, 65, + 66, 67, 68, -1, 70, -1, 72, -1, 74, -1, + 76, -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, -1, -1, - 9, 10, 11, 12, 13, 14, -1, 16, -1, -1, + 9, 10, 11, -1, -1, 14, -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, -1, -1, -1, -1, - 29, 30, 31, 32, 33, 34, -1, 36, -1, -1, - -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, - -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, - 59, -1, 61, -1, -1, -1, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - -1, -1, 81, 82, 83, 84, 85, 86, 87, -1, + 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 59, -1, -1, -1, -1, -1, -1, 66, 67, 68, + 69, 70, 71, -1, 73, 74, 75, 76, 77, 78, + -1, -1, 81, 82, 83, 84, 85, 86, -1, -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, -1, -1, 9, 10, 11, - 12, 13, 14, -1, 16, -1, -1, -1, 20, 21, + -1, -1, 14, -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, -1, -1, -1, -1, 29, 30, 31, - 32, 33, 34, -1, 36, -1, -1, -1, 40, -1, - 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, - -1, 53, -1, 55, -1, -1, -1, 59, -1, 61, - -1, -1, -1, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, -1, -1, 81, - 82, 83, 84, 85, 86, 87, -1, -1, -1, -1, - 92, -1, -1, -1, -1, -1, -1, -1, -1, + 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 43, -1, -1, -1, 47, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 59, -1, -1, + -1, -1, -1, 65, 66, 67, -1, 69, 70, 71, + -1, 73, 74, 75, 76, 77, 78, -1, -1, 81, + 82, 83, 84, 85, 86, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, + 5, 6, -1, -1, 9, 10, 11, -1, -1, 14, + -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, + -1, -1, -1, -1, 29, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, + -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, + 55, -1, -1, -1, 59, -1, -1, -1, -1, -1, + 65, 66, 67, -1, 69, 70, 71, -1, 73, 74, + 75, 76, 77, 78, -1, -1, 81, 82, 83, 84, + 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, + -1, 9, -1, 11, 12, 13, 14, -1, -1, -1, + -1, -1, -1, 21, 22, -1, -1, -1, -1, -1, + -1, 29, 30, -1, -1, 33, 34, -1, 36, -1, + -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, + -1, -1, -1, 51, -1, 53, -1, -1, -1, -1, + -1, 59, -1, 61, -1, -1, -1, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, -1, -1, 81, 82, 83, 84, 85, -1, 87, + -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, + -1, -1, -1, 4, -1, -1, -1, -1, 9, -1, + 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, + 21, 22, -1, -1, -1, -1, -1, -1, 29, 30, + -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, + -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, + 51, -1, 53, -1, -1, -1, -1, -1, 59, -1, + 61, -1, -1, -1, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, -1, -1, + 81, 82, 83, 84, 85, -1, 87, -1, -1, -1, + -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, + 4, 5, 6, -1, -1, 9, 10, 11, 12, 13, + 14, -1, 16, -1, -1, -1, 20, 21, 22, -1, + -1, -1, -1, -1, -1, 29, 30, 31, 32, 33, + 34, -1, 36, -1, -1, -1, 40, -1, 42, 43, + 44, -1, -1, 47, -1, -1, -1, 51, -1, 53, + -1, -1, -1, -1, -1, 59, -1, 61, -1, -1, + -1, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, -1, -1, 81, 82, 83, + 84, 85, 86, 87, -1, -1, -1, -1, 92, -1, + -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, + -1, -1, 9, 10, 11, 12, 13, 14, -1, 16, + -1, -1, -1, 20, 21, 22, -1, -1, -1, -1, + -1, -1, 29, 30, 31, 32, 33, 34, -1, 36, + -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, + 47, -1, -1, -1, 51, -1, 53, -1, 55, -1, + -1, -1, 59, -1, 61, -1, -1, -1, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, -1, -1, 81, 82, 83, 84, 85, 86, + 87, -1, -1, -1, -1, 92, -1, -1, -1, -1, + -1, -1, -1, -1, - 13, 15, 25, 3, 15, 15, 3, 25, 3, 15, - 2, 15, 2, 25, 3, 11, 19, 15, 67, 13, - 3, 104, 15, 4, 15, 3, 2, 15, 2, 15, - 3, 15, 3, 35, 21, 3, 15, 36, 3, 19, - 25, 2, 2, 25, 21, 15, 15, 98, 15, 15, - 2, 4, 15, 15, 2, 93, 3, 21, 2, 2, - 35, 3, 2, 35, 15, 3, 21, 3, 2, 15, - 15, 2, 2, 2, 15, 3, 35, 35, 35, 35, - 3, 35, 3, 3, 21, 35, 35, 96, 15, 3, - 2, 4, 3, 2, 2, 100, 35, 3, 3, 2, - 35, 2, -1, -1, -1, 15, -1, -1, -1, -1, - -1, 44, 44, 46, 46, 13, -1, -1, 44, 44, - 44, 46, 46, 15, 15, 44, 44, 44, 54, 44, - 49, 49, 49, 3, 49, 15, -1, 44, -1, -1, - 44, 48, 44, 41, 48, 44, 37, 46, 44, 44, - 35, 44, 35, 46, 49, 40, 58, 40, 44, 3, - 44, -1, 48, 68, 60, 49, 44, 44, 44, 44, - -1, 49, 49, 49, 49, 85, 44, 44, 81, 46, - 81, 44, 44, 46, 52, 44, 44, 46, 50, 44, - 31, 46, 50, 13, 35, 87, 44, 2, 68, 47, - 20, 44, 44, 46, 46, 44, 13, 44, 47, 46, - 44, 44, 46, 44, 44, 46, 49, 13, 44, 99, - 46, 44, 44, 46, 68, 44, 56, 44, 50, 46, - 49, 44, -1, 44, 41, 44, 15, 50, 49, -1, - 49, 13, 44, 13, 44, 41, 16, 49, 57, 49, - 20, -1, -1, -1, -1, 66, 28, 29, 37, 38, - 44, 61, -1, 44, 66, 49, 44, 51, 49, 44, - 51, 49, -1, 51, 49, 44, 44, 44, -1, 44, - 49, 49, 49, 13, 49, -1, 16, 55, 53, 44, - 20, 66, 59, 44, 49, 5, -1, 66, 49, 13, - 51, 3, 16, 13, -1, 13, 20, -1, -1, -1, - -1, 66, 20, 21, 22, 23, 24, -1, 28, 29, - -1, 35, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 68, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 35, 15, 15, 15, 2, 15, 3, 2, 25, 3, + 15, 15, 104, 15, 4, 3, 3, 3, 19, 15, + 2, 21, 15, 15, 3, 67, 25, 3, 19, 2, + 15, 2, 15, 13, 15, 19, 25, 3, 15, 11, + 15, 2, 96, 3, 2, 15, 2, 25, 3, 2, + 15, 100, 15, 93, 3, 2, 15, 98, 15, 2, + 2, 35, 3, 3, 15, 2, 35, 35, 35, 21, + 2, 25, 3, 35, 4, 21, 15, 2, 2, 15, + 2, 4, 3, 3, 3, 35, 2, 35, 21, 3, + 35, 3, 36, 21, 3, 13, 2, 35, 13, -1, + 35, 35, 2, -1, 15, 13, 35, -1, 16, -1, + -1, 40, -1, -1, -1, -1, 13, 44, 44, 46, + 46, 13, 15, -1, 16, -1, 41, 44, -1, 46, + 35, 44, -1, 46, 44, 40, 46, 44, 3, 46, + 44, 44, 44, 44, 41, 44, 49, 49, 49, 44, + 49, 46, 2, 44, 58, 46, 44, 44, 44, 15, + 46, 49, 49, 44, 44, 44, 46, 44, 44, 44, + 49, 15, 49, 49, 44, 81, 44, 52, 44, 60, + 50, 81, 50, 44, 50, 44, 44, 44, 99, 3, + 49, 49, 13, 37, 87, 56, 44, 54, 44, 20, + 3, 49, 48, 68, 44, 44, 44, 44, 48, 48, + 47, 44, 50, 46, 44, 44, 46, 46, 44, 44, + 46, 44, 47, 46, 44, 44, 46, 46, 44, 85, + 46, 3, 13, 31, 44, 15, 44, 35, -1, 49, + 44, 49, 44, 51, 44, 49, -1, 49, 44, 49, + -1, 61, -1, 49, 68, -1, 13, 37, 38, 16, + 41, 57, 66, -1, 66, 68, 66, 44, 44, 44, + -1, -1, 49, 49, 49, 51, 51, 44, 55, 44, + 44, 44, 49, 44, 49, 49, 49, 51, 49, -1, + 53, 13, 59, -1, 13, 5, 68, 16, 20, 18, + 5, 66, -1, 13, -1, 66, 28, 29, 13, -1, + 20, -1, -1, -1, -1, 20, 35, -1, 28, 29, + 13, -1, -1, 28, 29, -1, -1, 20, 21, 22, + 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 13, + -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 5, -1, -1, -1, -1, -1, - -1, -1, 13, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 28, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -987,6 +984,6 @@ const short QDeclarativeJSGrammar::action_check [] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1}; + -1, -1}; QT_END_NAMESPACE diff --git a/src/declarative/qml/parser/qdeclarativejsgrammar_p.h b/src/declarative/qml/parser/qdeclarativejsgrammar_p.h index 32bb12b..064c67a 100644 --- a/src/declarative/qml/parser/qdeclarativejsgrammar_p.h +++ b/src/declarative/qml/parser/qdeclarativejsgrammar_p.h @@ -164,15 +164,15 @@ public: T_XOR = 79, T_XOR_EQ = 80, - ACCEPT_STATE = 639, - RULE_COUNT = 345, - STATE_COUNT = 640, + ACCEPT_STATE = 645, + RULE_COUNT = 347, + STATE_COUNT = 646, TERMINAL_COUNT = 101, NON_TERMINAL_COUNT = 106, - GOTO_INDEX_OFFSET = 640, - GOTO_INFO_OFFSET = 2699, - GOTO_CHECK_OFFSET = 2699 + GOTO_INDEX_OFFSET = 646, + GOTO_INFO_OFFSET = 2714, + GOTO_CHECK_OFFSET = 2714 }; static const char *const spell []; diff --git a/src/declarative/qml/parser/qdeclarativejsparser.cpp b/src/declarative/qml/parser/qdeclarativejsparser.cpp index 3cf73b1..170c7fa 100644 --- a/src/declarative/qml/parser/qdeclarativejsparser.cpp +++ b/src/declarative/qml/parser/qdeclarativejsparser.cpp @@ -487,80 +487,124 @@ case 60: { } break; case 61: { - sym(1).Node = makeAstNode(driver->nodePool(), sym(1).Node); + AST::UiPublicMember *node = makeAstNode (driver->nodePool(), sym(4).sval, sym(6).sval); + node->typeModifier = sym(2).sval; + node->propertyToken = loc(1); + node->typeModifierToken = loc(2); + node->typeToken = loc(4); + node->identifierToken = loc(6); + node->semicolonToken = loc(7); // insert a fake ';' before ':' + + AST::UiQualifiedId *propertyName = makeAstNode(driver->nodePool(), sym(6).sval); + propertyName->identifierToken = loc(6); + propertyName->next = 0; + + AST::UiArrayBinding *binding = makeAstNode (driver->nodePool(), + propertyName, sym(9).UiArrayMemberList->finish()); + binding->colonToken = loc(7); + binding->lbracketToken = loc(8); + binding->rbracketToken = loc(10); + + node->binding = binding; + + sym(1).Node = node; } break; case 62: { + AST::UiPublicMember *node = makeAstNode (driver->nodePool(), sym(2).sval, sym(3).sval); + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(3); + node->semicolonToken = loc(4); // insert a fake ';' before ':' + + AST::UiQualifiedId *propertyName = makeAstNode(driver->nodePool(), sym(3).sval); + propertyName->identifierToken = loc(3); + propertyName->next = 0; + + AST::UiObjectBinding *binding = makeAstNode (driver->nodePool(), + propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer); + binding->colonToken = loc(4); + + node->binding = binding; + + sym(1).Node = node; +} break; + +case 63: { sym(1).Node = makeAstNode(driver->nodePool(), sym(1).Node); } break; case 64: { + sym(1).Node = makeAstNode(driver->nodePool(), sym(1).Node); +} break; + +case 66: { QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_PROPERTY]); sym(1).sval = driver->intern(s.constData(), s.length()); break; } -case 65: { +case 67: { QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_SIGNAL]); sym(1).sval = driver->intern(s.constData(), s.length()); break; } -case 66: { +case 68: { QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_READONLY]); sym(1).sval = driver->intern(s.constData(), s.length()); break; } -case 67: { +case 69: { QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_ON]); sym(1).sval = driver->intern(s.constData(), s.length()); break; } -case 68: { +case 70: { AST::ThisExpression *node = makeAstNode (driver->nodePool()); node->thisToken = loc(1); sym(1).Node = node; } break; -case 69: { +case 71: { AST::IdentifierExpression *node = makeAstNode (driver->nodePool(), sym(1).sval); node->identifierToken = loc(1); sym(1).Node = node; } break; -case 70: { +case 72: { AST::NullExpression *node = makeAstNode (driver->nodePool()); node->nullToken = loc(1); sym(1).Node = node; } break; -case 71: { +case 73: { AST::TrueLiteral *node = makeAstNode (driver->nodePool()); node->trueToken = loc(1); sym(1).Node = node; } break; -case 72: { +case 74: { AST::FalseLiteral *node = makeAstNode (driver->nodePool()); node->falseToken = loc(1); sym(1).Node = node; } break; -case 73: { +case 75: { AST::NumericLiteral *node = makeAstNode (driver->nodePool(), sym(1).dval); node->literalToken = loc(1); sym(1).Node = node; } break; -case 74: -case 75: { +case 76: +case 77: { AST::StringLiteral *node = makeAstNode (driver->nodePool(), sym(1).sval); node->literalToken = loc(1); sym(1).Node = node; } break; -case 76: { +case 78: { bool rx = lexer->scanRegExp(Lexer::NoPrefix); if (!rx) { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); @@ -574,7 +618,7 @@ case 76: { sym(1).Node = node; } break; -case 77: { +case 79: { bool rx = lexer->scanRegExp(Lexer::EqualPrefix); if (!rx) { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); @@ -588,28 +632,28 @@ case 77: { sym(1).Node = node; } break; -case 78: { +case 80: { AST::ArrayLiteral *node = makeAstNode (driver->nodePool(), (AST::Elision *) 0); node->lbracketToken = loc(1); node->rbracketToken = loc(2); sym(1).Node = node; } break; -case 79: { +case 81: { AST::ArrayLiteral *node = makeAstNode (driver->nodePool(), sym(2).Elision->finish()); node->lbracketToken = loc(1); node->rbracketToken = loc(3); sym(1).Node = node; } break; -case 80: { +case 82: { AST::ArrayLiteral *node = makeAstNode (driver->nodePool(), sym(2).ElementList->finish ()); node->lbracketToken = loc(1); node->rbracketToken = loc(3); sym(1).Node = node; } break; -case 81: { +case 83: { AST::ArrayLiteral *node = makeAstNode (driver->nodePool(), sym(2).ElementList->finish (), (AST::Elision *) 0); node->lbracketToken = loc(1); @@ -618,7 +662,7 @@ case 81: { sym(1).Node = node; } break; -case 82: { +case 84: { AST::ArrayLiteral *node = makeAstNode (driver->nodePool(), sym(2).ElementList->finish (), sym(4).Elision->finish()); node->lbracketToken = loc(1); @@ -627,7 +671,7 @@ case 82: { sym(1).Node = node; } break; -case 83: { +case 85: { AST::ObjectLiteral *node = 0; if (sym(2).Node) node = makeAstNode (driver->nodePool(), @@ -639,7 +683,7 @@ case 83: { sym(1).Node = node; } break; -case 84: { +case 86: { AST::ObjectLiteral *node = makeAstNode (driver->nodePool(), sym(2).PropertyNameAndValueList->finish ()); node->lbraceToken = loc(1); @@ -647,14 +691,14 @@ case 84: { sym(1).Node = node; } break; -case 85: { +case 87: { AST::NestedExpression *node = makeAstNode(driver->nodePool(), sym(2).Expression); node->lparenToken = loc(1); node->rparenToken = loc(3); sym(1).Node = node; } break; -case 86: { +case 88: { if (AST::ArrayMemberExpression *mem = AST::cast(sym(1).Expression)) { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken, QLatin1String("Ignored annotation"))); @@ -674,48 +718,48 @@ case 86: { } } break; -case 87: { +case 89: { sym(1).Node = makeAstNode (driver->nodePool(), (AST::Elision *) 0, sym(1).Expression); } break; -case 88: { +case 90: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).Elision->finish(), sym(2).Expression); } break; -case 89: { +case 91: { AST::ElementList *node = makeAstNode (driver->nodePool(), sym(1).ElementList, (AST::Elision *) 0, sym(3).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 90: { +case 92: { AST::ElementList *node = makeAstNode (driver->nodePool(), sym(1).ElementList, sym(3).Elision->finish(), sym(4).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 91: { +case 93: { AST::Elision *node = makeAstNode (driver->nodePool()); node->commaToken = loc(1); sym(1).Node = node; } break; -case 92: { +case 94: { AST::Elision *node = makeAstNode (driver->nodePool(), sym(1).Elision); node->commaToken = loc(2); sym(1).Node = node; } break; -case 93: { +case 95: { AST::PropertyNameAndValueList *node = makeAstNode (driver->nodePool(), sym(1).PropertyName, sym(3).Expression); node->colonToken = loc(2); sym(1).Node = node; } break; -case 94: { +case 96: { AST::PropertyNameAndValueList *node = makeAstNode (driver->nodePool(), sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression); node->commaToken = loc(2); @@ -723,40 +767,36 @@ case 94: { sym(1).Node = node; } break; -case 95: { +case 97: { AST::IdentifierPropertyName *node = makeAstNode (driver->nodePool(), sym(1).sval); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 96: -case 97: { +case 98: +case 99: { AST::IdentifierPropertyName *node = makeAstNode (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount())); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 98: { +case 100: { AST::StringLiteralPropertyName *node = makeAstNode (driver->nodePool(), sym(1).sval); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 99: { +case 101: { AST::NumericLiteralPropertyName *node = makeAstNode (driver->nodePool(), sym(1).dval); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 100: { +case 102: { AST::IdentifierPropertyName *node = makeAstNode (driver->nodePool(), sym(1).sval); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 101: - -case 102: - case 103: case 104: @@ -814,25 +854,29 @@ case 129: case 130: case 131: + +case 132: + +case 133: { sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount()); } break; -case 136: { +case 138: { AST::ArrayMemberExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).Expression); node->lbracketToken = loc(2); node->rbracketToken = loc(4); sym(1).Node = node; } break; -case 137: { +case 139: { AST::FieldMemberExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).sval); node->dotToken = loc(2); node->identifierToken = loc(3); sym(1).Node = node; } break; -case 138: { +case 140: { AST::NewMemberExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression, sym(4).ArgumentList); node->newToken = loc(1); node->lparenToken = loc(3); @@ -840,316 +884,309 @@ case 138: { sym(1).Node = node; } break; -case 140: { +case 142: { AST::NewExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->newToken = loc(1); sym(1).Node = node; } break; -case 141: { +case 143: { AST::CallExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList); node->lparenToken = loc(2); node->rparenToken = loc(4); sym(1).Node = node; } break; -case 142: { +case 144: { AST::CallExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList); node->lparenToken = loc(2); node->rparenToken = loc(4); sym(1).Node = node; } break; -case 143: { +case 145: { AST::ArrayMemberExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).Expression); node->lbracketToken = loc(2); node->rbracketToken = loc(4); sym(1).Node = node; } break; -case 144: { +case 146: { AST::FieldMemberExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).sval); node->dotToken = loc(2); node->identifierToken = loc(3); sym(1).Node = node; } break; -case 145: { +case 147: { sym(1).Node = 0; } break; -case 146: { +case 148: { sym(1).Node = sym(1).ArgumentList->finish(); } break; -case 147: { +case 149: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).Expression); } break; -case 148: { +case 150: { AST::ArgumentList *node = makeAstNode (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 152: { +case 154: { AST::PostIncrementExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression); node->incrementToken = loc(2); sym(1).Node = node; } break; -case 153: { +case 155: { AST::PostDecrementExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression); node->decrementToken = loc(2); sym(1).Node = node; } break; -case 155: { +case 157: { AST::DeleteExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->deleteToken = loc(1); sym(1).Node = node; } break; -case 156: { +case 158: { AST::VoidExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->voidToken = loc(1); sym(1).Node = node; } break; -case 157: { +case 159: { AST::TypeOfExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->typeofToken = loc(1); sym(1).Node = node; } break; -case 158: { +case 160: { AST::PreIncrementExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->incrementToken = loc(1); sym(1).Node = node; } break; -case 159: { +case 161: { AST::PreDecrementExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->decrementToken = loc(1); sym(1).Node = node; } break; -case 160: { +case 162: { AST::UnaryPlusExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->plusToken = loc(1); sym(1).Node = node; } break; -case 161: { +case 163: { AST::UnaryMinusExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->minusToken = loc(1); sym(1).Node = node; } break; -case 162: { +case 164: { AST::TildeExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->tildeToken = loc(1); sym(1).Node = node; } break; -case 163: { +case 165: { AST::NotExpression *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->notToken = loc(1); sym(1).Node = node; } break; -case 165: { +case 167: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Mul, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 166: { +case 168: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Div, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 167: { +case 169: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Mod, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 169: { +case 171: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Add, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 170: { +case 172: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Sub, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 172: { +case 174: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::LShift, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 173: { +case 175: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::RShift, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 174: { +case 176: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::URShift, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 176: { +case 178: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Lt, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 177: { +case 179: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Gt, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 178: { +case 180: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Le, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 179: { +case 181: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Ge, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 180: { +case 182: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 181: { +case 183: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::In, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 183: { +case 185: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Lt, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 184: { +case 186: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Gt, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 185: { +case 187: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Le, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 186: { +case 188: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Ge, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 187: { +case 189: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 189: { +case 191: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Equal, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 190: { +case 192: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::NotEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 191: { +case 193: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 192: { +case 194: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 194: { +case 196: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::Equal, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 195: { +case 197: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::NotEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 196: { +case 198: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 197: { - AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, - QSOperator::StrictNotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - case 199: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, - QSOperator::BitAnd, sym(3).Expression); + QSOperator::StrictNotEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; @@ -1163,7 +1200,7 @@ case 201: { case 203: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, - QSOperator::BitXor, sym(3).Expression); + QSOperator::BitAnd, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; @@ -1177,7 +1214,7 @@ case 205: { case 207: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, - QSOperator::BitOr, sym(3).Expression); + QSOperator::BitXor, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; @@ -1191,7 +1228,7 @@ case 209: { case 211: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, - QSOperator::And, sym(3).Expression); + QSOperator::BitOr, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; @@ -1205,7 +1242,7 @@ case 213: { case 215: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, - QSOperator::Or, sym(3).Expression); + QSOperator::And, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; @@ -1218,6 +1255,13 @@ case 217: { } break; case 219: { + AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, + QSOperator::Or, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; +} break; + +case 221: { AST::ConditionalExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).Expression, sym(5).Expression); node->questionToken = loc(2); @@ -1225,7 +1269,7 @@ case 219: { sym(1).Node = node; } break; -case 221: { +case 223: { AST::ConditionalExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).Expression, sym(5).Expression); node->questionToken = loc(2); @@ -1233,112 +1277,112 @@ case 221: { sym(1).Node = node; } break; -case 223: { +case 225: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(2).ival, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 225: { +case 227: { AST::BinaryExpression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(2).ival, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 226: { +case 228: { sym(1).ival = QSOperator::Assign; } break; -case 227: { +case 229: { sym(1).ival = QSOperator::InplaceMul; } break; -case 228: { +case 230: { sym(1).ival = QSOperator::InplaceDiv; } break; -case 229: { +case 231: { sym(1).ival = QSOperator::InplaceMod; } break; -case 230: { +case 232: { sym(1).ival = QSOperator::InplaceAdd; } break; -case 231: { +case 233: { sym(1).ival = QSOperator::InplaceSub; } break; -case 232: { +case 234: { sym(1).ival = QSOperator::InplaceLeftShift; } break; -case 233: { +case 235: { sym(1).ival = QSOperator::InplaceRightShift; } break; -case 234: { +case 236: { sym(1).ival = QSOperator::InplaceURightShift; } break; -case 235: { +case 237: { sym(1).ival = QSOperator::InplaceAnd; } break; -case 236: { +case 238: { sym(1).ival = QSOperator::InplaceXor; } break; -case 237: { +case 239: { sym(1).ival = QSOperator::InplaceOr; } break; -case 239: { +case 241: { AST::Expression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 240: { +case 242: { sym(1).Node = 0; } break; -case 243: { +case 245: { AST::Expression *node = makeAstNode (driver->nodePool(), sym(1).Expression, sym(3).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 244: { +case 246: { sym(1).Node = 0; } break; -case 261: { +case 263: { AST::Block *node = makeAstNode (driver->nodePool(), sym(2).StatementList); node->lbraceToken = loc(1); node->rbraceToken = loc(3); sym(1).Node = node; } break; -case 262: { +case 264: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).Statement); } break; -case 263: { +case 265: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).StatementList, sym(2).Statement); } break; -case 264: { +case 266: { sym(1).Node = 0; } break; -case 265: { +case 267: { sym(1).Node = sym(1).StatementList->finish (); } break; -case 267: { +case 269: { AST::VariableStatement *node = makeAstNode (driver->nodePool(), sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST)); node->declarationKindToken = loc(1); @@ -1346,76 +1390,76 @@ case 267: { sym(1).Node = node; } break; -case 268: { +case 270: { sym(1).ival = T_CONST; } break; -case 269: { +case 271: { sym(1).ival = T_VAR; } break; -case 270: { +case 272: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).VariableDeclaration); } break; -case 271: { +case 273: { AST::VariableDeclarationList *node = makeAstNode (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration); node->commaToken = loc(2); sym(1).Node = node; } break; -case 272: { +case 274: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).VariableDeclaration); } break; -case 273: { +case 275: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration); } break; -case 274: { +case 276: { AST::VariableDeclaration *node = makeAstNode (driver->nodePool(), sym(1).sval, sym(2).Expression); node->identifierToken = loc(1); sym(1).Node = node; } break; -case 275: { +case 277: { AST::VariableDeclaration *node = makeAstNode (driver->nodePool(), sym(1).sval, sym(2).Expression); node->identifierToken = loc(1); sym(1).Node = node; } break; -case 276: { +case 278: { // ### TODO: AST for initializer sym(1) = sym(2); } break; -case 277: { +case 279: { sym(1).Node = 0; } break; -case 279: { +case 281: { // ### TODO: AST for initializer sym(1) = sym(2); } break; -case 280: { +case 282: { sym(1).Node = 0; } break; -case 282: { +case 284: { AST::EmptyStatement *node = makeAstNode (driver->nodePool()); node->semicolonToken = loc(1); sym(1).Node = node; } break; -case 284: { +case 286: { AST::ExpressionStatement *node = makeAstNode (driver->nodePool(), sym(1).Expression); node->semicolonToken = loc(2); sym(1).Node = node; } break; -case 285: { +case 287: { AST::IfStatement *node = makeAstNode (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement); node->ifToken = loc(1); node->lparenToken = loc(2); @@ -1424,7 +1468,7 @@ case 285: { sym(1).Node = node; } break; -case 286: { +case 288: { AST::IfStatement *node = makeAstNode (driver->nodePool(), sym(3).Expression, sym(5).Statement); node->ifToken = loc(1); node->lparenToken = loc(2); @@ -1432,7 +1476,7 @@ case 286: { sym(1).Node = node; } break; -case 288: { +case 290: { AST::DoWhileStatement *node = makeAstNode (driver->nodePool(), sym(2).Statement, sym(5).Expression); node->doToken = loc(1); node->whileToken = loc(3); @@ -1442,7 +1486,7 @@ case 288: { sym(1).Node = node; } break; -case 289: { +case 291: { AST::WhileStatement *node = makeAstNode (driver->nodePool(), sym(3).Expression, sym(5).Statement); node->whileToken = loc(1); node->lparenToken = loc(2); @@ -1450,7 +1494,7 @@ case 289: { sym(1).Node = node; } break; -case 290: { +case 292: { AST::ForStatement *node = makeAstNode (driver->nodePool(), sym(3).Expression, sym(5).Expression, sym(7).Expression, sym(9).Statement); node->forToken = loc(1); @@ -1461,7 +1505,7 @@ case 290: { sym(1).Node = node; } break; -case 291: { +case 293: { AST::LocalForStatement *node = makeAstNode (driver->nodePool(), sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression, sym(8).Expression, sym(10).Statement); @@ -1474,7 +1518,7 @@ case 291: { sym(1).Node = node; } break; -case 292: { +case 294: { AST:: ForEachStatement *node = makeAstNode (driver->nodePool(), sym(3).Expression, sym(5).Expression, sym(7).Statement); node->forToken = loc(1); @@ -1484,7 +1528,7 @@ case 292: { sym(1).Node = node; } break; -case 293: { +case 295: { AST::LocalForEachStatement *node = makeAstNode (driver->nodePool(), sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement); node->forToken = loc(1); @@ -1495,14 +1539,14 @@ case 293: { sym(1).Node = node; } break; -case 295: { +case 297: { AST::ContinueStatement *node = makeAstNode (driver->nodePool()); node->continueToken = loc(1); node->semicolonToken = loc(2); sym(1).Node = node; } break; -case 297: { +case 299: { AST::ContinueStatement *node = makeAstNode (driver->nodePool(), sym(2).sval); node->continueToken = loc(1); node->identifierToken = loc(2); @@ -1510,14 +1554,14 @@ case 297: { sym(1).Node = node; } break; -case 299: { +case 301: { AST::BreakStatement *node = makeAstNode (driver->nodePool()); node->breakToken = loc(1); node->semicolonToken = loc(2); sym(1).Node = node; } break; -case 301: { +case 303: { AST::BreakStatement *node = makeAstNode (driver->nodePool(), sym(2).sval); node->breakToken = loc(1); node->identifierToken = loc(2); @@ -1525,14 +1569,14 @@ case 301: { sym(1).Node = node; } break; -case 303: { +case 305: { AST::ReturnStatement *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->returnToken = loc(1); node->semicolonToken = loc(3); sym(1).Node = node; } break; -case 304: { +case 306: { AST::WithStatement *node = makeAstNode (driver->nodePool(), sym(3).Expression, sym(5).Statement); node->withToken = loc(1); node->lparenToken = loc(2); @@ -1540,7 +1584,7 @@ case 304: { sym(1).Node = node; } break; -case 305: { +case 307: { AST::SwitchStatement *node = makeAstNode (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock); node->switchToken = loc(1); node->lparenToken = loc(2); @@ -1548,90 +1592,90 @@ case 305: { sym(1).Node = node; } break; -case 306: { +case 308: { AST::CaseBlock *node = makeAstNode (driver->nodePool(), sym(2).CaseClauses); node->lbraceToken = loc(1); node->rbraceToken = loc(3); sym(1).Node = node; } break; -case 307: { +case 309: { AST::CaseBlock *node = makeAstNode (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses); node->lbraceToken = loc(1); node->rbraceToken = loc(5); sym(1).Node = node; } break; -case 308: { +case 310: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).CaseClause); } break; -case 309: { +case 311: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause); } break; -case 310: { +case 312: { sym(1).Node = 0; } break; -case 311: { +case 313: { sym(1).Node = sym(1).CaseClauses->finish (); } break; -case 312: { +case 314: { AST::CaseClause *node = makeAstNode (driver->nodePool(), sym(2).Expression, sym(4).StatementList); node->caseToken = loc(1); node->colonToken = loc(3); sym(1).Node = node; } break; -case 313: { +case 315: { AST::DefaultClause *node = makeAstNode (driver->nodePool(), sym(3).StatementList); node->defaultToken = loc(1); node->colonToken = loc(2); sym(1).Node = node; } break; -case 314: -case 315: { +case 316: +case 317: { AST::LabelledStatement *node = makeAstNode (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()), sym(3).Statement); node->identifierToken = loc(1); node->colonToken = loc(2); sym(1).Node = node; } break; -case 316: { +case 318: { AST::LabelledStatement *node = makeAstNode (driver->nodePool(), sym(1).sval, sym(3).Statement); node->identifierToken = loc(1); node->colonToken = loc(2); sym(1).Node = node; } break; -case 318: { +case 320: { AST::ThrowStatement *node = makeAstNode (driver->nodePool(), sym(2).Expression); node->throwToken = loc(1); node->semicolonToken = loc(3); sym(1).Node = node; } break; -case 319: { +case 321: { AST::TryStatement *node = makeAstNode (driver->nodePool(), sym(2).Statement, sym(3).Catch); node->tryToken = loc(1); sym(1).Node = node; } break; -case 320: { +case 322: { AST::TryStatement *node = makeAstNode (driver->nodePool(), sym(2).Statement, sym(3).Finally); node->tryToken = loc(1); sym(1).Node = node; } break; -case 321: { +case 323: { AST::TryStatement *node = makeAstNode (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally); node->tryToken = loc(1); sym(1).Node = node; } break; -case 322: { +case 324: { AST::Catch *node = makeAstNode (driver->nodePool(), sym(3).sval, sym(5).Block); node->catchToken = loc(1); node->lparenToken = loc(2); @@ -1640,20 +1684,20 @@ case 322: { sym(1).Node = node; } break; -case 323: { +case 325: { AST::Finally *node = makeAstNode (driver->nodePool(), sym(2).Block); node->finallyToken = loc(1); sym(1).Node = node; } break; -case 325: { +case 327: { AST::DebuggerStatement *node = makeAstNode (driver->nodePool()); node->debuggerToken = loc(1); node->semicolonToken = loc(2); sym(1).Node = node; } break; -case 326: { +case 328: { AST::FunctionDeclaration *node = makeAstNode (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody); node->functionToken = loc(1); node->identifierToken = loc(2); @@ -1664,7 +1708,7 @@ case 326: { sym(1).Node = node; } break; -case 327: { +case 329: { AST::FunctionExpression *node = makeAstNode (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody); node->functionToken = loc(1); if (sym(2).sval) @@ -1676,60 +1720,60 @@ case 327: { sym(1).Node = node; } break; -case 328: { +case 330: { AST::FormalParameterList *node = makeAstNode (driver->nodePool(), sym(1).sval); node->identifierToken = loc(1); sym(1).Node = node; } break; -case 329: { +case 331: { AST::FormalParameterList *node = makeAstNode (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval); node->commaToken = loc(2); node->identifierToken = loc(3); sym(1).Node = node; } break; -case 330: { +case 332: { sym(1).Node = 0; } break; -case 331: { +case 333: { sym(1).Node = sym(1).FormalParameterList->finish (); } break; -case 332: { +case 334: { sym(1).Node = 0; } break; -case 334: { +case 336: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).SourceElements->finish ()); } break; -case 335: { +case 337: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).SourceElements->finish ()); } break; -case 336: { +case 338: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).SourceElement); } break; -case 337: { +case 339: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement); } break; -case 338: { +case 340: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).Statement); } break; -case 339: { +case 341: { sym(1).Node = makeAstNode (driver->nodePool(), sym(1).FunctionDeclaration); } break; -case 340: { +case 342: { sym(1).sval = 0; } break; -case 342: { +case 344: { sym(1).Node = 0; } break; diff --git a/src/declarative/qml/parser/qdeclarativejsparser_p.h b/src/declarative/qml/parser/qdeclarativejsparser_p.h index 3864398..8838fbe 100644 --- a/src/declarative/qml/parser/qdeclarativejsparser_p.h +++ b/src/declarative/qml/parser/qdeclarativejsparser_p.h @@ -235,9 +235,9 @@ protected: -#define J_SCRIPT_REGEXPLITERAL_RULE1 76 +#define J_SCRIPT_REGEXPLITERAL_RULE1 78 -#define J_SCRIPT_REGEXPLITERAL_RULE2 77 +#define J_SCRIPT_REGEXPLITERAL_RULE2 79 QT_QML_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index 9fff294..2b9cd4b 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -397,7 +397,7 @@ Object *ProcessAST::defineObjectBinding(AST::UiQualifiedId *qualifiedId, bool on if (string.isStringList()) { QStringList urls = string.asStringList(); // We need to add this as a resource - for (int ii = 0; ii < urls.count(); ++ii) + for (int ii = 0; ii < urls.count(); ++ii) _parser->_refUrls << QUrl(urls.at(ii)); } } @@ -503,7 +503,7 @@ bool ProcessAST::visit(AST::UiImport *node) error.setColumn(node->importIdToken.startColumn); _parser->_errors << error; return false; - } + } import.location = location(startLoc, endLoc); @@ -637,7 +637,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node) property.isDefaultProperty = node->isDefaultMember; property.type = type; if (type >= Object::DynamicProperty::Custom) { - QDeclarativeScriptParser::TypeReference *typeRef = + QDeclarativeScriptParser::TypeReference *typeRef = _parser->findOrCreateType(memberType); typeRef->refObjects.append(_stateStack.top().object); } @@ -660,9 +660,12 @@ bool ProcessAST::visit(AST::UiPublicMember *node) } _stateStack.top().object->dynamicProperties << property; + + // process QML-like initializers (e.g. property Object o: Object {}) + accept(node->binding); } - return true; + return false; } @@ -996,7 +999,7 @@ QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extra for (int ii = 0; ii < length; ++ii) { const QChar &c = data[ii]; - if (c.isSpace()) + if (c.isSpace()) continue; if (c == forwardSlash) { diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index e2cf5ca..0f11498 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -1065,7 +1065,6 @@ void tst_qdeclarativelanguage::defaultPropertyListOrder() void tst_qdeclarativelanguage::declaredPropertyValues() { QDeclarativeComponent component(&engine, TEST_FILE("declaredPropertyValues.qml")); - QEXPECT_FAIL("", "QTBUG-7860", Abort); VERIFY_ERRORS(0); } -- cgit v0.12 From a0df2ac07c75882618b40657e1485dda3204880e Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Mon, 22 Feb 2010 14:53:52 +0100 Subject: adds a timeout option to QThreadPool::waitForDone(); Task-number: QTBUG-2695 Reviewed-by: Benjamin Poulain --- src/corelib/concurrent/qthreadpool.cpp | 18 +++++++++++++----- src/corelib/concurrent/qthreadpool.h | 2 +- src/corelib/concurrent/qthreadpool_p.h | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/corelib/concurrent/qthreadpool.cpp b/src/corelib/concurrent/qthreadpool.cpp index 9e4189e..a4057f1 100644 --- a/src/corelib/concurrent/qthreadpool.cpp +++ b/src/corelib/concurrent/qthreadpool.cpp @@ -41,6 +41,7 @@ #include "qthreadpool.h" #include "qthreadpool_p.h" +#include "qelapsedtimer.h" #ifndef QT_NO_THREAD @@ -288,11 +289,18 @@ void QThreadPoolPrivate::reset() isExiting = false; } -void QThreadPoolPrivate::waitForDone() +void QThreadPoolPrivate::waitForDone(int msecs) { QMutexLocker locker(&mutex); - while (!(queue.isEmpty() && activeThreads == 0)) - noActiveThreads.wait(locker.mutex()); + if (msecs < 0){ + while (!(queue.isEmpty() && activeThreads == 0)) + noActiveThreads.wait(locker.mutex()); + } else { + QElapsedTimer timer; + timer.start(); + while (!(queue.isEmpty() && activeThreads == 0) && (timer.elapsed() < msecs)) + noActiveThreads.wait(locker.mutex(), msecs - timer.elapsed()); + } } /*! \internal @@ -610,10 +618,10 @@ void QThreadPool::releaseThread() /*! Waits for each thread to exit and removes all threads from the thread pool. */ -void QThreadPool::waitForDone() +void QThreadPool::waitForDone(int msecs) { Q_D(QThreadPool); - d->waitForDone(); + d->waitForDone(msecs); d->reset(); } diff --git a/src/corelib/concurrent/qthreadpool.h b/src/corelib/concurrent/qthreadpool.h index cc1e059..9895c41 100644 --- a/src/corelib/concurrent/qthreadpool.h +++ b/src/corelib/concurrent/qthreadpool.h @@ -84,7 +84,7 @@ public: void reserveThread(); void releaseThread(); - void waitForDone(); + void waitForDone(int msecs = -1); }; QT_END_NAMESPACE diff --git a/src/corelib/concurrent/qthreadpool_p.h b/src/corelib/concurrent/qthreadpool_p.h index 8a2cf98..1a0e4ab 100644 --- a/src/corelib/concurrent/qthreadpool_p.h +++ b/src/corelib/concurrent/qthreadpool_p.h @@ -82,7 +82,7 @@ public: void startThread(QRunnable *runnable = 0); void reset(); - void waitForDone(); + void waitForDone(int msecs = -1); bool startFrontRunnable(); void stealRunnable(QRunnable *); -- cgit v0.12 From 33a2afa8cccc38302539573f8d3559976bf4cc91 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Thu, 18 Mar 2010 22:13:30 +0100 Subject: Remove the "Insert unicode control character" menu entry on X11. It's still displayed when it seems to make sense with respect to the active keyboard layouts. It can also be enabled from qtconfig. Task-number: QTBUG-9186 Reviewed-by: Denis --- src/gui/inputmethod/qximinputcontext_x11.cpp | 54 +++++++++++++++++++++++++++- src/gui/kernel/qkeymapper_x11.cpp | 5 ++- src/gui/text/qtextcontrol.cpp | 4 +-- src/gui/widgets/qlineedit.cpp | 4 +-- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp index 68ade38..d048b36 100644 --- a/src/gui/inputmethod/qximinputcontext_x11.cpp +++ b/src/gui/inputmethod/qximinputcontext_x11.cpp @@ -344,7 +344,13 @@ static XFontSet getFontSet(const QFont &f) return (fontsetCache[i] == (XFontSet)-1) ? 0 : fontsetCache[i]; } - +extern bool qt_use_rtl_extensions; // from qapplication_x11.cpp +#ifndef QT_NO_XKB +extern void q_getLocaleAndDirection(QLocale *locale, + Qt::LayoutDirection *direction, + const QByteArray &layoutName, + const QByteArray &variantName); +#endif QXIMInputContext::QXIMInputContext() { @@ -375,6 +381,52 @@ QXIMInputContext::QXIMInputContext() else QXIMInputContext::create_xim(); #endif // USE_X11R6_XIM + +#ifndef QT_NO_XKB + if (X11->use_xkb) { + QByteArray layoutName; + QByteArray variantName; + + Atom type = XNone; + int format = 0; + ulong nitems = 0; + ulong bytesAfter = 0; + uchar *data = 0; + if (XGetWindowProperty(X11->display, RootWindow(X11->display, 0), ATOM(_XKB_RULES_NAMES), 0, 1024, + false, XA_STRING, &type, &format, &nitems, &bytesAfter, &data) == Success + && type == XA_STRING && format == 8 && nitems > 2) { + + char *names[5] = { 0, 0, 0, 0, 0 }; + char *p = reinterpret_cast(data), *end = p + nitems; + int i = 0; + do { + names[i++] = p; + p += qstrlen(p) + 1; + } while (p < end); + + QList layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(','); + QList variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(','); + for (int i = 0; i < qMin(layoutNames.count(), variantNames.count()); ++i ) { + QLocale keyboardInputLocale; + Qt::LayoutDirection keyboardInputDirection; + QByteArray variantName = variantNames.at(i); + const int dashPos = variantName.indexOf("-"); + if (dashPos >= 0) + variantName.truncate(dashPos); + q_getLocaleAndDirection(&keyboardInputLocale, + &keyboardInputDirection, + layoutNames.at(i), + variantName); + if (keyboardInputDirection == Qt::RightToLeft) + qt_use_rtl_extensions = true; + } + } + + if (data) + XFree(data); + } +#endif // QT_NO_XKB + } diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index 428ac3e..807959c 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF)) #endif -static void getLocaleAndDirection(QLocale *locale, +void q_getLocaleAndDirection(QLocale *locale, Qt::LayoutDirection *direction, const QByteArray &layoutName, const QByteArray &variantName) @@ -523,7 +523,7 @@ void QKeyMapperPrivate::clearMappings() // if (keyboardLayoutName.isEmpty()) // qWarning("Qt: unable to determine keyboard layout, please talk to qt-bugs@trolltech.com"); ? - getLocaleAndDirection(&keyboardInputLocale, + q_getLocaleAndDirection(&keyboardInputLocale, &keyboardInputDirection, layoutName, variantName); @@ -534,7 +534,6 @@ void QKeyMapperPrivate::clearMappings() << "direction =" << keyboardInputDirection; #endif - if (data) XFree(data); } else diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 6864fe1..671dfc0 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -91,7 +91,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_CONTEXTMENU -#if defined(Q_WS_WIN) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) extern bool qt_use_rtl_extensions; #endif #endif @@ -2080,7 +2080,7 @@ QMenu *QTextControl::createStandardContextMenu(const QPointF &pos, QWidget *pare } #endif -#if defined(Q_WS_WIN) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) if ((d->interactionFlags & Qt::TextEditable) && qt_use_rtl_extensions) { #else if (d->interactionFlags & Qt::TextEditable) { diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 817547c..0b8dca9 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -2046,7 +2046,7 @@ void QLineEdit::contextMenuEvent(QContextMenuEvent *event) } } -#if defined(Q_WS_WIN) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) extern bool qt_use_rtl_extensions; #endif @@ -2118,7 +2118,7 @@ QMenu *QLineEdit::createStandardContextMenu() } #endif -#if defined(Q_WS_WIN) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) if (!d->control->isReadOnly() && qt_use_rtl_extensions) { #else if (!d->control->isReadOnly()) { -- cgit v0.12 From 8c186194030df820ac67a5793f2dbf5df268a25a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 31 Mar 2010 15:35:14 +0100 Subject: Fix broken test case Symbian and WinCE don't have . and .. directory entries. Other test cases in this autotest make allowance for this, so I have done the same thing for the updateFileLists test case. Reviewed-by: mread --- tests/auto/qdir/tst_qdir.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index ba18bbb..c8c835f 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -1470,9 +1470,16 @@ void tst_QDir::updateFileLists() QDir dir("update-file-lists"); +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE) + //no . and .. on these OS. + QCOMPARE(dir.count(), uint(4)); + QCOMPARE(dir.entryList().size(), 4); + QCOMPARE(dir.entryInfoList().size(), 4); +#else QCOMPARE(dir.count(), uint(6)); QCOMPARE(dir.entryList().size(), 6); QCOMPARE(dir.entryInfoList().size(), 6); +#endif dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot); -- cgit v0.12 From 152c6f2deeaa4caa384561c0d865d13b50d44a42 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 31 Mar 2010 16:16:41 +0100 Subject: Fix regression on Symbian commit c43400792b637c744ca840a4ecb339ffdb27c604 made "x:/" a root directory only on windows. It should be a root on symbian too. Reviewed-by: mread --- src/corelib/io/qdir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 1b60936..e54d95e 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2125,7 +2125,7 @@ QString QDir::cleanPath(const QString &path) QString ret = (used == len ? name : QString(out, used)); // Strip away last slash except for root directories if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) { -#ifdef Q_OS_WIN +#if defined (Q_OS_WIN) || defined (Q_OS_SYMBIAN) if (!(ret.length() == 3 && ret.at(1) == QLatin1Char(':'))) #endif ret.chop(1); -- cgit v0.12 From 6b074cf855276f7ec67f7b69fe91f0243291c50d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 31 Mar 2010 17:28:37 +0200 Subject: Fix compilation with Sun CC: no semi-colon after Q_ENUM. Error was: "graphicsitems/qdeclarativepathview_p.h", line 80: Error: "}" expected instead of ";" Reviewed-by: Olivier Goffart --- src/declarative/graphicsitems/qdeclarativepathview_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p.h index 0079891..a00f4c0 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p.h @@ -77,7 +77,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativePathView : public QDeclarativeItem Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(int pathItemCount READ pathItemCount WRITE setPathItemCount NOTIFY pathItemCountChanged) - Q_ENUMS(HighlightRangeMode); + Q_ENUMS(HighlightRangeMode) public: QDeclarativePathView(QDeclarativeItem *parent=0); -- cgit v0.12 From 664fdc07056b8497a68518d0f89d689ff399702e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 31 Mar 2010 11:15:58 +0200 Subject: interpret source language "en" as "POSIX" (more precisely: "none specified") we set it to that value when writing xliff, as the header is mandatory and no better value is possible. it seems unlikely that an unqualified "english" would be used if somebody meant to actually specify a source language, so this hack should be ok. --- tests/auto/linguist/lconvert/data/msgid.ts | 2 +- tools/linguist/shared/xliff.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/linguist/lconvert/data/msgid.ts b/tests/auto/linguist/lconvert/data/msgid.ts index ab65845..f89fa74 100644 --- a/tests/auto/linguist/lconvert/data/msgid.ts +++ b/tests/auto/linguist/lconvert/data/msgid.ts @@ -1,6 +1,6 @@ - + Dialog2 diff --git a/tools/linguist/shared/xliff.cpp b/tools/linguist/shared/xliff.cpp index 20303ec..6411426 100644 --- a/tools/linguist/shared/xliff.cpp +++ b/tools/linguist/shared/xliff.cpp @@ -503,6 +503,8 @@ bool XLIFFHandler::startElement(const QString& namespaceURI, m_language.replace(QLatin1Char('-'), QLatin1Char('_')); m_sourceLanguage = atts.value(QLatin1String("source-language")); m_sourceLanguage.replace(QLatin1Char('-'), QLatin1Char('_')); + if (m_sourceLanguage == QLatin1String("en")) + m_sourceLanguage.clear(); } else if (localName == QLatin1String("group")) { if (atts.value(QLatin1String("restype")) == QLatin1String(restypeContext)) { m_context = atts.value(QLatin1String("resname")); -- cgit v0.12 From 0226221643e9f88c9b50ede7677b523d143025f3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 30 Mar 2010 18:25:27 +0200 Subject: fix updating of X-Source-Language PO header --- tools/linguist/shared/po.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 3354d61..393290c 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -630,6 +630,9 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) transl.remove(QRegExp(QLatin1String("\\bX-Language:[^\n]*\n"))); if (!translator.languageCode().isEmpty()) transl += QLatin1String("X-Language: ") + translator.languageCode() + QLatin1Char('\n'); + transl.remove(QRegExp(QLatin1String("\\bX-Source-Language:[^\n]*\n"))); + if (!translator.sourceLanguageCode().isEmpty()) + transl += QLatin1String("X-Source-Language: ") + translator.sourceLanguageCode() + QLatin1Char('\n'); } out << poEscapedString(prefix, QLatin1String("msgstr"), noWrap, transl); } else { -- cgit v0.12 From e07e8a02aab1dec4f91323d2912a54b3a78b075a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 31 Mar 2010 11:24:55 +0200 Subject: make PO header handling less of a monster hack instead of doing string editing magic, parse the header properly. don't add a template file comment, either - it's not mandatory, after all. --- tools/linguist/shared/po.cpp | 124 ++++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 44 deletions(-) diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 393290c..19e2f13 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -354,6 +354,11 @@ static void slurpComment(QString &msg, const QStringList &lines, int & l) --l; } +static QString makePoHeader(const QString &str) +{ + return QLatin1String("po-header-") + str.toLower().replace(QLatin1Char('-'), QLatin1Char('_')); +} + bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) { const QChar quote = QLatin1Char('"'); @@ -385,7 +390,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) lines.append(in.readLine().trimmed()); lines.append(QString()); - int l = 0; + int l = 0, lastCmtLine = -1; PoItem item; for (; l != lines.size(); ++l) { QString line = lines.at(l); @@ -406,23 +411,51 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) line = lines.at(l); } if (item.msgId.isEmpty()) { - QRegExp rx(QLatin1String("\\bX-Language: ([^\n]*)\n")); - int idx = rx.indexIn(item.msgStr.first()); - if (idx >= 0) { - translator.setLanguageCode(rx.cap(1)); - item.msgStr.first().remove(idx, rx.matchedLength()); - } - QRegExp rx2(QLatin1String("\\bX-Source-Language: ([^\n]*)\n")); - int idx2 = rx2.indexIn(item.msgStr.first()); - if (idx2 >= 0) { - translator.setSourceLanguageCode(rx2.cap(1)); - item.msgStr.first().remove(idx2, rx2.matchedLength()); + QStringList hdrOrder; + foreach (const QString &hdr, + item.msgStr.first().split(QLatin1Char('\n'), QString::SkipEmptyParts)) { + int idx = hdr.indexOf(QLatin1Char(':')); + if (idx < 0) { + cd.appendError(QString::fromLatin1("Unexpected PO header format '%1'\n") + .arg(hdr)); + error = true; + break; + } + QString hdrName = hdr.left(idx).trimmed(); + QString hdrValue = hdr.mid(idx + 1).trimmed(); + hdrOrder << hdrName; + if (hdrName == QLatin1String("X-Language")) + translator.setLanguageCode(hdrValue); + else if (hdrName == QLatin1String("X-Source-Language")) + translator.setSourceLanguageCode(hdrValue); + else if (hdrName == QLatin1String("X-Virgin-Header")) + ; // legacy + else + translator.setExtra(makePoHeader(hdrName), hdrValue); } - if (item.msgStr.first().indexOf( - QRegExp(QLatin1String("\\bX-Virgin-Header:[^\n]*\n"))) >= 0) { - item = PoItem(); - continue; + // Eliminate the field if only headers we added are present in standard order. + // Keep in sync with savePO + static const char * const dfltHdrs[] = { "X-Language", "X-Source-Language" }; + uint cdh = 0; + for (int cho = 0; cho < hdrOrder.length(); cho++) { + for (;; cdh++) { + if (cdh == sizeof(dfltHdrs)/sizeof(dfltHdrs[0])) { + translator.setExtra(QLatin1String("po-headers"), + hdrOrder.join(QLatin1String(","))); + goto doneho; + } + if (hdrOrder.at(cho) == QLatin1String(dfltHdrs[cdh])) { + cdh++; + break; + } + } } + doneho: + if (lastCmtLine != -1) + translator.setExtra(QLatin1String("po-header_comment"), + static_cast(lines.mid(0, lastCmtLine + 1)).join(QLatin1String("\n"))); + item = PoItem(); + continue; } // build translator message TranslatorMessage msg; @@ -533,6 +566,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) error = true; break; } + lastCmtLine = l; } else if (line.startsWith(QLatin1String("msgctxt "))) { item.tscomment = slurpEscapedString(lines, l, 8, QString(), cd); } else if (line.startsWith(QLatin1String("msgid "))) { @@ -551,33 +585,44 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) return !error && cd.errors().isEmpty(); } +static void addPoHeader(Translator::ExtraData &headers, QStringList &hdrOrder, + const char *name, const QString &value) +{ + QString qName = QLatin1String(name); + if (!hdrOrder.contains(qName)) + hdrOrder << qName; + headers[makePoHeader(qName)] = value; +} + bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) { bool ok = true; QTextStream out(&dev); out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec); - bool first = true; - if (translator.messages().isEmpty() || !translator.messages().first().sourceText().isEmpty()) { - out << - "# SOME DESCRIPTIVE TITLE.\n" - "# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n" - "# This file is distributed under the same license as the PACKAGE package.\n" - "# FIRST AUTHOR , YEAR.\n" - "#\n" - "#, fuzzy\n" - "msgid \"\"\n" - "msgstr \"\"\n" - "\"X-Virgin-Header: remove this line if you change anything in the header.\\n\"\n"; - if (!translator.languageCode().isEmpty()) - out << "\"X-Language: " << translator.languageCode() << "\\n\"\n"; - if (!translator.sourceLanguageCode().isEmpty()) - out << "\"X-Source-Language: " << translator.sourceLanguageCode() << "\\n\"\n"; - first = false; + QString cmt = translator.extra(QLatin1String("po-header_comment")); + if (!cmt.isEmpty()) + out << cmt << '\n'; + out << "msgid \"\"\n"; + Translator::ExtraData headers = translator.extras(); + QStringList hdrOrder = translator.extra(QLatin1String("po-headers")).split( + QLatin1Char(','), QString::SkipEmptyParts); + // Keep in sync with loadPO + if (!translator.languageCode().isEmpty()) + addPoHeader(headers, hdrOrder, "X-Language", translator.languageCode()); + if (!translator.sourceLanguageCode().isEmpty()) + addPoHeader(headers, hdrOrder, "X-Source-Language", translator.sourceLanguageCode()); + QString hdrStr; + foreach (const QString &hdr, hdrOrder) { + hdrStr += hdr; + hdrStr += QLatin1String(": "); + hdrStr += headers.value(makePoHeader(hdr)); + hdrStr += QLatin1Char('\n'); } + out << poEscapedString(QString(), QString::fromLatin1("msgstr"), true, hdrStr); + foreach (const TranslatorMessage &msg, translator.messages()) { - if (!first) - out << endl; + out << endl; if (!msg.translatorComment().isEmpty()) out << poEscapedLines(QLatin1String("#"), true, msg.translatorComment()); @@ -626,14 +671,6 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.sourceText()); if (!msg.isPlural()) { QString transl = msg.translation(); - if (first) { - transl.remove(QRegExp(QLatin1String("\\bX-Language:[^\n]*\n"))); - if (!translator.languageCode().isEmpty()) - transl += QLatin1String("X-Language: ") + translator.languageCode() + QLatin1Char('\n'); - transl.remove(QRegExp(QLatin1String("\\bX-Source-Language:[^\n]*\n"))); - if (!translator.sourceLanguageCode().isEmpty()) - transl += QLatin1String("X-Source-Language: ") + translator.sourceLanguageCode() + QLatin1Char('\n'); - } out << poEscapedString(prefix, QLatin1String("msgstr"), noWrap, transl); } else { QString plural = msg.extra(QLatin1String("po-msgid_plural")); @@ -649,7 +686,6 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) str); } } - first = false; } return ok; } -- cgit v0.12 From 2aad03302a80f609359ba6bb29aab9fdad08d608 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 31 Mar 2010 11:30:49 +0200 Subject: fix writing of length variant separators in the singular case --- tools/linguist/shared/po.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 19e2f13..bdd8c25 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -671,6 +671,8 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.sourceText()); if (!msg.isPlural()) { QString transl = msg.translation(); + transl.replace(QChar(Translator::BinaryVariantSeparator), + QChar(Translator::TextVariantSeparator)); out << poEscapedString(prefix, QLatin1String("msgstr"), noWrap, transl); } else { QString plural = msg.extra(QLatin1String("po-msgid_plural")); -- cgit v0.12 From ba40d481456095304729d0ef4279e0a53281798a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 30 Mar 2010 12:40:34 +0200 Subject: support gettext POT files these are in fact the same as PO files, only that exporting to one automatically drops translations. --- tools/linguist/shared/po.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index bdd8c25..87b2a8a 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -692,6 +692,13 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) return ok; } +static bool savePOT(const Translator &translator, QIODevice &dev, ConversionData &cd) +{ + Translator ttor = translator; + ttor.dropTranslations(); + return savePO(ttor, dev, cd); +} + int initPO() { Translator::FileFormat format; @@ -702,6 +709,13 @@ int initPO() format.fileType = Translator::FileFormat::TranslationSource; format.priority = 1; Translator::registerFileFormat(format); + format.extension = QLatin1String("pot"); + format.description = QObject::tr("GNU Gettext localization template files"); + format.loader = &loadPO; + format.saver = &savePOT; + format.fileType = Translator::FileFormat::TranslationSource; + format.priority = -1; + Translator::registerFileFormat(format); return 1; } -- cgit v0.12 From 89c369f344455a11259b29854a3556650a88c63d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 31 Mar 2010 11:32:48 +0200 Subject: don't mark untranslated messages as fuzzy in PO files ... as this is what gettext processors expect. --- tests/auto/linguist/lconvert/data/endless-po-loop.ts | 4 ++-- tests/auto/linguist/lconvert/data/msgid.ts | 8 ++++---- tests/auto/linguist/lconvert/data/singular.po | 3 --- tests/auto/linguist/lconvert/data/wrapping.po | 1 - tools/linguist/shared/po.cpp | 4 ++-- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tests/auto/linguist/lconvert/data/endless-po-loop.ts b/tests/auto/linguist/lconvert/data/endless-po-loop.ts index 6212fbd..8aa7215 100644 --- a/tests/auto/linguist/lconvert/data/endless-po-loop.ts +++ b/tests/auto/linguist/lconvert/data/endless-po-loop.ts @@ -5,12 +5,12 @@ Assistant This is some text which introduces the DonauDampfSchifffahrtsKapitaensMuetzeMitKomischenUltraViolettenFransenUndEinemKnopf - + %n document(s) found. - + diff --git a/tests/auto/linguist/lconvert/data/msgid.ts b/tests/auto/linguist/lconvert/data/msgid.ts index f89fa74..39401d8 100644 --- a/tests/auto/linguist/lconvert/data/msgid.ts +++ b/tests/auto/linguist/lconvert/data/msgid.ts @@ -5,23 +5,23 @@ Dialog2 %n files - + %n cars - + Age: %1 - + func3 - + diff --git a/tests/auto/linguist/lconvert/data/singular.po b/tests/auto/linguist/lconvert/data/singular.po index a0d4019..e0cfafb 100644 --- a/tests/auto/linguist/lconvert/data/singular.po +++ b/tests/auto/linguist/lconvert/data/singular.po @@ -9,7 +9,6 @@ msgstr "translated" msgid "untranslated two" msgstr "translated" -#, fuzzy #| msgid "old untranslated" msgid "untranslated two b" msgstr "" @@ -20,7 +19,6 @@ msgstr "" msgid "untranslated three" msgstr "translated" -#, fuzzy #| msgid "old untranslated" #| msgid_plural "old untranslated plural" msgid "untranslated three b" @@ -31,7 +29,6 @@ msgstr "" msgid "untranslated four" msgstr "translated" -#, fuzzy #| msgid_plural "old untranslated only plural" msgid "untranslated four b" msgstr "" diff --git a/tests/auto/linguist/lconvert/data/wrapping.po b/tests/auto/linguist/lconvert/data/wrapping.po index 39b7fbe..8223611 100644 --- a/tests/auto/linguist/lconvert/data/wrapping.po +++ b/tests/auto/linguist/lconvert/data/wrapping.po @@ -3,7 +3,6 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 87b2a8a..2895143 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -482,7 +482,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) msg.setTranslations(item.msgStr); if (isObsolete) msg.setType(TranslatorMessage::Obsolete); - else if (item.isFuzzy) + else if (item.isFuzzy || (!msg.sourceText().isEmpty() && !msg.isTranslated())) msg.setType(TranslatorMessage::Unfinished); else msg.setType(TranslatorMessage::Finished); @@ -645,7 +645,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) bool noWrap = false; QStringList flags; - if (msg.type() == TranslatorMessage::Unfinished) + if (msg.type() == TranslatorMessage::Unfinished && msg.isTranslated()) flags.append(QLatin1String("fuzzy")); TranslatorMessage::ExtraData::const_iterator itr = msg.extras().find(QLatin1String("po-flags")); -- cgit v0.12 From 1999331085a56242372c42f1dadfeeb0281e3f82 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 30 Mar 2010 15:33:48 +0200 Subject: simplify arabic plural rule --- tools/linguist/shared/numerus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linguist/shared/numerus.cpp b/tools/linguist/shared/numerus.cpp index d45dfed..287dd03 100644 --- a/tools/linguist/shared/numerus.cpp +++ b/tools/linguist/shared/numerus.cpp @@ -100,7 +100,7 @@ static const uchar arabicRules[] = Q_EQ, 1, Q_NEWRULE, Q_EQ, 2, Q_NEWRULE, Q_MOD_100 | Q_BETWEEN, 3, 10, Q_NEWRULE, - Q_MOD_100 | Q_NOT | Q_BETWEEN, 0, 2 }; + Q_MOD_100 | Q_GEQ, 11 }; static const uchar tagalogRules[] = { Q_LEQ, 1, Q_NEWRULE, Q_MOD_10 | Q_EQ, 4, Q_OR, Q_MOD_10 | Q_EQ, 6, Q_OR, Q_MOD_10 | Q_EQ, 9 }; -- cgit v0.12 From 81c35b4d95a0da4d2b104aa84ba5de93d0d94d1d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 31 Mar 2010 12:54:38 +0200 Subject: add Plural-Forms header in PO writer --- tests/auto/linguist/lconvert/data/makeplurals.pl | 9 ++-- .../auto/linguist/lconvert/data/test-kde-fuzzy.po | 2 +- .../linguist/lconvert/data/test-kde-multiline.po | 2 +- .../linguist/lconvert/data/test-kde-plurals.po | 2 +- tests/auto/linguist/lconvert/data/test1-de.po | 2 +- tools/linguist/linguist/messagemodel.cpp | 2 +- tools/linguist/shared/numerus.cpp | 57 ++++++++++++++-------- tools/linguist/shared/po.cpp | 24 ++++++++- tools/linguist/shared/qm.cpp | 4 +- tools/linguist/shared/translator.cpp | 2 +- tools/linguist/shared/translator.h | 2 +- 11 files changed, 74 insertions(+), 34 deletions(-) diff --git a/tests/auto/linguist/lconvert/data/makeplurals.pl b/tests/auto/linguist/lconvert/data/makeplurals.pl index d933a3e..9707ef0 100755 --- a/tests/auto/linguist/lconvert/data/makeplurals.pl +++ b/tests/auto/linguist/lconvert/data/makeplurals.pl @@ -57,7 +57,7 @@ sub makeit2($$$) } } -sub makeit($$) +sub makeit($$$) { open OUTFILE, ">${OUTDIR}plural-$_[0].po" || die "cannot write file in $OUTDIR"; print OUTFILE <=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po b/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po index b3f6e03..fc9ae77 100644 --- a/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po +++ b/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KAider 0.1\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: kgverify.cpp:459 #, fuzzy, kde-format diff --git a/tests/auto/linguist/lconvert/data/test-kde-multiline.po b/tests/auto/linguist/lconvert/data/test-kde-multiline.po index 0ca714c..662c02e 100644 --- a/tests/auto/linguist/lconvert/data/test-kde-multiline.po +++ b/tests/auto/linguist/lconvert/data/test-kde-multiline.po @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KAider 0.1\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: kdmshutdown.cpp:706 #, kde-format diff --git a/tests/auto/linguist/lconvert/data/test-kde-plurals.po b/tests/auto/linguist/lconvert/data/test-kde-plurals.po index 6c85d74..9f74de0 100644 --- a/tests/auto/linguist/lconvert/data/test-kde-plurals.po +++ b/tests/auto/linguist/lconvert/data/test-kde-plurals.po @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KAider 0.1\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Language: de_DE\n" #: kgverify.cpp:505 diff --git a/tests/auto/linguist/lconvert/data/test1-de.po b/tests/auto/linguist/lconvert/data/test1-de.po index 256b8e9..a4523bb 100644 --- a/tests/auto/linguist/lconvert/data/test1-de.po +++ b/tests/auto/linguist/lconvert/data/test1-de.po @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KAider 0.1\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Language: de_DE\n" #: lib/acl.c:107 lib/acl.c:121 lib/acl.c:138 lib/acl.c:165 lib/acl.c:174 diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp index 4e2b473..39ba9fd 100644 --- a/tools/linguist/linguist/messagemodel.cpp +++ b/tools/linguist/linguist/messagemodel.cpp @@ -402,7 +402,7 @@ bool DataModel::setLanguageAndCountry(QLocale::Language lang, QLocale::Country c if (lang == QLocale::C || uint(lang) > uint(QLocale::LastLanguage)) // XXX does this make any sense? lang = QLocale::English; QByteArray rules; - bool ok = getNumerusInfo(lang, country, &rules, &m_numerusForms); + bool ok = getNumerusInfo(lang, country, &rules, &m_numerusForms, 0); m_localizedLanguage = QCoreApplication::translate("MessageEditor", QLocale::languageToString(lang).toAscii()); m_countRefNeeds.clear(); for (int i = 0; i < rules.size(); ++i) { diff --git a/tools/linguist/shared/numerus.cpp b/tools/linguist/shared/numerus.cpp index 287dd03..c002119 100644 --- a/tools/linguist/shared/numerus.cpp +++ b/tools/linguist/shared/numerus.cpp @@ -318,28 +318,45 @@ struct NumerusTableEntry { const char * const *forms; const QLocale::Language *languages; const QLocale::Country *countries; + const char * const gettextRules; }; static const NumerusTableEntry numerusTable[] = { - { 0, 0, japaneseStyleForms, japaneseStyleLanguages, 0 }, - { englishStyleRules, sizeof(englishStyleRules), englishStyleForms, englishStyleLanguages, 0 }, + { 0, 0, japaneseStyleForms, japaneseStyleLanguages, 0, "nplurals=1; plural=0;" }, + { englishStyleRules, sizeof(englishStyleRules), englishStyleForms, englishStyleLanguages, 0, + "nplurals=2; plural=(n != 1);" }, { frenchStyleRules, sizeof(frenchStyleRules), frenchStyleForms, frenchStyleLanguages, - frenchStyleCountries }, - { latvianRules, sizeof(latvianRules), latvianForms, latvianLanguage, 0 }, - { icelandicRules, sizeof(icelandicRules), icelandicForms, icelandicLanguage, 0 }, - { irishStyleRules, sizeof(irishStyleRules), irishStyleForms, irishStyleLanguages, 0 }, - { slovakRules, sizeof(slovakRules), slovakForms, slovakLanguages, 0 }, - { macedonianRules, sizeof(macedonianRules), macedonianForms, macedonianLanguage, 0 }, - { lithuanianRules, sizeof(lithuanianRules), lithuanianForms, lithuanianLanguage, 0 }, - { russianStyleRules, sizeof(russianStyleRules), russianStyleForms, russianStyleLanguages, 0 }, - { polishRules, sizeof(polishRules), polishForms, polishLanguage, 0 }, - { romanianRules, sizeof(romanianRules), romanianForms, romanianLanguages, 0 }, - { slovenianRules, sizeof(slovenianRules), slovenianForms, slovenianLanguage, 0 }, - { malteseRules, sizeof(malteseRules), malteseForms, malteseLanguage, 0 }, - { welshRules, sizeof(welshRules), welshForms, welshLanguage, 0 }, - { arabicRules, sizeof(arabicRules), arabicForms, arabicLanguage, 0 }, - { tagalogRules, sizeof(tagalogRules), tagalogForms, tagalogLanguage, 0 }, - { catalanRules, sizeof(catalanRules), catalanForms, catalanLanguage, 0 } + frenchStyleCountries, "nplurals=2; plural=(n > 1);" }, + { latvianRules, sizeof(latvianRules), latvianForms, latvianLanguage, 0, + "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" }, + { icelandicRules, sizeof(icelandicRules), icelandicForms, icelandicLanguage, 0, + "nplurals=2; plural=(n%10==1 && n%100!=11 ? 0 : 1);" }, + { irishStyleRules, sizeof(irishStyleRules), irishStyleForms, irishStyleLanguages, 0, + "nplurals=3; plural=(n==1 ? 0 : n==2 ? 1 : 2);" }, + { slovakRules, sizeof(slovakRules), slovakForms, slovakLanguages, 0, + "nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);" }, + { macedonianRules, sizeof(macedonianRules), macedonianForms, macedonianLanguage, 0, + "nplurals=3; plural=(n%100==1 ? 0 : n%100==2 ? 1 : 2);" }, + { lithuanianRules, sizeof(lithuanianRules), lithuanianForms, lithuanianLanguage, 0, + "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" }, + { russianStyleRules, sizeof(russianStyleRules), russianStyleForms, russianStyleLanguages, 0, + "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }, + { polishRules, sizeof(polishRules), polishForms, polishLanguage, 0, + "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }, + { romanianRules, sizeof(romanianRules), romanianForms, romanianLanguages, 0, + "nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2);" }, + { slovenianRules, sizeof(slovenianRules), slovenianForms, slovenianLanguage, 0, + "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" }, + { malteseRules, sizeof(malteseRules), malteseForms, malteseLanguage, 0, + "nplurals=4; plural=(n==1 ? 0 : (n==0 || (n%100>=1 && n%100<=10)) ? 1 : (n%100>=11 && n%100<=19) ? 2 : 3);" }, + { welshRules, sizeof(welshRules), welshForms, welshLanguage, 0, + "nplurals=5; plural=(n==0 ? 0 : n==1 ? 1 : (n>=2 && n<=5) ? 2 : n==6 ? 3 : 4);" }, + { arabicRules, sizeof(arabicRules), arabicForms, arabicLanguage, 0, + "nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : (n%100>=3 && n%100<=10) ? 3 : n%100>=11 ? 4 : 5);" }, + { tagalogRules, sizeof(tagalogRules), tagalogForms, tagalogLanguage, 0, + "nplurals=3; plural=(n==1 ? 0 : (n%10==4 || n%10==6 || n%10== 9) ? 1 : 2);" }, + { catalanRules, sizeof(catalanRules), catalanForms, catalanLanguage, 0, + "nplurals=3; plural=(n==1 ? 0 : (n==11 || n/1000==11 || n/1000000==11 || n/1000000000==11) ? 1 : 2);" }, }; static const int NumerusTableSize = sizeof(numerusTable) / sizeof(numerusTable[0]); @@ -352,7 +369,7 @@ static const uchar magic[MagicLength] = { }; bool getNumerusInfo(QLocale::Language language, QLocale::Country country, - QByteArray *rules, QStringList *forms) + QByteArray *rules, QStringList *forms, const char **gettextRules) { while (true) { for (int i = 0; i < NumerusTableSize; ++i) { @@ -365,6 +382,8 @@ bool getNumerusInfo(QLocale::Language language, QLocale::Country country, *rules = QByteArray::fromRawData(reinterpret_cast(entry.rules), entry.rulesSize); } + if (gettextRules) + *gettextRules = entry.gettextRules; if (forms) { forms->clear(); for (int k = 0; entry.forms[k]; ++k) diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 2895143..ab24e15 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -412,6 +412,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) } if (item.msgId.isEmpty()) { QStringList hdrOrder; + QString pluralForms; foreach (const QString &hdr, item.msgStr.first().split(QLatin1Char('\n'), QString::SkipEmptyParts)) { int idx = hdr.indexOf(QLatin1Char(':')); @@ -428,14 +429,26 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) translator.setLanguageCode(hdrValue); else if (hdrName == QLatin1String("X-Source-Language")) translator.setSourceLanguageCode(hdrValue); + else if (hdrName == QLatin1String("Plural-Forms")) + pluralForms = hdrValue; else if (hdrName == QLatin1String("X-Virgin-Header")) ; // legacy else translator.setExtra(makePoHeader(hdrName), hdrValue); } + if (!pluralForms.isEmpty()) { + if (translator.languageCode().isEmpty()) { + translator.setExtra(makePoHeader(QLatin1String("Plural-Forms")), + pluralForms); + } else { + // FIXME: have fun with making a consistency check ... + } + } // Eliminate the field if only headers we added are present in standard order. // Keep in sync with savePO - static const char * const dfltHdrs[] = { "X-Language", "X-Source-Language" }; + static const char * const dfltHdrs[] = { + "Plural-Forms", "X-Language", "X-Source-Language" + }; uint cdh = 0; for (int cho = 0; cho < hdrOrder.length(); cho++) { for (;; cdh++) { @@ -608,8 +621,15 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) QStringList hdrOrder = translator.extra(QLatin1String("po-headers")).split( QLatin1Char(','), QString::SkipEmptyParts); // Keep in sync with loadPO - if (!translator.languageCode().isEmpty()) + if (!translator.languageCode().isEmpty()) { + QLocale::Language l; + QLocale::Country c; + Translator::languageAndCountry(translator.languageCode(), &l, &c); + const char *gettextRules; + if (getNumerusInfo(l, c, 0, 0, &gettextRules)) + addPoHeader(headers, hdrOrder, "Plural-Forms", QLatin1String(gettextRules)); addPoHeader(headers, hdrOrder, "X-Language", translator.languageCode()); + } if (!translator.sourceLanguageCode().isEmpty()) addPoHeader(headers, hdrOrder, "X-Source-Language", translator.sourceLanguageCode()); QString hdrStr; diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index de1284f..e2c4f4a 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -564,7 +564,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) Translator::languageAndCountry(translator.languageCode(), &l, &c); QStringList numerusForms; bool guessPlurals = true; - if (getNumerusInfo(l, c, 0, &numerusForms)) + if (getNumerusInfo(l, c, 0, &numerusForms, 0)) guessPlurals = (numerusForms.count() == 1); QString context, contextUtf8; @@ -704,7 +704,7 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData QLocale::Country c; Translator::languageAndCountry(translator.languageCode(), &l, &c); QByteArray rules; - if (getNumerusInfo(l, c, &rules, 0)) + if (getNumerusInfo(l, c, &rules, 0, 0)) releaser.setNumerusRules(rules); releaser.setCodecName(translator.codecName()); diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp index 4331ce6..465355d 100644 --- a/tools/linguist/shared/translator.cpp +++ b/tools/linguist/shared/translator.cpp @@ -652,7 +652,7 @@ void Translator::normalizeTranslations(ConversionData &cd) int numPlurals = 1; if (l != QLocale::C) { QStringList forms; - if (getNumerusInfo(l, c, 0, &forms)) + if (getNumerusInfo(l, c, 0, &forms, 0)) numPlurals = forms.count(); // includes singular } for (int i = 0; i < m_messages.count(); ++i) { diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index 0b88c07..bb199f0 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -233,7 +233,7 @@ private: }; bool getNumerusInfo(QLocale::Language language, QLocale::Country country, - QByteArray *rules, QStringList *forms); + QByteArray *rules, QStringList *forms, const char **gettextRules); /* This is a quick hack. The proper way to handle this would be -- cgit v0.12 From 11330487204a69a8afc998666f18350730ec1b09 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 30 Mar 2010 16:09:09 +0200 Subject: make variable naming politically correct :-D --- tools/linguist/shared/numerus.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/linguist/shared/numerus.cpp b/tools/linguist/shared/numerus.cpp index c002119..6066732 100644 --- a/tools/linguist/shared/numerus.cpp +++ b/tools/linguist/shared/numerus.cpp @@ -64,7 +64,7 @@ static const uchar icelandicRules[] = static const uchar irishStyleRules[] = { Q_EQ, 1, Q_NEWRULE, Q_EQ, 2 }; -static const uchar slovakRules[] = +static const uchar slovakStyleRules[] = { Q_EQ, 1, Q_NEWRULE, Q_BETWEEN, 2, 4 }; static const uchar macedonianRules[] = @@ -114,7 +114,7 @@ static const char * const frenchStyleForms[] = { "Singular", "Plural", 0 }; static const char * const icelandicForms[] = { "Singular", "Plural", 0 }; static const char * const latvianForms[] = { "Singular", "Plural", "Nullar", 0 }; static const char * const irishStyleForms[] = { "Singular", "Dual", "Plural", 0 }; -static const char * const slovakForms[] = { "Singular", "Paucal", "Plural", 0 }; +static const char * const slovakStyleForms[] = { "Singular", "Paucal", "Plural", 0 }; static const char * const macedonianForms[] = { "Singular", "Dual", "Plural", 0 }; static const char * const lithuanianForms[] = { "Singular", "Paucal", "Plural", 0 }; static const char * const russianStyleForms[] = { "Singular", "Dual", "Plural", 0 }; @@ -279,7 +279,7 @@ static const QLocale::Language irishStyleLanguages[] = { QLocale::Sanskrit, EOL }; -static const QLocale::Language slovakLanguages[] = { QLocale::Slovak, QLocale::Czech, EOL }; +static const QLocale::Language slovakStyleLanguages[] = { QLocale::Slovak, QLocale::Czech, EOL }; static const QLocale::Language macedonianLanguage[] = { QLocale::Macedonian, EOL }; static const QLocale::Language lithuanianLanguage[] = { QLocale::Lithuanian, EOL }; static const QLocale::Language russianStyleLanguages[] = { @@ -333,7 +333,7 @@ static const NumerusTableEntry numerusTable[] = { "nplurals=2; plural=(n%10==1 && n%100!=11 ? 0 : 1);" }, { irishStyleRules, sizeof(irishStyleRules), irishStyleForms, irishStyleLanguages, 0, "nplurals=3; plural=(n==1 ? 0 : n==2 ? 1 : 2);" }, - { slovakRules, sizeof(slovakRules), slovakForms, slovakLanguages, 0, + { slovakStyleRules, sizeof(slovakStyleRules), slovakStyleForms, slovakStyleLanguages, 0, "nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);" }, { macedonianRules, sizeof(macedonianRules), macedonianForms, macedonianLanguage, 0, "nplurals=3; plural=(n%100==1 ? 0 : n%100==2 ? 1 : 2);" }, -- cgit v0.12 From 1294e8cbcf2b0c6b52aef0c948ee32260bff8230 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 31 Mar 2010 14:46:30 +0200 Subject: handle encoding of PO files --- tests/auto/linguist/lconvert/data/makeplurals.pl | 3 + tests/auto/linguist/lconvert/data/singular.po | 3 + .../linguist/lconvert/data/test-broken-utf8.po.out | 3 + .../linguist/lconvert/data/test-escapes.po.out | 3 + .../auto/linguist/lconvert/data/test-slurp.po.out | 3 + tests/auto/linguist/lconvert/data/wrapping.po | 2 +- tools/linguist/shared/po.cpp | 336 +++++++++++++-------- 7 files changed, 218 insertions(+), 135 deletions(-) diff --git a/tests/auto/linguist/lconvert/data/makeplurals.pl b/tests/auto/linguist/lconvert/data/makeplurals.pl index 9707ef0..a2d1d700 100755 --- a/tests/auto/linguist/lconvert/data/makeplurals.pl +++ b/tests/auto/linguist/lconvert/data/makeplurals.pl @@ -63,6 +63,9 @@ sub makeit($$$) print OUTFILE <\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #, no-wrap diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index ab24e15..bf1a142 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -201,55 +202,54 @@ public: public: - QString id; - QString context; - QString tscomment; - QString oldTscomment; - QString lineNumber; - QString fileName; - QString references; - QString translatorComments; - QString automaticComments; - QString msgId; - QString oldMsgId; - QStringList msgStr; + QByteArray id; + QByteArray context; + QByteArray tscomment; + QByteArray oldTscomment; + QByteArray lineNumber; + QByteArray fileName; + QByteArray references; + QByteArray translatorComments; + QByteArray automaticComments; + QByteArray msgId; + QByteArray oldMsgId; + QList msgStr; bool isPlural; bool isFuzzy; QHash extra; }; -static bool isTranslationLine(const QString &line) +static bool isTranslationLine(const QByteArray &line) { - return line.startsWith(QLatin1String("#~ msgstr")) - || line.startsWith(QLatin1String("msgstr")); + return line.startsWith("#~ msgstr") || line.startsWith("msgstr"); } -static QString slurpEscapedString(const QStringList &lines, int & l, - int offset, const QString &prefix, ConversionData &cd) +static QByteArray slurpEscapedString(const QList &lines, int &l, + int offset, const QByteArray &prefix, ConversionData &cd) { - QString msg; + QByteArray msg; int stoff; for (; l < lines.size(); ++l) { - const QString &line = lines.at(l); + const QByteArray &line = lines.at(l); if (line.isEmpty() || !line.startsWith(prefix)) break; - while (line[offset].isSpace()) // No length check, as string has no trailing spaces. + while (::isspace(line[offset])) // No length check, as string has no trailing spaces. offset++; - if (line[offset].unicode() != '"') + if (line[offset] != '"') break; offset++; forever { if (offset == line.length()) goto premature_eol; - ushort c = line[offset++].unicode(); + uchar c = line[offset++]; if (c == '"') { if (offset == line.length()) break; - while (line[offset].isSpace()) + while (::isspace(line[offset])) offset++; - if (line[offset++].unicode() != '"') { + if (line[offset++] != '"') { cd.appendError(QString::fromLatin1( "PO parsing error: extra characters on line %1.") .arg(l + 1)); @@ -260,34 +260,34 @@ static QString slurpEscapedString(const QStringList &lines, int & l, if (c == '\\') { if (offset == line.length()) goto premature_eol; - c = line[offset++].unicode(); + c = line[offset++]; switch (c) { case 'r': - msg += QLatin1Char('\r'); // Maybe just throw it away? + msg += '\r'; // Maybe just throw it away? break; case 'n': - msg += QLatin1Char('\n'); + msg += '\n'; break; case 't': - msg += QLatin1Char('\t'); + msg += '\t'; break; case 'v': - msg += QLatin1Char('\v'); + msg += '\v'; break; case 'a': - msg += QLatin1Char('\a'); + msg += '\a'; break; case 'b': - msg += QLatin1Char('\b'); + msg += '\b'; break; case 'f': - msg += QLatin1Char('\f'); + msg += '\f'; break; case '"': - msg += QLatin1Char('"'); + msg += '"'; break; case '\\': - msg += QLatin1Char('\\'); + msg += '\\'; break; case '0': case '1': @@ -298,28 +298,28 @@ static QString slurpEscapedString(const QStringList &lines, int & l, case '6': case '7': stoff = offset - 1; - while ((c = line[offset].unicode()) >= '0' && c <= '7') + while ((c = line[offset]) >= '0' && c <= '7') if (++offset == line.length()) goto premature_eol; - msg += QChar(line.mid(stoff, offset - stoff).toUInt(0, 8)); + msg += line.mid(stoff, offset - stoff).toUInt(0, 8); break; case 'x': stoff = offset; - while (isxdigit(line[offset].unicode())) + while (::isxdigit(line[offset])) if (++offset == line.length()) goto premature_eol; - msg += QChar(line.mid(stoff, offset - stoff).toUInt(0, 16)); + msg += line.mid(stoff, offset - stoff).toUInt(0, 16); break; default: cd.appendError(QString::fromLatin1( "PO parsing error: invalid escape '\\%1' (line %2).") - .arg(QChar(c)).arg(l + 1)); - msg += QLatin1Char('\\'); - msg += QChar(c); + .arg(QChar((uint)c)).arg(l + 1)); + msg += '\\'; + msg += c; break; } } else { - msg += QChar(c); + msg += c; } } offset = prefix.size(); @@ -330,26 +330,25 @@ static QString slurpEscapedString(const QStringList &lines, int & l, premature_eol: cd.appendError(QString::fromLatin1( "PO parsing error: premature end of line %1.").arg(l + 1)); - return QString(); + return QByteArray(); } -static void slurpComment(QString &msg, const QStringList &lines, int & l) +static void slurpComment(QByteArray &msg, const QList &lines, int & l) { - const QChar newline = QLatin1Char('\n'); - QString prefix = lines.at(l); + QByteArray prefix = lines.at(l); for (int i = 1; ; i++) { - if (prefix.at(i).unicode() != ' ') { + if (prefix.at(i) != ' ') { prefix.truncate(i); break; } } for (; l < lines.size(); ++l) { - const QString &line = lines.at(l); + const QByteArray &line = lines.at(l); if (line.startsWith(prefix)) msg += line.mid(prefix.size()); - else if (line != QLatin1String("#")) + else if (line != "#") break; - msg += newline; + msg += '\n'; } --l; } @@ -359,12 +358,33 @@ static QString makePoHeader(const QString &str) return QLatin1String("po-header-") + str.toLower().replace(QLatin1Char('-'), QLatin1Char('_')); } +static QByteArray QByteArrayList_join(const QList &that, char sep) +{ + int totalLength = 0; + const int size = that.size(); + + for (int i = 0; i < size; ++i) + totalLength += that.at(i).size(); + + if (size > 0) + totalLength += size - 1; + + QByteArray res; + if (totalLength == 0) + return res; + res.reserve(totalLength); + for (int i = 0; i < that.size(); ++i) { + if (i) + res += sep; + res += that.at(i); + } + return res; +} + bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) { - const QChar quote = QLatin1Char('"'); - const QChar newline = QLatin1Char('\n'); - QTextStream in(&dev); - in.setCodec(cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource); + QTextCodec *codec = QTextCodec::codecForName( + cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource); bool error = false; // format of a .po file entry: @@ -385,25 +405,23 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) // ... // we need line based lookahead below. - QStringList lines; - while (!in.atEnd()) - lines.append(in.readLine().trimmed()); - lines.append(QString()); + QList lines; + while (!dev.atEnd()) + lines.append(dev.readLine().trimmed()); + lines.append(QByteArray()); int l = 0, lastCmtLine = -1; PoItem item; for (; l != lines.size(); ++l) { - QString line = lines.at(l); + QByteArray line = lines.at(l); if (line.isEmpty()) continue; if (isTranslationLine(line)) { - bool isObsolete = line.startsWith(QLatin1String("#~ msgstr")); - const QString prefix = QLatin1String(isObsolete ? "#~ " : ""); + bool isObsolete = line.startsWith("#~ msgstr"); + const QByteArray prefix = isObsolete ? "#~ " : ""; while (true) { - int idx = line.indexOf(QLatin1Char(' '), prefix.length()); - QString str = slurpEscapedString(lines, l, idx, prefix, cd); - str.replace(QChar(Translator::TextVariantSeparator), - QChar(Translator::BinaryVariantSeparator)); + int idx = line.indexOf(' ', prefix.length()); + QByteArray str = slurpEscapedString(lines, l, idx, prefix, cd); item.msgStr.append(str); if (l + 1 >= lines.size() || !isTranslationLine(lines.at(l + 1))) break; @@ -411,35 +429,67 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) line = lines.at(l); } if (item.msgId.isEmpty()) { - QStringList hdrOrder; - QString pluralForms; - foreach (const QString &hdr, - item.msgStr.first().split(QLatin1Char('\n'), QString::SkipEmptyParts)) { - int idx = hdr.indexOf(QLatin1Char(':')); + QHash extras; + QList hdrOrder; + QByteArray pluralForms; + foreach (const QByteArray &hdr, item.msgStr.first().split('\n')) { + if (hdr.isEmpty()) + continue; + int idx = hdr.indexOf(':'); if (idx < 0) { cd.appendError(QString::fromLatin1("Unexpected PO header format '%1'\n") - .arg(hdr)); + .arg(QString::fromLatin1(hdr))); error = true; break; } - QString hdrName = hdr.left(idx).trimmed(); - QString hdrValue = hdr.mid(idx + 1).trimmed(); + QByteArray hdrName = hdr.left(idx).trimmed(); + QByteArray hdrValue = hdr.mid(idx + 1).trimmed(); hdrOrder << hdrName; - if (hdrName == QLatin1String("X-Language")) - translator.setLanguageCode(hdrValue); - else if (hdrName == QLatin1String("X-Source-Language")) - translator.setSourceLanguageCode(hdrValue); - else if (hdrName == QLatin1String("Plural-Forms")) + if (hdrName == "X-Language") { + translator.setLanguageCode(QString::fromLatin1(hdrValue)); + } else if (hdrName == "X-Source-Language") { + translator.setSourceLanguageCode(QString::fromLatin1(hdrValue)); + } else if (hdrName == "Plural-Forms") { pluralForms = hdrValue; - else if (hdrName == QLatin1String("X-Virgin-Header")) - ; // legacy - else - translator.setExtra(makePoHeader(hdrName), hdrValue); + } else if (hdrName == "MIME-Version") { + // just assume it is 1.0 + } else if (hdrName == "Content-Type") { + if (cd.m_codecForSource.isEmpty()) { + if (!hdrValue.startsWith("text/plain; charset=")) { + cd.appendError(QString::fromLatin1("Unexpected Content-Type header '%1'\n") + .arg(QString::fromLatin1(hdrValue))); + error = true; + // This will avoid a flood of conversion errors. + codec = QTextCodec::codecForName("latin1"); + } else { + QByteArray cod = hdrValue.mid(20); + QTextCodec *cdc = QTextCodec::codecForName(cod); + if (!cdc) { + cd.appendError(QString::fromLatin1("Unsupported codec '%1'\n") + .arg(QString::fromLatin1(cod))); + error = true; + // This will avoid a flood of conversion errors. + codec = QTextCodec::codecForName("latin1"); + } else { + codec = cdc; + } + } + } + } else if (hdrName == "Content-Transfer-Encoding") { + if (hdrValue != "8bit") { + cd.appendError(QString::fromLatin1("Unexpected Content-Transfer-Encoding '%1'\n") + .arg(QString::fromLatin1(hdrValue))); + return false; + } + } else if (hdrName == "X-Virgin-Header") { + // legacy + } else { + extras[makePoHeader(QString::fromLatin1(hdrName))] = hdrValue; + } } if (!pluralForms.isEmpty()) { if (translator.languageCode().isEmpty()) { - translator.setExtra(makePoHeader(QLatin1String("Plural-Forms")), - pluralForms); + extras[makePoHeader(QLatin1String("Plural-Forms"))] = pluralForms; } else { // FIXME: have fun with making a consistency check ... } @@ -447,17 +497,18 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) // Eliminate the field if only headers we added are present in standard order. // Keep in sync with savePO static const char * const dfltHdrs[] = { + "MIME-Version", "Content-Type", "Content-Transfer-Encoding", "Plural-Forms", "X-Language", "X-Source-Language" }; uint cdh = 0; for (int cho = 0; cho < hdrOrder.length(); cho++) { for (;; cdh++) { if (cdh == sizeof(dfltHdrs)/sizeof(dfltHdrs[0])) { - translator.setExtra(QLatin1String("po-headers"), - hdrOrder.join(QLatin1String(","))); + extras[QLatin1String("po-headers")] = + QByteArrayList_join(hdrOrder, ','); goto doneho; } - if (hdrOrder.at(cho) == QLatin1String(dfltHdrs[cdh])) { + if (hdrOrder.at(cho) == dfltHdrs[cdh]) { cdh++; break; } @@ -465,18 +516,22 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) } doneho: if (lastCmtLine != -1) - translator.setExtra(QLatin1String("po-header_comment"), - static_cast(lines.mid(0, lastCmtLine + 1)).join(QLatin1String("\n"))); + extras[QLatin1String("po-header_comment")] = + QByteArrayList_join(lines.mid(0, lastCmtLine + 1), '\n'); + for (QHash::ConstIterator it = extras.constBegin(), + end = extras.constEnd(); + it != end; ++it) + translator.setExtra(it.key(), codec->toUnicode(it.value())); item = PoItem(); continue; } // build translator message TranslatorMessage msg; - msg.setContext(item.context); + msg.setContext(codec->toUnicode(item.context)); if (!item.references.isEmpty()) { foreach (const QString &ref, - item.references.split(QRegExp(QLatin1String("\\s")), - QString::SkipEmptyParts)) { + codec->toUnicode(item.references).split( + QRegExp(QLatin1String("\\s")), QString::SkipEmptyParts)) { int pos = ref.lastIndexOf(QLatin1Char(':')); if (pos != -1) msg.addReference(ref.left(pos), ref.mid(pos + 1).toInt()); @@ -484,15 +539,22 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) } else if (isObsolete) { msg.setFileName(QLatin1String(MAGIC_OBSOLETE_REFERENCE)); } - msg.setId(item.id); - msg.setSourceText(item.msgId); - msg.setOldSourceText(item.oldMsgId); - msg.setComment(item.tscomment); - msg.setOldComment(item.oldTscomment); - msg.setExtraComment(item.automaticComments); - msg.setTranslatorComment(item.translatorComments); + msg.setId(codec->toUnicode(item.id)); + msg.setSourceText(codec->toUnicode(item.msgId)); + msg.setOldSourceText(codec->toUnicode(item.oldMsgId)); + msg.setComment(codec->toUnicode(item.tscomment)); + msg.setOldComment(codec->toUnicode(item.oldTscomment)); + msg.setExtraComment(codec->toUnicode(item.automaticComments)); + msg.setTranslatorComment(codec->toUnicode(item.translatorComments)); msg.setPlural(item.isPlural || item.msgStr.size() > 1); - msg.setTranslations(item.msgStr); + QStringList translations; + foreach (const QByteArray &bstr, item.msgStr) { + QString str = codec->toUnicode(bstr); + str.replace(QChar(Translator::TextVariantSeparator), + QChar(Translator::BinaryVariantSeparator)); + translations << str; + } + msg.setTranslations(translations); if (isObsolete) msg.setType(TranslatorMessage::Obsolete); else if (item.isFuzzy || (!msg.sourceText().isEmpty() && !msg.isTranslated())) @@ -506,16 +568,16 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) //qDebug() << flags << msg.m_extra; translator.append(msg); item = PoItem(); - } else if (line.startsWith(QLatin1Char('#'))) { - switch(line.size() < 2 ? 0 : line.at(1).unicode()) { + } else if (line.startsWith('#')) { + switch (line.size() < 2 ? 0 : line.at(1)) { case ':': item.references += line.mid(3); - item.references += newline; + item.references += '\n'; break; case ',': { QStringList flags = - line.mid(2).split(QRegExp(QLatin1String("[, ]")), - QString::SkipEmptyParts); + QString::fromLatin1(line.mid(2)).split( + QRegExp(QLatin1String("[, ]")), QString::SkipEmptyParts); if (flags.removeOne(QLatin1String("fuzzy"))) item.isFuzzy = true; TranslatorMessage::ExtraData::const_iterator it = @@ -527,71 +589,73 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) break; } case 0: - item.translatorComments += newline; + item.translatorComments += '\n'; break; case ' ': slurpComment(item.translatorComments, lines, l); break; case '.': - if (line.startsWith(QLatin1String("#. ts-context "))) { + if (line.startsWith("#. ts-context ")) { item.context = line.mid(14); - } else if (line.startsWith(QLatin1String("#. ts-id "))) { + } else if (line.startsWith("#. ts-id ")) { item.id = line.mid(9); } else { item.automaticComments += line.mid(3); - item.automaticComments += newline; + item.automaticComments += '\n'; } break; case '|': - if (line.startsWith(QLatin1String("#| msgid "))) { - item.oldMsgId = slurpEscapedString(lines, l, 9, QLatin1String("#| "), cd); - } else if (line.startsWith(QLatin1String("#| msgid_plural "))) { - QString extra = slurpEscapedString(lines, l, 16, QLatin1String("#| "), cd); + if (line.startsWith("#| msgid ")) { + item.oldMsgId = slurpEscapedString(lines, l, 9, "#| ", cd); + } else if (line.startsWith("#| msgid_plural ")) { + QByteArray extra = slurpEscapedString(lines, l, 16, "#| ", cd); if (extra != item.oldMsgId) - item.extra[QLatin1String("po-old_msgid_plural")] = extra; - } else if (line.startsWith(QLatin1String("#| msgctxt "))) { - item.oldTscomment = slurpEscapedString(lines, l, 11, QLatin1String("#| "), cd); + item.extra[QLatin1String("po-old_msgid_plural")] = + codec->toUnicode(extra); + } else if (line.startsWith("#| msgctxt ")) { + item.oldTscomment = slurpEscapedString(lines, l, 11, "#| ", cd); } else { cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'\n")) - .arg(l + 1).arg(lines[l])); + .arg(l + 1).arg(codec->toUnicode(lines[l]))); error = true; } break; case '~': - if (line.startsWith(QLatin1String("#~ msgid "))) { - item.msgId = slurpEscapedString(lines, l, 9, QLatin1String("#~ "), cd); - } else if (line.startsWith(QLatin1String("#~ msgid_plural "))) { - QString extra = slurpEscapedString(lines, l, 16, QLatin1String("#~ "), cd); + if (line.startsWith("#~ msgid ")) { + item.msgId = slurpEscapedString(lines, l, 9, "#~ ", cd); + } else if (line.startsWith("#~ msgid_plural ")) { + QByteArray extra = slurpEscapedString(lines, l, 16, "#~ ", cd); if (extra != item.msgId) - item.extra[QLatin1String("po-msgid_plural")] = extra; + item.extra[QLatin1String("po-msgid_plural")] = + codec->toUnicode(extra); item.isPlural = true; - } else if (line.startsWith(QLatin1String("#~ msgctxt "))) { - item.tscomment = slurpEscapedString(lines, l, 11, QLatin1String("#~ "), cd); + } else if (line.startsWith("#~ msgctxt ")) { + item.tscomment = slurpEscapedString(lines, l, 11, "#~ ", cd); } else { cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'\n")) - .arg(l + 1).arg(lines[l])); + .arg(l + 1).arg(codec->toUnicode(lines[l]))); error = true; } break; default: cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'\n")) - .arg(l + 1).arg(lines[l])); + .arg(l + 1).arg(codec->toUnicode(lines[l]))); error = true; break; } lastCmtLine = l; - } else if (line.startsWith(QLatin1String("msgctxt "))) { - item.tscomment = slurpEscapedString(lines, l, 8, QString(), cd); - } else if (line.startsWith(QLatin1String("msgid "))) { - item.msgId = slurpEscapedString(lines, l, 6, QString(), cd); - } else if (line.startsWith(QLatin1String("msgid_plural "))) { - QString extra = slurpEscapedString(lines, l, 13, QString(), cd); + } else if (line.startsWith("msgctxt ")) { + item.tscomment = slurpEscapedString(lines, l, 8, QByteArray(), cd); + } else if (line.startsWith("msgid ")) { + item.msgId = slurpEscapedString(lines, l, 6, QByteArray(), cd); + } else if (line.startsWith("msgid_plural ")) { + QByteArray extra = slurpEscapedString(lines, l, 13, QByteArray(), cd); if (extra != item.msgId) - item.extra[QLatin1String("po-msgid_plural")] = extra; + item.extra[QLatin1String("po-msgid_plural")] = codec->toUnicode(extra); item.isPlural = true; } else { cd.appendError(QString(QLatin1String("PO-format error in line %1: '%2'\n")) - .arg(l + 1).arg(lines[l])); + .arg(l + 1).arg(codec->toUnicode(lines[l]))); error = true; } } @@ -621,6 +685,10 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) QStringList hdrOrder = translator.extra(QLatin1String("po-headers")).split( QLatin1Char(','), QString::SkipEmptyParts); // Keep in sync with loadPO + addPoHeader(headers, hdrOrder, "MIME-Version", QLatin1String("1.0")); + addPoHeader(headers, hdrOrder, "Content-Type", + QLatin1String("text/plain; charset=" + out.codec()->name())); + addPoHeader(headers, hdrOrder, "Content-Transfer-Encoding", QLatin1String("8bit")); if (!translator.languageCode().isEmpty()) { QLocale::Language l; QLocale::Country c; -- cgit v0.12 From 15f0dccc03440cb3c07133d2565da32b892ca2fc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 30 Mar 2010 19:46:59 +0200 Subject: handle qt-format PO flags --- tools/linguist/shared/po.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index bf1a142..097b4bf 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -580,6 +580,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) QRegExp(QLatin1String("[, ]")), QString::SkipEmptyParts); if (flags.removeOne(QLatin1String("fuzzy"))) item.isFuzzy = true; + flags.removeOne(QLatin1String("qt-format")); TranslatorMessage::ExtraData::const_iterator it = item.extra.find(QLatin1String("po-flags")); if (it != item.extra.end()) @@ -673,6 +674,8 @@ static void addPoHeader(Translator::ExtraData &headers, QStringList &hdrOrder, bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) { + QString str_format = QLatin1String("-format"); + bool ok = true; QTextStream out(&dev); out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec); @@ -732,16 +735,36 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) } bool noWrap = false; + bool skipFormat = false; QStringList flags; if (msg.type() == TranslatorMessage::Unfinished && msg.isTranslated()) flags.append(QLatin1String("fuzzy")); TranslatorMessage::ExtraData::const_iterator itr = msg.extras().find(QLatin1String("po-flags")); if (itr != msg.extras().end()) { - if (itr->split(QLatin1String(", ")).contains(QLatin1String("no-wrap"))) + QStringList atoms = itr->split(QLatin1String(", ")); + foreach (const QString &atom, atoms) + if (atom.endsWith(str_format)) { + skipFormat = true; + break; + } + if (atoms.contains(QLatin1String("no-wrap"))) noWrap = true; flags.append(*itr); } + if (!skipFormat) { + QString source = msg.sourceText(); + // This is fuzzy logic, as we don't know whether the string is + // actually used with QString::arg(). + for (int off = 0; (off = source.indexOf(QLatin1Char('%'), off)) >= 0; ) { + if (++off >= source.length()) + break; + if (source.at(off) == QLatin1Char('n') || source.at(off).isDigit()) { + flags.append(QLatin1String("qt-format")); + break; + } + } + } if (!flags.isEmpty()) out << "#, " << flags.join(QLatin1String(", ")) << '\n'; -- cgit v0.12 From bf04c256c8d39df1206c197821df8913f90bb43c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 31 Mar 2010 21:12:17 +0200 Subject: Fix compilation on Windows: forgot to change one toTime_tHelper --- src/corelib/tools/qdatetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 69b232d..dc1666a 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -4013,7 +4013,7 @@ static void localToUtc(QDate &date, QTime &time, int isdst) localTM.tm_year = fakeDate.year() - 1900; localTM.tm_isdst = (int)isdst; #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) - time_t secsSince1Jan1970UTC = toTime_tHelper(fakeDate, time); + time_t secsSince1Jan1970UTC = toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)); #else #if defined(Q_OS_WIN) _tzset(); -- cgit v0.12 From d5e6111c62bc4437243fb1d6389e3af180f623d7 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 1 Apr 2010 01:43:20 +0200 Subject: Attempt to fix the test. Reviewed-by:TrustMe --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 3d86c48..9229c7c 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -10054,9 +10054,9 @@ void tst_QGraphicsItem::updateMicroFocus() QTRY_COMPARE(QApplication::activeWindow(), static_cast(&parent)); input.doUpdateMicroFocus(); QApplication::processEvents(); - QCOMPARE(ic.nbUpdates, 1); + QTRY_COMPARE(ic.nbUpdates, 1); //No update since view2 does not have the focus. - QCOMPARE(ic2.nbUpdates, 0); + QTRY_COMPARE(ic2.nbUpdates, 0); } void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() -- cgit v0.12 From b1748ec7a9fdcd74fcf05af3903623c7165420ad Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Thu, 1 Apr 2010 10:42:49 +1000 Subject: doc - fix sellingp --- doc/src/declarative/modules.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index 13658d8..6b2e64e 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -83,7 +83,7 @@ For either type of module, a \c qmldir file in the module directory defines the optional for location modules, but only for local filesystem content or a single remote content with a namespace. The second exception is explained in more detail in the section below on Namespaces. -\seciont2 The Import Path +\section2 The Import Path Installed modules are searched for on the import path. The \c -L option to the \l {Qt Declarative UI Runtime}{qml} runtime adds paths to the import path. -- cgit v0.12 From c6bf3c14c4900f710789f634ccd91e0ee097da9f Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Thu, 1 Apr 2010 12:33:10 +1000 Subject: Renamed widgets example to proxywidgets to avoid conflicts Task-number: QTBUG-9518 Reviewed-by: Martin Jones --- examples/declarative/declarative.pro | 2 +- .../declarative/proxywidgets/ProxyWidgets/qmldir | 1 + examples/declarative/proxywidgets/README | 4 + examples/declarative/proxywidgets/proxywidgets.cpp | 99 ++++++++++++++++++++++ examples/declarative/proxywidgets/proxywidgets.pro | 22 +++++ examples/declarative/proxywidgets/proxywidgets.qml | 53 ++++++++++++ examples/declarative/widgets/MyWidgets/qmldir | 1 - examples/declarative/widgets/README | 4 - examples/declarative/widgets/mywidgets.cpp | 99 ---------------------- examples/declarative/widgets/mywidgets.pro | 19 ----- examples/declarative/widgets/mywidgets.qml | 53 ------------ 11 files changed, 180 insertions(+), 177 deletions(-) create mode 100644 examples/declarative/proxywidgets/ProxyWidgets/qmldir create mode 100644 examples/declarative/proxywidgets/README create mode 100644 examples/declarative/proxywidgets/proxywidgets.cpp create mode 100644 examples/declarative/proxywidgets/proxywidgets.pro create mode 100644 examples/declarative/proxywidgets/proxywidgets.qml delete mode 100644 examples/declarative/widgets/MyWidgets/qmldir delete mode 100644 examples/declarative/widgets/README delete mode 100644 examples/declarative/widgets/mywidgets.cpp delete mode 100644 examples/declarative/widgets/mywidgets.pro delete mode 100644 examples/declarative/widgets/mywidgets.qml diff --git a/examples/declarative/declarative.pro b/examples/declarative/declarative.pro index 5fc1cf0..00d3c05 100644 --- a/examples/declarative/declarative.pro +++ b/examples/declarative/declarative.pro @@ -6,7 +6,7 @@ SUBDIRS = \ imageprovider \ objectlistmodel \ plugins \ - widgets + proxywidgets # These examples contain no C++ and can simply be copied sources.files = \ diff --git a/examples/declarative/proxywidgets/ProxyWidgets/qmldir b/examples/declarative/proxywidgets/ProxyWidgets/qmldir new file mode 100644 index 0000000..e55267c --- /dev/null +++ b/examples/declarative/proxywidgets/ProxyWidgets/qmldir @@ -0,0 +1 @@ +plugin proxywidgetsplugin diff --git a/examples/declarative/proxywidgets/README b/examples/declarative/proxywidgets/README new file mode 100644 index 0000000..f50fa22 --- /dev/null +++ b/examples/declarative/proxywidgets/README @@ -0,0 +1,4 @@ +To run: + + make install + qml proxywidgets.qml diff --git a/examples/declarative/proxywidgets/proxywidgets.cpp b/examples/declarative/proxywidgets/proxywidgets.cpp new file mode 100644 index 0000000..47d0cb9 --- /dev/null +++ b/examples/declarative/proxywidgets/proxywidgets.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +class MyPushButton : public QGraphicsProxyWidget +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + +public: + MyPushButton(QGraphicsItem* parent = 0) + : QGraphicsProxyWidget(parent) + { + widget = new QPushButton("MyPushButton"); + widget->setAttribute(Qt::WA_NoSystemBackground); + setWidget(widget); + + QObject::connect(widget, SIGNAL(clicked(bool)), this, SIGNAL(clicked(bool))); + } + + QString text() const + { + return widget->text(); + } + + void setText(const QString& text) + { + if (text != widget->text()) { + widget->setText(text); + emit textChanged(); + } + } + +Q_SIGNALS: + void clicked(bool); + void textChanged(); + +private: + QPushButton *widget; +}; + +class ProxyWidgetsPlugin : public QDeclarativeExtensionPlugin +{ + Q_OBJECT +public: + void registerTypes(const char *uri) + { + qmlRegisterType(uri, 1, 0, "MyPushButton"); + } +}; + +#include "proxywidgets.moc" + +QML_DECLARE_TYPE(MyPushButton) + +Q_EXPORT_PLUGIN2(proxywidgetsplugin, ProxyWidgetsPlugin); diff --git a/examples/declarative/proxywidgets/proxywidgets.pro b/examples/declarative/proxywidgets/proxywidgets.pro new file mode 100644 index 0000000..eb85191 --- /dev/null +++ b/examples/declarative/proxywidgets/proxywidgets.pro @@ -0,0 +1,22 @@ +TEMPLATE = lib +DESTDIR = ProxyWidgets +TARGET = proxywidgetsplugin +CONFIG += qt plugin +QT += declarative +VERSION = 1.0.0 + +SOURCES += proxywidgets.cpp + +sources.files += proxywidgets.pro proxywidgets.cpp proxywidgets.qml + +sources.path += $$[QT_INSTALL_EXAMPLES]/declarative/plugins + +target.path += $$[QT_INSTALL_EXAMPLES]/declarative/plugins + +INSTALLS += sources target + +symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) + +symbian:{ + TARGET.EPOCALLOWDLLDATA = 1 +} \ No newline at end of file diff --git a/examples/declarative/proxywidgets/proxywidgets.qml b/examples/declarative/proxywidgets/proxywidgets.qml new file mode 100644 index 0000000..023de71 --- /dev/null +++ b/examples/declarative/proxywidgets/proxywidgets.qml @@ -0,0 +1,53 @@ +import Qt 4.6 +import "ProxyWidgets" 1.0 + +Rectangle { + id: window + width: 640; height: 480; color: palette.window + + property int margin: 30 + + SystemPalette { id: palette } + + MyPushButton { + id: button1; x: margin; y: margin; text: "Right"; onClicked: window.state = "right" + transformOriginPoint: Qt.point(width / 2, height / 2) + } + + MyPushButton { + id: button2; x: margin; y: margin + 30; text: "Bottom"; onClicked: window.state = "bottom" + transformOriginPoint: Qt.point(width / 2, height / 2) + } + + MyPushButton { + id: button3; x: margin; y: margin + 60; text: "Quit"; onClicked: Qt.quit() + transformOriginPoint: Qt.point(width / 2, height / 2) + } + + states: [ + State { + name: "right" + PropertyChanges { target: button1; x: window.width - width - margin; text: "Left"; onClicked: window.state = "" } + PropertyChanges { target: button2; x: window.width - width - margin } + PropertyChanges { target: button3; x: window.width - width - margin } + PropertyChanges { target: window; color: Qt.darker(palette.window) } + }, + State { + name: "bottom" + PropertyChanges { target: button1; y: window.height - height - margin; rotation: 180 } + PropertyChanges { + target: button2; x: button1.x + button1.width + 10; y: window.height - height - margin; rotation: 180 + text: "Top"; onClicked: window.state = "" + } + PropertyChanges { target: button3; x: button2.x + button2.width + 10; y: window.height - height - margin; rotation: 180 } + PropertyChanges { target: window; color: Qt.lighter(palette.window) } + } + ] + + transitions: Transition { + ParallelAnimation { + NumberAnimation { properties: "x,y,rotation"; duration: 600; easing.type: "OutQuad" } + ColorAnimation { target: window; duration: 600 } + } + } +} diff --git a/examples/declarative/widgets/MyWidgets/qmldir b/examples/declarative/widgets/MyWidgets/qmldir deleted file mode 100644 index dc1d10e..0000000 --- a/examples/declarative/widgets/MyWidgets/qmldir +++ /dev/null @@ -1 +0,0 @@ -plugin mywidgetsplugin diff --git a/examples/declarative/widgets/README b/examples/declarative/widgets/README deleted file mode 100644 index f85a1e8..0000000 --- a/examples/declarative/widgets/README +++ /dev/null @@ -1,4 +0,0 @@ -To run: - - make install - qml mywidgets.qml diff --git a/examples/declarative/widgets/mywidgets.cpp b/examples/declarative/widgets/mywidgets.cpp deleted file mode 100644 index e17240d..0000000 --- a/examples/declarative/widgets/mywidgets.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include - -class MyPushButton : public QGraphicsProxyWidget -{ - Q_OBJECT - Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) - -public: - MyPushButton(QGraphicsItem* parent = 0) - : QGraphicsProxyWidget(parent) - { - widget = new QPushButton("MyPushButton"); - widget->setAttribute(Qt::WA_NoSystemBackground); - setWidget(widget); - - QObject::connect(widget, SIGNAL(clicked(bool)), this, SIGNAL(clicked(bool))); - } - - QString text() const - { - return widget->text(); - } - - void setText(const QString& text) - { - if (text != widget->text()) { - widget->setText(text); - emit textChanged(); - } - } - -Q_SIGNALS: - void clicked(bool); - void textChanged(); - -private: - QPushButton *widget; -}; - -class MyWidgetsPlugin : public QDeclarativeExtensionPlugin -{ - Q_OBJECT -public: - void registerTypes(const char *uri) - { - qmlRegisterType(uri, 1, 0, "MyPushButton"); - } -}; - -#include "mywidgets.moc" - -QML_DECLARE_TYPE(MyPushButton) - -Q_EXPORT_PLUGIN2(mywidgetsplugin, MyWidgetsPlugin); diff --git a/examples/declarative/widgets/mywidgets.pro b/examples/declarative/widgets/mywidgets.pro deleted file mode 100644 index 258edb1..0000000 --- a/examples/declarative/widgets/mywidgets.pro +++ /dev/null @@ -1,19 +0,0 @@ -TEMPLATE = lib -DESTDIR = MyWidgets -TARGET = mywidgetsplugin -CONFIG += qt plugin -QT += declarative -VERSION = 1.0.0 - -SOURCES += mywidgets.cpp - -sources.files += mywidgets.pro mywidgets.cpp mywidgets.qml - -sources.path += $$[QT_INSTALL_EXAMPLES]/declarative/plugins - -target.path += $$[QT_INSTALL_EXAMPLES]/declarative/plugins - -INSTALLS += sources target - -symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - diff --git a/examples/declarative/widgets/mywidgets.qml b/examples/declarative/widgets/mywidgets.qml deleted file mode 100644 index b1efed4..0000000 --- a/examples/declarative/widgets/mywidgets.qml +++ /dev/null @@ -1,53 +0,0 @@ -import Qt 4.6 -import "MyWidgets" 1.0 - -Rectangle { - id: window - width: 640; height: 480; color: palette.window - - property int margin: 30 - - SystemPalette { id: palette } - - MyPushButton { - id: button1; x: margin; y: margin; text: "Right"; onClicked: window.state = "right" - transformOriginPoint: Qt.point(width / 2, height / 2) - } - - MyPushButton { - id: button2; x: margin; y: margin + 30; text: "Bottom"; onClicked: window.state = "bottom" - transformOriginPoint: Qt.point(width / 2, height / 2) - } - - MyPushButton { - id: button3; x: margin; y: margin + 60; text: "Quit"; onClicked: Qt.quit() - transformOriginPoint: Qt.point(width / 2, height / 2) - } - - states: [ - State { - name: "right" - PropertyChanges { target: button1; x: window.width - width - margin; text: "Left"; onClicked: window.state = "" } - PropertyChanges { target: button2; x: window.width - width - margin } - PropertyChanges { target: button3; x: window.width - width - margin } - PropertyChanges { target: window; color: Qt.darker(palette.window) } - }, - State { - name: "bottom" - PropertyChanges { target: button1; y: window.height - height - margin; rotation: 180 } - PropertyChanges { - target: button2; x: button1.x + button1.width + 10; y: window.height - height - margin; rotation: 180 - text: "Top"; onClicked: window.state = "" - } - PropertyChanges { target: button3; x: button2.x + button2.width + 10; y: window.height - height - margin; rotation: 180 } - PropertyChanges { target: window; color: Qt.lighter(palette.window) } - } - ] - - transitions: Transition { - ParallelAnimation { - NumberAnimation { properties: "x,y,rotation"; duration: 600; easing.type: "OutQuad" } - ColorAnimation { target: window; duration: 600 } - } - } -} -- cgit v0.12 From 5631e6311e068670781f0d6804cbfbc2d929b367 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Thu, 1 Apr 2010 12:36:59 +1000 Subject: Fix compilation on Symbian winscw Task-number: Reviewed-by: Aaron Kennedy --- src/declarative/graphicsitems/qdeclarativeanchors.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeanchors.cpp b/src/declarative/graphicsitems/qdeclarativeanchors.cpp index dc1f09d..ffcedda 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanchors.cpp @@ -1059,7 +1059,7 @@ bool QDeclarativeAnchorsPrivate::checkVAnchorValid(QDeclarativeAnchorLine anchor return true; } -#include - QT_END_NAMESPACE +#include + -- cgit v0.12 From c8e5d788936059254e81377e6318ee9e975c1040 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Thu, 1 Apr 2010 12:40:48 +1000 Subject: Fix plugin example compilation on Symbian arm Task-number: QTBUG-9520 Reviewed-by: Martin Jones --- examples/declarative/plugins/plugin.cpp | 18 +++++++----------- examples/declarative/plugins/plugins.pro | 7 ++++++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/examples/declarative/plugins/plugin.cpp b/examples/declarative/plugins/plugin.cpp index 741f68a..fb51b0c 100644 --- a/examples/declarative/plugins/plugin.cpp +++ b/examples/declarative/plugins/plugin.cpp @@ -46,7 +46,7 @@ #include #include -// Implements a "Time" class with hour and minute properties +// Implements a "TimeModel" class with hour and minute properties // that change on-the-minute yet efficiently sleep the rest // of the time. @@ -97,14 +97,14 @@ private: QBasicTimer timer; }; -class Time : public QObject +class TimeModel : public QObject { Q_OBJECT Q_PROPERTY(int hour READ hour NOTIFY timeChanged) Q_PROPERTY(int minute READ minute NOTIFY timeChanged) public: - Time(QObject *parent=0) : QObject(parent) + TimeModel(QObject *parent=0) : QObject(parent) { if (++instances == 1) { if (!timer) @@ -114,7 +114,7 @@ public: } } - ~Time() + ~TimeModel() { if (--instances == 0) { timer->stop(); @@ -133,12 +133,8 @@ private: static int instances; }; -int Time::instances=0; -MinuteTimer *Time::timer=0; - - -QML_DECLARE_TYPE(Time); - +int TimeModel::instances=0; +MinuteTimer *TimeModel::timer=0; class QExampleQmlPlugin : public QDeclarativeExtensionPlugin { @@ -147,7 +143,7 @@ public: void registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("com.nokia.TimeExample")); - qmlRegisterType