diff options
author | Martin Jones <martin.jones@nokia.com> | 2010-12-01 07:36:41 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2010-12-01 07:36:41 (GMT) |
commit | a305814f8f59f634943d8d5f8d87d2fd49891cb3 (patch) | |
tree | 42ed4e6afecbf36af2750e2eeaed87117ab942a6 /src | |
parent | 6258fc281f5b66b2634b81a2633b117165cea7ef (diff) | |
parent | 1337a3e031477aa4d628d01252557dee622629ff (diff) | |
download | Qt-a305814f8f59f634943d8d5f8d87d2fd49891cb3.zip Qt-a305814f8f59f634943d8d5f8d87d2fd49891cb3.tar.gz Qt-a305814f8f59f634943d8d5f8d87d2fd49891cb3.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into qtquick11
Diffstat (limited to 'src')
123 files changed, 2138 insertions, 992 deletions
diff --git a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp index de3f46f..ff39eccc4 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp +++ b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp @@ -62,19 +62,21 @@ namespace Phonon VideoRendererEVR::VideoRendererEVR(QWidget *target) : m_target(target) { + if (QSysInfo::WindowsVersion < QSysInfo::WV_VISTA) + return; m_filter = Filter(CLSID_EnhancedVideoRenderer, IID_IBaseFilter); if (!m_filter) { return; } ComPointer<IMFVideoDisplayControl> filterControl = getService<IMFVideoDisplayControl>(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); - if (!filterControl) { + if (!filterControl || + FAILED(filterControl->SetVideoWindow(reinterpret_cast<HWND>(target->winId()))) || + FAILED(filterControl->SetAspectRatioMode(MFVideoARMode_None)) || // We're in control of the size + !getService<IMFVideoMixerControl>(m_filter, MR_VIDEO_MIXER_SERVICE, IID_IMFVideoMixerControl) || + !getService<IMFVideoProcessor>(m_filter, MR_VIDEO_MIXER_SERVICE, IID_IMFVideoProcessor)) { m_filter = Filter(); //will release the interface - return; } - - filterControl->SetVideoWindow(reinterpret_cast<HWND>(target->winId())); - filterControl->SetAspectRatioMode(MFVideoARMode_None); // We're in control of the size } QImage VideoRendererEVR::snapshot() const diff --git a/src/3rdparty/phonon/phonon/effectwidget.cpp b/src/3rdparty/phonon/phonon/effectwidget.cpp index a2fe50f..edcbe1f 100644 --- a/src/3rdparty/phonon/phonon/effectwidget.cpp +++ b/src/3rdparty/phonon/phonon/effectwidget.cpp @@ -112,7 +112,7 @@ void EffectWidgetPrivate::autogenerateUi() #endif QWidget *control = 0; - switch (para.type()) { + switch (int(para.type())) { case QVariant::String: { QComboBox *cb = new QComboBox(q); diff --git a/src/3rdparty/phonon/phonon/globalconfig.cpp b/src/3rdparty/phonon/phonon/globalconfig.cpp index be751ce..f83ebc4 100644 --- a/src/3rdparty/phonon/phonon/globalconfig.cpp +++ b/src/3rdparty/phonon/phonon/globalconfig.cpp @@ -97,7 +97,7 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q static QList<int> sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, Phonon::Category category, QList<int> &defaultList) { - Q_ASSERT(config); + Q_ASSERT(config); Q_UNUSED(config); Q_ASSERT(backendConfig); Q_ASSERT(type == AudioOutputDeviceType || type == AudioCaptureDeviceType); diff --git a/src/3rdparty/phonon/phonon/mediacontroller.cpp b/src/3rdparty/phonon/phonon/mediacontroller.cpp index 59fd5c7..37af3f7 100644 --- a/src/3rdparty/phonon/phonon/mediacontroller.cpp +++ b/src/3rdparty/phonon/phonon/mediacontroller.cpp @@ -76,9 +76,9 @@ MediaController::~MediaController() MediaController::Features MediaController::supportedFeatures() const { if (!d || !d->media) { - return false; + return Features(); } - IFACE false; + IFACE Features(); Features ret; if (iface->hasInterface(AddonInterface::AngleInterface)) { ret |= Angles; diff --git a/src/3rdparty/phonon/phonon/pulsesupport.cpp b/src/3rdparty/phonon/phonon/pulsesupport.cpp index 642843f..b1ba196 100644 --- a/src/3rdparty/phonon/phonon/pulsesupport.cpp +++ b/src/3rdparty/phonon/phonon/pulsesupport.cpp @@ -56,7 +56,7 @@ static int debugLevel() { static int level = -1; if (level < 1) { level = 0; - QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DEBUG"); + QByteArray pulseenv = qgetenv("PHONON_PULSEAUDIO_DEBUG"); int l = pulseenv.toInt(); if (l > 0) level = (l > 2 ? 2 : l); @@ -71,18 +71,18 @@ static void logMessage(const QString &message, int priority, QObject *obj) QString output; if (obj) { // Strip away namespace from className - QString className(obj->metaObject()->className()); + QByteArray 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); + className.constData(), obj); } else { output = message; } if (priority <= debugLevel()) { - qDebug() << QString("PulseSupport(%1): %2").arg(priority).arg(output); + qDebug() << QString::fromLatin1("PulseSupport(%1): %2").arg(priority).arg(output); } } } @@ -96,7 +96,7 @@ class AudioDevice : 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["description"] = QLatin1String(""); // 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! @@ -158,8 +158,8 @@ static void createGenericDevices() 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)); + s_outputDeviceIndexes.insert(QLatin1String("sink:default"), index); + s_outputDevices.insert(index, AudioDevice(QLatin1String("sink:default"), QObject::tr("PulseAudio Sound Server"), QLatin1String("audio-backend-pulseaudio"), 0)); for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { Phonon::Category cat = static_cast<Phonon::Category>(i); s_outputDevicePriorities[cat].insert(0, index); @@ -169,8 +169,8 @@ static void createGenericDevices() 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)); + s_captureDeviceIndexes.insert(QLatin1String("source:default"), index); + s_captureDevices.insert(index, AudioDevice(QLatin1String("source:default"), QObject::tr("PulseAudio Sound Server"), QLatin1String("audio-backend-pulseaudio"), 0)); for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { Phonon::Category cat = static_cast<Phonon::Category>(i); s_captureDevicePriorities[cat].insert(0, index); @@ -397,7 +397,7 @@ void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *us if (pa_context_errno(c) == PA_ERR_NOENTITY) return; - logMessage(QString("Sink input callback failure")); + logMessage(QLatin1String("Sink input callback failure")); return; } @@ -409,8 +409,8 @@ void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *us // 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; + logMessage(QString::fromLatin1("Found PulseAudio stream index %1 for Phonon Output Stream %2").arg(i->index).arg(QLatin1String(t))); + s_outputStreamIndexMap[QLatin1String(t)] = i->index; // Find the sink's phonon index and notify whoever cares... if (PA_INVALID_INDEX != i->sink) { @@ -426,8 +426,8 @@ void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *us } 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); + logMessage(QLatin1String("Letting the rest of phonon know about this")); + s_instance->emitUsingDevice(QLatin1String(t), device); } } } @@ -441,7 +441,7 @@ void source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, vo if (pa_context_errno(c) == PA_ERR_NOENTITY) return; - logMessage(QString("Source output callback failure")); + logMessage(QLatin1String("Source output callback failure")); return; } @@ -453,8 +453,8 @@ void source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, vo // 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; + logMessage(QString::fromLatin1("Found PulseAudio stream index %1 for Phonon Capture Stream %2").arg(i->index).arg(QLatin1String(t))); + s_captureStreamIndexMap[QLatin1String(t)] = i->index; // Find the source's phonon index and notify whoever cares... if (PA_INVALID_INDEX != i->source) { @@ -470,8 +470,8 @@ void source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, vo } 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); + logMessage(QLatin1String("Letting the rest of phonon know about this")); + s_instance->emitUsingDevice(QLatin1String(t), device); } } } @@ -486,17 +486,17 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t 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)); + logMessage(QString::fromLatin1("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)); + logMessage(QString::fromLatin1("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")); + logMessage(QLatin1String("pa_context_get_sink_input_info() failed")); return; } pa_operation_unref(o); @@ -508,17 +508,17 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t 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)); + logMessage(QString::fromLatin1("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)); + logMessage(QString::fromLatin1("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")); + logMessage(QLatin1String("pa_context_get_sink_input_info() failed")); return; } pa_operation_unref(o); @@ -528,29 +528,27 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t } -static const char* statename(pa_context_state_t state) +static QString 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"; + case PA_CONTEXT_UNCONNECTED: return QLatin1String("Unconnected"); + case PA_CONTEXT_CONNECTING: return QLatin1String("Connecting"); + case PA_CONTEXT_AUTHORIZING: return QLatin1String("Authorizing"); + case PA_CONTEXT_SETTING_NAME: return QLatin1String("Setting Name"); + case PA_CONTEXT_READY: return QLatin1String("Ready"); + case PA_CONTEXT_FAILED: return QLatin1String("Failed"); + case PA_CONTEXT_TERMINATED: return QLatin1String("Terminated"); } - static QString unknown; - unknown = QString("Unknown state: %0").arg(state); - return unknown.toAscii().constData(); + return QString::fromLatin1("Unknown state: %0").arg(state); } 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)))); + logMessage(QString::fromLatin1("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 @@ -566,7 +564,7 @@ static void context_state_callback(pa_context *c, void *) 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")); + logMessage(QLatin1String("pa_context_subscribe() failed")); return; } pa_operation_unref(o); @@ -639,27 +637,27 @@ PulseSupport::PulseSupport() { #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; + s_roleCategoryMap[QLatin1String("none")] = Phonon::NoCategory; + s_roleCategoryMap[QLatin1String("video")] = Phonon::VideoCategory; + s_roleCategoryMap[QLatin1String("music")] = Phonon::MusicCategory; + s_roleCategoryMap[QLatin1String("game")] = Phonon::GameCategory; + s_roleCategoryMap[QLatin1String("event")] = Phonon::NotificationCategory; + s_roleCategoryMap[QLatin1String("phone")] = Phonon::CommunicationCategory; + //s_roleCategoryMap[QLatin1String("animation")]; // No Mapping + //s_roleCategoryMap[QLatin1String("production")]; // No Mapping + s_roleCategoryMap[QLatin1String("a11y")] = Phonon::AccessibilityCategory; // To allow for easy debugging, give an easy way to disable this pulseaudio check - QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DISABLE"); + QByteArray pulseenv = qgetenv("PHONON_PULSEAUDIO_DISABLE"); if (pulseenv.toInt()) { - logMessage("PulseAudio support disabled: PHONON_PULSEAUDIO_DISABLE is set"); + logMessage(QLatin1String("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."); + if (strcmp(QAbstractEventDispatcher::instance()->metaObject()->className(), + "QGuiEventDispatcherGlib") != 0) { + logMessage(QLatin1String("Disabling PulseAudio integration for lack of GLib event loop.")); return; } @@ -667,21 +665,21 @@ PulseSupport::PulseSupport() // 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"); + logMessage(QLatin1String("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"); + logMessage(QLatin1String("PulseAudio support disabled: Unable to create context")); pa_mainloop_free(p_test_mainloop); return; } - logMessage("Probing for PulseAudio..."); + logMessage(QLatin1String("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<pa_context_flags_t>(0), NULL) < 0) { - logMessage(QString("PulseAudio support disabled: %1").arg(pa_strerror(pa_context_errno(p_test_context)))); + logMessage(QString::fromLatin1("PulseAudio support disabled: %1").arg(QString::fromLocal8Bit(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); @@ -693,7 +691,7 @@ PulseSupport::PulseSupport() pa_mainloop_iterate(p_test_mainloop, 1, NULL); if (!PA_CONTEXT_IS_GOOD(pa_context_get_state(p_test_context))) { - logMessage("PulseAudio probe complete."); + logMessage(QLatin1String("PulseAudio probe complete.")); break; } } @@ -702,12 +700,12 @@ PulseSupport::PulseSupport() pa_mainloop_free(p_test_mainloop); if (!s_pulseActive) { - logMessage("PulseAudio support is not available."); + logMessage(QLatin1String("PulseAudio support is not available.")); return; } // If we're still here, PA is available. - logMessage("PulseAudio support enabled"); + logMessage(QLatin1String("PulseAudio support enabled")); // Now we connect for real using a proper main loop that we can forget // all about processing. @@ -856,7 +854,7 @@ static void setDevicePriority(Category category, QStringList list) if (role.isEmpty()) return; - logMessage(QString("Reindexing %1: %2").arg(role).arg(list.join(", "))); + logMessage(QString::fromLatin1("Reindexing %1: %2").arg(role).arg(list.join(QLatin1String(", ")))); char **devices; devices = pa_xnew(char *, list.size()+1); @@ -926,7 +924,7 @@ void PulseSupport::setStreamPropList(Category category, QString streamUuid) if (role.isEmpty()) return; - logMessage(QString("Setting role to %1 for streamindex %2").arg(role).arg(streamUuid)); + logMessage(QString::fromLatin1("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 @@ -952,30 +950,30 @@ bool PulseSupport::setOutputDevice(QString streamUuid, int device) { return true; if (!s_outputDevices.contains(device)) { - logMessage(QString("Attempting to set Output Device for invalid device id %1.").arg(device)); + logMessage(QString::fromLatin1("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)); + logMessage(QString::fromLatin1("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")); + logMessage(QLatin1String("... 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)); + logMessage(QString::fromLatin1("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")); + logMessage(QLatin1String("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")); + logMessage(QLatin1String("... 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 @@ -991,30 +989,30 @@ bool PulseSupport::setCaptureDevice(QString streamUuid, int device) { return true; if (!s_captureDevices.contains(device)) { - logMessage(QString("Attempting to set Capture Device for invalid device id %1.").arg(device)); + logMessage(QString::fromLatin1("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)); + logMessage(QString::fromLatin1("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")); + logMessage(QString::fromLatin1("... 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)); + logMessage(QString::fromLatin1("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")); + logMessage(QString::fromLatin1("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")); + logMessage(QString::fromLatin1("... 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 @@ -1025,7 +1023,7 @@ void PulseSupport::clearStreamCache(QString streamUuid) { Q_UNUSED(streamUuid); return; #else - logMessage(QString("Clearing stream cache for stream %1").arg(streamUuid)); + logMessage(QString::fromLatin1("Clearing stream cache for stream %1").arg(streamUuid)); s_outputStreamIndexMap.remove(streamUuid); s_captureStreamIndexMap.remove(streamUuid); #endif diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 9b97c8b..5bb3c57 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -1351,26 +1351,30 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) } } - if (!ev->commitString().isEmpty()) + if (renderTextControl && ev->replacementLength() > 0) { + renderTextControl->setSelectionStart(qMax(renderTextControl->selectionStart() + ev->replacementStart(), 0)); + renderTextControl->setSelectionEnd(qMin(renderTextControl->selectionStart() + ev->replacementLength(), static_cast<int>(renderTextControl->text().length()))); + // Commit regardless of whether commitString is empty, to get rid of selection. editor->confirmComposition(ev->commitString()); - else { - // 1. empty preedit with a selection attribute, and start/end of 0 cancels composition - // 2. empty preedit with a selection attribute, and start/end of non-0 updates selection of current preedit text - // 3. populated preedit with a selection attribute, and start/end of 0 or non-0 updates selection of supplied preedit text - // 4. otherwise event is updating supplied pre-edit text - QString preedit = ev->preeditString(); + } else if (!ev->commitString().isEmpty()) { + editor->confirmComposition(ev->commitString()); + } + // 1. empty preedit with a selection attribute, and start/end of 0 cancels composition + // 2. empty preedit with a selection attribute, and start/end of non-0 updates selection of current preedit text + // 3. populated preedit with a selection attribute, and start/end of 0 or non-0 updates selection of supplied preedit text + // 4. otherwise event is updating supplied pre-edit text + QString preedit = ev->preeditString(); #if QT_VERSION >= 0x040600 - if (hasSelection) { - QString text = (renderTextControl) ? QString(renderTextControl->text()) : QString(); - if (preedit.isEmpty() && selection.start + selection.length > 0) - preedit = text; - editor->setComposition(preedit, underlines, - (selection.length < 0) ? selection.start + selection.length : selection.start, - (selection.length < 0) ? selection.start : selection.start + selection.length); - } else + if (hasSelection) { + QString text = (renderTextControl) ? QString(renderTextControl->text()) : QString(); + if (preedit.isEmpty() && selection.start + selection.length > 0) + preedit = text; + editor->setComposition(preedit, underlines, + (selection.length < 0) ? selection.start + selection.length : selection.start, + (selection.length < 0) ? selection.start : selection.start + selection.length); + } else #endif - editor->setComposition(preedit, underlines, preedit.length(), 0); - } + editor->setComposition(preedit, underlines, preedit.length(), 0); ev->accept(); } diff --git a/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri b/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri index f2282f8..b98617f 100644 --- a/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri +++ b/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri @@ -1,5 +1,5 @@ -QT_WEBKIT_VERSION = 4.7.1 +QT_WEBKIT_VERSION = 4.7.2 QT_WEBKIT_MAJOR_VERSION = 4 QT_WEBKIT_MINOR_VERSION = 7 -QT_WEBKIT_PATCH_VERSION = 1 +QT_WEBKIT_PATCH_VERSION = 2 QT_CONFIG += webkit 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 b7ffb8a..31cf277 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1502,6 +1502,20 @@ void tst_QWebPage::inputMethods() QCOMPARE(value, QString("QtWebKit")); #endif + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event(QString(), attributes); + event.setCommitString("XXX", 0, 0); + page->event(&event); + event.setCommitString(QString(), -2, 2); // Erase two characters. + page->event(&event); + event.setCommitString(QString(), -1, 1); // Erase one character. + page->event(&event); + variant = page->inputMethodQuery(Qt::ImSurroundingText); + value = variant.value<QString>(); + QCOMPARE(value, QString("QtWebKit")); + } + // Cancel current composition first inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant()); QInputMethodEvent eventSelection4("", inputAttributes); diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 4800716..86800ef 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -27,3 +27,5 @@ linux*:!static:!linux-armcc:!linux-gcce { # Compensate for lack of platform defines in Symbian3 and Symbian4 symbian: DEFINES += SYMBIAN_VERSION_$$upper($$replace(SYMBIAN_VERSION,\\.,_)) + +include(../../../tools/shared/symbian/epocroot.pri) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 35607d5..b148a1d 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -44,11 +44,11 @@ #include <stddef.h> -#define QT_VERSION_STR "4.7.1" +#define QT_VERSION_STR "4.7.2" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x040701 +#define QT_VERSION 0x040702 /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 957abbf..898b860 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -62,6 +62,10 @@ QT_END_NAMESPACE # include "private/qcore_mac_p.h" #endif +#ifdef QLIBRARYINFO_EPOCROOT +# include "symbian/epocroot_p.h" +#endif + #include "qconfig.cpp" QT_BEGIN_NAMESPACE @@ -433,6 +437,14 @@ QLibraryInfo::location(LibraryLocation loc) QString::fromLocal8Bit(qgetenv(ret.mid(rep + 2, reg_var.matchedLength() - 3).toLatin1().constData()).constData())); } + +#ifdef QLIBRARYINFO_EPOCROOT + // $${EPOCROOT} is a special case, resolve it similarly to qmake. + QRegExp epocrootMatcher(QLatin1String("\\$\\$\\{EPOCROOT\\}")); + if ((rep = epocrootMatcher.indexIn(ret)) != -1) + ret.replace(rep, epocrootMatcher.matchedLength(), qt_epocRoot()); +#endif + config->endGroup(); } } diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 18c3c9f..1e6dcee 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -228,8 +228,14 @@ void QPollingFileSystemWatcherEngine::timeout() dit.remove(); emit directoryChanged(path, true); } else if (x.value() != fi) { - x.value() = fi; - emit directoryChanged(path, false); + fi.refresh(); + if (!fi.exists()) { + dit.remove(); + emit directoryChanged(path, true); + } else { + x.value() = fi; + emit directoryChanged(path, false); + } } } diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 378ad20..3664396 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -117,67 +117,77 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths, QStringList *files, QStringList *directories) { - QMutexLocker locker(&mutex); - QStringList p = paths; - QMutableListIterator<QString> it(p); - while (it.hasNext()) { - QString path = it.next(); - int fd; + { + QMutexLocker locker(&mutex); + + QMutableListIterator<QString> it(p); + while (it.hasNext()) { + QString path = it.next(); + int fd; #if defined(O_EVTONLY) - fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY); + fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY); #else - fd = qt_safe_open(QFile::encodeName(path), O_RDONLY); + fd = qt_safe_open(QFile::encodeName(path), O_RDONLY); #endif - if (fd == -1) { - perror("QKqueueFileSystemWatcherEngine::addPaths: open"); - continue; - } + if (fd == -1) { + perror("QKqueueFileSystemWatcherEngine::addPaths: open"); + continue; + } + if (fd >= (int)FD_SETSIZE / 2 && fd < (int)FD_SETSIZE) { + int fddup = fcntl(fd, F_DUPFD, FD_SETSIZE); + if (fddup != -1) { + ::close(fd); + fd = fddup; + } + } + fcntl(fd, F_SETFD, FD_CLOEXEC); - QT_STATBUF st; - if (QT_FSTAT(fd, &st) == -1) { - perror("QKqueueFileSystemWatcherEngine::addPaths: fstat"); - ::close(fd); - continue; - } - int id = (S_ISDIR(st.st_mode)) ? -fd : fd; - if (id < 0) { - if (directories->contains(path)) { + QT_STATBUF st; + if (QT_FSTAT(fd, &st) == -1) { + perror("QKqueueFileSystemWatcherEngine::addPaths: fstat"); ::close(fd); continue; } - } else { - if (files->contains(path)) { + int id = (S_ISDIR(st.st_mode)) ? -fd : fd; + if (id < 0) { + if (directories->contains(path)) { + ::close(fd); + continue; + } + } else { + if (files->contains(path)) { + ::close(fd); + continue; + } + } + + struct kevent kev; + EV_SET(&kev, + fd, + EVFILT_VNODE, + EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, + 0, + 0); + if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) { + perror("QKqueueFileSystemWatcherEngine::addPaths: kevent"); ::close(fd); continue; } - } - struct kevent kev; - EV_SET(&kev, - fd, - EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, - NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, - 0, - 0); - if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) { - perror("QKqueueFileSystemWatcherEngine::addPaths: kevent"); - ::close(fd); - continue; - } + it.remove(); + if (id < 0) { + DEBUG() << "QKqueueFileSystemWatcherEngine: added directory path" << path; + directories->append(path); + } else { + DEBUG() << "QKqueueFileSystemWatcherEngine: added file path" << path; + files->append(path); + } - it.remove(); - if (id < 0) { - DEBUG() << "QKqueueFileSystemWatcherEngine: added directory path" << path; - directories->append(path); - } else { - DEBUG() << "QKqueueFileSystemWatcherEngine: added file path" << path; - files->append(path); + pathToID.insert(path, id); + idToPath.insert(id, path); } - - pathToID.insert(path, id); - idToPath.insert(id, path); } if (!isRunning()) @@ -192,43 +202,35 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths QStringList *files, QStringList *directories) { - QMutexLocker locker(&mutex); - + bool isEmpty; QStringList p = paths; - QMutableListIterator<QString> it(p); - while (it.hasNext()) { - QString path = it.next(); - int id = pathToID.take(path); - QString x = idToPath.take(id); - if (x.isEmpty() || x != path) - continue; - - int fd = id < 0 ? -id : id; - struct kevent kev; - EV_SET(&kev, - fd, - EVFILT_VNODE, - EV_DELETE, - NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, - 0, - 0); - if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) { - perror("QKqueueFileSystemWatcherEngine::removeWatch: kevent"); - } - ::close(fd); + { + QMutexLocker locker(&mutex); + if (pathToID.isEmpty()) + return p; + + QMutableListIterator<QString> it(p); + while (it.hasNext()) { + QString path = it.next(); + int id = pathToID.take(path); + QString x = idToPath.take(id); + if (x.isEmpty() || x != path) + continue; - it.remove(); - if (id < 0) - directories->removeAll(path); - else - files->removeAll(path); + ::close(id < 0 ? -id : id); + + it.remove(); + if (id < 0) + directories->removeAll(path); + else + files->removeAll(path); + } + isEmpty = pathToID.isEmpty(); } - if (pathToID.isEmpty()) { + if (isEmpty) { stop(); - locker.unlock(); wait(); - locker.relock(); } else { write(kqpipe[1], "@", 1); } @@ -243,19 +245,15 @@ void QKqueueFileSystemWatcherEngine::stop() void QKqueueFileSystemWatcherEngine::run() { - static const struct timespec ZeroTimeout = { 0, 0 }; - forever { + int r; struct kevent kev; DEBUG() << "QKqueueFileSystemWatcherEngine: waiting for kevents..."; - int r = kevent(kqfd, 0, 0, &kev, 1, 0); + EINTR_LOOP(r, kevent(kqfd, 0, 0, &kev, 1, 0)); if (r < 0) { perror("QKqueueFileSystemWatcherEngine: error during kevent wait"); return; - } - - QMutexLocker locker(&mutex); - do { + } else { int fd = kev.ident; DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter; @@ -287,6 +285,8 @@ void QKqueueFileSystemWatcherEngine::run() break; } } else { + QMutexLocker locker(&mutex); + int id = fd; QString path = idToPath.value(id); if (path.isEmpty()) { @@ -295,12 +295,12 @@ void QKqueueFileSystemWatcherEngine::run() path = idToPath.value(id); if (path.isEmpty()) { DEBUG() << "QKqueueFileSystemWatcherEngine: received a kevent for a file we're not watching"; - goto process_next_event; + continue; } } if (kev.filter != EVFILT_VNODE) { DEBUG() << "QKqueueFileSystemWatcherEngine: received a kevent with the wrong filter"; - goto process_next_event; + continue; } if ((kev.fflags & (NOTE_DELETE | NOTE_REVOKE | NOTE_RENAME)) != 0) { @@ -315,31 +315,15 @@ void QKqueueFileSystemWatcherEngine::run() else emit fileChanged(path, true); } else { - DEBUG() << path << "changed, re-enabling watch"; + DEBUG() << path << "changed"; if (id < 0) emit directoryChanged(path, false); else emit fileChanged(path, false); - - // renable the watch - EV_SET(&kev, - fd, - EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, - NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, - 0, - 0); - if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) { - perror("QKqueueFileSystemWatcherEngine::processKqueueEvents: kevent EV_ADD"); - } } } - - // are there any more? -process_next_event: - r = kevent(kqfd, 0, 0, &kev, 1, &ZeroTimeout); - } while (r > 0); + } } } diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index 003e781..5b283a5 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -1050,6 +1050,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a newProc->Resume(); newProc->Close(); + delete newProc; return true; } diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp index 78556c3..da76b74 100644 --- a/src/corelib/kernel/qtcore_eval.cpp +++ b/src/corelib/kernel/qtcore_eval.cpp @@ -90,14 +90,14 @@ static const char will_shutdown_now[] = static int qt_eval_is_supported() { - const char *const license_key = qt_eval_key_data + 12; + const volatile char *const license_key = qt_eval_key_data + 12; // fast fail if (!qt_eval_key_data[0] || !*license_key) return -1; // is this an unsupported evaluation? - const char* typecode = license_key; + const volatile char *typecode = license_key; int field = 2; for ( ; field && *typecode; ++typecode) if (*typecode == '-') diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 69b70cb..6fb182b 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -482,8 +482,10 @@ int QThread::exec() Q_D(QThread); QMutexLocker locker(&d->mutex); d->data->quitNow = false; - if (d->exited) + if (d->exited) { + d->exited = false; return d->returnCode; + } locker.unlock(); QEventLoop eventLoop; diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index a44a0e8..e3b587d 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -97,6 +97,11 @@ # define SCHED_IDLE 5 #endif +#if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0) +#define QT_HAS_THREAD_PRIORITY_SCHEDULING +#endif + + QT_BEGIN_NAMESPACE #ifndef QT_NO_THREAD @@ -503,6 +508,7 @@ void QThread::usleep(unsigned long usecs) thread_sleep(&ti); } +#ifdef QT_HAS_THREAD_PRIORITY_SCHEDULING // Does some magic and calculate the Unix scheduler priorities // sched_policy is IN/OUT: it must be set to a valid policy before calling this function // sched_priority is OUT only @@ -533,6 +539,7 @@ static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_pr *sched_priority = prio; return true; } +#endif void QThread::start(Priority priority) { @@ -553,7 +560,7 @@ void QThread::start(Priority priority) d->priority = priority; -#if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && !defined(Q_OS_SYMBIAN) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0) +#if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING) && !defined(Q_OS_SYMBIAN) // ### Need to implement thread sheduling and priorities for symbian os. Implementation removed for now switch (priority) { case InheritPriority: @@ -594,7 +601,7 @@ void QThread::start(Priority priority) break; } } -#endif // _POSIX_THREAD_PRIORITY_SCHEDULING +#endif // QT_HAS_THREAD_PRIORITY_SCHEDULING #ifdef Q_OS_SYMBIAN if (d->stackSize == 0) @@ -757,7 +764,7 @@ void QThread::setPriority(Priority priority) // copied from start() with a few modifications: -#if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0) +#ifdef QT_HAS_THREAD_PRIORITY_SCHEDULING int sched_policy; sched_param param; diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index d152682..83d6dcd 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -7308,6 +7308,7 @@ Q_CORE_EXPORT char *qdtoa( double d, int mode, int ndigits, int *decpt, int *sig Q_CORE_EXPORT double qstrtod(const char *s00, const char **se, bool *ok) { + errno = 0; double ret = strtod((char*)s00, (char**)se); if (ok) { if((ret == 0.0l && errno == ERANGE) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 1bd00da..67145b8 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -203,6 +203,8 @@ public: void disconnectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const char *signal); + void registerService(const QString &serviceName); + void unregisterService(const QString &serviceName); bool handleMessage(const QDBusMessage &msg); void waitForFinished(QDBusPendingCallPrivate *pcall); @@ -247,9 +249,11 @@ public slots: void socketWrite(int); void objectDestroyed(QObject *o); void relaySignal(QObject *obj, const QMetaObject *, int signalId, const QVariantList &args); - void _q_serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); - void registerService(const QString &serviceName); - void unregisterService(const QString &serviceName); + +private slots: + void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner); + void registerServiceNoLock(const QString &serviceName); + void unregisterServiceNoLock(const QString &serviceName); signals: void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); @@ -303,6 +307,9 @@ public: QObject *receiver, const char *signal, int minMIdx, bool buildSignature); static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *); + static bool checkReplyForDelivery(QDBusConnectionPrivate *target, QObject *object, + int idx, const QList<int> &metaTypes, + const QDBusMessage &msg); static QDBusCallDeliveryEvent *prepareReply(QDBusConnectionPrivate *target, QObject *object, int idx, const QList<int> &metaTypes, const QDBusMessage &msg); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index a5d8ada..1842e5a 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -552,6 +552,9 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) (*(*list)[i])(amsg); } + if (!ref) + return false; + switch (amsg.type()) { case QDBusMessage::SignalMessage: handleSignal(amsg); @@ -713,6 +716,8 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags, return -1; } +static QDBusCallDeliveryEvent * const DIRECT_DELIVERY = (QDBusCallDeliveryEvent *)1; + QDBusCallDeliveryEvent* QDBusConnectionPrivate::prepareReply(QDBusConnectionPrivate *target, QObject *object, int idx, const QList<int> &metaTypes, @@ -736,6 +741,8 @@ QDBusCallDeliveryEvent* QDBusConnectionPrivate::prepareReply(QDBusConnectionPriv // we can deliver // prepare for the call + if (target == object) + return DIRECT_DELIVERY; return new QDBusCallDeliveryEvent(QDBusConnection(target), idx, target, msg, metaTypes); } @@ -750,6 +757,12 @@ void QDBusConnectionPrivate::activateSignal(const QDBusConnectionPrivate::Signal // Slots can optionally have one final parameter that is a QDBusMessage // Slots receive read-only copies of the message (i.e., pass by value or by const-ref) QDBusCallDeliveryEvent *call = prepareReply(this, hook.obj, hook.midx, hook.params, msg); + if (call == DIRECT_DELIVERY) { + // short-circuit delivery + Q_ASSERT(this == hook.obj); + deliverCall(this, 0, msg, hook.params, hook.midx); + return; + } if (call) postEventToThread(ActivateSignalAction, hook.obj, call); } @@ -1207,11 +1220,11 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in q_dbus_message_unref(msg); } -void QDBusConnectionPrivate::_q_serviceOwnerChanged(const QString &name, - const QString &oldOwner, const QString &newOwner) +void QDBusConnectionPrivate::serviceOwnerChangedNoLock(const QString &name, + const QString &oldOwner, const QString &newOwner) { Q_UNUSED(oldOwner); - QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this); +// QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this); WatchedServicesHash::Iterator it = watchedServices.find(name); if (it == watchedServices.end()) return; @@ -1686,11 +1699,11 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError hook.obj = this; hook.params << QMetaType::Void << QVariant::String; // both functions take a QString as parameter and return void - hook.midx = staticMetaObject.indexOfSlot("registerService(QString)"); + hook.midx = staticMetaObject.indexOfSlot("registerServiceNoLock(QString)"); Q_ASSERT(hook.midx != -1); signalHooks.insert(QLatin1String("NameAcquired:" DBUS_INTERFACE_DBUS), hook); - hook.midx = staticMetaObject.indexOfSlot("unregisterService(QString)"); + hook.midx = staticMetaObject.indexOfSlot("unregisterServiceNoLock(QString)"); Q_ASSERT(hook.midx != -1); signalHooks.insert(QLatin1String("NameLost:" DBUS_INTERFACE_DBUS), hook); @@ -2081,7 +2094,7 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook // we need to watch for this service changing connectSignal(dbusServiceString(), QString(), dbusInterfaceString(), QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), - this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + this, SLOT(serviceOwnerChangedNoLock(QString,QString,QString))); data.owner = getNameOwnerNoCache(hook.service); qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:" << data.owner << ")"; @@ -2342,12 +2355,22 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa void QDBusConnectionPrivate::registerService(const QString &serviceName) { QDBusWriteLocker locker(RegisterServiceAction, this); + registerServiceNoLock(serviceName); +} + +void QDBusConnectionPrivate::registerServiceNoLock(const QString &serviceName) +{ serviceNames.append(serviceName); } void QDBusConnectionPrivate::unregisterService(const QString &serviceName) { QDBusWriteLocker locker(UnregisterServiceAction, this); + unregisterServiceNoLock(serviceName); +} + +void QDBusConnectionPrivate::unregisterServiceNoLock(const QString &serviceName) +{ serviceNames.removeAll(serviceName); } diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp index 8c86ae8..849df73 100644 --- a/src/declarative/debugger/qdeclarativedebugservice.cpp +++ b/src/declarative/debugger/qdeclarativedebugservice.cpp @@ -226,9 +226,11 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() server->waitForConnection(); } } else { - qWarning(QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " - "Format is -qmljsdebugger=port:<port>[,block]").arg( - appD->qmljsDebugArgumentsString()).toAscii().constData()); + const QString message = + QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " + "Format is -qmljsdebugger=port:<port>[,block]"). + arg(appD->qmljsDebugArgumentsString()); + qWarning("%s", qPrintable(message)); } } #endif diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index 4e35f87..c770a85 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -519,7 +519,7 @@ void QDeclarativeBorderImage::doUpdate() void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { Q_D(QDeclarativeBorderImage); - if (d->pix.isNull()) + if (d->pix.isNull() || d->width() <= 0.0 || d->height() <= 0.0) return; bool oldAA = p->testRenderHint(QPainter::Antialiasing); @@ -528,7 +528,23 @@ void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth); const QDeclarativeScaleGrid *border = d->getScaleGrid(); - QMargins margins(border->left(), border->top(), border->right(), border->bottom()); + int left = border->left(); + int right = border->right(); + qreal borderWidth = left + right; + if (borderWidth > 0.0 && d->width() < borderWidth) { + qreal diff = borderWidth - d->width() - 1; + left -= qRound(diff * qreal(left) / borderWidth); + right -= qRound(diff * qreal(right) / borderWidth); + } + int top = border->top(); + int bottom = border->bottom(); + qreal borderHeight = top + bottom; + if (borderHeight > 0.0 && d->height() < borderHeight) { + qreal diff = borderHeight - d->height() - 1; + top -= qRound(diff * qreal(top) / borderHeight); + bottom -= qRound(diff * qreal(bottom) / borderHeight); + } + QMargins margins(left, top, right, bottom); QTileRules rules((Qt::TileRule)d->horizontalTileMode, (Qt::TileRule)d->verticalTileMode); qDrawBorderPixmap(p, QRect(0, 0, (int)d->width(), (int)d->height()), margins, d->pix, d->pix.rect(), margins, rules); if (d->smooth) { diff --git a/src/declarative/graphicsitems/qdeclarativeevents.cpp b/src/declarative/graphicsitems/qdeclarativeevents.cpp index 61fd562..4b5e777 100644 --- a/src/declarative/graphicsitems/qdeclarativeevents.cpp +++ b/src/declarative/graphicsitems/qdeclarativeevents.cpp @@ -108,6 +108,34 @@ Item { so that ancestor items do not also respond to the same event. */ +/*! + \qmlproperty int KeyEvent::modifiers + + This property holds the keyboard modifier flags that existed immediately + before the event occurred. + + It contains a bitwise combination of: + \list + \o Qt.NoModifier - No modifier key is pressed. + \o Qt.ShiftModifier - A Shift key on the keyboard is pressed. + \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed. + \o Qt.AltModifier - An Alt key on the keyboard is pressed. + \o Qt.MetaModifier - A Meta key on the keyboard is pressed. + \o Qt.KeypadModifier - A keypad button is pressed. + \endlist + + For example, to react to a Shift key + Enter key combination: + \qml + Item { + focus: true + Keys.onPressed: { + if ((event.key == Qt.Key_Enter) && (event.modifiers & Qt.ShiftModifier)) + doSomething(); + } + } + \endqml +*/ + /*! \qmlclass MouseEvent QDeclarativeMouseEvent @@ -199,7 +227,7 @@ Item { \qml MouseArea { onClicked: { - if (mouse.button == Qt.LeftButton && mouse.modifiers & Qt.ShiftModifier) + if ((mouse.button == Qt.LeftButton) && (mouse.modifiers & Qt.ShiftModifier)) doSomething(); } } diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 6f38f63..1615b0f 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -219,12 +219,8 @@ public: } } else { qreal pos = (modelIndex / columns) * rowSize(); - if (header) { - qreal headerSize = flow == QDeclarativeGridView::LeftToRight - ? header->item->height() - : header->item->width(); - pos += headerSize; - } + if (header) + pos += headerSize(); return pos; } return 0; @@ -291,11 +287,9 @@ public: if (item->index == -1) continue; qreal itemTop = item->rowPos(); - if (item->index == model->count()-1 || (itemTop+rowSize()/2 >= pos)) + if (itemTop+rowSize()/2 >= pos && itemTop - rowSize()/2 <= pos) return item; } - if (visibleItems.count() && visibleItems.first()->rowPos() <= pos) - return visibleItems.first(); return 0; } @@ -315,6 +309,16 @@ public: return index; } + qreal headerSize() const { + if (!header) + return 0.0; + + return flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + } + + virtual void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_Q(const QDeclarativeGridView); QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); @@ -878,14 +882,11 @@ void QDeclarativeGridViewPrivate::updateHeader() if (header) { if (visibleItems.count()) { qreal startPos = startPosition(); - qreal headerSize = flow == QDeclarativeGridView::LeftToRight - ? header->item->height() - : header->item->width(); if (visibleIndex == 0) { - header->setPosition(0, startPos - headerSize); + header->setPosition(0, startPos - headerSize()); } else { - if (position() <= startPos || header->rowPos() > startPos - headerSize) - header->setPosition(0, startPos - headerSize); + if (position() <= startPos || header->rowPos() > startPos - headerSize()) + header->setPosition(0, startPos - headerSize()); } } else { header->setPosition(0, 0); @@ -920,10 +921,14 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m qreal bottomPos = qMax(bottomItem->rowPos() - highlightRangeEnd, -minExtent); pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos; } else if (topItem) { - pos = qMax(qMin(topItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); + if (topItem->index == 0 && header && position()+highlightRangeStart < header->rowPos()+headerSize()/2) + pos = header->rowPos() - highlightRangeStart; + else + pos = qMax(qMin(topItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); } else if (bottomItem) { pos = qMax(qMin(bottomItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); } else { + QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); fixupDuration = oldDuration; return; } @@ -1764,8 +1769,10 @@ void QDeclarativeGridView::setFooter(QDeclarativeComponent *footer) d->footer = 0; } d->footerComponent = footer; - d->updateFooter(); - d->updateGrid(); + if (isComponentComplete()) { + d->updateFooter(); + d->updateGrid(); + } emit footerChanged(); } } @@ -1794,9 +1801,11 @@ void QDeclarativeGridView::setHeader(QDeclarativeComponent *header) d->header = 0; } d->headerComponent = header; - d->updateHeader(); - d->updateFooter(); - d->updateGrid(); + if (isComponentComplete()) { + d->updateHeader(); + d->updateFooter(); + d->updateGrid(); + } emit headerChanged(); } } @@ -2221,6 +2230,8 @@ void QDeclarativeGridView::componentComplete() { Q_D(QDeclarativeGridView); QDeclarativeFlickable::componentComplete(); + d->updateHeader(); + d->updateFooter(); d->updateGrid(); if (d->isValid()) { refill(); diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index c9eb258..e07292b 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -470,7 +470,7 @@ QRectF QDeclarativeImage::boundingRect() const void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { Q_D(QDeclarativeImage); - if (d->pix.isNull()) + if (d->pix.pixmap().isNull() ) return; bool oldAA = p->testRenderHint(QPainter::Antialiasing); diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index e0df751..9d6fe12 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -421,58 +421,28 @@ void QDeclarativeItemKeyFilter::componentComplete() \since 4.7 \brief The KeyNavigation attached property supports key navigation by arrow keys. - It is common in key-based UIs to use arrow keys to navigate - between focused items. The KeyNavigation property provides a - convenient way of specifying which item will gain focus - when an arrow key is pressed. The following example provides - key navigation for a 2x2 grid of items. - - \code - Grid { - columns: 2 - width: 100; height: 100 - Rectangle { - id: item1 - focus: true - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item2 - KeyNavigation.down: item3 - } - Rectangle { - id: item2 - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item1 - KeyNavigation.down: item4 - } - Rectangle { - id: item3 - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item4 - KeyNavigation.up: item1 - } - Rectangle { - id: item4 - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item3 - KeyNavigation.up: item2 - } - } - \endcode + Key-based user interfaces commonly allow the use of arrow keys to navigate between + focusable items. The KeyNavigation attached property enables this behavior by providing a + convenient way to specify the item that should gain focus when an arrow or tab key is pressed. + + The following example provides key navigation for a 2x2 grid of items: - By default KeyNavigation receives key events after the item it is attached to. - If the item accepts an arrow key event, the KeyNavigation - attached property will not receive an event for that key. Setting the - \l priority property to KeyNavigation.BeforeItem allows handling - of the key events before normal item processing. + \snippet doc/src/snippets/declarative/keynavigation.qml 0 - If an item has been set for a direction and the KeyNavigation - attached property receives the corresponding - key press and release events, the events will be accepted by - KeyNavigation and will not propagate any further. + The top-left item initially receives focus by setting \l {Item::}{focus} to + \c true. When an arrow key is pressed, the focus will move to the + appropriate item, as defined by the value that has been set for + the KeyNavigation \l left, \l right, \l up or \l down properties. + + Note that if a KeyNavigation attached property receives the key press and release + events for a requested arrow or tab key, the event is accepted and does not + propagate any further. + + By default, KeyNavigation receives key events after the item to which it is attached. + If the item accepts the key event, the KeyNavigation attached property will not + receive an event for that key. Setting the \l priority property to + \c KeyNavigation.BeforeItem allows the event to be used for key navigation + before the item, rather than after. \sa {Keys}{Keys attached property} */ @@ -599,7 +569,7 @@ void QDeclarativeKeyNavigationAttached::setBacktab(QDeclarativeItem *i) \list \o KeyNavigation.BeforeItem - process the key events before normal - item key processing. If the event is accepted it will not + item key processing. If the event is used for key navigation, it will be accepted and will not be passed on to the item. \o KeyNavigation.AfterItem (default) - process the key events after normal item key handling. If the item accepts the key event it will not be diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index f85fa27..d8635b9 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -259,7 +259,7 @@ public: QDeclarativeStateGroup *_states(); QDeclarativeStateGroup *_stateGroup; - QDeclarativeItem::TransformOrigin origin:4; + QDeclarativeItem::TransformOrigin origin:5; bool widthValid:1; bool heightValid:1; bool componentComplete:1; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 450b6af..845da79 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -402,6 +402,8 @@ public: void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_Q(QDeclarativeListView); QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); + if (!q->isComponentComplete()) + return; if (item != contentItem && (!highlight || item != highlight->item)) { if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height()) || (orient == QDeclarativeListView::Horizontal && newGeometry.width() != oldGeometry.width())) { @@ -1123,8 +1125,6 @@ void QDeclarativeListViewPrivate::updateHeader() QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); header = new FxListItem(item, q); - if (visibleItems.isEmpty()) - visiblePos = header->size(); } } if (header) { @@ -1137,6 +1137,8 @@ void QDeclarativeListViewPrivate::updateHeader() header->setPosition(startPos - header->size()); } } else { + if (itemCount == 0) + visiblePos = header->size(); header->setPosition(0); } } @@ -1185,10 +1187,14 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m FxListItem *bottomItem = snapItemAt(position()+highlightRangeEnd); qreal pos; if (topItem) { - pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); + if (topItem->index == 0 && header && position()+highlightRangeStart < header->position()+header->size()/2) + pos = header->position() - highlightRangeStart; + else + pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); } else if (bottomItem) { pos = qMax(qMin(bottomItem->position() - highlightRangeStart, -maxExtent), -minExtent); } else { + QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); fixupDuration = oldDuration; return; } @@ -2211,8 +2217,10 @@ void QDeclarativeListView::setFooter(QDeclarativeComponent *footer) d->footerComponent = footer; d->minExtentDirty = true; d->maxExtentDirty = true; - d->updateFooter(); - d->updateViewport(); + if (isComponentComplete()) { + d->updateFooter(); + d->updateViewport(); + } emit footerChanged(); } } @@ -2243,9 +2251,11 @@ void QDeclarativeListView::setHeader(QDeclarativeComponent *header) d->headerComponent = header; d->minExtentDirty = true; d->maxExtentDirty = true; - d->updateHeader(); - d->updateFooter(); - d->updateViewport(); + if (isComponentComplete()) { + d->updateHeader(); + d->updateFooter(); + d->updateViewport(); + } emit headerChanged(); } } @@ -2655,6 +2665,8 @@ void QDeclarativeListView::componentComplete() Q_D(QDeclarativeListView); QDeclarativeFlickable::componentComplete(); updateSections(); + d->updateHeader(); + d->updateFooter(); if (d->isValid()) { refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp index 7686dde..dedb3f7 100644 --- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp +++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp @@ -420,6 +420,10 @@ void QDeclarativeRectangle::generateRoundedRect() p.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, d->rectImage.width()-(pw+1), d->rectImage.height()-(pw+1)), d->radius, d->radius); else p.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, d->rectImage.width()-pw, d->rectImage.height()-pw), d->radius, d->radius); + + // end painting before inserting pixmap + // to pixmap cache to avoid a deep copy + p.end(); QPixmapCache::insert(key, d->rectImage); } } @@ -454,6 +458,10 @@ void QDeclarativeRectangle::generateBorderedRect() p.drawRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, d->rectImage.width()-(pw+1), d->rectImage.height()-(pw+1))); else p.drawRect(QRectF(qreal(pw)/2, qreal(pw)/2, d->rectImage.width()-pw, d->rectImage.height()-pw)); + + // end painting before inserting pixmap + // to pixmap cache to avoid a deep copy + p.end(); QPixmapCache::insert(key, d->rectImage); } } diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 82c444e..303b21c 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -436,12 +436,13 @@ void QDeclarativeTextPrivate::invalidateImageCache() { Q_Q(QDeclarativeText); - if (imageCacheDirty) - return; - - imageCacheDirty = true; - imageCache = QPixmap(); + if(cacheAllTextAsImage || style != QDeclarativeText::Normal){//If actually using the image cache + if (imageCacheDirty) + return; + imageCacheDirty = true; + imageCache = QPixmap(); + } if (q->isComponentComplete()) q->update(); } diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp index e8da367..14a1109 100644 --- a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp @@ -361,10 +361,18 @@ void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p) d->position = p; } + QPen oldPen = priv->state->pen; + QColor currentColor = oldPen.color(); for (int ii = 0; ii < itemCount; ++ii) { QStaticTextItem &item = d->items[ii]; + if (item.color.isValid() && currentColor != item.color) { + painter->setPen(item.color); + currentColor = item.color; + } priv->extended->drawStaticTextItem(&item); } + if (currentColor != oldPen.color()) + painter->setPen(oldPen); } QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index c8b4c7d..309d372 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -56,6 +56,158 @@ QT_BEGIN_NAMESPACE +QDeclarativeAbstractBinding::QDeclarativeAbstractBinding() +: m_object(0), m_propertyIndex(-1), m_mePtr(0), m_prevBinding(0), m_nextBinding(0) +{ +} + +QDeclarativeAbstractBinding::~QDeclarativeAbstractBinding() +{ + Q_ASSERT(m_prevBinding == 0); + Q_ASSERT(m_mePtr == 0); +} + +/*! +Destroy the binding. Use this instead of calling delete. + +Bindings are free to implement their own memory management, so the delete operator is not +necessarily safe. The default implementation clears the binding, removes it from the object +and calls delete. +*/ +void QDeclarativeAbstractBinding::destroy() +{ + removeFromObject(); + clear(); + + delete this; +} + +/*! +Add this binding to \a object. + +This transfers ownership of the binding to the object, marks the object's property as +being bound. + +However, it does not enable the binding itself or call update() on it. +*/ +void QDeclarativeAbstractBinding::addToObject(QObject *object, int index) +{ + Q_ASSERT(object); + + if (m_object == object && m_propertyIndex == index) + return; + + removeFromObject(); + + Q_ASSERT(!m_prevBinding); + + m_object = object; + m_propertyIndex = index; + + QDeclarativeData *data = QDeclarativeData::get(object, true); + + if (index & 0xFF000000) { + // Value type + + int coreIndex = index & 0xFFFFFF; + + // Find the value type proxy (if there is one) + QDeclarativeValueTypeProxyBinding *proxy = 0; + if (data->hasBindingBit(coreIndex)) { + QDeclarativeAbstractBinding *b = data->bindings; + while (b && b->propertyIndex() != coreIndex) + b = b->m_nextBinding; + Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy); + proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(b); + } + + if (!proxy) { + proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex); + proxy->addToObject(object, coreIndex); + } + + m_nextBinding = proxy->m_bindings; + if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; + m_prevBinding = &proxy->m_bindings; + proxy->m_bindings = this; + + } else { + m_nextBinding = data->bindings; + if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; + m_prevBinding = &data->bindings; + data->bindings = this; + + data->setBindingBit(m_object, index); + } +} + +/*! +Remove the binding from the object. +*/ +void QDeclarativeAbstractBinding::removeFromObject() +{ + if (m_prevBinding) { + int index = propertyIndex(); + + *m_prevBinding = m_nextBinding; + if (m_nextBinding) m_nextBinding->m_prevBinding = m_prevBinding; + m_prevBinding = 0; + m_nextBinding = 0; + + if (index & 0xFF000000) { + // Value type - we don't remove the proxy from the object. It will sit their happily + // doing nothing until it is removed by a write, a binding change or it is reused + // to hold more sub-bindings. + } else if (m_object) { + QDeclarativeData *data = QDeclarativeData::get(m_object, false); + if (data) data->clearBindingBit(index); + } + + m_object = 0; + m_propertyIndex = -1; + } +} + +static void bindingDummyDeleter(QDeclarativeAbstractBinding *) +{ +} + +QDeclarativeAbstractBinding::Pointer QDeclarativeAbstractBinding::weakPointer() +{ + if (m_selfPointer.isNull()) + m_selfPointer = QSharedPointer<QDeclarativeAbstractBinding>(this, bindingDummyDeleter); + + return m_selfPointer.toWeakRef(); +} + +void QDeclarativeAbstractBinding::clear() +{ + if (m_mePtr) { + *m_mePtr = 0; + m_mePtr = 0; + } +} + +QString QDeclarativeAbstractBinding::expression() const +{ + return QLatin1String("<Unknown>"); +} + +QObject *QDeclarativeAbstractBinding::object() const +{ + return m_object; +} + +int QDeclarativeAbstractBinding::propertyIndex() const +{ + return m_propertyIndex; +} + +void QDeclarativeAbstractBinding::setEnabled(bool enabled, QDeclarativePropertyPrivate::WriteFlags flags) +{ + if (enabled) update(flags); +} + void QDeclarativeBindingPrivate::refresh() { Q_Q(QDeclarativeBinding); @@ -271,20 +423,8 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF d->enabled = e; setNotifyOnValueChanged(e); - QDeclarativeAbstractBinding::setEnabled(e, flags); - - if (e) { - addToObject(d->property.object()); + if (e) update(flags); - } else { - removeFromObject(); - } -} - -int QDeclarativeBinding::propertyIndex() -{ - Q_D(QDeclarativeBinding); - return QDeclarativePropertyPrivate::bindingIndex(d->property); } bool QDeclarativeBinding::enabled() const @@ -299,127 +439,6 @@ QString QDeclarativeBinding::expression() const return QDeclarativeExpression::expression(); } -QDeclarativeAbstractBinding::QDeclarativeAbstractBinding() -: m_object(0), m_mePtr(0), m_prevBinding(0), m_nextBinding(0) -{ -} - -QDeclarativeAbstractBinding::~QDeclarativeAbstractBinding() -{ - Q_ASSERT(m_prevBinding == 0); - Q_ASSERT(m_mePtr == 0); -} - -void QDeclarativeAbstractBinding::destroy() -{ - removeFromObject(); - clear(); - - delete this; -} - -void QDeclarativeAbstractBinding::addToObject(QObject *object) -{ - Q_ASSERT(object); - - if (m_object == object) - return; - - int index = propertyIndex(); - - removeFromObject(); - - Q_ASSERT(!m_prevBinding); - - m_object = object; - QDeclarativeData *data = QDeclarativeData::get(object, true); - - if (index & 0xFF000000) { - // Value type - - int coreIndex = index & 0xFFFFFF; - - // Find the value type proxy (if there is one) - QDeclarativeValueTypeProxyBinding *proxy = 0; - if (data->hasBindingBit(coreIndex)) { - QDeclarativeAbstractBinding *b = data->bindings; - while (b && b->propertyIndex() != coreIndex) - b = b->m_nextBinding; - Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy); - proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(b); - } - - if (!proxy) - proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex); - proxy->addToObject(object); - - m_nextBinding = proxy->m_bindings; - if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; - m_prevBinding = &proxy->m_bindings; - proxy->m_bindings = this; - - } else { - m_nextBinding = data->bindings; - if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; - m_prevBinding = &data->bindings; - data->bindings = this; - - data->setBindingBit(m_object, index); - } -} - -void QDeclarativeAbstractBinding::removeFromObject() -{ - if (m_prevBinding) { - int index = propertyIndex(); - - *m_prevBinding = m_nextBinding; - if (m_nextBinding) m_nextBinding->m_prevBinding = m_prevBinding; - m_prevBinding = 0; - m_nextBinding = 0; - - if (index & 0xFF000000) { - // Value type - we don't remove the proxy from the object. It will sit their happily - // doing nothing for ever more. - } else if (m_object) { - QDeclarativeData *data = QDeclarativeData::get(m_object, false); - if (data) data->clearBindingBit(index); - } - - m_object = 0; - } -} - -static void bindingDummyDeleter(QDeclarativeAbstractBinding *) -{ -} - -QDeclarativeAbstractBinding::Pointer QDeclarativeAbstractBinding::weakPointer() -{ - if (m_selfPointer.isNull()) - m_selfPointer = QSharedPointer<QDeclarativeAbstractBinding>(this, bindingDummyDeleter); - - return m_selfPointer.toWeakRef(); -} - -void QDeclarativeAbstractBinding::clear() -{ - if (m_mePtr) { - *m_mePtr = 0; - m_mePtr = 0; - } -} - -QString QDeclarativeAbstractBinding::expression() const -{ - return QLatin1String("<Unknown>"); -} - -void QDeclarativeAbstractBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags) -{ - if (e) m_mePtr = 0; -} - QDeclarativeValueTypeProxyBinding::QDeclarativeValueTypeProxyBinding(QObject *o, int index) : m_object(o), m_index(index), m_bindings(0) { @@ -437,16 +456,10 @@ QDeclarativeValueTypeProxyBinding::~QDeclarativeValueTypeProxyBinding() void QDeclarativeValueTypeProxyBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) { if (e) { - addToObject(m_object); - QDeclarativeAbstractBinding *bindings = m_bindings; - m_bindings = 0; recursiveEnable(bindings, flags); } else { - removeFromObject(); - QDeclarativeAbstractBinding *bindings = m_bindings; - m_bindings = 0; recursiveDisable(bindings); } } @@ -456,13 +469,7 @@ void QDeclarativeValueTypeProxyBinding::recursiveEnable(QDeclarativeAbstractBind if (!b) return; - QDeclarativeAbstractBinding *next = b->m_nextBinding; - b->m_prevBinding = 0; - b->m_nextBinding = 0; - Q_ASSERT(b->m_mePtr == 0); - b->m_mePtr = &b; - - recursiveEnable(next, flags); + recursiveEnable(b->m_nextBinding, flags); if (b) b->setEnabled(true, flags); @@ -475,19 +482,8 @@ void QDeclarativeValueTypeProxyBinding::recursiveDisable(QDeclarativeAbstractBin recursiveDisable(b->m_nextBinding); - b->setEnabled(false, 0); - - Q_ASSERT(b->m_prevBinding == 0); - Q_ASSERT(b->m_nextBinding == 0); - b->m_nextBinding = m_bindings; - if (b->m_nextBinding) b->m_nextBinding->m_prevBinding = &b->m_nextBinding; - b->m_prevBinding = &m_bindings; - m_bindings = b; -} - -int QDeclarativeValueTypeProxyBinding::propertyIndex() -{ - return m_index; + if (b) + b->setEnabled(false, 0); } void QDeclarativeValueTypeProxyBinding::update(QDeclarativePropertyPrivate::WriteFlags) @@ -504,4 +500,25 @@ QDeclarativeAbstractBinding *QDeclarativeValueTypeProxyBinding::binding(int prop return binding; } +/*! +Removes a collection of bindings, corresponding to the set bits in \a mask. +*/ +void QDeclarativeValueTypeProxyBinding::removeBindings(quint32 mask) +{ + QDeclarativeAbstractBinding *binding = m_bindings; + while (binding) { + if (mask & (1 << (binding->propertyIndex() >> 24))) { + QDeclarativeAbstractBinding *remove = binding; + binding = remove->m_nextBinding; + *remove->m_prevBinding = remove->m_nextBinding; + if (remove->m_nextBinding) remove->m_nextBinding->m_prevBinding = remove->m_prevBinding; + remove->m_prevBinding = 0; + remove->m_nextBinding = 0; + remove->destroy(); + } else { + binding = binding->m_nextBinding; + } + } +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index 0b9bde6..7823a3d 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -78,14 +78,16 @@ public: enum Type { PropertyBinding, ValueTypeProxy }; virtual Type bindingType() const { return PropertyBinding; } + QObject *object() const; + int propertyIndex() const; + void setEnabled(bool e) { setEnabled(e, QDeclarativePropertyPrivate::DontRemoveBinding); } virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags) = 0; - virtual int propertyIndex() = 0; void update() { update(QDeclarativePropertyPrivate::DontRemoveBinding); } virtual void update(QDeclarativePropertyPrivate::WriteFlags) = 0; - void addToObject(QObject *); + void addToObject(QObject *, int); void removeFromObject(); static Pointer getPointer(QDeclarativeAbstractBinding *p) { return p ? p->weakPointer() : Pointer(); } @@ -98,12 +100,14 @@ private: Pointer weakPointer(); friend class QDeclarativeData; + friend class QDeclarativeComponentPrivate; friend class QDeclarativeValueTypeProxyBinding; friend class QDeclarativePropertyPrivate; friend class QDeclarativeVME; friend class QtSharedPointer::ExternalRefCount<QDeclarativeAbstractBinding>; QObject *m_object; + int m_propertyIndex; QDeclarativeAbstractBinding **m_mePtr; QDeclarativeAbstractBinding **m_prevBinding; QDeclarativeAbstractBinding *m_nextBinding; @@ -118,11 +122,12 @@ public: virtual Type bindingType() const { return ValueTypeProxy; } virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags); - virtual int propertyIndex(); virtual void update(QDeclarativePropertyPrivate::WriteFlags); QDeclarativeAbstractBinding *binding(int propertyIndex); + void removeBindings(quint32 mask); + protected: ~QDeclarativeValueTypeProxyBinding(); @@ -154,7 +159,6 @@ public: // Inherited from QDeclarativeAbstractBinding virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags); - virtual int propertyIndex(); virtual void update(QDeclarativePropertyPrivate::WriteFlags flags); virtual QString expression() const; diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index 4922913..48f8b84 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -188,7 +188,6 @@ public: // Inherited from QDeclarativeAbstractBinding virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags); - virtual int propertyIndex(); virtual void update(QDeclarativePropertyPrivate::WriteFlags flags); virtual void destroy(); @@ -295,14 +294,6 @@ QDeclarativeAbstractBinding *QDeclarativeCompiledBindings::configBinding(int ind void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) { - if (e) { - addToObject(target); - } else { - removeFromObject(); - } - - QDeclarativeAbstractBinding::setEnabled(e, flags); - if (enabled != e) { enabled = e; @@ -310,11 +301,6 @@ void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarati } } -int QDeclarativeCompiledBindingsPrivate::Binding::propertyIndex() -{ - return property & 0xFFFF; -} - void QDeclarativeCompiledBindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags) { QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding); diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 01c2176..4749bf8 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -946,6 +946,16 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) QDeclarativePropertyCache::Data::IsVMEFunction, QDeclarativePropertyCache::Data::IsVMESignal); + // Add flag for alias properties + if (!obj->synthdata.isEmpty()) { + const QDeclarativeVMEMetaData *vmeMetaData = + reinterpret_cast<const QDeclarativeVMEMetaData *>(obj->synthdata.constData()); + for (int ii = 0; ii < vmeMetaData->aliasCount; ++ii) { + int index = obj->metaObject()->propertyOffset() + vmeMetaData->propertyCount + ii; + propertyCache->property(index)->flags |= QDeclarativePropertyCache::Data::IsAlias; + } + } + if (obj == unitRoot) { propertyCache->addref(); output->rootPropertyCache = propertyCache; @@ -1003,7 +1013,8 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) seenDefer = true; continue; } - genValueProperty(prop, obj); + if (!prop->isAlias) + genValueProperty(prop, obj); } if (seenDefer) { QDeclarativeInstruction defer; @@ -1113,25 +1124,56 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) } foreach(Property *prop, obj->valueTypeProperties) { - QDeclarativeInstruction fetch; - fetch.type = QDeclarativeInstruction::FetchValueType; - fetch.fetchValue.property = prop->index; - fetch.fetchValue.type = prop->type; - fetch.line = prop->location.start.line; + if (!prop->isAlias) + genValueTypeProperty(obj, prop); + } - output->bytecode << fetch; + foreach(Property *prop, obj->valueProperties) { + if (prop->isDeferred) + continue; + if (prop->isAlias) + genValueProperty(prop, obj); + } + + foreach(Property *prop, obj->valueTypeProperties) { + if (prop->isAlias) + genValueTypeProperty(obj, prop); + } +} +void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *prop) +{ + QDeclarativeInstruction fetch; + fetch.type = QDeclarativeInstruction::FetchValueType; + fetch.fetchValue.property = prop->index; + fetch.fetchValue.type = prop->type; + fetch.fetchValue.bindingSkipList = 0; + fetch.line = prop->location.start.line; + + if (obj->type == -1 || output->types.at(obj->type).component) { + // We only have to do this if this is a composite type. If it is a builtin + // type it can't possibly already have bindings that need to be cleared. foreach(Property *vprop, prop->value->valueProperties) { - genPropertyAssignment(vprop, prop->value, prop); + if (!vprop->values.isEmpty()) { + Q_ASSERT(vprop->index >= 0 && vprop->index < 32); + fetch.fetchValue.bindingSkipList |= (1 << vprop->index); + } } + } - QDeclarativeInstruction pop; - pop.type = QDeclarativeInstruction::PopValueType; - pop.fetchValue.property = prop->index; - pop.fetchValue.type = prop->type; - pop.line = prop->location.start.line; - output->bytecode << pop; + output->bytecode << fetch; + + foreach(Property *vprop, prop->value->valueProperties) { + genPropertyAssignment(vprop, prop->value, prop); } + + QDeclarativeInstruction pop; + pop.type = QDeclarativeInstruction::PopValueType; + pop.fetchValue.property = prop->index; + pop.fetchValue.type = prop->type; + pop.fetchValue.bindingSkipList = 0; + pop.line = prop->location.start.line; + output->bytecode << pop; } void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) @@ -1440,10 +1482,22 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, if (p.name()) { prop->type = p.userType(); } - } - if (prop->index != -1) - prop->parent->setBindingBit(prop->index); + // Check if this is an alias + if (prop->index != -1 && + prop->parent && + prop->parent->type != -1 && + output->types.at(prop->parent->type).component) { + + QDeclarativePropertyCache *cache = output->types.at(prop->parent->type).component->rootPropertyCache; + if (cache && cache->property(prop->index) && + cache->property(prop->index)->flags & QDeclarativePropertyCache::Data::IsAlias) + prop->isAlias = true; + } + + if (prop->index != -1 && !prop->values.isEmpty()) + prop->parent->setBindingBit(prop->index); + } if (!prop->isDefault && prop->name == "id" && !ctxt.isSubContext()) { @@ -1778,6 +1832,12 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name))); } + + if (prop->isAlias) { + foreach (Property *vtProp, prop->value->properties) + vtProp->isAlias = true; + } + COMPILE_CHECK(buildValueTypeProperty(enginePrivate->valueTypes[prop->type], prop->value, obj, ctxt.incr())); obj->addValueTypeProperty(prop); @@ -2439,7 +2499,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn if (p.type == Object::DynamicProperty::Alias) { if (mode == ResolveAliases) { ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++; - compileAlias(builder, dynamicData, obj, p); + COMPILE_CHECK(compileAlias(builder, dynamicData, obj, p)); } else { // Need a fake signal so that the metaobject remains consistent across // the resolve and non-resolve alias runs @@ -2710,7 +2770,10 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi } QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreBinding; + if (!prop->isAlias) + store.type = QDeclarativeInstruction::StoreBinding; + else + store.type = QDeclarativeInstruction::StoreBindingOnAlias; store.assignBinding.value = output->indexForByteArray(ref.compiledData); store.assignBinding.context = ref.bindingContext.stack; store.assignBinding.owner = ref.bindingContext.owner; @@ -2785,13 +2848,17 @@ bool QDeclarativeCompiler::completeComponentBuild() expr.expression = binding.expression; expr.imports = unit->imports(); - int index = bindingCompiler.compile(expr, enginePrivate); - if (index != -1) { - binding.dataType = BindingReference::Experimental; - binding.compiledIndex = index; - componentStat.optimizedBindings.append(iter.key()->location); - continue; - } + // ### We don't currently optimize for bindings on alias's - because + // of the solution to QTBUG-13719 + if (!binding.property->isAlias) { + int index = bindingCompiler.compile(expr, enginePrivate); + if (index != -1) { + binding.dataType = BindingReference::Experimental; + binding.compiledIndex = index; + componentStat.optimizedBindings.append(iter.key()->location); + continue; + } + } binding.dataType = BindingReference::QtScript; diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index 5cd1fd2..7d76ad9 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -252,6 +252,7 @@ private: void genObject(QDeclarativeParser::Object *obj); void genObjectBody(QDeclarativeParser::Object *obj); + void genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *); void genComponent(QDeclarativeParser::Object *obj); void genValueProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj); void genListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj); diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 5be41ab..a72e04e 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -878,9 +878,12 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> bv = state->bindValues.at(ii); for (int jj = 0; jj < bv.count; ++jj) { - if(bv.at(jj)) + if(bv.at(jj)) { + // XXX akennedy + bv.at(jj)->m_mePtr = 0; bv.at(jj)->setEnabled(true, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); + } } QDeclarativeEnginePrivate::clear(bv); } diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h index def4188..4767169 100644 --- a/src/declarative/qml/qdeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedata_p.h @@ -65,6 +65,7 @@ class QDeclarativeContext; class QDeclarativePropertyCache; class QDeclarativeContextData; class QDeclarativeNotifier; +class QDeclarativeDataExtended; // This class is structured in such a way, that simply zero'ing it is the // default state for elemental object allocations. This is crucial in the // workings of the QDeclarativeInstruction::CreateSimpleObject instruction. @@ -150,17 +151,13 @@ public: } } + bool hasExtendedData() const { return extendedData != 0; } QDeclarativeNotifier *objectNameNotifier() const; QHash<int, QObject *> *attachedProperties() const; - struct ExtendedData { - ExtendedData(); - ~ExtendedData(); - - QHash<int, QObject *> attachedProperties; - void *objectNameNotifier; - }; - mutable ExtendedData *extendedData; +private: + // For objectNameNotifier and attachedProperties + mutable QDeclarativeDataExtended *extendedData; }; template<class T> diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 5122bdf..48bf3d1 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -898,9 +898,7 @@ void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership own if (!object) return; - // No need to do anything if CppOwnership and there is no QDeclarativeData as - // the current ownership must be CppOwnership - QDeclarativeData *ddata = QDeclarativeData::get(object, ownership == JavaScriptOwnership); + QDeclarativeData *ddata = QDeclarativeData::get(object, true); if (!ddata) return; @@ -960,7 +958,7 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre if (!data) return 0; // Attached properties are only on objects created by QML - QObject *rv = data->extendedData?data->attachedProperties()->value(id):0; + QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0; if (rv || !create) return rv; @@ -988,6 +986,35 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object, return qmlAttachedPropertiesObjectById(*idCache, object, create); } +class QDeclarativeDataExtended { +public: + QDeclarativeDataExtended(); + ~QDeclarativeDataExtended(); + + QHash<int, QObject *> attachedProperties; + QDeclarativeNotifier objectNameNotifier; +}; + +QDeclarativeDataExtended::QDeclarativeDataExtended() +{ +} + +QDeclarativeDataExtended::~QDeclarativeDataExtended() +{ +} + +QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const +{ + if (!extendedData) extendedData = new QDeclarativeDataExtended; + return &extendedData->objectNameNotifier; +} + +QHash<int, QObject *> *QDeclarativeData::attachedProperties() const +{ + if (!extendedData) extendedData = new QDeclarativeDataExtended; + return &extendedData->attachedProperties; +} + void QDeclarativeData::destroyed(QObject *object) { if (deferredComponent) @@ -1078,28 +1105,6 @@ void QDeclarativeData::setBindingBit(QObject *obj, int bit) bindingBits[bit / 32] |= (1 << (bit % 32)); } -QDeclarativeData::ExtendedData::ExtendedData() -: objectNameNotifier(0) -{ -} - -QDeclarativeData::ExtendedData::~ExtendedData() -{ - ((QDeclarativeNotifier *)&objectNameNotifier)->~QDeclarativeNotifier(); -} - -QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const -{ - if (!extendedData) extendedData = new ExtendedData; - return (QDeclarativeNotifier *)&extendedData->objectNameNotifier; -} - -QHash<int, QObject *> *QDeclarativeData::attachedProperties() const -{ - if (!extendedData) extendedData = new ExtendedData; - return &extendedData->attachedProperties; -} - /*! Creates a QScriptValue allowing you to use \a object in QML script. \a engine is the QDeclarativeEngine it is to be created in. @@ -2228,8 +2233,9 @@ bool QDeclarative_isFileCaseCorrect(const QString &fileName) if (a != c) return false; } +#else + Q_UNUSED(fileName) #endif - return true; } diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index 1767d2f..818c15d 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -63,7 +63,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << line << "\t" << "INIT\t\t\t" << instr->init.bindingsSize << "\t" << instr->init.parserStatusSize << "\t" << instr->init.contextCache << "\t" << instr->init.compiledBinding; break; case QDeclarativeInstruction::CreateObject: - qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t\t\t" << types.at(instr->create.type).className; + qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t" << instr->create.bindingBits << "\t\t" << types.at(instr->create.type).className; break; case QDeclarativeInstruction::CreateSimpleObject: qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE_SIMPLE\t\t" << instr->createSimple.typeSize; @@ -174,6 +174,9 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) case QDeclarativeInstruction::StoreBinding: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context; break; + case QDeclarativeInstruction::StoreBindingOnAlias: + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_BINDING_ALIAS\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context; + break; case QDeclarativeInstruction::StoreCompiledBinding: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_COMPILED_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context; break; @@ -203,7 +206,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH\t\t\t" << instr->fetch.property; break; case QDeclarativeInstruction::FetchValueType: - qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_VALUE\t\t" << instr->fetchValue.property << "\t" << instr->fetchValue.type; + qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_VALUE\t\t" << instr->fetchValue.property << "\t" << instr->fetchValue.type << "\t" << instr->fetchValue.bindingSkipList; break; case QDeclarativeInstruction::PopFetchedObject: qWarning().nospace() << idx << "\t\t" << line << "\t" << "POP"; diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index f0b032c..94676fc 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -132,6 +132,7 @@ public: AssignCustomType, /* assignCustomType */ StoreBinding, /* assignBinding */ + StoreBindingOnAlias, /* assignBinding */ StoreCompiledBinding, /* assignBinding */ StoreValueSource, /* assignValueSource */ StoreValueInterceptor, /* assignValueInterceptor */ @@ -214,6 +215,7 @@ public: struct FetchValueInstruction { int property; int type; + quint32 bindingSkipList; }; struct FetchQmlListInstruction { int property; diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index eff59df..b0bc5bb 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -69,7 +69,7 @@ struct ObjectData : public QScriptDeclarativeClass::Object { virtual ~ObjectData() { if (object && !object->parent()) { QDeclarativeData *ddata = QDeclarativeData::get(object, false); - if (ddata && !ddata->indestructible && 0 == --ddata->objectDataRefCount) + if (ddata && !ddata->indestructible && 0 == --ddata->objectDataRefCount) object->deleteLater(); } } @@ -808,7 +808,14 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) } return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId<QVariant>()) { - return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)&data))); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e); + QScriptValue rv = ep->scriptValueFromVariant(*((QVariant *)&data)); + if (rv.isQObject()) { + QObject *object = rv.toQObject(); + if (object) + QDeclarativeData::get(object, true)->setImplicitDestructible(); + } + return QScriptDeclarativeClass::Value(engine, rv); } else { return QScriptDeclarativeClass::Value(); } diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp index 8d00ef8..effecb1 100644 --- a/src/declarative/qml/qdeclarativeparser.cpp +++ b/src/declarative/qml/qdeclarativeparser.cpp @@ -205,13 +205,13 @@ QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o) QDeclarativeParser::Property::Property() : parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false), - isValueTypeSubProperty(false) + isValueTypeSubProperty(false), isAlias(false) { } QDeclarativeParser::Property::Property(const QByteArray &n) : parent(0), type(0), index(-1), value(0), name(n), isDefault(false), - isDeferred(false), isValueTypeSubProperty(false) + isDeferred(false), isValueTypeSubProperty(false), isAlias(false) { } diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 77184c2..633847d 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -358,6 +358,9 @@ namespace QDeclarativeParser bool isDeferred; // True if this property is a value-type pseudo-property bool isValueTypeSubProperty; + // True if this property is a property alias. Set by the + // QDeclarativeCompiler + bool isAlias; LocationSpan location; LocationRange listValueRange; diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 1395e97..df0917f 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -607,26 +607,7 @@ QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that) if (!that.isProperty() || !that.d->object) return 0; - QDeclarativeData *data = QDeclarativeData::get(that.d->object); - if (!data) - return 0; - - if (!data->hasBindingBit(that.d->core.coreIndex)) - return 0; - - QDeclarativeAbstractBinding *binding = data->bindings; - while (binding && binding->propertyIndex() != that.d->core.coreIndex) - binding = binding->m_nextBinding; - - if (binding && that.d->valueType.valueTypeCoreIdx != -1) { - if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { - QDeclarativeValueTypeProxyBinding *proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(binding); - - binding = proxy->binding(bindingIndex(that)); - } - } - - return binding; + return binding(that.d->object, that.d->core.coreIndex, that.d->valueType.valueTypeCoreIdx); } /*! @@ -658,12 +639,106 @@ QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that, } QDeclarativeAbstractBinding * +QDeclarativePropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex) +{ + QDeclarativeData *data = QDeclarativeData::get(object); + if (!data) + return 0; + + QDeclarativePropertyCache::Data *propertyData = + data->propertyCache?data->propertyCache->property(coreIndex):0; + if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) { + const QDeclarativeVMEMetaObject *vme = + static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex)); + + QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) + return 0; + + // This will either be a value type sub-reference or an alias to a value-type sub-reference not both + Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); + return binding(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex); + } + + if (!data->hasBindingBit(coreIndex)) + return 0; + + QDeclarativeAbstractBinding *binding = data->bindings; + while (binding && binding->propertyIndex() != coreIndex) + binding = binding->m_nextBinding; + + if (binding && valueTypeIndex != -1) { + if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { + int index = coreIndex | (valueTypeIndex << 24); + binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index); + } + } + + return binding; +} + +void QDeclarativePropertyPrivate::findAliasTarget(QObject *object, int bindingIndex, + QObject **targetObject, int *targetBindingIndex) +{ + int coreIndex = bindingIndex & 0xFFFFFF; + int valueTypeIndex = bindingIndex >> 24; + if (valueTypeIndex == 0) valueTypeIndex = -1; + + QDeclarativeData *data = QDeclarativeData::get(object, false); + if (data) { + QDeclarativePropertyCache::Data *propertyData = + data->propertyCache?data->propertyCache->property(coreIndex):0; + if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) { + const QDeclarativeVMEMetaObject *vme = + static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex)); + QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + if (vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { + // This will either be a value type sub-reference or an alias to a value-type sub-reference not both + Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); + + int aBindingIndex = aCoreIndex; + if (aValueTypeIndex != -1) + aBindingIndex |= aValueTypeIndex << 24; + else if (valueTypeIndex != -1) + aBindingIndex |= valueTypeIndex << 24; + + findAliasTarget(aObject, aBindingIndex, targetObject, targetBindingIndex); + return; + } + } + } + + *targetObject = object; + *targetBindingIndex = bindingIndex; +} + +QDeclarativeAbstractBinding * QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex, QDeclarativeAbstractBinding *newBinding, WriteFlags flags) { QDeclarativeData *data = QDeclarativeData::get(object, 0 != newBinding); QDeclarativeAbstractBinding *binding = 0; + if (data) { + QDeclarativePropertyCache::Data *propertyData = + data->propertyCache?data->propertyCache->property(coreIndex):0; + if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) { + const QDeclarativeVMEMetaObject *vme = + static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex)); + + QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { + if (newBinding) newBinding->destroy(); + return 0; + } + + // This will either be a value type sub-reference or an alias to a value-type sub-reference not both + Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); + return setBinding(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex, + newBinding, flags); + } + } + if (data && data->hasBindingBit(coreIndex)) { binding = data->bindings; @@ -671,16 +746,72 @@ QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valu binding = binding->m_nextBinding; } - if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { - int index = coreIndex | (valueTypeIndex << 24); + int index = coreIndex; + if (valueTypeIndex != -1) + index |= (valueTypeIndex << 24); + + if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index); + + if (binding) { + binding->removeFromObject(); + binding->setEnabled(false, 0); } + if (newBinding) { + newBinding->addToObject(object, index); + newBinding->setEnabled(true, flags); + } + + return binding; +} + +QDeclarativeAbstractBinding * +QDeclarativePropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valueTypeIndex, + QDeclarativeAbstractBinding *newBinding) +{ + QDeclarativeData *data = QDeclarativeData::get(object, 0 != newBinding); + QDeclarativeAbstractBinding *binding = 0; + + if (data) { + QDeclarativePropertyCache::Data *propertyData = + data->propertyCache?data->propertyCache->property(coreIndex):0; + if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) { + const QDeclarativeVMEMetaObject *vme = + static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex)); + + QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { + if (newBinding) newBinding->destroy(); + return 0; + } + + // This will either be a value type sub-reference or an alias to a value-type sub-reference not both + Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); + return setBindingNoEnable(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex, + newBinding); + } + } + + if (data && data->hasBindingBit(coreIndex)) { + binding = data->bindings; + + while (binding && binding->propertyIndex() != coreIndex) + binding = binding->m_nextBinding; + } + + int index = coreIndex; + if (valueTypeIndex != -1) + index |= (valueTypeIndex << 24); + + if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) + binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index); + if (binding) - binding->setEnabled(false); + binding->removeFromObject(); if (newBinding) - newBinding->setEnabled(true, flags); + newBinding->addToObject(object, index); return binding; } @@ -1392,11 +1523,26 @@ static inline int QMetaObject_methods(const QMetaObject *metaObject) int className; int classInfoCount, classInfoData; int methodCount, methodData; + int propertyCount, propertyData; }; return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount; } +static inline int QMetaObject_properties(const QMetaObject *metaObject) +{ + struct Private + { + int revision; + int className; + int classInfoCount, classInfoData; + int methodCount, methodData; + int propertyCount, propertyData; + }; + + return reinterpret_cast<const Private *>(metaObject->d.data)->propertyCount; +} + static inline void flush_vme_signal(const QObject *object, int index) { QDeclarativeData *data = static_cast<QDeclarativeData *>(QObjectPrivate::get(const_cast<QObject *>(object))->declarativeData); @@ -1437,4 +1583,19 @@ bool QDeclarativePropertyPrivate::connect(const QObject *sender, int signal_inde return QMetaObject::connect(sender, signal_index, receiver, method_index, type, types); } +/*! +Return \a metaObject's [super] meta object that provides data for \a property. +*/ +const QMetaObject *QDeclarativePropertyPrivate::metaObjectForProperty(const QMetaObject *metaObject, int property) +{ + int propertyOffset = metaObject->propertyOffset(); + + while (propertyOffset > property) { + metaObject = metaObject->d.superdata; + propertyOffset -= QMetaObject_properties(metaObject); + } + + return metaObject; +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h index a9d6979..6392f88 100644 --- a/src/declarative/qml/qdeclarativeproperty_p.h +++ b/src/declarative/qml/qdeclarativeproperty_p.h @@ -68,7 +68,7 @@ class QDeclarativeExpression; class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativePropertyPrivate { public: - enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02 }; + enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02, RemoveBindingOnAliasWrite = 0x04 }; Q_DECLARE_FLAGS(WriteFlags, WriteFlag) QDeclarativePropertyPrivate() @@ -108,9 +108,13 @@ public: const QVariant &value, int flags); static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &, QDeclarativeContextData *, WriteFlags flags = 0); + static void findAliasTarget(QObject *, int, QObject **, int *); static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */, QDeclarativeAbstractBinding *, WriteFlags flags = DontRemoveBinding); + static QDeclarativeAbstractBinding *setBindingNoEnable(QObject *, int coreIndex, int valueTypeIndex /* -1 */, + QDeclarativeAbstractBinding *); + static QDeclarativeAbstractBinding *binding(QObject *, int coreIndex, int valueTypeIndex /* -1 */); static QByteArray saveValueType(const QMetaObject *, int, const QMetaObject *, int); @@ -120,7 +124,6 @@ public: static bool equal(const QMetaObject *, const QMetaObject *); static bool canConvert(const QMetaObject *from, const QMetaObject *to); - // "Public" (to QML) methods static QDeclarativeAbstractBinding *binding(const QDeclarativeProperty &that); static QDeclarativeAbstractBinding *setBinding(const QDeclarativeProperty &that, @@ -136,6 +139,7 @@ public: static bool connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type = 0, int *types = 0); + static const QMetaObject *metaObjectForProperty(const QMetaObject *, int); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags) diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 0adcdbd..dd9a224 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -320,7 +320,6 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb { Q_ASSERT(engine); Q_ASSERT(metaObject); - QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); clear(); diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 922010d..f7c5daa 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -83,6 +83,7 @@ public: IsConstant = 0x00000001, IsWritable = 0x00000002, IsResettable = 0x00000004, + IsAlias = 0x00000008, // These are mutualy exclusive IsFunction = 0x00000010, diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index b9e9cec..5dc6ffd 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -109,36 +109,54 @@ void QDeclarativeValueTypeFactory::registerValueTypes() QDeclarativeValueType *QDeclarativeValueTypeFactory::valueType(int t) { + QDeclarativeValueType *rv = 0; + switch (t) { case QVariant::Point: - return new QDeclarativePointValueType; + rv = new QDeclarativePointValueType; + break; case QVariant::PointF: - return new QDeclarativePointFValueType; + rv = new QDeclarativePointFValueType; + break; case QVariant::Size: - return new QDeclarativeSizeValueType; + rv = new QDeclarativeSizeValueType; + break; case QVariant::SizeF: - return new QDeclarativeSizeFValueType; + rv = new QDeclarativeSizeFValueType; + break; case QVariant::Rect: - return new QDeclarativeRectValueType; + rv = new QDeclarativeRectValueType; + break; case QVariant::RectF: - return new QDeclarativeRectFValueType; + rv = new QDeclarativeRectFValueType; + break; case QVariant::Vector2D: - return new QDeclarativeVector2DValueType; + rv = new QDeclarativeVector2DValueType; + break; case QVariant::Vector3D: - return new QDeclarativeVector3DValueType; + rv = new QDeclarativeVector3DValueType; + break; case QVariant::Vector4D: - return new QDeclarativeVector4DValueType; + rv = new QDeclarativeVector4DValueType; + break; case QVariant::Quaternion: - return new QDeclarativeQuaternionValueType; + rv = new QDeclarativeQuaternionValueType; + break; case QVariant::Matrix4x4: - return new QDeclarativeMatrix4x4ValueType; + rv = new QDeclarativeMatrix4x4ValueType; + break; case QVariant::EasingCurve: - return new QDeclarativeEasingValueType; + rv = new QDeclarativeEasingValueType; + break; case QVariant::Font: - return new QDeclarativeFontValueType; + rv = new QDeclarativeFontValueType; + break; default: - return 0; + break; } + + Q_ASSERT(!rv || rv->metaObject()->propertyCount() < 32); + return rv; } QDeclarativeValueType::QDeclarativeValueType(QObject *parent) diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index db90aff..c742dec 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -154,7 +154,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); int status = -1; //for dbus - QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor; + QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor | + QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite; for (int ii = start; !isError() && ii < (start + count); ++ii) { const QDeclarativeInstruction &instr = comp->bytecode.at(ii); @@ -664,6 +665,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, break; case QDeclarativeInstruction::StoreBinding: + case QDeclarativeInstruction::StoreBindingOnAlias: { QObject *target = stack.at(stack.count() - 1 - instr.assignBinding.owner); @@ -675,14 +677,20 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, int coreIndex = mp.index(); - if (stack.count() == 1 && bindingSkipList.testBit(coreIndex)) + if ((stack.count() - instr.assignBinding.owner) == 1 && bindingSkipList.testBit(coreIndex)) break; QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, comp->name, instr.line, 0); bindValues.append(bind); bind->m_mePtr = &bindValues.values[bindValues.count - 1]; bind->setTarget(mp); - bind->addToObject(target); + + if (instr.type == QDeclarativeInstruction::StoreBindingOnAlias) { + QDeclarativeAbstractBinding *old = QDeclarativePropertyPrivate::setBindingNoEnable(target, coreIndex, QDeclarativePropertyPrivate::valueTypeCoreIndex(mp), bind); + if (old) { old->destroy(); } + } else { + bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp)); + } } break; @@ -701,7 +709,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); bindValues.append(binding); binding->m_mePtr = &bindValues.values[bindValues.count - 1]; - binding->addToObject(target); + binding->addToObject(target, property); } break; @@ -874,8 +882,26 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, case QDeclarativeInstruction::FetchValueType: { QObject *target = stack.top(); - QDeclarativeValueType *valueHandler = - ep->valueTypes[instr.fetchValue.type]; + + if (instr.fetchValue.bindingSkipList != 0) { + // Possibly need to clear bindings + QDeclarativeData *targetData = QDeclarativeData::get(target); + if (targetData) { + QDeclarativeAbstractBinding *binding = + QDeclarativePropertyPrivate::binding(target, instr.fetchValue.property, -1); + + if (binding && binding->bindingType() != QDeclarativeAbstractBinding::ValueTypeProxy) { + QDeclarativePropertyPrivate::setBinding(target, instr.fetchValue.property, -1, 0); + binding->destroy(); + } else if (binding) { + QDeclarativeValueTypeProxyBinding *proxy = + static_cast<QDeclarativeValueTypeProxyBinding *>(binding); + proxy->removeBindings(instr.fetchValue.bindingSkipList); + } + } + } + + QDeclarativeValueType *valueHandler = ep->valueTypes[instr.fetchValue.type]; valueHandler->read(target, instr.fetchValue.property); stack.push(valueHandler); } diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index e28062b..38c1709 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -46,6 +46,7 @@ #include "qdeclarativeexpression.h" #include "private/qdeclarativeexpression_p.h" #include "private/qdeclarativecontext_p.h" +#include "private/qdeclarativebinding_p.h" Q_DECLARE_METATYPE(QScriptValue); @@ -589,7 +590,21 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (d->isObjectAlias()) { *reinterpret_cast<QObject **>(a[0]) = target; return -1; - } else if (d->isValueTypeAlias()) { + } + + // Remove binding (if any) on write + if(c == QMetaObject::WriteProperty) { + int flags = *reinterpret_cast<int*>(a[3]); + if (flags & QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite) { + QDeclarativeData *targetData = QDeclarativeData::get(target); + if (targetData && targetData->hasBindingBit(d->propertyIndex())) { + QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::setBinding(target, d->propertyIndex(), d->isValueTypeAlias()?d->valueTypeIndex():-1, 0); + if (binding) binding->destroy(); + } + } + } + + if (d->isValueTypeAlias()) { // Value type property QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); @@ -821,6 +836,36 @@ void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v) return writeVarProperty(index - propOffset, v); } +bool QDeclarativeVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const +{ + Q_ASSERT(index >= propOffset + metaData->propertyCount); + + *target = 0; + *coreIndex = -1; + *valueTypeIndex = -1; + + if (!ctxt) + return false; + + QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + (index - propOffset - metaData->propertyCount); + QDeclarativeContext *context = ctxt->asQDeclarativeContext(); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context); + + *target = ctxtPriv->data->idValues[d->contextIdx].data(); + if (!*target) + return false; + + if (d->isObjectAlias()) { + } else if (d->isValueTypeAlias()) { + *coreIndex = d->propertyIndex(); + *valueTypeIndex = d->valueTypeIndex(); + } else { + *coreIndex = d->propertyIndex(); + } + + return true; +} + void QDeclarativeVMEMetaObject::connectAlias(int aliasId) { if (!aConnected.testBit(aliasId)) { diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h index 5134763..7b6b410 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject_p.h +++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h @@ -138,6 +138,7 @@ public: QDeclarativeCompiledData *compiledData); ~QDeclarativeVMEMetaObject(); + bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const; void registerInterceptor(int index, int valueIndex, QDeclarativePropertyValueInterceptor *interceptor); QScriptValue vmeMethod(int index); int vmeMethodLineNumber(int index); @@ -146,6 +147,7 @@ public: void setVMEProperty(int index, const QScriptValue &); void connectAliasSignal(int index); + protected: virtual int metaCall(QMetaObject::Call _c, int _id, void **_a); diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index 5ef568f..7c0a7f0 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -684,7 +684,7 @@ void QDeclarativePixmapStore::timerEvent(QTimerEvent *) } QDeclarativePixmapReply::QDeclarativePixmapReply(QDeclarativePixmapData *d) -: data(d), reader(0), loading(false), redirectCount(0), requestSize(d->requestSize) +: data(d), reader(0), requestSize(d->requestSize), loading(false), redirectCount(0) { if (finishedIndex == -1) { finishedIndex = QDeclarativePixmapReply::staticMetaObject.indexOfSignal("finished()"); diff --git a/src/gui/dialogs/dialogs.pri b/src/gui/dialogs/dialogs.pri index 4e1b9a7..c25b6d5 100644 --- a/src/gui/dialogs/dialogs.pri +++ b/src/gui/dialogs/dialogs.pri @@ -108,6 +108,15 @@ SOURCES += \ dialogs/qwizard.cpp \ dialogs/qprintpreviewdialog.cpp +symbian:contains(QT_CONFIG, s60) { + LIBS += -lcommondialogs + SOURCES += dialogs/qfiledialog_symbian.cpp \ + dialogs/qcolordialog_symbian.cpp +} + FORMS += dialogs/qpagesetupwidget.ui RESOURCES += dialogs/qprintdialog.qrc RESOURCES += dialogs/qmessagebox.qrc + +# Compensate for lack of platform defines in Symbian3 +symbian: DEFINES += SYMBIAN_VERSION_$$upper($$replace(SYMBIAN_VERSION,\\.,_)) diff --git a/src/gui/dialogs/qabstractprintdialog.cpp b/src/gui/dialogs/qabstractprintdialog.cpp index 25d9ebb..641419f 100644 --- a/src/gui/dialogs/qabstractprintdialog.cpp +++ b/src/gui/dialogs/qabstractprintdialog.cpp @@ -65,6 +65,9 @@ class QPrintDialogPrivate : public QAbstractPrintDialogPrivate customize settings shown in print dialogs, but it is not used directly. Use QPrintDialog to display a print dialog in your application. + In Symbian, there is no support for printing. Hence, this dialog should not + be used in Symbian. + \sa QPrintDialog, QPrinter, {Printing with Qt} */ diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp index e9b5720..a66a979 100644 --- a/src/gui/dialogs/qcolordialog.cpp +++ b/src/gui/dialogs/qcolordialog.cpp @@ -1952,6 +1952,12 @@ void QColorDialog::open(QObject *receiver, const char *member) \sa QDialog::open() */ +/* + For Symbian color dialogs +*/ +#ifdef Q_WS_S60 +extern QColor qtSymbianGetColor(const QColor &initial); +#endif /*! \since 4.5 @@ -1961,10 +1967,19 @@ void QColorDialog::open(QObject *receiver, const char *member) QColor::isValid()) color if the user cancels the dialog. The \a options argument allows you to customize the dialog. + + On Symbian, this static function will use the native color dialog and not a QColorDialog. + On Symbian the parameters \a title and \a parent has no relevance and the + \a options parameter is only used to define if the native color dialog is + used or not. */ QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title, ColorDialogOptions options) { +#ifdef Q_WS_S60 + if (!(options & DontUseNativeDialog)) + return qtSymbianGetColor(initial); +#endif QColorDialog dlg(parent); if (!title.isEmpty()) dlg.setWindowTitle(title); @@ -1979,10 +1994,16 @@ QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QStr returns that color. The color is initially set to \a initial. The dialog is a child of \a parent. It returns an invalid (see QColor::isValid()) color if the user cancels the dialog. + + On Symbian, this static function will use the native + color dialog and not a QColorDialog. */ QColor QColorDialog::getColor(const QColor &initial, QWidget *parent) { +#ifdef Q_WS_S60 + return qtSymbianGetColor(initial); +#endif return getColor(initial, parent, QString(), ColorDialogOptions(0)); } diff --git a/src/gui/dialogs/qcolordialog_symbian.cpp b/src/gui/dialogs/qcolordialog_symbian.cpp new file mode 100644 index 0000000..8f73f7c --- /dev/null +++ b/src/gui/dialogs/qcolordialog_symbian.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcolordialog_p.h" + +#ifndef QT_NO_COLORDIALOG + + +#include "qcolor.h" +#include "private/qguiplatformplugin_p.h" + +#ifdef Q_WS_S60 +#include <AknColourSelectionGrid.h> +#endif + +#include "private/qt_s60_p.h" + +QT_BEGIN_NAMESPACE + +QColor launchSymbianColorDialog(QColor initial) +{ + QColor currentColor = QColor::Invalid; +#ifdef Q_WS_S60 + QT_TRAP_THROWING( + CArrayFixFlat<TRgb>* array = new( ELeave ) CArrayFixFlat<TRgb>(17); + CleanupStack::PushL(array); + array->AppendL(KRgbBlack); + array->AppendL(KRgbDarkGray); + array->AppendL(KRgbDarkRed); + array->AppendL(KRgbDarkGreen); + array->AppendL(KRgbDarkYellow); + array->AppendL(KRgbDarkBlue); + array->AppendL(KRgbDarkMagenta); + array->AppendL(KRgbDarkCyan); + array->AppendL(KRgbRed); + array->AppendL(KRgbGreen); + array->AppendL(KRgbYellow); + array->AppendL(KRgbBlue); + array->AppendL(KRgbMagenta); + array->AppendL(KRgbCyan); + array->AppendL(KRgbGray); + array->AppendL(KRgbWhite); + + TRgb initialColour(initial.red(), initial.green(), initial.blue(), initial.alpha()); + + TBool noneChosen = EFalse; // If true shows the default colour button + CAknColourSelectionGrid* colourSelectionGrid = + CAknColourSelectionGrid::NewL(array, EFalse, noneChosen, initialColour); + CleanupStack::PushL(colourSelectionGrid); + + if (colourSelectionGrid->ExecuteLD()) { + currentColor.setRgb(initialColour.Red(), initialColour.Green(), + initialColour.Blue(), initialColour.Alpha()); + } + CleanupStack::Pop(colourSelectionGrid); + CleanupStack::PopAndDestroy(array); + ); +#endif + return currentColor; +} + +QColor qtSymbianGetColor(const QColor &initial) +{ + return launchSymbianColorDialog(initial); +} + +QT_END_NAMESPACE + +#endif // QT_NO_COLORDIALOG diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index b7a0026..fbdc522 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -282,8 +282,8 @@ QDialog::QDialog(QWidget *parent, Qt::WindowFlags f) QDialog::QDialog(QWidget *parent, const char *name, bool modal, Qt::WindowFlags f) : QWidget(*new QDialogPrivate, parent, f - | QFlag(modal ? Qt::WShowModal : 0) - | QFlag((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : 0) + | QFlag(modal ? Qt::WShowModal : Qt::WindowType(0)) + | QFlag((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)) ) { setObjectName(QString::fromAscii(name)); diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index fc3c186..f3f7469 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -1616,6 +1616,25 @@ extern QStringList qt_win_get_open_file_names(const QFileDialogArgs &args, extern QString qt_win_get_existing_directory(const QFileDialogArgs &args); #endif +/* + For Symbian file dialogs +*/ +#if defined(Q_WS_S60) +extern QString qtSymbianGetOpenFileName(const QString &caption, + const QString &dir, + const QString &filter); + +extern QStringList qtSymbianGetOpenFileNames(const QString &caption, + const QString &dir, + const QString &filter); + +extern QString qtSymbianGetSaveFileName(const QString &caption, + const QString &dir); + +extern QString qtSymbianGetExistingDirectory(const QString &caption, + const QString &dir); +#endif + /*! This is a convenience static function that returns an existing file selected by the user. If the user presses Cancel, it returns a null string. @@ -1644,8 +1663,8 @@ extern QString qt_win_get_existing_directory(const QFileDialogArgs &args); The dialog's caption is set to \a caption. If \a caption is not specified then a default caption will be used. - On Windows and Mac OS X, this static function will use the native file - dialog and not a QFileDialog. + On Windows, Mac OS X and Symbian^3, this static function will use the + native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not dispatch any QTimers, and if \a parent is not 0 then it will position the @@ -1657,6 +1676,10 @@ extern QString qt_win_get_existing_directory(const QFileDialogArgs &args); \a options includes DontResolveSymlinks, the file dialog will treat symlinks as regular directories. + On Symbian^3 the parameter \a selectedFilter has no meaning and the + \a options parameter is only used to define if the native file dialog is + used. + \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog yourself using one of the QFileDialog constructors. @@ -1672,6 +1695,10 @@ QString QFileDialog::getOpenFileName(QWidget *parent, { if (qt_filedialog_open_filename_hook && !(options & DontUseNativeDialog)) return qt_filedialog_open_filename_hook(parent, caption, dir, filter, selectedFilter, options); +#if defined(Q_WS_S60) + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog)) + return qtSymbianGetOpenFileName(caption, dir, filter); +#endif QFileDialogArgs args; args.parent = parent; args.caption = caption; @@ -1722,8 +1749,8 @@ QString QFileDialog::getOpenFileName(QWidget *parent, The dialog's caption is set to \a caption. If \a caption is not specified then a default caption will be used. - On Windows and Mac OS X, this static function will use the native file - dialog and not a QFileDialog. + On Windows, Mac OS X and Symbian^3, this static function will use the + native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not dispatch any QTimers, and if \a parent is not 0 then it will position the @@ -1741,6 +1768,10 @@ QString QFileDialog::getOpenFileName(QWidget *parent, \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 10 + On Symbian^3 the parameter \a selectedFilter has no meaning and the + \a options parameter is only used to define if the native file dialog is + used. + \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog yourself using one of the QFileDialog constructors. @@ -1756,6 +1787,10 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, { if (qt_filedialog_open_filenames_hook && !(options & DontUseNativeDialog)) return qt_filedialog_open_filenames_hook(parent, caption, dir, filter, selectedFilter, options); +#if defined(Q_WS_S60) + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog)) + return qtSymbianGetOpenFileNames(caption, dir, filter); +#endif QFileDialogArgs args; args.parent = parent; args.caption = caption; @@ -1813,8 +1848,8 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, The dialog's caption is set to \a caption. If \a caption is not specified, a default caption will be used. - On Windows and Mac OS X, this static function will use the native file - dialog and not a QFileDialog. + On Windows, Mac OS X and Symbian^3, this static function will use the + native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not dispatch any QTimers, and if \a parent is not 0 then it will position the @@ -1827,6 +1862,10 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, \a options includes DontResolveSymlinks the file dialog will treat symlinks as regular directories. + On Symbian^3 the parameters \a filter and \a selectedFilter have no + meaning. The \a options parameter is only used to define if the native file + dialog is used. + \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog yourself using one of the QFileDialog constructors. @@ -1842,6 +1881,10 @@ QString QFileDialog::getSaveFileName(QWidget *parent, { if (qt_filedialog_save_filename_hook && !(options & DontUseNativeDialog)) return qt_filedialog_save_filename_hook(parent, caption, dir, filter, selectedFilter, options); +#if defined(Q_WS_S60) + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog)) + return qtSymbianGetSaveFileName(caption, dir); +#endif QFileDialogArgs args; args.parent = parent; args.caption = caption; @@ -1890,9 +1933,9 @@ QString QFileDialog::getSaveFileName(QWidget *parent, pass. To ensure a native file dialog, \l{QFileDialog::}{ShowDirsOnly} must be set. - On Windows and Mac OS X, this static function will use the native file - dialog and not a QFileDialog. On Windows CE, if the device has no native - file dialog, a QFileDialog will be used. + On Windows, Mac OS X and Symbian^3, this static function will use the + native file dialog and not a QFileDialog. On Windows CE, if the device has + no native file dialog, a QFileDialog will be used. On Unix/X11, the normal behavior of the file dialog is to resolve and follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp}, @@ -1904,6 +1947,9 @@ QString QFileDialog::getSaveFileName(QWidget *parent, dispatch any QTimers, and if \a parent is not 0 then it will position the dialog just below the parent's title bar. + On Symbian^3 the \a options parameter is only used to define if the native + file dialog is used. + \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog yourself using one of the QFileDialog constructors. @@ -1917,6 +1963,10 @@ QString QFileDialog::getExistingDirectory(QWidget *parent, { if (qt_filedialog_existing_directory_hook && !(options & DontUseNativeDialog)) return qt_filedialog_existing_directory_hook(parent, caption, dir, options); +#if defined(Q_WS_S60) + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog)) + return qtSymbianGetExistingDirectory(caption, dir); +#endif QFileDialogArgs args; args.parent = parent; args.caption = caption; diff --git a/src/gui/dialogs/qfiledialog_symbian.cpp b/src/gui/dialogs/qfiledialog_symbian.cpp new file mode 100644 index 0000000..1f70305 --- /dev/null +++ b/src/gui/dialogs/qfiledialog_symbian.cpp @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfiledialog.h" + +#ifndef QT_NO_FILEDIALOG + +#include <private/qfiledialog_p.h> +#if defined(Q_WS_S60) && defined(SYMBIAN_VERSION_SYMBIAN3) +#include <driveinfo.h> +#include <AknCommonDialogsDynMem.h> +#include <CAknMemorySelectionDialogMultiDrive.h> +#include <MAknFileFilter.h> +#endif +#include "private/qcore_symbian_p.h" + +QT_BEGIN_NAMESPACE + +enum DialogMode { DialogOpen, DialogSave, DialogFolder }; +#if defined(Q_WS_S60) && defined(SYMBIAN_VERSION_SYMBIAN3) +class CExtensionFilter : public MAknFileFilter +{ +public: + void setFilter(const QString filter) + { + filterList.clear(); + if (filter.left(2) == QLatin1String("*.")) { + //Filter has only extensions + filterList << filter.split(" "); + return; + } else { + //Extensions are in parenthesis and there may be several filters + QStringList separatedFilters(filter.split(QLatin1String(";;"))); + for (int i = 0; i < separatedFilters.size(); i++) { + if (separatedFilters.at(i).contains(QLatin1String("(*)"))) { + filterList << QLatin1String("(*)"); + return; + } + } + QRegExp rx("\\(([^\\)]*)\\)"); + int pos = 0; + while ((pos = rx.indexIn(filter, pos)) != -1) { + filterList << rx.cap(1).split(QLatin1String(" ")); + pos += rx.matchedLength(); + } + } + } + + TBool Accept(const TDesC &/*aDriveAndPath*/, const TEntry &aEntry) const + { + if (aEntry.IsDir()) + return ETrue; + + //If no filter for files, all can be accepted + if (filterList.isEmpty()) + return ETrue; + + if (filterList == QStringList(QLatin1String("(*)"))) + return ETrue; + + for (int i = 0; i < filterList.size(); ++i) { + QString extension = filterList.at(i); + //remove '*' from the beginning of the extension + if (extension.at(0) == QLatin1Char('*')) + extension = extension.mid(1); + + QString fileName = qt_TDesC2QString(aEntry.iName); + if (fileName.endsWith(extension)) + return ETrue; + } + return EFalse; + } + +private: + QStringList filterList; +}; +#endif + +static QString launchSymbianDialog(const QString dialogCaption, const QString startDirectory, + const QString filter, DialogMode dialogMode) +{ + QString selection; +#if defined(Q_WS_S60) && defined(SYMBIAN_VERSION_SYMBIAN3) + QT_TRAP_THROWING( + TFileName startFolder; + if (!startDirectory.isEmpty()) { + QString dir = QDir::toNativeSeparators(startDirectory); + startFolder = qt_QString2TPtrC(dir); + } + TInt types = AknCommonDialogsDynMem::EMemoryTypeMMCExternal| + AknCommonDialogsDynMem::EMemoryTypeInternalMassStorage| + AknCommonDialogsDynMem::EMemoryTypePhone; + + TPtrC titlePtr(qt_QString2TPtrC(dialogCaption)); + TFileName target; + bool select = false; + if (dialogMode == DialogOpen) { + CExtensionFilter* extensionFilter = new (ELeave) CExtensionFilter; + CleanupStack::PushL(extensionFilter); + extensionFilter->setFilter(filter); + select = AknCommonDialogsDynMem::RunSelectDlgLD(types, target, + startFolder, NULL, NULL, titlePtr, extensionFilter); + CleanupStack::Pop(extensionFilter); + } else if (dialogMode == DialogSave) { + select = AknCommonDialogsDynMem::RunSaveDlgLD(types, target, + startFolder, NULL, NULL, titlePtr); + } else if (dialogMode == DialogFolder) { + select = AknCommonDialogsDynMem::RunFolderSelectDlgLD(types, target, startFolder, + 0, 0, titlePtr, NULL, NULL); + } + if (select) + selection.append(qt_TDesC2QString(target)); + ); +#endif + return selection; +} + +QString qtSymbianGetOpenFileName(const QString &caption, + const QString &dir, + const QString &filter) +{ + return launchSymbianDialog(caption, dir, filter, DialogOpen); +} + +QStringList qtSymbianGetOpenFileNames(const QString &caption, + const QString &dir, + const QString &filter) +{ + QString fileName; + fileName.append(launchSymbianDialog(caption, dir, filter, DialogOpen)); + QStringList fileList; + fileList << fileName; + + return fileList; +} + +QString qtSymbianGetSaveFileName(const QString &caption, + const QString &dir) +{ + return launchSymbianDialog(caption, dir, QString(), DialogSave); +} + +QString qtSymbianGetExistingDirectory(const QString &caption, + const QString &dir) +{ + QString folderCaption; + if (!caption.isEmpty()) { + folderCaption.append(caption); + } else { + // Title for folder selection dialog is mandatory + folderCaption.append(QFileDialog::tr("Find Directory")); + } + return launchSymbianDialog(folderCaption, dir, QString(), DialogFolder); +} + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index fe25b0f..2f8b9e2 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -776,10 +776,8 @@ QMessageBox::QMessageBox(QWidget *parent) added at any time using addButton(). The \a parent and \a f arguments are passed to the QDialog constructor. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. On Mac OS X, if \a parent is not 0 and you want your message box to appear as a Qt::Sheet of that parent, set the message box's @@ -1549,10 +1547,8 @@ static QMessageBox::StandardButton showNewMessageBox(QWidget *parent, \key Esc was pressed instead, the \l{Default and Escape Keys} {escape button} is returned. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \sa question(), warning(), critical() */ @@ -1579,10 +1575,8 @@ QMessageBox::StandardButton QMessageBox::information(QWidget *parent, const QStr \key Esc was pressed instead, the \l{Default and Escape Keys} {escape button} is returned. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \sa information(), warning(), critical() */ @@ -1607,10 +1601,8 @@ QMessageBox::StandardButton QMessageBox::question(QWidget *parent, const QString \key Esc was pressed instead, the \l{Default and Escape Keys} {escape button} is returned. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \sa question(), information(), critical() */ @@ -1635,10 +1627,8 @@ QMessageBox::StandardButton QMessageBox::warning(QWidget *parent, const QString \key Esc was pressed instead, the \l{Default and Escape Keys} {escape button} is returned. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog @@ -1670,7 +1660,7 @@ QMessageBox::StandardButton QMessageBox::critical(QWidget *parent, const QString The about box has a single button labelled "OK". On Mac OS X, the about box is popped up as a modeless window; on other platforms, - it is currently a window modal. + it is currently application modal. \sa QWidget::windowIcon(), QApplication::activeWindow() */ @@ -1723,7 +1713,7 @@ void QMessageBox::about(QWidget *parent, const QString &title, const QString &te QApplication provides this functionality as a slot. On Mac OS X, the about box is popped up as a modeless window; on - other platforms, it is currently window modal. + other platforms, it is currently application modal. \sa QApplication::aboutQt() */ @@ -1983,10 +1973,8 @@ void QMessageBoxPrivate::retranslateStrings() \snippet doc/src/snippets/dialogs/dialogs.cpp 2 - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. The \a parent and \a f arguments are passed to the QDialog constructor. @@ -2035,10 +2023,8 @@ QMessageBox::QMessageBox(const QString &title, const QString &text, Icon icon, Returns the identity (QMessageBox::Ok, or QMessageBox::No, etc.) of the button that was clicked. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog @@ -2073,10 +2059,8 @@ int QMessageBox::information(QWidget *parent, const QString &title, const QStrin supply 0, 1 or 2 to make pressing \key Esc equivalent to clicking the relevant button. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog @@ -2125,10 +2109,8 @@ int QMessageBox::information(QWidget *parent, const QString &title, const QStrin Returns the identity (QMessageBox::Yes, or QMessageBox::No, etc.) of the button that was clicked. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog @@ -2163,10 +2145,8 @@ int QMessageBox::question(QWidget *parent, const QString &title, const QString& supply 0, 1 or 2 to make pressing Escape equivalent to clicking the relevant button. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog @@ -2215,10 +2195,8 @@ int QMessageBox::question(QWidget *parent, const QString &title, const QString& Returns the identity (QMessageBox::Ok or QMessageBox::No or ...) of the button that was clicked. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog @@ -2253,10 +2231,8 @@ int QMessageBox::warning(QWidget *parent, const QString &title, const QString& t supply 0, 1, or 2 to make pressing Escape equivalent to clicking the relevant button. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog @@ -2304,10 +2280,8 @@ int QMessageBox::warning(QWidget *parent, const QString &title, const QString& t Returns the identity (QMessageBox::Ok, or QMessageBox::No, etc.) of the button that was clicked. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog @@ -2343,10 +2317,8 @@ int QMessageBox::critical(QWidget *parent, const QString &title, const QString& supply 0, 1, or 2 to make pressing Escape equivalent to clicking the relevant button. - If \a parent is 0, the message box is an \l{Qt::ApplicationModal} - {application modal} dialog box. If \a parent is a widget, the - message box is \l{Qt::WindowModal} {window modal} relative to \a - parent. + The message box is an \l{Qt::ApplicationModal} {application modal} + dialog box. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog diff --git a/src/gui/dialogs/qpagesetupdialog.cpp b/src/gui/dialogs/qpagesetupdialog.cpp index 5d77de1..b5be942 100644 --- a/src/gui/dialogs/qpagesetupdialog.cpp +++ b/src/gui/dialogs/qpagesetupdialog.cpp @@ -62,6 +62,9 @@ QT_BEGIN_NAMESPACE page margins set on a QPrinter won't show in the native Mac OS X page setup dialog. + In Symbian, there is no support for printing. Hence, this dialog should not + be used in Symbian. + \sa QPrinter, QPrintDialog */ diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp index f21343e..d74742a 100644 --- a/src/gui/dialogs/qprintpreviewdialog.cpp +++ b/src/gui/dialogs/qprintpreviewdialog.cpp @@ -676,6 +676,8 @@ void QPrintPreviewDialogPrivate::_q_zoomFactorChanged() Call QPrintPreviewDialog::exec() to show the preview dialog. \endlist + In Symbian, there is no support for printing. Hence, this dialog should not + be used in Symbian. \sa QPrinter, QPrintDialog, QPageSetupDialog, QPrintPreviewWidget */ diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 15cc109..29415ed 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -165,8 +165,10 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) if (chosenVisualInfo) { // Skip size checks if implementation supports non-matching visual // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444). - if (QEgl::hasExtension("EGL_NV_post_convert_rounding")) + if (QEgl::hasExtension("EGL_NV_post_convert_rounding")) { + XFree(chosenVisualInfo); return visualId; + } int visualRedSize = countBits(chosenVisualInfo->red_mask); int visualGreenSize = countBits(chosenVisualInfo->green_mask); diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp index 3fc7f10..20ebab6 100644 --- a/src/gui/graphicsview/qgraphicsgridlayout.cpp +++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp @@ -64,6 +64,17 @@ removeAt() will remove an item from the layout, without destroying it. + \section1 Size Hints and Size Policies in QGraphicsGridLayout + + QGraphicsGridLayout respects each item's size hints and size policies, + and when a cell in the grid has more space than the items can fill, each item + is arranged according to the layout's alignment for that item. You can set + an alignment for each item by calling setAlignment(), and check the + alignment for any item by calling alignment(). You can also set the alignment + for an entire row or column by calling setRowAlignment() and setColumnAlignment() + respectively. By default, items are aligned to the top left. + + \sa QGraphicsLinearLayout, QGraphicsWidget */ diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index e43f7fa..016cfbf 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.cpp +++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp @@ -137,19 +137,28 @@ void QGraphicsLayoutItemPrivate::init() QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint) const { Q_Q(const QGraphicsLayoutItem); - if (!sizeHintCacheDirty && cachedConstraint == constraint) - return cachedSizeHints; + QSizeF *sizeHintCache; + const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0; + if (hasConstraint) { + if (!sizeHintWithConstraintCacheDirty && constraint == cachedConstraint) + return cachedSizeHintsWithConstraints; + sizeHintCache = cachedSizeHintsWithConstraints; + } else { + if (!sizeHintCacheDirty) + return cachedSizeHints; + sizeHintCache = cachedSizeHints; + } for (int i = 0; i < Qt::NSizeHints; ++i) { - cachedSizeHints[i] = constraint; + sizeHintCache[i] = constraint; if (userSizeHints) - combineSize(cachedSizeHints[i], userSizeHints[i]); + combineSize(sizeHintCache[i], userSizeHints[i]); } - QSizeF &minS = cachedSizeHints[Qt::MinimumSize]; - QSizeF &prefS = cachedSizeHints[Qt::PreferredSize]; - QSizeF &maxS = cachedSizeHints[Qt::MaximumSize]; - QSizeF &descentS = cachedSizeHints[Qt::MinimumDescent]; + QSizeF &minS = sizeHintCache[Qt::MinimumSize]; + QSizeF &prefS = sizeHintCache[Qt::PreferredSize]; + QSizeF &maxS = sizeHintCache[Qt::MaximumSize]; + QSizeF &descentS = sizeHintCache[Qt::MinimumDescent]; normalizeHints(minS.rwidth(), prefS.rwidth(), maxS.rwidth(), descentS.rwidth()); normalizeHints(minS.rheight(), prefS.rheight(), maxS.rheight(), descentS.rheight()); @@ -175,9 +184,13 @@ QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint) // Not supported yet // COMBINE_SIZE(descentS, q->sizeHint(Qt::MinimumDescent, constraint)); - cachedConstraint = constraint; - sizeHintCacheDirty = false; - return cachedSizeHints; + if (hasConstraint) { + cachedConstraint = constraint; + sizeHintWithConstraintCacheDirty = false; + } else { + sizeHintCacheDirty = false; + } + return sizeHintCache; } diff --git a/src/gui/graphicsview/qgraphicslayoutitem_p.h b/src/gui/graphicsview/qgraphicslayoutitem_p.h index b752e03..d72ee9f 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem_p.h +++ b/src/gui/graphicsview/qgraphicslayoutitem_p.h @@ -85,8 +85,10 @@ public: QSizeF *userSizeHints; mutable QSizeF cachedSizeHints[Qt::NSizeHints]; mutable QSizeF cachedConstraint; + mutable QSizeF cachedSizeHintsWithConstraints[Qt::NSizeHints]; mutable quint32 sizeHintCacheDirty : 1; + mutable quint32 sizeHintWithConstraintCacheDirty : 1; quint32 isLayout : 1; quint32 ownedByLayout : 1; diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 7e8d19f..244a728 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -75,7 +75,7 @@ is arranged according to the layout's alignment for that item. You can set an alignment for each item by calling setAlignment(), and check the alignment for any item by calling alignment(). By default, items are - centered both vertically and horizontally. + aligned to the top left. \section1 Spacing within QGraphicsLinearLayout @@ -446,7 +446,7 @@ void QGraphicsLinearLayout::setAlignment(QGraphicsLayoutItem *item, Qt::Alignmen /*! Returns the alignment for \a item. The default alignment is - Qt::AlignCenter. + Qt::AlignTop | Qt::AlignLeft. The alignment decides how the item is positioned within its assigned space in the case where there's more space available in the layout than the diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index e486b4d..f1055ba 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -166,7 +166,7 @@ void QGridLayoutRowData::reset(int count) hasIgnoreFlag = false; } -void QGridLayoutRowData::distributeMultiCells() +void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo) { MultiCellMap::const_iterator i = multiCellMap.constBegin(); for (; i != multiCellMap.constEnd(); ++i) { @@ -185,7 +185,7 @@ void QGridLayoutRowData::distributeMultiCells() qreal extra = compare(box, totalBox, j); if (extra > 0.0) { calculateGeometries(start, end, box.q_sizes(j), dummy.data(), newSizes.data(), - 0, totalBox); + 0, totalBox, rowInfo); for (int k = 0; k < span; ++k) extras[k].q_sizes(j) = newSizes[k]; @@ -202,11 +202,12 @@ void QGridLayoutRowData::distributeMultiCells() void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSize, qreal *positions, qreal *sizes, qreal *descents, - const QGridLayoutBox &totalBox) + const QGridLayoutBox &totalBox, + const QGridLayoutRowInfo &rowInfo) { Q_ASSERT(end > start); - targetSize = qBound(totalBox.q_minimumSize, targetSize, totalBox.q_maximumSize); + targetSize = qMax(totalBox.q_minimumSize, targetSize); int n = end - start; QVarLengthArray<qreal> newSizes(n); @@ -246,16 +247,22 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz } } } else { - stealBox(start, end, PreferredSize, positions, sizes); + bool isLargerThanMaximum = (targetSize > totalBox.q_maximumSize); + if (isLargerThanMaximum) { + stealBox(start, end, MaximumSize, positions, sizes); + sumAvailable = targetSize - totalBox.q_maximumSize; + } else { + stealBox(start, end, PreferredSize, positions, sizes); + sumAvailable = targetSize - totalBox.q_preferredSize; + } - sumAvailable = targetSize - totalBox.q_preferredSize; if (sumAvailable > 0.0) { qreal sumCurrentAvailable = sumAvailable; bool somethingHasAMaximumSize = false; - qreal sumPreferredSizes = 0.0; + qreal sumSizes = 0.0; for (int i = 0; i < n; ++i) - sumPreferredSizes += sizes[i]; + sumSizes += sizes[i]; for (int i = 0; i < n; ++i) { if (ignore.testBit(start + i)) { @@ -265,7 +272,16 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz } const QGridLayoutBox &box = boxes.at(start + i); - qreal desired = box.q_maximumSize - box.q_preferredSize; + qreal boxSize; + + qreal desired; + if (isLargerThanMaximum) { + boxSize = box.q_maximumSize; + desired = rowInfo.boxes.value(start + i).q_maximumSize - boxSize; + } else { + boxSize = box.q_preferredSize; + desired = box.q_maximumSize - boxSize; + } if (desired == 0.0) { newSizes[i] = sizes[i]; factors[i] = 0.0; @@ -284,17 +300,17 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz } else if (stretch <= 0) { factors[i] = 0.0; } else { - qreal ultimatePreferredSize; - qreal ultimateSumPreferredSizes; - qreal x = ((stretch * sumPreferredSizes) - - (sumStretches * box.q_preferredSize)) + qreal ultimateSize; + qreal ultimateSumSizes; + qreal x = ((stretch * sumSizes) + - (sumStretches * boxSize)) / (sumStretches - stretch); if (x >= 0.0) { - ultimatePreferredSize = box.q_preferredSize + x; - ultimateSumPreferredSizes = sumPreferredSizes + x; + ultimateSize = boxSize + x; + ultimateSumSizes = sumSizes + x; } else { - ultimatePreferredSize = box.q_preferredSize; - ultimateSumPreferredSizes = (sumStretches * box.q_preferredSize) + ultimateSize = boxSize; + ultimateSumSizes = (sumStretches * boxSize) / stretch; } @@ -303,17 +319,17 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz (at the expense of the stretch factors, which are not fully respected during the transition). */ - ultimatePreferredSize = ultimatePreferredSize * 3 / 2; - ultimateSumPreferredSizes = ultimateSumPreferredSizes * 3 / 2; + ultimateSize = ultimateSize * 3 / 2; + ultimateSumSizes = ultimateSumSizes * 3 / 2; - qreal beta = ultimateSumPreferredSizes - sumPreferredSizes; + qreal beta = ultimateSumSizes - sumSizes; if (!beta) { factors[i] = 1; } else { qreal alpha = qMin(sumCurrentAvailable, beta); - qreal ultimateFactor = (stretch * ultimateSumPreferredSizes / sumStretches) - - (box.q_preferredSize); - qreal transitionalFactor = sumCurrentAvailable * (ultimatePreferredSize - box.q_preferredSize) / beta; + qreal ultimateFactor = (stretch * ultimateSumSizes / sumStretches) + - (boxSize); + qreal transitionalFactor = sumCurrentAvailable * (ultimateSize - boxSize) / beta; factors[i] = ((alpha * ultimateFactor) + ((beta - alpha) * transitionalFactor)) / beta; @@ -336,11 +352,16 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz if (newSizes[i] >= 0.0) continue; - const QGridLayoutBox &box = boxes.at(start + i); + qreal maxBoxSize; + if (isLargerThanMaximum) + maxBoxSize = rowInfo.boxes.value(start + i).q_maximumSize; + else + maxBoxSize = boxes.at(start + i).q_maximumSize; + qreal avail = sumCurrentAvailable * factors[i] / sumFactors; - if (sizes[i] + avail >= box.q_maximumSize) { - newSizes[i] = box.q_maximumSize; - sumCurrentAvailable -= box.q_maximumSize - sizes[i]; + if (sizes[i] + avail >= maxBoxSize) { + newSizes[i] = maxBoxSize; + sumCurrentAvailable -= maxBoxSize - sizes[i]; sumFactors -= factors[i]; keepGoing = (sumCurrentAvailable > 0.0); if (!keepGoing) @@ -637,7 +658,7 @@ QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal heig if (dynamicConstraintOrientation() == Qt::Vertical) { if (size.width() > cellWidth) size = effectiveMaxSize(QSizeF(cellWidth, -1)); - } else if(size.height() > cellHeight) { + } else if (size.height() > cellHeight) { size = effectiveMaxSize(QSizeF(-1, cellHeight)); } } @@ -1107,63 +1128,58 @@ QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHi { QGridLayoutBox sizehint_totalBoxes[NOrientations]; - if(rowCount() < 1 || columnCount() < 1 || !hasDynamicConstraint()) { + bool sizeHintCalculated = false; + + if (hasDynamicConstraint() && rowCount() > 0 && columnCount() > 0) { + if (constraintOrientation() == Qt::Vertical) { + //We have items whose height depends on their width + if (constraint.width() >= 0) { + if (q_cachedDataForStyleInfo != styleInfo) + ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); + else + sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; + QVector<qreal> sizehint_xx; + QVector<qreal> sizehint_widths; + + sizehint_xx.resize(columnCount()); + sizehint_widths.resize(columnCount()); + qreal width = constraint.width(); + //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as + //constraints to find the row heights + q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(), + 0, sizehint_totalBoxes[Hor], q_infos[Hor]); + ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical); + sizeHintCalculated = true; + } + } else { + if (constraint.height() >= 0) { + //We have items whose width depends on their height + ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); + QVector<qreal> sizehint_yy; + QVector<qreal> sizehint_heights; + + sizehint_yy.resize(rowCount()); + sizehint_heights.resize(rowCount()); + qreal height = constraint.height(); + //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as + //constraints to find the column widths + q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(), + 0, sizehint_totalBoxes[Ver], q_infos[Ver]); + ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, sizehint_yy.data(), sizehint_heights.data(), Qt::Vertical); + sizeHintCalculated = true; + } + } + } + + if (!sizeHintCalculated) { //No items with height for width, so it doesn't matter which order we do these in - if(q_cachedDataForStyleInfo != styleInfo) { + if (q_cachedDataForStyleInfo != styleInfo) { ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); } else { sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; sizehint_totalBoxes[Ver] = q_totalBoxes[Ver]; } - } else if(constraintOrientation() == Qt::Vertical) { - //We have items whose width depends on their height - if(q_cachedDataForStyleInfo != styleInfo) - ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); - else - sizehint_totalBoxes[Hor] = q_totalBoxes[Hor]; - QVector<qreal> sizehint_xx; - QVector<qreal> sizehint_widths; - - sizehint_xx.resize(columnCount()); - sizehint_widths.resize(columnCount()); - qreal width = constraint.width(); - if(width < 0) { - /* It's not obvious what the behaviour should be. */ -/* if(which == Qt::MaximumSize) - width = sizehint_totalBoxes[Hor].q_maximumSize; - else if(which == Qt::MinimumSize) - width = sizehint_totalBoxes[Hor].q_minimumSize; - else*/ - width = sizehint_totalBoxes[Hor].q_preferredSize; - } - //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as - //constraints to find the row heights - q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(), - 0, sizehint_totalBoxes[Hor]); - ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical); - } else { - //We have items whose height depends on their width - ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); - QVector<qreal> sizehint_yy; - QVector<qreal> sizehint_heights; - - sizehint_yy.resize(rowCount()); - sizehint_heights.resize(rowCount()); - qreal height = constraint.height(); - if(height < 0) { -/* if(which == Qt::MaximumSize) - height = sizehint_totalBoxes[Ver].q_maximumSize; - else if(which == Qt::MinimumSize) - height = sizehint_totalBoxes[Ver].q_minimumSize; - else*/ - height = sizehint_totalBoxes[Ver].q_preferredSize; - } - //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as - //constraints to find the column widths - q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(), - 0, sizehint_totalBoxes[Ver]); - ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, sizehint_yy.data(), sizehint_heights.data(), Qt::Vertical); } switch (which) { @@ -1622,7 +1638,8 @@ void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGri { rowData->reset(rowCount(orientation)); fillRowData(rowData, styleInfo, colPositions, colSizes, orientation); - rowData->distributeMultiCells(); + const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; + rowData->distributeMultiCells(rowInfo); *totalBox = rowData->totalBox(0, rowCount(orientation)); //We have items whose width depends on their height } @@ -1685,28 +1702,28 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, q_heights.resize(rowCount()); q_descents.resize(rowCount()); - if(constraintOrientation() != Qt::Horizontal) { + if (constraintOrientation() != Qt::Horizontal) { //We might have items whose width depends on their height ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal); //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as //constraints to find the row heights q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), - 0, q_totalBoxes[Hor]); + 0, q_totalBoxes[Hor], q_infos[Hor] ); ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, q_xx.data(), q_widths.data(), Qt::Vertical); //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), - q_descents.data(), q_totalBoxes[Ver]); + q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); } else { //We have items whose height depends on their width ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical); //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as //constraints to find the column widths q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), - q_descents.data(), q_totalBoxes[Ver]); + q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, q_yy.data(), q_heights.data(), Qt::Horizontal); //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), - 0, q_totalBoxes[Hor]); + 0, q_totalBoxes[Hor], q_infos[Hor]); } } diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h index 02c74b0..44efbba 100644 --- a/src/gui/graphicsview/qgridlayoutengine_p.h +++ b/src/gui/graphicsview/qgridlayoutengine_p.h @@ -224,13 +224,16 @@ public: typedef QMap<QPair<int, int>, QGridLayoutMultiCellData> MultiCellMap; +class QGridLayoutRowInfo; + class QGridLayoutRowData { public: void reset(int count); - void distributeMultiCells(); + void distributeMultiCells(const QGridLayoutRowInfo &rowInfo); void calculateGeometries(int start, int end, qreal targetSize, qreal *positions, qreal *sizes, - qreal *descents, const QGridLayoutBox &totalBox); + qreal *descents, const QGridLayoutBox &totalBox, + const QGridLayoutRowInfo &rowInfo); QGridLayoutBox totalBox(int start, int end) const; void stealBox(int start, int end, int which, qreal *positions, qreal *sizes); diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 7b81761..acc8deb 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -827,7 +827,7 @@ QVariant QAbstractItemView::inputMethodQuery(Qt::InputMethodQuery query) const deleted. QAbstractItemView does not take ownership of \a delegate. \note If a delegate has been assigned to both a row and a column, the row - delegate (i.e., this delegate) will take presedence and manage the + delegate (i.e., this delegate) will take precedence and manage the intersecting cell index. \warning You should not share the same instance of a delegate between views. @@ -885,7 +885,7 @@ QAbstractItemDelegate *QAbstractItemView::itemDelegateForRow(int row) const deleted. QAbstractItemView does not take ownership of \a delegate. \note If a delegate has been assigned to both a row and a column, the row - delegate will take presedence and manage the intersecting cell index. + delegate will take precedence and manage the intersecting cell index. \warning You should not share the same instance of a delegate between views. Doing so can cause incorrect or unintuitive editing behavior since each diff --git a/src/gui/itemviews/qstandarditemmodel.cpp b/src/gui/itemviews/qstandarditemmodel.cpp index 767b5a9..7d20bbb 100644 --- a/src/gui/itemviews/qstandarditemmodel.cpp +++ b/src/gui/itemviews/qstandarditemmodel.cpp @@ -1130,7 +1130,7 @@ Qt::ItemFlags QStandardItem::flags() const meaning that the user can interact with the item; if \a enabled is false, the user cannot interact with the item. - This flag takes presedence over the other item flags; e.g. if an item is not + This flag takes precedence over the other item flags; e.g. if an item is not enabled, it cannot be selected by the user, even if the Qt::ItemIsSelectable flag has been set. diff --git a/src/gui/kernel/qsound_s60.cpp b/src/gui/kernel/qsound_s60.cpp index df2830b..accfce2 100644 --- a/src/gui/kernel/qsound_s60.cpp +++ b/src/gui/kernel/qsound_s60.cpp @@ -150,7 +150,7 @@ void QAuServerS60::playCompleted(QAuBucketS60 *bucket, int error) } else { // We don't have a way to inform about errors -> just decrement loops // in order that QSound::isFinished will return true; - while (decLoop(sound)) {} + while (decLoop(sound) > 0) {} if (staticPlayingSounds.removeAll(sound)) delete sound; } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 39c734e..c5f64e5 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1673,13 +1673,8 @@ void QWidgetPrivate::setWinId(WId id) // set widget identifier } if(oldWinId != id) { - // Do not emit an event when the old winId is destroyed. This only - // happens (a) during widget destruction, and (b) immediately prior - // to creation of a new winId, for example as a result of re-parenting. - if(id != 0) { - QEvent e(QEvent::WinIdChange); - QCoreApplication::sendEvent(q, &e); - } + QEvent e(QEvent::WinIdChange); + QCoreApplication::sendEvent(q, &e); } } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index ca1e3fc..6a27469 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -226,6 +226,7 @@ struct QTLWExtra { #endif #elif defined(Q_OS_SYMBIAN) uint inExpose : 1; // Prevents drawing recursion + uint nativeWindowTransparencyEnabled : 1; // Tracks native window transparency #endif }; diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 97917ba..609307c 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -767,17 +767,24 @@ void QWidgetPrivate::s60UpdateIsOpaque() if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground)) return; + createTLExtra(); + RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow()); #ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE window->SetSurfaceTransparency(!isOpaque); + extra->topextra->nativeWindowTransparencyEnabled = !isOpaque; #else if (!isOpaque) { const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA)); - if (window->SetTransparencyAlphaChannel() == KErrNone) + if (window->SetTransparencyAlphaChannel() == KErrNone) { window->SetBackgroundColor(TRgb(255, 255, 255, 0)); - } else + extra->topextra->nativeWindowTransparencyEnabled = 1; + } + } else if (extra->topextra->nativeWindowTransparencyEnabled) { window->SetTransparentRegion(TRegionFix<1>()); + extra->topextra->nativeWindowTransparencyEnabled = 0; + } #endif } @@ -936,6 +943,7 @@ void QWidgetPrivate::registerDropSite(bool /* on */) void QWidgetPrivate::createTLSysExtra() { extra->topextra->inExpose = 0; + extra->topextra->nativeWindowTransparencyEnabled = 0; } void QWidgetPrivate::deleteTLSysExtra() diff --git a/src/gui/painting/qemulationpaintengine.cpp b/src/gui/painting/qemulationpaintengine.cpp index 0510b10..714d5de 100644 --- a/src/gui/painting/qemulationpaintengine.cpp +++ b/src/gui/painting/qemulationpaintengine.cpp @@ -268,6 +268,15 @@ void QEmulationPaintEngine::setState(QPainterState *s) real_engine->setState(s); } +void QEmulationPaintEngine::beginNativePainting() +{ + real_engine->beginNativePainting(); +} + +void QEmulationPaintEngine::endNativePainting() +{ + real_engine->endNativePainting(); +} void QEmulationPaintEngine::fillBGRect(const QRectF &r) { diff --git a/src/gui/painting/qemulationpaintengine_p.h b/src/gui/painting/qemulationpaintengine_p.h index 5835f10..e283645 100644 --- a/src/gui/painting/qemulationpaintengine_p.h +++ b/src/gui/painting/qemulationpaintengine_p.h @@ -93,6 +93,9 @@ public: virtual void setState(QPainterState *s); + virtual void beginNativePainting(); + virtual void endNativePainting(); + virtual uint flags() const {return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate;} inline QPainterState *state() { return (QPainterState *)QPaintEngine::state; } diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index ba5d164..bd68d2a 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1390,7 +1390,7 @@ int QPdfBaseEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const void QPdfBaseEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) { Q_D(QPdfBaseEngine); - switch (key) { + switch (int(key)) { case PPK_CollateCopies: d->collate = value.toBool(); break; @@ -1480,7 +1480,7 @@ QVariant QPdfBaseEngine::property(PrintEnginePropertyKey key) const Q_D(const QPdfBaseEngine); QVariant ret; - switch (key) { + switch (int(key)) { case PPK_CollateCopies: ret = d->collate; break; diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 2daa1f0..eab9cf6 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -143,7 +143,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const // no room on the current line, start new glyph strip m_cx = 0; m_cy += m_currentRowHeight + paddingDoubled; - m_currentRowHeight = 0; // New row + m_currentRowHeight = c.h + margin * 2; // New row } } if (m_cy + c.h > m_h) { diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 5fe9050..2f09529 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -1438,10 +1438,11 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, const QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &voptAdj, widget); QRect textRect = subElementRect(SE_ItemViewItemText, &voptAdj, widget); const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget); - const bool singleSelection = - (itemView->selectionMode() == QAbstractItemView::SingleSelection || - itemView->selectionMode() == QAbstractItemView::NoSelection); - const bool selectItems = (itemView->selectionBehavior() == QAbstractItemView::SelectItems); + + const bool singleSelection = itemView && + ((itemView->selectionMode() == QAbstractItemView::SingleSelection || + itemView->selectionMode() == QAbstractItemView::NoSelection)); + const bool selectItems = itemView && (itemView->selectionBehavior() == QAbstractItemView::SelectItems); // draw themed background for itemview unless background brush has been defined. if (vopt->backgroundBrush == Qt::NoBrush) { @@ -2536,6 +2537,56 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) if (toolBtn->subControls & SC_ToolButtonMenu) sz += QSize(pixelMetric(PM_MenuButtonIndicator), 0); + + //Make toolbuttons in toolbar stretch the whole screen area + if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) { + const QToolBar *tb = qobject_cast<const QToolBar *>(widget->parentWidget()); + const bool parentCanGrowHorizontally = !(tb->sizePolicy().horizontalPolicy() == QSizePolicy::Fixed || + tb->sizePolicy().horizontalPolicy() == QSizePolicy::Maximum) && tb->orientation() == Qt::Horizontal; + + if (parentCanGrowHorizontally) { + int visibleButtons = 0; + //Make the auto-stretch to happen only for horizontal orientation + if (tb && tb->orientation() == Qt::Horizontal) { + QList<QAction*> actionList = tb->actions(); + for (int i = 0; i < actionList.count(); i++) { + if (actionList.at(i)->isVisible()) + visibleButtons++; + } + } + + if (widget->parentWidget() && visibleButtons > 0) { + QWidget *w = const_cast<QWidget *>(widget); + int toolBarMaxWidth = 0; + int totalMargin = 0; + while (w) { + //honor fixed width parents + if (w->maximumWidth() == w->minimumWidth()) + toolBarMaxWidth = qMax(toolBarMaxWidth, w->maximumWidth()); + if (w->layout() && w->windowType() == Qt::Widget) { + totalMargin += w->layout()->contentsMargins().left() + + w->layout()->contentsMargins().right(); + } + w = w->parentWidget(); + } + totalMargin += 2 * pixelMetric(QStyle::PM_ToolBarFrameWidth); + + if (toolBarMaxWidth == 0) + toolBarMaxWidth = + QApplication::desktop()->availableGeometry(widget->parentWidget()).width(); + //Reduce the margins, toolbar frame, item spacing and internal margin from available area + toolBarMaxWidth -= totalMargin; + + //ensure that buttons are side-by-side and not on top of each other + const int toolButtonWidth = (toolBarMaxWidth / visibleButtons) + - pixelMetric(QStyle::PM_ToolBarItemSpacing) + - pixelMetric(QStyle::PM_ToolBarItemMargin) + //toolbar frame needs to be reduced again, since QToolBarLayout adds it for each toolbar action + - 2 * pixelMetric(QStyle::PM_ToolBarFrameWidth) - 1; + sz.setWidth(qMax(toolButtonWidth, sz.width())); + } + } + } break; case CT_PushButton: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 7b75d40..92f53ff 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -698,7 +698,7 @@ void QS60StylePrivate::deleteStoredSettings() { QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); settings.beginGroup(QLatin1String("QS60Style")); - settings.remove(""); + settings.remove(QString()); settings.endGroup(); } @@ -717,7 +717,6 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const QT_TRAP_THROWING( CRepository *themeRepository = CRepository::NewLC(personalisationUID); if (themeRepository) { - static const TInt KThemePkgIDDesSize = 23; //size of the stored theme package ID TBuf<32> value; //themeID is currently max of 8 + 1 + 8 characters, but lets have some extra space const TUint32 key = 0x00000002; //active theme key in the repository error = themeRepository->Get(key, value); @@ -747,7 +746,7 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const return storedColor; } } - settings.remove(""); //if color was invalid, or theme has been changed, just delete all stored settings + settings.remove(QString()); //if color was invalid, or theme has been changed, just delete all stored settings } } #endif diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp index 3ebfab2..be8f794 100644 --- a/src/gui/styles/qstyle.cpp +++ b/src/gui/styles/qstyle.cpp @@ -2456,6 +2456,8 @@ QDebug operator<<(QDebug debug, QStyle::State state) qSort(states); debug << states.join(QLatin1String(" | ")); debug << ')'; +#else + Q_UNUSED(state); #endif return debug; } diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp index 4780edf..05ca793 100644 --- a/src/gui/styles/qstyleoption.cpp +++ b/src/gui/styles/qstyleoption.cpp @@ -5483,6 +5483,8 @@ QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType) case QStyleOption::SO_GraphicsItem: debug << "SO_GraphicsItem"; break; } +#else + Q_UNUSED(optionType); #endif return debug; } @@ -5496,6 +5498,8 @@ QDebug operator<<(QDebug debug, const QStyleOption &option) debug << ',' << option.state; debug << ',' << option.rect; debug << ')'; +#else + Q_UNUSED(option); #endif return debug; } diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index b7e4be2..c06be3b 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -429,7 +429,7 @@ void QFontEngineXLFD::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFl { int i = glyphs->numGlyphs; XCharStruct *xcs; - // inlined for better perfomance + // inlined for better performance if (!_fs->per_char) { xcs = &_fs->min_bounds; while (i != 0) { diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 46db253..fdbb680 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -265,10 +265,18 @@ private: friend QDataStream &operator>>(QDataStream &, QTextFormat &); }; -// this is only safe if sizeof(int) == sizeof(float) +// this is only safe because sizeof(int) == sizeof(float) static inline uint hash(float d) { +#ifdef Q_CC_GNU + // this is a GCC extension and isn't guaranteed to work in other compilers + // the reinterpret_cast below generates a strict-aliasing warning with GCC + union { float f; uint u; } cvt; + cvt.f = d; + return cvt.u; +#else return reinterpret_cast<uint&>(d); +#endif } static inline uint hash(const QColor &color) diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp index cd023cb..56c2b98 100644 --- a/src/gui/util/qdesktopservices_s60.cpp +++ b/src/gui/util/qdesktopservices_s60.cpp @@ -45,32 +45,29 @@ #include <qurl.h> #include <private/qcore_symbian_p.h> -#include <txtrich.h> // CRichText #include <f32file.h> // TDriveUnit etc +#include <pathinfo.h> // PathInfo + +#ifndef USE_SCHEMEHANDLER +#ifdef Q_WS_S60 +// This flag changes the implementation to use S60 CDcoumentHandler +// instead of apparc when opening the files +#define USE_DOCUMENTHANDLER +#endif + +#include <txtrich.h> // CRichText #include <eikenv.h> // CEikonEnv #include <apgcli.h> // RApaLsSession #include <apgtask.h> // TApaTaskList, TApaTask #include <rsendas.h> // RSendAs #include <rsendasmessage.h> // RSendAsMessage -#ifdef Q_WS_S60 -// This flag changes the implementation to use S60 CDcoumentHandler -// instead of apparch when opening the files -#define USE_DOCUMENTHANDLER +#ifdef USE_DOCUMENTHANDLER +#include <DocumentHandler.h> // CDocumentHandler +#include <AknServerApp.h> #endif - -// copied from miutset.h, so we don't get a dependency into the app layer -const TUid KUidMsgTypeSMTP = {0x10001028}; // 268439592 - -#ifdef Q_OS_SYMBIAN -# include <pathinfo.h> // PathInfo -# ifdef USE_DOCUMENTHANDLER -# include <DocumentHandler.h> // CDocumentHandler -# include <AknServerApp.h> -# endif -#else -# warning CDocumentHandler requires support for S60 -# undef USE_DOCUMENTHANDLER // Fallback to RApaLsSession based implementation +#else // USE_SCHEMEHANDLER +#include <schemehandler.h> #endif QT_BEGIN_NAMESPACE @@ -79,6 +76,10 @@ _LIT(KCacheSubDir, "Cache\\"); _LIT(KSysBin, "\\Sys\\Bin\\"); _LIT(KBrowserPrefix, "4 " ); _LIT(KFontsDir, "z:\\resource\\Fonts\\"); + +#ifndef USE_SCHEMEHANDLER +// copied from miutset.h, so we don't get a dependency into the app layer +const TUid KUidMsgTypeSMTP = {0x10001028}; // 268439592 const TUid KUidBrowser = { 0x10008D39 }; template<class R> @@ -137,7 +138,6 @@ private: Q_GLOBAL_STATIC(QS60DocumentHandler, qt_s60_documenthandler); #endif - static void handleMailtoSchemeLX(const QUrl &url) { // this function has many intermingled leaves and throws. Qt and Symbian objects do not have @@ -155,12 +155,10 @@ static void handleMailtoSchemeLX(const QUrl &url) QStringList ccs = cc.split(QLatin1String(","), QString::SkipEmptyParts); QStringList bccs = bcc.split(QLatin1String(","), QString::SkipEmptyParts); - RSendAs sendAs; User::LeaveIfError(sendAs.Connect()); QAutoClose<RSendAs> sendAsCleanup(sendAs); - CSendAsAccounts* accounts = CSendAsAccounts::NewL(); CleanupStack::PushL(accounts); sendAs.AvailableAccountsL(KUidMsgTypeSMTP, *accounts); @@ -249,47 +247,6 @@ static bool handleOtherSchemes(const QUrl &url) return err ? false : true; } -static TDriveUnit exeDrive() -{ - RProcess me; - TFileName processFileName = me.FileName(); - TDriveUnit drive(processFileName); - return drive; -} - -static TDriveUnit writableExeDrive() -{ - TDriveUnit drive = exeDrive(); - if(drive.operator TInt() == EDriveZ) - return TDriveUnit(EDriveC); - return drive; -} - -static TPtrC writableDataRoot() -{ - TDriveUnit drive = exeDrive(); -#ifdef Q_OS_SYMBIAN - switch(drive.operator TInt()){ - case EDriveC: - return PathInfo::PhoneMemoryRootPath(); - break; - case EDriveE: - return PathInfo::MemoryCardRootPath(); - break; - case EDriveZ: - // It is not possible to write on ROM drive -> - // return phone mem root path instead - return PathInfo::PhoneMemoryRootPath(); - break; - default: - return PathInfo::PhoneMemoryRootPath(); - break; - } -#else -#warning No fallback implementation of writableDataRoot() - return 0; -#endif -} static void openDocumentL(const TDesC& aUrl) { @@ -314,13 +271,44 @@ static void openDocumentL(const TDesC& aUrl) #endif } -#ifdef USE_SCHEMEHANDLER +static bool launchWebBrowser(const QUrl &url) +{ + if (!url.isValid()) + return false; + + if (url.scheme() == QLatin1String("mailto")) { + return handleMailtoScheme(url); + } + return handleOtherSchemes( url ); +} + +static bool openDocument(const QUrl &file) +{ + if (!file.isValid()) + return false; + + QString filePath = file.toLocalFile(); + filePath = QDir::toNativeSeparators(filePath); + TPtrC filePathPtr(qt_QString2TPtrC(filePath)); + TRAPD(err, openDocumentL(filePathPtr)); + return err ? false : true; +} + +#else //USE_SCHEMEHANDLER // The schemehandler component only exist in private SDK. This implementation // exist here just for convenience in case that we need to use it later on // The schemehandle based implementation is not yet tested. // The biggest advantage of schemehandler is that it can handle // wide range of schemes and is extensible by plugins +static void handleUrlL(const TDesC& aUrl) +{ + CSchemeHandler* schemeHandler = CSchemeHandler::NewL(aUrl); + CleanupStack::PushL(schemeHandler); + schemeHandler->HandleUrlStandaloneL(); // Process the Url in standalone mode + CleanupStack::PopAndDestroy(); +} + static bool handleUrl(const QUrl &url) { if (!url.isValid()) @@ -332,13 +320,6 @@ static bool handleUrl(const QUrl &url) return err ? false : true; } -static void handleUrlL(const TDesC& aUrl) -{ - CSchemeHandler* schemeHandler = CSchemeHandler::NewL(aUrl); - CleanupStack::PushL(schemeHandler); - schemeHandler->HandleUrlStandaloneL(); // Process the Url in standalone mode - CleanupStack::PopAndDestroy(); -} static bool launchWebBrowser(const QUrl &url) { return handleUrl(url); @@ -346,31 +327,48 @@ static bool launchWebBrowser(const QUrl &url) static bool openDocument(const QUrl &file) { - return handleUrl(url); + return handleUrl(file); } -#endif -static bool launchWebBrowser(const QUrl &url) -{ - if (!url.isValid()) - return false; +#endif //USE_SCHEMEHANDLER - if (url.scheme() == QLatin1String("mailto")) { - return handleMailtoScheme(url); - } - return handleOtherSchemes( url ); +// Common functions to all implementations + +static TDriveUnit exeDrive() +{ + RProcess me; + TFileName processFileName = me.FileName(); + TDriveUnit drive(processFileName); + return drive; } -static bool openDocument(const QUrl &file) +static TDriveUnit writableExeDrive() { - if (!file.isValid()) - return false; + TDriveUnit drive = exeDrive(); + if (drive.operator TInt() == EDriveZ) + return TDriveUnit(EDriveC); + return drive; +} - QString filePath = file.toLocalFile(); - filePath = QDir::toNativeSeparators(filePath); - TPtrC filePathPtr(qt_QString2TPtrC(filePath)); - TRAPD(err, openDocumentL(filePathPtr)); - return err ? false : true; +static TPtrC writableDataRoot() +{ + TDriveUnit drive = exeDrive(); + switch (drive.operator TInt()){ + case EDriveC: + return PathInfo::PhoneMemoryRootPath(); + break; + case EDriveE: + return PathInfo::MemoryCardRootPath(); + break; + case EDriveZ: + // It is not possible to write on ROM drive -> + // return phone mem root path instead + return PathInfo::PhoneMemoryRootPath(); + break; + default: + return PathInfo::PhoneMemoryRootPath(); + break; + } } QString QDesktopServices::storageLocation(StandardLocation type) @@ -395,21 +393,15 @@ QString QDesktopServices::storageLocation(StandardLocation type) break; case MusicLocation: path.Append(writableDataRoot()); -#ifdef Q_OS_SYMBIAN path.Append(PathInfo::SoundsPath()); -#endif break; case MoviesLocation: path.Append(writableDataRoot()); -#ifdef Q_OS_SYMBIAN path.Append(PathInfo::VideosPath()); -#endif break; case PicturesLocation: path.Append(writableDataRoot()); -#ifdef Q_OS_SYMBIAN path.Append(PathInfo::ImagesPath()); -#endif break; case TempLocation: return QDir::tempPath(); diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri index bea520e..d1c4ff8 100644 --- a/src/gui/util/util.pri +++ b/src/gui/util/util.pri @@ -43,12 +43,17 @@ embedded { } symbian { - LIBS += -lsendas2 -letext -lapmime -lplatformenv - contains(QT_CONFIG, s60) { - contains(CONFIG, is_using_gnupoc) { - LIBS += -lcommonui - } else { - LIBS += -lCommonUI + LIBS += -letext -lplatformenv + contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { + LIBS += -lsendas2 -lapmime + contains(QT_CONFIG, s60) { + contains(CONFIG, is_using_gnupoc) { + LIBS += -lcommonui + } else { + LIBS += -lCommonUI + } } + } else { + DEFINES += USE_SCHEMEHANDLER } -} +}
\ No newline at end of file diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp index abab33c..9c71004 100644 --- a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp +++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp @@ -279,7 +279,7 @@ void QDeclarativeFolderListModel::classBegin() void QDeclarativeFolderListModel::componentComplete() { - if (!d->folder.isValid() || !QDir().exists(d->folder.toLocalFile())) + if (!d->folder.isValid() || d->folder.toLocalFile().isEmpty() || !QDir().exists(d->folder.toLocalFile())) setFolder(QUrl(QLatin1String("file://")+QDir::currentPath())); if (!d->folderIndex.isValid()) diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index 25622a4..3617d24 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -63,7 +63,9 @@ QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray dev, QAudio::Mode device = QLatin1String(dev); this->mode = mode; +#if (SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) checkSurround(); +#endif } QAudioDeviceInfoInternal::~QAudioDeviceInfoInternal() @@ -394,9 +396,11 @@ void QAudioDeviceInfoInternal::updateLists() } channelz.append(1); channelz.append(2); +#if (SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) if (surround40) channelz.append(4); if (surround51) channelz.append(6); if (surround71) channelz.append(8); +#endif sizez.append(8); sizez.append(16); sizez.append(32); @@ -494,6 +498,7 @@ QByteArray QAudioDeviceInfoInternal::defaultOutputDevice() return devices.first(); } +#if (SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) void QAudioDeviceInfoInternal::checkSurround() { QList<QByteArray> devices; @@ -534,5 +539,6 @@ void QAudioDeviceInfoInternal::checkSurround() } snd_device_name_free_hint(hints); } +#endif QT_END_NAMESPACE diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h index 8525980..5f7e5e8 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h @@ -98,10 +98,12 @@ private: bool open(); void close(); +#if (SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) void checkSurround(); bool surround40; bool surround51; bool surround71; +#endif QString device; QAudio::Mode mode; diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 4d27531..0531595 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -327,8 +327,6 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket Q_ASSERT(socket); Q_ASSERT(reply); - Q_Q(QHttpNetworkConnection); - resend = false; //create the response header to be used with QAuthenticatorPrivate. QList<QPair<QByteArray, QByteArray> > fields = reply->header(); @@ -854,12 +852,17 @@ QHttpNetworkReply* QHttpNetworkConnection::sendRequest(const QHttpNetworkRequest return d->queueRequest(request); } -bool QHttpNetworkConnection::isEncrypted() const +bool QHttpNetworkConnection::isSsl() const { Q_D(const QHttpNetworkConnection); return d->encrypt; } +QHttpNetworkConnectionChannel *QHttpNetworkConnection::channels() const +{ + return d_func()->channels; +} + #ifndef QT_NO_NETWORKPROXY void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy) { diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 8461426c..9f23cbf 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -108,7 +108,9 @@ public: QNetworkProxy transparentProxy() const; #endif - bool isEncrypted() const; + bool isSsl() const; + + QHttpNetworkConnectionChannel *channels() const; #ifndef QT_NO_OPENSSL void setSslConfiguration(const QSslConfiguration &config); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 02daa50..c8caad4 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -180,7 +180,6 @@ bool QHttpNetworkConnectionChannel::sendRequest() reply->d_func()->autoDecompress = request.d->autoDecompress; reply->d_func()->pipeliningUsed = false; - pendingEncrypt = false; // if the url contains authentication parameters, use the new ones // both channels will use the new authentication parameters if (!request.url().userInfo().isEmpty() && request.withCredentials()) { @@ -1019,6 +1018,7 @@ void QHttpNetworkConnectionChannel::_q_encrypted() if (!socket) return; // ### error state = QHttpNetworkConnectionChannel::IdleState; + pendingEncrypt = false; sendRequest(); } diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 442086a..fd18042 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -158,6 +158,8 @@ public: bool isSocketWaiting() const; bool isSocketReading() const; + friend class QNetworkAccessHttpBackend; + protected slots: void _q_receiveReply(); void _q_bytesWritten(qint64 bytes); // proceed sending diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index e4eb7c4..21bc427 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -188,6 +188,12 @@ QByteArray QHttpNetworkReply::readAny() return d->responseData.read(); } +QByteArray QHttpNetworkReply::readAll() +{ + Q_D(QHttpNetworkReply); + return d->responseData.readAll(); +} + void QHttpNetworkReply::setDownstreamLimited(bool dsl) { Q_D(QHttpNetworkReply); diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 3f79d81..9cf805c 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -126,6 +126,7 @@ public: qint64 bytesAvailable() const; qint64 bytesAvailableNextBlock() const; QByteArray readAny(); + QByteArray readAll(); void setDownstreamLimited(bool t); bool isFinished() const; diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 05eb6cb..12b6400 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -142,6 +142,7 @@ void QNetworkAccessBackend::emitReplyUploadProgress(qint64 bytesSent, qint64 byt QNetworkAccessBackend::QNetworkAccessBackend() : manager(0) , reply(0) + , synchronous(false) { } diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h index 7faa5cb..c9ec37e 100644 --- a/src/network/access/qnetworkaccessbackend_p.h +++ b/src/network/access/qnetworkaccessbackend_p.h @@ -157,6 +157,9 @@ public: QVariant attribute(QNetworkRequest::Attribute code) const; void setAttribute(QNetworkRequest::Attribute code, const QVariant &value); + bool isSynchronous() { return synchronous; } + void setSynchronous(bool sync) { synchronous = sync; } + // return true if the QNonContiguousByteDevice of the upload // data needs to support reset(). Currently needed for HTTP. // This will possibly enable buffering of the upload data. @@ -166,6 +169,8 @@ public: virtual bool canResume() const { return false; } virtual void setResumeOffset(quint64 offset) { Q_UNUSED(offset); } + virtual bool processRequestSynchronously() { return false; } + protected: // Create the device used for reading the upload data QNonContiguousByteDevice* createUploadByteDevice(); @@ -200,6 +205,7 @@ private: friend class QNetworkReplyImplPrivate; QNetworkAccessManagerPrivate *manager; QNetworkReplyImplPrivate *reply; + bool synchronous; }; class QNetworkAccessBackendFactory diff --git a/src/network/access/qnetworkaccessdatabackend.cpp b/src/network/access/qnetworkaccessdatabackend.cpp index efb6e3e..74aebdb 100644 --- a/src/network/access/qnetworkaccessdatabackend.cpp +++ b/src/network/access/qnetworkaccessdatabackend.cpp @@ -122,4 +122,10 @@ bool QNetworkAccessDataBackend::waitForUpstreamBytesWritten(int) return false; } +bool QNetworkAccessDataBackend::processRequestSynchronously() +{ + start(); + return true; +} + QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccessdatabackend_p.h b/src/network/access/qnetworkaccessdatabackend_p.h index a7c63d5..0e5a494 100644 --- a/src/network/access/qnetworkaccessdatabackend_p.h +++ b/src/network/access/qnetworkaccessdatabackend_p.h @@ -68,6 +68,8 @@ public: virtual void closeUpstreamChannel(); virtual bool waitForDownstreamReadyRead(int msecs); virtual bool waitForUpstreamBytesWritten(int msecs); + + virtual bool processRequestSynchronously(); }; class QNetworkAccessDataBackendFactory: public QNetworkAccessBackendFactory diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 80b05a4..9df5d7b 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -50,6 +50,7 @@ #include "qnetworkrequest_p.h" #include "qnetworkcookie_p.h" #include "QtCore/qdatetime.h" +#include "QtCore/qelapsedtimer.h" #include "QtNetwork/qsslconfiguration.h" #ifndef QT_NO_HTTP @@ -318,7 +319,10 @@ void QNetworkAccessHttpBackend::disconnectFromHttp() // Get the object cache that stores our QHttpNetworkConnection objects QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); - cache->releaseEntry(cacheKey); + + // synchronous calls are not put into the cache, so for them the key is empty + if (!cacheKey.isEmpty()) + cache->releaseEntry(cacheKey); } // This is abut disconnecting signals, not about disconnecting TCP connections @@ -639,34 +643,49 @@ void QNetworkAccessHttpBackend::open() if (transparentProxy.type() == QNetworkProxy::DefaultProxy && cacheProxy.type() == QNetworkProxy::DefaultProxy) { // unsuitable proxies - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), - Q_ARG(QString, tr("No suitable proxy found"))); - QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); - return; + if (isSynchronous()) { + error(QNetworkReply::ProxyNotFoundError, tr("No suitable proxy found")); + finished(); + } else { + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), + Q_ARG(QString, tr("No suitable proxy found"))); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); + } + return; } #endif - // check if we have an open connection to this host - cacheKey = makeCacheKey(this, theProxy); - QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); - // the http object is actually a QHttpNetworkConnection - http = static_cast<QNetworkAccessCachedHttpConnection *>(cache->requestEntryNow(cacheKey)); - if (http == 0) { - // no entry in cache; create an object - // the http object is actually a QHttpNetworkConnection - http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt); - + if (isSynchronous()) { + // for synchronous requests, we just create a new connection + http = new QHttpNetworkConnection(1, url.host(), url.port(), encrypt, this); #ifndef QT_NO_NETWORKPROXY http->setTransparentProxy(transparentProxy); http->setCacheProxy(cacheProxy); #endif + postRequest(); + processRequestSynchronously(); + } else { + // check if we have an open connection to this host + cacheKey = makeCacheKey(this, theProxy); + QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); + // the http object is actually a QHttpNetworkConnection + http = static_cast<QNetworkAccessCachedHttpConnection *>(cache->requestEntryNow(cacheKey)); + if (http == 0) { + // no entry in cache; create an object + // the http object is actually a QHttpNetworkConnection + http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt); - // cache the QHttpNetworkConnection corresponding to this cache key - cache->addEntry(cacheKey, http); - } +#ifndef QT_NO_NETWORKPROXY + http->setTransparentProxy(transparentProxy); + http->setCacheProxy(cacheProxy); +#endif - postRequest(); + // cache the QHttpNetworkConnection corresponding to this cache key + cache->addEntry(cacheKey, static_cast<QNetworkAccessCachedHttpConnection *>(http.data())); + } + postRequest(); + } } void QNetworkAccessHttpBackend::closeDownstreamChannel() @@ -1125,6 +1144,87 @@ void QNetworkAccessHttpBackend::setResumeOffset(quint64 offset) resumeOffset = offset; } +bool QNetworkAccessHttpBackend::processRequestSynchronously() +{ + QHttpNetworkConnectionChannel *channel = &http->channels()[0]; + + // Disconnect all socket signals. They will only confuse us when using waitFor* + QObject::disconnect(channel->socket, 0, 0, 0); + + qint64 timeout = 20*1000; // 20 sec + QElapsedTimer timeoutTimer; + + bool waitResult = channel->socket->waitForConnected(timeout); + timeoutTimer.start(); + + if (!waitResult || channel->socket->state() != QAbstractSocket::ConnectedState) { + error(QNetworkReply::UnknownNetworkError, QLatin1String("could not connect")); + return false; + } + channel->_q_connected(); // this will send the request (via sendRequest()) + +#ifndef QT_NO_OPENSSL + if (http->isSsl()) { + qint64 remainingTimeEncrypted = timeout - timeoutTimer.elapsed(); + if (!static_cast<QSslSocket *>(channel->socket)->waitForEncrypted(remainingTimeEncrypted)) { + error(QNetworkReply::SslHandshakeFailedError, + QLatin1String("could not encrypt or timeout while encrypting")); + return false; + } + channel->_q_encrypted(); + } +#endif + + // if we get a 401 or 407, we might need to send the request twice, see below + bool authenticating = false; + + do { + channel->sendRequest(); + + qint64 remainingTimeBytesWritten; + while(channel->socket->bytesToWrite() > 0 || + channel->state == QHttpNetworkConnectionChannel::WritingState) { + remainingTimeBytesWritten = timeout - timeoutTimer.elapsed(); + channel->sendRequest(); // triggers channel->socket->write() + if (!channel->socket->waitForBytesWritten(remainingTimeBytesWritten)) { + error(QNetworkReply::TimeoutError, + QLatin1String("could not write bytes to socket or timeout while writing")); + return false; + } + } + + qint64 remainingTimeBytesRead = timeout - timeoutTimer.elapsed(); + // Loop for at most remainingTime until either the socket disconnects + // or the reply is finished + do { + waitResult = channel->socket->waitForReadyRead(remainingTimeBytesRead); + remainingTimeBytesRead = timeout - timeoutTimer.elapsed(); + if (!waitResult || remainingTimeBytesRead <= 0 + || channel->socket->state() != QAbstractSocket::ConnectedState) { + error(QNetworkReply::TimeoutError, + QLatin1String("could not read from socket or timeout while reading")); + return false; + } + + if (channel->socket->bytesAvailable()) + channel->_q_readyRead(); + + if (!httpReply) + return false; // we got a 401 or 407 and cannot handle it (it might happen that + // disconnectFromHttp() was called, in that case the reply is zero) + // ### I am quite sure this does not work for NTLM + // ### how about uploading to an auth / proxyAuth site? + + authenticating = (httpReply->statusCode() == 401 || httpReply->statusCode() == 407); + + if (httpReply->isFinished()) + break; + } while (remainingTimeBytesRead > 0); + } while (authenticating); + + return true; +} + QT_END_NAMESPACE #endif // QT_NO_HTTP diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h index 5de3429..cc2f9ac 100644 --- a/src/network/access/qnetworkaccesshttpbackend_p.h +++ b/src/network/access/qnetworkaccesshttpbackend_p.h @@ -99,6 +99,8 @@ public: bool canResume() const; void setResumeOffset(quint64 offset); + virtual bool processRequestSynchronously(); + private slots: void replyReadyRead(); void replyFinished(); @@ -111,7 +113,7 @@ private slots: private: QHttpNetworkReply *httpReply; - QPointer<QNetworkAccessCachedHttpConnection> http; + QPointer<QHttpNetworkConnection> http; QByteArray cacheKey; QNetworkAccessBackendUploadIODevice *uploadDevice; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index effd79e..4bc036e 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1060,12 +1060,14 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera priv->backend->setParent(reply); priv->backend->reply = priv; } - // fourth step: setup the reply - priv->setup(op, request, outgoingData); #ifndef QT_NO_OPENSSL reply->setSslConfiguration(request.sslConfiguration()); #endif + + // fourth step: setup the reply + priv->setup(op, request, outgoingData); + return reply; } @@ -1141,6 +1143,11 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend } } + // if we emit a signal here in synchronous mode, the user might spin + // an event loop, which might recurse and lead to problems + if (backend->isSynchronous()) + return; + backend->reply->urlForLastAuthentication = url; emit q->authenticationRequired(backend->reply->q_func(), authenticator); cacheCredentials(url, authenticator); @@ -1168,6 +1175,11 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac } } + // if we emit a signal here in synchronous mode, the user might spin + // an event loop, which might recurse and lead to problems + if (backend->isSynchronous()) + return; + backend->reply->lastProxyAuthentication = proxy; emit q->proxyAuthenticationRequired(proxy, authenticator); cacheProxyCredentials(proxy, authenticator); diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 5850494..cf6e674 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -85,7 +85,7 @@ void QNetworkReplyImplPrivate::_q_startOperation() } #ifndef QT_NO_BEARERMANAGEMENT - if (!backend->start()) { + if (!backend->start()) { // ### we should call that method even if bearer is not used // backend failed to start because the session state is not Connected. // QNetworkAccessManager will call reply->backend->start() again for us when the session // state changes. @@ -109,11 +109,15 @@ void QNetworkReplyImplPrivate::_q_startOperation() } #endif - if (state != Finished) { - if (operation == QNetworkAccessManager::GetOperation) - pendingNotifications.append(NotifyDownstreamReadyWrite); + if (backend->isSynchronous()) { + state = Finished; + } else { + if (state != Finished) { + if (operation == QNetworkAccessManager::GetOperation) + pendingNotifications.append(NotifyDownstreamReadyWrite); - handleNotifications(); + handleNotifications(); + } } } @@ -287,7 +291,25 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const url = request.url(); operation = op; - if (outgoingData && backend) { + q->QIODevice::open(QIODevice::ReadOnly); + // Internal code that does a HTTP reply for the synchronous Ajax + // in QtWebKit. + QVariant synchronousHttpAttribute = req.attribute( + static_cast<QNetworkRequest::Attribute>(QNetworkRequest::DownloadBufferAttribute + 1)); + if (synchronousHttpAttribute.toBool()) { + backend->setSynchronous(true); + if (outgoingData && outgoingData->isSequential()) { + outgoingDataBuffer = new QRingBuffer(); + QByteArray data; + do { + data = outgoingData->readAll(); + if (data.isEmpty()) + break; + outgoingDataBuffer->append(data); + } while (1); + } + } + if (outgoingData && backend && !backend->isSynchronous()) { // there is data to be uploaded, e.g. HTTP POST. if (!backend->needsResetableUploadData() || !outgoingData->isSequential()) { @@ -298,7 +320,7 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const } else { bool bufferingDisallowed = req.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute, - false).toBool(); + false).toBool(); if (bufferingDisallowed) { // if a valid content-length header for the request was supplied, we can disable buffering @@ -323,17 +345,18 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const // for HTTP, we want to send out the request as fast as possible to the network, without // invoking methods in a QueuedConnection #ifndef QT_NO_HTTP - if (qobject_cast<QNetworkAccessHttpBackend *>(backend)) { + if (qobject_cast<QNetworkAccessHttpBackend *>(backend) || (backend && backend->isSynchronous())) { _q_startOperation(); } else { QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); } #else - QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); + if (backend->isSynchronous()) + _q_startOperation(); + else + QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); #endif // QT_NO_HTTP - } - - q->QIODevice::open(QIODevice::ReadOnly); + } } void QNetworkReplyImplPrivate::backendNotify(InternalNotifications notification) diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index cdadf0f..9bcc900 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -85,6 +85,9 @@ public: MaximumDownloadBufferSizeAttribute, // internal DownloadBufferAttribute, // internal + // (DownloadBufferAttribute + 1) is reserved internal for QSynchronousHttpNetworkReply + // add the enum in 4.8 + User = 1000, UserMax = 32767 }; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 1e0bced..5b42578 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -322,9 +322,9 @@ bool QLocalSocketPrivate::completeAsyncRead() // buffer. We will read the remaining data in the next call. break; case ERROR_PIPE_NOT_CONNECTED: - setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); - // fall through + return false; default: + setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); return false; } } diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index a3ea555..275c7be 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -716,7 +716,7 @@ QSslCertificate QSslCertificatePrivate::QSslCertificate_from_X509(X509 *x509) static bool matchLineFeed(const QByteArray &pem, int *offset) { - char ch; + char ch = 0; // ignore extra whitespace at the end of the line while (*offset < pem.size() && (ch = pem.at(*offset)) == ' ') diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 0479d83..99b5a95 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -656,8 +656,16 @@ TInt CSymbianCertificateRetriever::ThreadEntryPoint(TAny* aParams) void CSymbianCertificateRetriever::ConstructL() { - User::LeaveIfError(iThread.Create(_L("CertWorkerThread"), - CSymbianCertificateRetriever::ThreadEntryPoint, 16384, NULL, this)); + TInt err; + int i=0; + QString name(QLatin1String("CertWorkerThread-%1")); + //recently closed thread names remain in use for a while until all handles have been closed + //including users of RUndertaker + do { + err = iThread.Create(qt_QString2TPtrC(name.arg(i++)), + CSymbianCertificateRetriever::ThreadEntryPoint, 16384, NULL, this); + } while (err == KErrAlreadyExists); + User::LeaveIfError(err); } void CSymbianCertificateRetriever::DoCancel() diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp index 85f604a..75d5ce2 100644 --- a/src/opengl/gl2paintengineex/qtriangulator.cpp +++ b/src/opengl/gl2paintengineex/qtriangulator.cpp @@ -339,7 +339,7 @@ static inline qint64 qPointDistanceFromLine(const QPodPoint &p, const QPodPoint static inline bool qPointIsLeftOfLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2) { - return qPointDistanceFromLine(p, v1, v2) < 0; + return QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p, v1, v2) < 0; } // Return: @@ -1741,7 +1741,7 @@ bool QTriangulator<T>::ComplexToSimple::calculateIntersection(int left, int righ Intersection intersection; intersection.leftEdge = left; intersection.rightEdge = right; - intersection.intersectionPoint = qIntersectionPoint(u1, u2, v1, v2); + intersection.intersectionPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(u1, u2, v1, v2); if (!intersection.intersectionPoint.isValid()) return false; @@ -1767,10 +1767,10 @@ bool QTriangulator<T>::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int return true; if (upper.x > qMax(l.x, u.x)) return false; - qint64 d = qPointDistanceFromLine(upper, l, u); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(upper, l, u); // d < 0: left, d > 0: right, d == 0: on top if (d == 0) - d = qPointDistanceFromLine(m_parent->m_vertices.at(leftEdge.lower()), l, u); + d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u); return d < 0; } @@ -1814,7 +1814,7 @@ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSim while (current) { const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower()); const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper()); - qint64 d = qPointDistanceFromLine(point, v1, v2); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2); if (d == 0) { result.first = result.second = current; break; @@ -1828,7 +1828,7 @@ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSim while (current) { const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower()); const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper()); - qint64 d = qPointDistanceFromLine(point, v1, v2); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2); Q_ASSERT(d >= 0); if (d == 0) { result.first = current; @@ -1842,7 +1842,7 @@ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSim while (current) { const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower()); const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper()); - qint64 d = qPointDistanceFromLine(point, v1, v2); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2); Q_ASSERT(d <= 0); if (d == 0) { result.second = current; @@ -1864,7 +1864,7 @@ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSim while (current) { const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower()); const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper()); - qint64 d = qPointDistanceFromLine(point, v1, v2); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2); if (d == 0) break; if (d < 0) { @@ -1885,7 +1885,7 @@ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSim while (current) { const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower()); const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper()); - qint64 d = qPointDistanceFromLine(point, v1, v2); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2); Q_ASSERT(d >= 0); if (d == 0) { current = current->left; @@ -1899,7 +1899,7 @@ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSim while (current) { const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower()); const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper()); - qint64 d = qPointDistanceFromLine(point, v1, v2); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2); Q_ASSERT(d <= 0); if (d == 0) { current = current->right; @@ -1962,7 +1962,7 @@ void QTriangulator<T>::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node template <typename T> void QTriangulator<T>::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint) { - QIntersectionPoint eventPoint2 = qIntersectionPoint(eventPoint); + QIntersectionPoint eventPoint2 = QT_PREPEND_NAMESPACE(qIntersectionPoint)(eventPoint); while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint < eventPoint2) { Intersection intersection = m_topIntersection.pop(); @@ -2056,7 +2056,7 @@ void QTriangulator<T>::ComplexToSimple::calculateIntersections() QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> range = bounds(event.point); QRBTree<int>::Node *leftNode = range.first ? m_edgeList.previous(range.first) : 0; int vertex = (event.type == Event::Upper ? m_edges.at(event.edge).upper() : m_edges.at(event.edge).lower()); - QIntersectionPoint eventPoint = qIntersectionPoint(event.point); + QIntersectionPoint eventPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point); if (range.first != 0) { splitEdgeListRange(range.first, range.second, vertex, eventPoint); @@ -2213,7 +2213,7 @@ void QTriangulator<T>::ComplexToSimple::removeUnwantedEdgesAndConnect() while (current != b.second) { Q_ASSERT(current); Q_ASSERT(m_edges.at(current->data).node == current); - Q_ASSERT(qIntersectionPoint(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(m_edges.at(current->data).to))); + Q_ASSERT(QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(m_edges.at(current->data).to))); Q_ASSERT(m_parent->m_vertices.at(m_edges.at(current->data).from) == event.point || m_parent->m_vertices.at(m_edges.at(current->data).to) == event.point); insertEdgeIntoVectorIfWanted(orderedEdges, current->data); current = m_edgeList.next(current); @@ -2612,10 +2612,10 @@ bool QTriangulator<T>::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int const Edge &rightEdge = m_edges.at(rightEdgeIndex); const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper()); const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower()); - qint64 d = qPointDistanceFromLine(m_parent->m_vertices.at(leftEdge.upper()), l, u); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.upper()), l, u); // d < 0: left, d > 0: right, d == 0: on top if (d == 0) - d = qPointDistanceFromLine(m_parent->m_vertices.at(leftEdge.lower()), l, u); + d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u); return d < 0; } @@ -2645,7 +2645,7 @@ QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfPoint(in while (current) { const QPodPoint &p1 = m_parent->m_vertices.at(m_edges.at(current->data).lower()); const QPodPoint &p2 = m_parent->m_vertices.at(m_edges.at(current->data).upper()); - qint64 d = qPointDistanceFromLine(m_parent->m_vertices.at(pointIndex), p1, p2); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(pointIndex), p1, p2); if (d <= 0) { current = current->left; } else { @@ -2668,7 +2668,7 @@ void QTriangulator<T>::SimpleToMonotone::classifyVertex(int i) const QPodPoint &p1 = m_parent->m_vertices.at(e1.from); const QPodPoint &p2 = m_parent->m_vertices.at(e2.from); const QPodPoint &p3 = m_parent->m_vertices.at(e2.to); - qint64 d = qPointDistanceFromLine(p1, p2, p3); + qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p1, p2, p3); Q_ASSERT(d != 0 || (!startOrSplit && !endOrMerge)); e2.type = RegularVertex; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index ed9753e..18f1203 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2095,7 +2095,9 @@ void QGLContextPrivate::cleanup() void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled) { Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT); +#ifdef glEnableVertexAttribArray Q_ASSERT(glEnableVertexAttribArray); +#endif if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled) glDisableVertexAttribArray(arrayIndex); @@ -2108,7 +2110,9 @@ void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled void QGLContextPrivate::syncGlState() { +#ifdef glEnableVertexAttribArray Q_ASSERT(glEnableVertexAttribArray); +#endif for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) { if (vertexAttributeArraysEnabledState[i]) glEnableVertexAttribArray(i); diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index d33ea56..75dd1b6 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -97,7 +97,6 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) XVisualInfo visualInfo; XVisualInfo *vi; int numVisuals; - EGLint id = 0; visualInfo.visualid = QEgl::getCompatibleVisualId(config); vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); @@ -346,7 +345,7 @@ void QGLWidgetPrivate::recreateEglSurface() // old surface before re-creating a new one. Note: This should not be the case as the // surface should be deleted before the old window id. if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) { - qWarning("EGL surface for deleted window %x was not destroyed", eglSurfaceWindowId); + qWarning("EGL surface for deleted window %x was not destroyed", uint(eglSurfaceWindowId)); glcx->d_func()->destroyEglSurfaceForDevice(); } diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index 0b94f5a..2d9f6f1 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -74,7 +74,6 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge // Use the same configuration as the widget we are sharing with. ctx->setConfig(shareContext->config()); #if QGL_RENDER_TEXTURE - EGLint value = EGL_FALSE; if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE) textureFormat = EGL_TEXTURE_RGBA; else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index aea203f..b8e8bad 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1502,7 +1502,10 @@ void QVGPaintEnginePrivate::fill(VGPath path, const QBrush& brush, VGint rule) return; ensureBrush(brush); setFillRule(rule); + QPen savedPen = currentPen; + currentPen = Qt::NoPen; ensurePathTransform(); + currentPen = savedPen; vgDrawPath(path, VG_FILL_PATH); } @@ -3543,8 +3546,8 @@ void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) // Set the glyph drawing origin. VGfloat origin[2]; - origin[0] = positions[0].x.toReal(); - origin[1] = positions[0].y.toReal(); + origin[0] = positions[0].x.round().toReal(); + origin[1] = positions[0].y.round().toReal(); vgSetfv(VG_GLYPH_ORIGIN, 2, origin); // Fast anti-aliasing for paths, better for images. diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 509882b..c3c7def 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -214,7 +214,7 @@ void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags else if (!(flags & Qt::NoOpaqueDetection) && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) format = sourceFormat(); else - format = QImage::Format_RGB32; + format = image.hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32; if (inPlace && image.data_ptr()->convertInPlace(format, flags)) source = image; diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index 184ceb4..7f3501e 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -726,6 +726,7 @@ void QConnmanEngine::addNetworkConfiguration(const QString &networkPath) if(servicePath.isEmpty()) { id = QString::number(qHash(networkPath)); + serv = 0; } else { id = QString::number(qHash(servicePath)); serv = new QConnmanServiceInterface(servicePath,this); diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 952a444..0545422 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -216,7 +216,6 @@ void QConnmanManagerInterface::registerCounter(const QString &path, quint32 inte { QDBusReply<QList<QDBusObjectPath> > reply = this->call(QLatin1String("RegisterCounter"), QVariant::fromValue(path), QVariant::fromValue(interval)); - bool ok = true; if(reply.error().type() == QDBusError::InvalidArgs) { qWarning() << reply.error().message(); } @@ -225,7 +224,6 @@ void QConnmanManagerInterface::registerCounter(const QString &path, quint32 inte void QConnmanManagerInterface::unregisterCounter(const QString &path) { QDBusReply<QList<QDBusObjectPath> > reply = this->call(QLatin1String("UnregisterCounter"), QVariant::fromValue(path)); - bool ok = true; if(reply.error().type() == QDBusError::InvalidArgs) { qWarning() << reply.error().message(); } diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri index 84009d8..7cbffe0 100644 --- a/src/plugins/qpluginbase.pri +++ b/src/plugins/qpluginbase.pri @@ -1,6 +1,6 @@ TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.7.1 + VERSION=4.7.2 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } diff --git a/src/plugins/s60/feedback/feedback.pro b/src/plugins/s60/feedback/feedback.pro index 1069220..5e577ec 100644 --- a/src/plugins/s60/feedback/feedback.pro +++ b/src/plugins/s60/feedback/feedback.pro @@ -6,7 +6,7 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/s60/feedback INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE -contains(S60_VERSION, 5.0)|contains(S60_VERSION, symbian3) { +!contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { HEADERS += qtactileFeedback.h SOURCES += qtactileFeedback_s60.cpp diff --git a/src/plugins/s60/s60.pro b/src/plugins/s60/s60.pro index ffcd170..1ddf326 100644 --- a/src/plugins/s60/s60.pro +++ b/src/plugins/s60/s60.pro @@ -6,7 +6,7 @@ symbian { SUBDIRS += 3_1 3_2 } - contains(S60_VERSION, 5.0)|contains(S60_VERSION, symbian3) { + !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { SUBDIRS += feedback } diff --git a/src/qbase.pri b/src/qbase.pri index 4217618..3a40928 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -4,7 +4,7 @@ INCLUDEPATH *= $$QMAKE_INCDIR_QT/$$TARGET #just for today to have some compat isEmpty(QT_ARCH):!isEmpty(ARCH):QT_ARCH=$$ARCH #another compat that will rot for change #215700 TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.7.1 + VERSION=4.7.2 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } @@ -36,7 +36,7 @@ CONFIG += qt warn_on depend_includepath CONFIG += qmake_cache target_qt CONFIG -= fix_output_dirs win32|mac:!macx-xcode:CONFIG += debug_and_release -linux*-g++*:QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF +linux*:QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 65b8781..ff67bcf 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -87,7 +87,7 @@ symbian: { DEPLOYMENT += bearer_plugin } - contains(S60_VERSION, 5.0)|contains(S60_VERSION, symbian3) { + !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { feedback_plugin.sources = $$QT_BUILD_TREE/plugins/s60/feedback/qtactilefeedback$${QT_LIBINFIX}.dll feedback_plugin.path = c:$$QT_PLUGINS_BASE_DIR/feedback DEPLOYMENT += feedback_plugin @@ -191,11 +191,9 @@ symbian: { qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtOpenVG$${QT_LIBINFIX}.dll graphicssystems_plugins.sources += $$QT_BUILD_TREE/plugins/graphicssystems/qvggraphicssystem$${QT_LIBINFIX}.dll # OpenVG requires Symbian^3 or later - pkg_platform_dependencies -= \ - "[0x101F7961],0,0,0,{\"S60ProductID\"}" \ - "[0x102032BE],0,0,0,{\"S60ProductID\"}" \ - "[0x102752AE],0,0,0,{\"S60ProductID\"}" \ - "[0x1028315F],0,0,0,{\"S60ProductID\"}" + pkg_platform_dependencies = \ + "[0x20022E6D],0,0,0,{\"S60ProductID\"}" \ + "[0x20032DE7],0,0,0,{\"S60ProductID\"}" } contains(QT_CONFIG, opengl) { diff --git a/src/xmlpatterns/data/qatomicvalue.cpp b/src/xmlpatterns/data/qatomicvalue.cpp index ecc78bf..fc4cf2e 100644 --- a/src/xmlpatterns/data/qatomicvalue.cpp +++ b/src/xmlpatterns/data/qatomicvalue.cpp @@ -202,7 +202,7 @@ ItemType::Ptr AtomicValue::qtToXDMType(const QXmlItem &item) Q_ASSERT(item.isAtomicValue()); const QVariant v(item.toAtomicValue()); - switch(v.type()) + switch(int(v.type())) { case QVariant::Char: /* Fallthrough. */ |