diff options
Diffstat (limited to 'src')
102 files changed, 1222 insertions, 686 deletions
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 6fe71d6..128df75 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 8f5ca3ba5da63a47d4f90bbd867d3e8453443dd3 + ca7b2e1e1ca558050cf49dd8f7c9b35e4b9d4df5 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 8e1c965..40a2149 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,68 @@ +2010-01-14 Andreas Kling <andreas.kling@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Enable scrolling optimization for pages with embedded widgets + + https://bugs.webkit.org/show_bug.cgi?id=33373 + + Added a basic manual test for scrolling of embedded QWidgets. + + * manual-tests/qt/qtplugin-scrolling.html: Added. + * platform/ScrollView.cpp: + (WebCore::ScrollView::scrollContents): + (WebCore::ScrollView::setParent): + * platform/ScrollView.h: + * platform/qt/ScrollViewQt.cpp: + (WebCore::ScrollView::platformInit): + (WebCore::ScrollView::platformAddChild): + (WebCore::ScrollView::platformRemoveChild): + * plugins/qt/PluginViewQt.cpp: + (WebCore::PluginView::updatePluginWidget): + (WebCore::PluginView::invalidateRect): + +2010-01-29 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Turn off websocket support by default for Qt 4.6.x + https://bugs.webkit.org/show_bug.cgi?id=34284 + + * WebCore.pro: + +2010-01-26 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Simon Hausmann. + + [Qt] JavaScript prompt is currently broken. + https://bugs.webkit.org/show_bug.cgi?id=30914 + + Remove the manual test case in favor of an automated + test case in WebKit/qt/tests/qwebpage. + + * manual-tests/qt/java-script-prompt.html: Removed. + +2010-01-25 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + [Qt] Phone backup support for QtWebkit for Symbian devices. + https://bugs.webkit.org/show_bug.cgi?id=34077 + + * WebCore.pro: + +2010-01-21 Thiago Macieira <thiago.macieira@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix incorrect dependency to QtXmlPatterns in generated include/QtWebKit/QtWebKit header + + The generated file includes QtXmlPatterns/QtXmlPatterns, which is neither used/required by + the public QtWebKit API nor will it be available if Qt is configured with -no-xmlpatterns. + + * WebCore.pro: Trick syncqt to believe that xmlpatterns is not a dependency, so that it's not + included in the generated file. It'll still be used and linked to with this trick. + 2010-01-17 Srinidhi Shreedhara <srinidhi.shreedhara@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 04aba62..f364d3b 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -18,7 +18,10 @@ symbian: { " " webkitlibs.pkg_prerules = vendorinfo - DEPLOYMENT += webkitlibs + webkitbackup.sources = ../WebKit/qt/symbian/backup_registration.xml + webkitbackup.path = /private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) + + DEPLOYMENT += webkitlibs webkitbackup TARGET.UID3 = 0x200267C2 # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target. @@ -183,7 +186,7 @@ contains(DEFINES, ENABLE_SINGLE_THREADED=1) { } # Web Socket support. -!contains(DEFINES, ENABLE_WEB_SOCKETS=.): DEFINES += ENABLE_WEB_SOCKETS=1 +!contains(DEFINES, ENABLE_WEB_SOCKETS=.): DEFINES += ENABLE_WEB_SOCKETS=0 # XSLT support with QtXmlPatterns !contains(DEFINES, ENABLE_XSLT=.) { @@ -2780,7 +2783,7 @@ unix:!mac:CONFIG += link_pkgconfig contains(DEFINES, ENABLE_XSLT=1) { FEATURE_DEFINES_JAVASCRIPT += ENABLE_XSLT=1 - QT += xmlpatterns + tobe|!tobe: QT += xmlpatterns SOURCES += \ bindings/js/JSXSLTProcessorConstructor.cpp \ @@ -3415,14 +3418,8 @@ CONFIG(QTDIR_build):isEqual(QT_MAJOR_VERSION, 4):greaterThan(QT_MINOR_VERSION, 4 symbian { shared { - contains(MMP_RULES, defBlock) { - MMP_RULES -= defBlock - - MMP_RULES += "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE ../WebKit/qt/symbian/bwins/$${TARGET}.def" \ - "$${LITERAL_HASH}elif defined EABI" \ - "DEFFILE ../WebKit/qt/symbian/eabi/$${TARGET}.def" \ - "$${LITERAL_HASH}endif" + contains(CONFIG, def_files) { + defFilePath=../WebKit/qt/symbian } } } diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp index 12edc42..d270e37 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp @@ -216,7 +216,6 @@ #include "JSWebKitCSSTransformValue.h" #include "JSWebKitPoint.h" #include "JSWebKitTransitionEvent.h" -#include "JSWebSocket.h" #include "JSWheelEvent.h" #include "JSWorker.h" #include "JSXMLHttpRequest.h" @@ -247,7 +246,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSDOMWindow); /* Hash table */ -static const HashTableValue JSDOMWindowTableValues[297] = +static const HashTableValue JSDOMWindowTableValues[296] = { { "screen", DontDelete|ReadOnly, (intptr_t)jsDOMWindowScreen, (intptr_t)0 }, { "history", DontDelete|ReadOnly, (intptr_t)jsDOMWindowHistory, (intptr_t)0 }, @@ -540,7 +539,6 @@ static const HashTableValue JSDOMWindowTableValues[297] = { "MessageChannel", DontDelete, (intptr_t)jsDOMWindowMessageChannelConstructor, (intptr_t)setJSDOMWindowMessageChannelConstructor }, { "Worker", DontDelete, (intptr_t)jsDOMWindowWorkerConstructor, (intptr_t)setJSDOMWindowWorkerConstructor }, { "SharedWorker", DontDelete, (intptr_t)jsDOMWindowSharedWorkerConstructor, (intptr_t)setJSDOMWindowSharedWorkerConstructor }, - { "WebSocket", DontDelete, (intptr_t)jsDOMWindowWebSocketConstructor, (intptr_t)setJSDOMWindowWebSocketConstructor }, { "Plugin", DontDelete, (intptr_t)jsDOMWindowPluginConstructor, (intptr_t)setJSDOMWindowPluginConstructor }, { "PluginArray", DontDelete, (intptr_t)jsDOMWindowPluginArrayConstructor, (intptr_t)setJSDOMWindowPluginArrayConstructor }, { "MimeType", DontDelete, (intptr_t)jsDOMWindowMimeTypeConstructor, (intptr_t)setJSDOMWindowMimeTypeConstructor }, @@ -588,7 +586,7 @@ static JSC_CONST_HASHTABLE HashTable JSDOMWindowTable = #if ENABLE(PERFECT_HASH_SIZE) { 65535, JSDOMWindowTableValues, 0 }; #else - { 1068, 1023, JSDOMWindowTableValues, 0 }; + { 1067, 1023, JSDOMWindowTableValues, 0 }; #endif /* Hash table for prototype */ @@ -3275,14 +3273,6 @@ JSValue jsDOMWindowSharedWorkerConstructor(ExecState* exec, const Identifier&, c return castedThis->sharedWorker(exec); } -JSValue jsDOMWindowWebSocketConstructor(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - JSDOMWindow* castedThis = static_cast<JSDOMWindow*>(asObject(slot.slotBase())); - if (!castedThis->allowsAccessFrom(exec)) - return jsUndefined(); - return castedThis->webSocket(exec); -} - JSValue jsDOMWindowPluginConstructor(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSDOMWindow* castedThis = static_cast<JSDOMWindow*>(asObject(slot.slotBase())); @@ -5678,14 +5668,6 @@ void setJSDOMWindowSharedWorkerConstructor(ExecState* exec, JSObject* thisObject static_cast<JSDOMWindow*>(thisObject)->putDirect(Identifier(exec, "SharedWorker"), value); } -void setJSDOMWindowWebSocketConstructor(ExecState* exec, JSObject* thisObject, JSValue value) -{ - if (!static_cast<JSDOMWindow*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindow*>(thisObject)->putDirect(Identifier(exec, "WebSocket"), value); -} - void setJSDOMWindowPluginConstructor(ExecState* exec, JSObject* thisObject, JSValue value) { if (!static_cast<JSDOMWindow*>(thisObject)->allowsAccessFrom(exec)) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h index afc8106..5a087e7 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h @@ -82,7 +82,6 @@ public: JSC::JSValue messageChannel(JSC::ExecState*) const; JSC::JSValue worker(JSC::ExecState*) const; JSC::JSValue sharedWorker(JSC::ExecState*) const; - JSC::JSValue webSocket(JSC::ExecState*) const; JSC::JSValue audio(JSC::ExecState*) const; // Custom functions @@ -679,8 +678,6 @@ JSC::JSValue jsDOMWindowWorkerConstructor(JSC::ExecState*, const JSC::Identifier void setJSDOMWindowWorkerConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowSharedWorkerConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void setJSDOMWindowSharedWorkerConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); -JSC::JSValue jsDOMWindowWebSocketConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); -void setJSDOMWindowWebSocketConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowPluginConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void setJSDOMWindowPluginConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowPluginArrayConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); diff --git a/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp b/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp index ee8726a..e67daf9 100644 --- a/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp +++ b/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp @@ -507,7 +507,7 @@ void ScrollView::scrollContents(const IntSize& scrollDelta) hostWindow()->repaint(panScrollIconDirtyRect, true); } - if (canBlitOnScroll() && !rootPreventsBlitting()) { // The main frame can just blit the WebView window + if (canBlitOnScroll()) { // The main frame can just blit the WebView window // FIXME: Find a way to blit subframes without blitting overlapping content hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect); } else { @@ -597,14 +597,6 @@ void ScrollView::setParent(ScrollView* parentView) if (m_scrollbarsAvoidingResizer && parent()) parent()->adjustScrollbarsAvoidingResizerCount(-m_scrollbarsAvoidingResizer); -#if PLATFORM(QT) - if (m_widgetsPreventingBlitting && parent()) - parent()->adjustWidgetsPreventingBlittingCount(-m_widgetsPreventingBlitting); - - if (m_widgetsPreventingBlitting && parentView) - parentView->adjustWidgetsPreventingBlittingCount(m_widgetsPreventingBlitting); -#endif - Widget::setParent(parentView); if (m_scrollbarsAvoidingResizer && parent()) diff --git a/src/3rdparty/webkit/WebCore/platform/ScrollView.h b/src/3rdparty/webkit/WebCore/platform/ScrollView.h index 1950a54..5dacff5 100644 --- a/src/3rdparty/webkit/WebCore/platform/ScrollView.h +++ b/src/3rdparty/webkit/WebCore/platform/ScrollView.h @@ -305,16 +305,6 @@ private: NSScrollView<WebCoreFrameScrollView>* scrollView() const; #endif -#if PLATFORM(QT) -public: - void adjustWidgetsPreventingBlittingCount(int delta); -private: - bool rootPreventsBlitting() const { return root()->m_widgetsPreventingBlitting > 0; } - unsigned m_widgetsPreventingBlitting; -#else - bool rootPreventsBlitting() const { return false; } -#endif - #if PLATFORM(GTK) public: void setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj); diff --git a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp index 989b34c..714cac9 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp @@ -39,6 +39,7 @@ #include <QGraphicsProxyWidget> #include <QGraphicsScene> #include <QGraphicsView> +#include <QGraphicsWebView> #include <QListWidget> #include <QListWidgetItem> #include <QMenu> @@ -57,8 +58,10 @@ PopupMenu::PopupMenu(PopupMenuClient* client) PopupMenu::~PopupMenu() { - delete m_popup; - delete m_proxy; + // If we create a proxy, then the deletion of the proxy and the + // combo will be done by the proxy's parent (QGraphicsWebView) + if (!m_proxy) + delete m_popup; } void PopupMenu::clear() @@ -100,9 +103,8 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) if (QGraphicsView* view = qobject_cast<QGraphicsView*>(client->ownerWidget())) { if (!m_proxy) { - m_proxy = new QGraphicsProxyWidget; + m_proxy = new QGraphicsProxyWidget(qobject_cast<QGraphicsWebView*>(client->pluginParent())); m_proxy->setWidget(m_popup); - view->scene()->addItem(m_proxy); } else m_proxy->setVisible(true); m_proxy->setGeometry(rect); diff --git a/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp b/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp index f7ebbc7..f6a8167 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp @@ -44,9 +44,16 @@ QWebPopup::QWebPopup(PopupMenuClient* client) void QWebPopup::exec() { + // QCursor::pos() is not a great idea for a touch screen, but we don't need the coordinates + // as comboboxes with Qt on Maemo 5 come up in their full width on the screen. + // On the other platforms it's okay to use QCursor::pos(). +#if defined(Q_WS_MAEMO_5) + showPopup(); +#else QMouseEvent event(QEvent::MouseButtonPress, QCursor::pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QCoreApplication::sendEvent(this, &event); +#endif } void QWebPopup::showPopup() diff --git a/src/3rdparty/webkit/WebCore/platform/qt/ScrollViewQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/ScrollViewQt.cpp index ccbd751..17ad253 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/ScrollViewQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/ScrollViewQt.cpp @@ -36,32 +36,19 @@ namespace WebCore { void ScrollView::platformInit() { - m_widgetsPreventingBlitting = 0; } void ScrollView::platformDestroy() { } -// Windowed plugins are using native windows and are thus preventing -// us from doing any kind of scrolling optimization. - -void ScrollView::adjustWidgetsPreventingBlittingCount(int delta) -{ - m_widgetsPreventingBlitting += delta; - if (parent()) - parent()->adjustWidgetsPreventingBlittingCount(delta); -} - void ScrollView::platformAddChild(Widget*) { - adjustWidgetsPreventingBlittingCount(1); } void ScrollView::platformRemoveChild(Widget* child) { child->hide(); - adjustWidgetsPreventingBlittingCount(-1); } } diff --git a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp index e61736b..476ab8a 100644 --- a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp @@ -126,6 +126,10 @@ void PluginView::updatePluginWidget() // scroll, we need to move/resize immediately. if (!m_windowRect.intersects(frameView->frameRect())) setNPWindowIfNeeded(); + + // Make sure we get repainted afterwards. This is necessary for downward + // scrolling to move the plugin widget properly. + invalidate(); } void PluginView::setFocus() @@ -657,7 +661,8 @@ NPError PluginView::getValue(NPNVariable variable, void* value) void PluginView::invalidateRect(const IntRect& rect) { if (m_isWindowed) { - platformWidget()->update(rect); + if (platformWidget()) + platformWidget()->update(rect); return; } diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp index 29bde0d..e4c2afc 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp @@ -1369,6 +1369,11 @@ void QWebFrame::print(QPrinter *printer) const // paranoia check fromPage = qMax(1, fromPage); toPage = qMin(printContext.pageCount(), toPage); + if (toPage < fromPage) { + // if the user entered a page range outside the actual number + // of printable pages, just return + return; + } if (printer->pageOrder() == QPrinter::LastPageFirst) { int tmp = fromPage; diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index ee555f3..697570f 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,63 @@ +2010-01-28 Trond KjernÃ¥sen <trond@trolltech.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix for endless print loop when printing web pages + + * Api/qwebframe.cpp: + (QWebFrame::print): + +2010-01-26 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Show comboboxes on Maemo 5 + https://bugs.webkit.org/show_bug.cgi?id=34088 + + Don't try to show the combobox by simulating a mouse event from QCursor::pos() to + get the combobox position right. The position on Maemo 5 is independent from the mouse + and there's no QCursor::pos(). + + * WebCoreSupport/QtFallbackWebPopup.cpp: + (WebCore::QtFallbackWebPopup::show): + +2010-01-26 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Simon Hausmann. + + [Qt] JavaScript prompt is currently broken + https://bugs.webkit.org/show_bug.cgi?id=30914 + + In r52152 a patch was landed to convert a null QString + to an empty WebCore::String in case the prompt was accepted + but the default implementation returned the null QString. + + The patch tried to avoid assign to result twice and + was not checking the QString if it is null but the default + value. This lead to always returning an empty string on + successful prompts. Fix it by checking the variable 'x' + for isNull. + + The manual test case used didn't cover the case of non + empty input, replace it with an automatic test case that + should cover all cases. + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::runJavaScriptPrompt): Fix the bug. + * tests/qwebpage/tst_qwebpage.cpp: Add automatic test case + (JSPromptPage::JSPromptPage): + (JSPromptPage::javaScriptPrompt): + (tst_QWebPage::testJSPrompt): + +2010-01-25 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + [Qt] Phone backup support for QtWebkit for Symbian devices. + https://bugs.webkit.org/show_bug.cgi?id=34077 + + * symbian/backup_registration.xml: Added. + 2009-11-19 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index c5d2792..0c5df4a 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -281,7 +281,7 @@ bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914. - if (rc && result.isNull()) + if (rc && x.isNull()) result = String(""); else result = x; diff --git a/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml b/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml new file mode 100644 index 0000000..e026140 --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" standalone="yes"?> +<backup_registration> + <system_backup/> + <restore requires_reboot = "no"/> +</backup_registration> 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 ee1969d..0e04acc 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> + Copyright (C) 2010 Holger Hans Peter Freyther This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -154,6 +155,7 @@ private slots: void screenshot(); void originatingObjectInNetworkRequests(); + void testJSPrompt(); private: QWebView* m_view; @@ -1781,5 +1783,72 @@ void tst_QWebPage::originatingObjectInNetworkRequests() #endif } +/** + * Test fixups for https://bugs.webkit.org/show_bug.cgi?id=30914 + * + * From JS we test the following conditions. + * + * OK + QString() => SUCCESS, empty string (but not null) + * OK + "text" => SUCCESS, "text" + * CANCEL + QString() => CANCEL, null string + * CANCEL + "text" => CANCEL, null string + */ +class JSPromptPage : public QWebPage { + Q_OBJECT +public: + JSPromptPage() + {} + + bool javaScriptPrompt(QWebFrame* frame, const QString& msg, const QString& defaultValue, QString* result) + { + if (msg == QLatin1String("test1")) { + *result = QString(); + return true; + } else if (msg == QLatin1String("test2")) { + *result = QLatin1String("text"); + return true; + } else if (msg == QLatin1String("test3")) { + *result = QString(); + return false; + } else if (msg == QLatin1String("test4")) { + *result = QLatin1String("text"); + return false; + } + + qFatal("Unknown msg."); + return QWebPage::javaScriptPrompt(frame, msg, defaultValue, result); + } +}; + +void tst_QWebPage::testJSPrompt() +{ + JSPromptPage page; + bool res; + + // OK + QString() + res = page.mainFrame()->evaluateJavaScript( + "var retval = prompt('test1');" + "retval=='' && retval.length == 0;").toBool(); + QVERIFY(res); + + // OK + "text" + res = page.mainFrame()->evaluateJavaScript( + "var retval = prompt('test2');" + "retval=='text' && retval.length == 4;").toBool(); + QVERIFY(res); + + // Cancel + QString() + res = page.mainFrame()->evaluateJavaScript( + "var retval = prompt('test3');" + "retval===null;").toBool(); + QVERIFY(res); + + // Cancel + "text" + res = page.mainFrame()->evaluateJavaScript( + "var retval = prompt('test4');" + "retval===null;").toBool(); + QVERIFY(res); +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 722d6d3..9179485 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -98,7 +98,7 @@ static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QS if (!fileName.isEmpty() && QT_STAT(QFile::encodeName(fileName), &statBuf) == 0 && (statBuf.st_mode & S_IFMT) == S_IFREG) { - mode += "+"; + mode += '+'; } else { mode = "wb+"; } diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 2c31509..64015ce 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1091,30 +1091,23 @@ static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope) return int((uint(format) << 1) | uint(scope == QSettings::SystemScope)); } -static QString getPath(QSettings::Format format, QSettings::Scope scope) +static void initDefaultPaths(QMutexLocker *locker) { - Q_ASSERT((int)QSettings::NativeFormat == 0); - Q_ASSERT((int)QSettings::IniFormat == 1); - + PathHash *pathHash = pathHashFunc(); QString homePath = QDir::homePath(); QString systemPath; - QMutexLocker locker(globalMutex()); - PathHash *pathHash = pathHashFunc(); - bool loadSystemPath = pathHash->isEmpty(); - locker.unlock(); - - if (loadSystemPath) { - /* - QLibraryInfo::location() uses QSettings, so in order to - avoid a dead-lock, we can't hold the global mutex while - calling it. - */ - systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); - systemPath += QLatin1Char('/'); - } + locker->unlock(); + + /* + QLibraryInfo::location() uses QSettings, so in order to + avoid a dead-lock, we can't hold the global mutex while + calling it. + */ + systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); + systemPath += QLatin1Char('/'); - locker.relock(); + locker->relock(); if (pathHash->isEmpty()) { /* Lazy initialization of pathHash. We initialize the @@ -1155,6 +1148,17 @@ static QString getPath(QSettings::Format format, QSettings::Scope scope) #endif #endif } +} + +static QString getPath(QSettings::Format format, QSettings::Scope scope) +{ + Q_ASSERT((int)QSettings::NativeFormat == 0); + Q_ASSERT((int)QSettings::IniFormat == 1); + + QMutexLocker locker(globalMutex()); + PathHash *pathHash = pathHashFunc(); + if (pathHash->isEmpty()) + initDefaultPaths(&locker); QString result = pathHash->value(pathHashKey(format, scope)); if (!result.isEmpty()) @@ -3455,6 +3459,8 @@ void QSettings::setPath(Format format, Scope scope, const QString &path) { QMutexLocker locker(globalMutex()); PathHash *pathHash = pathHashFunc(); + if (pathHash->isEmpty()) + initDefaultPaths(&locker); pathHash->insert(pathHashKey(format, scope), path + QDir::separator()); } diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index a131d6c..076cc33 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3241,8 +3241,11 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) while (1) { int idx = nextDotDelimiter(domain, lastIdx); int labelLength = idx - lastIdx; - if (labelLength == 0) + if (labelLength == 0) { + if (idx == domain.length()) + break; return QString(); // two delimiters in a row -- empty label not allowed + } // RFC 3490 says, about the ToASCII operation: // 3. If the UseSTD3ASCIIRules flag is set, then perform these checks: diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 21816b9..1b4b356 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -130,7 +130,7 @@ multiple- or virtual-inheritance (that is, in cases where two different pointer addresses can refer to the same object). In that case, if a pointer is cast to a different type and its value changes, - QSharedPointer's pointer tracking mechanism mail fail to detect that the + QSharedPointer's pointer tracking mechanism may fail to detect that the object being tracked is the same. \omit diff --git a/src/dbus/qdbusargument.cpp b/src/dbus/qdbusargument.cpp index 3466d90..7defc9a 100644 --- a/src/dbus/qdbusargument.cpp +++ b/src/dbus/qdbusargument.cpp @@ -535,7 +535,6 @@ QDBusArgument &QDBusArgument::operator<<(const QByteArray &arg) /*! \internal - Returns the type signature of the D-Bus type this QDBusArgument \since 4.5 Appends the variant \a v. diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 30fa0b6..44abf7b 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1660,9 +1660,6 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError } QString busService = QLatin1String(DBUS_SERVICE_DBUS); - WatchedServicesHash::mapped_type &bus = watchedServices[busService]; - bus.refcount = 1; - bus.owner = getNameOwnerNoCache(busService); connectSignal(busService, QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), this, SLOT(registerService(QString))); connectSignal(busService, QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), @@ -2004,7 +2001,8 @@ bool QDBusConnectionPrivate::connectSignal(const QString &service, entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && - entry.midx == hook.midx) { + entry.midx == hook.midx && + entry.argumentMatch == hook.argumentMatch) { // no need to compare the parameters if it's the same slot return true; // already there } @@ -2046,10 +2044,7 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook // Do we need to watch for this name? if (shouldWatchService(hook.service)) { WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; - if (data.refcount) { - // already watching - ++data.refcount; - } else { + if (++data.refcount == 1) { // we need to watch for this service changing QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); connectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), @@ -2089,7 +2084,8 @@ bool QDBusConnectionPrivate::disconnectSignal(const QString &service, entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && - entry.midx == hook.midx) { + entry.midx == hook.midx && + entry.argumentMatch == hook.argumentMatch) { // no need to compare the parameters if it's the same slot disconnectSignal(it); return true; // it was there @@ -2105,19 +2101,6 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) { const SignalHook &hook = it.value(); - WatchedServicesHash::Iterator sit = watchedServices.find(hook.service); - if (sit != watchedServices.end()) { - if (sit.value().refcount == 1) { - watchedServices.erase(sit); - QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); - disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), - QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), - this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); - } else { - --sit.value().refcount; - } - } - bool erase = false; MatchRefCountHash::iterator i = matchRefCounts.find(hook.matchRule); if (i == matchRefCounts.end()) { @@ -2136,6 +2119,20 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) if (connection && erase) { qDBusDebug("Removing rule: %s", hook.matchRule.constData()); q_dbus_bus_remove_match(connection, hook.matchRule, NULL); + + // Successfully disconnected the signal + // Were we watching for this name? + WatchedServicesHash::Iterator sit = watchedServices.find(hook.service); + if (sit != watchedServices.end()) { + if (--sit.value().refcount == 0) { + watchedServices.erase(sit); + QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); + disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), + QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), + this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + } + } + } return signalHooks.erase(it); diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index f156e04..8ec328e 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qdbusargument_p.h" +#include "qdbusmetatype_p.h" #include "qdbusutil_p.h" QT_BEGIN_NAMESPACE @@ -167,7 +168,7 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) QByteArray tmpSignature; const char *signature = 0; - if (int(id) == qMetaTypeId<QDBusArgument>()) { + if (int(id) == QDBusMetaTypeId::argument) { // take the signature from the QDBusArgument object we're marshalling tmpSignature = qvariant_cast<QDBusArgument>(value).currentSignature().toLatin1(); @@ -353,7 +354,7 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) } // intercept QDBusArgument parameters here - if (id == qMetaTypeId<QDBusArgument>()) { + if (id == QDBusMetaTypeId::argument) { QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg); QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument); if (!d->message) diff --git a/src/declarative/graphicsitems/qmlgraphicsflickable.cpp b/src/declarative/graphicsitems/qmlgraphicsflickable.cpp index da031f1..c4edb28 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflickable.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsflickable.cpp @@ -819,6 +819,32 @@ void QmlGraphicsFlickable::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) } } +void QmlGraphicsFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + Q_D(QmlGraphicsFlickable); + if (!d->interactive) { + QmlGraphicsItem::wheelEvent(event); + } else if (yflick()) { + if (event->delta() > 0) + d->velocityY = qMax(event->delta() - d->verticalVelocity.value(), qreal(250.0)); + else + d->velocityY = qMin(event->delta() - d->verticalVelocity.value(), qreal(-250.0)); + d->flicked = false; + d->flickY(d->velocityY); + event->accept(); + } else if (xflick()) { + if (event->delta() > 0) + d->velocityX = qMax(event->delta() - d->horizontalVelocity.value(), qreal(250.0)); + else + d->velocityX = qMin(event->delta() - d->horizontalVelocity.value(), qreal(-250.0)); + d->flicked = false; + d->flickX(d->velocityX); + event->accept(); + } else { + QmlGraphicsItem::wheelEvent(event); + } +} + void QmlGraphicsFlickablePrivate::captureDelayedPress(QGraphicsSceneMouseEvent *event) { Q_Q(QmlGraphicsFlickable); diff --git a/src/declarative/graphicsitems/qmlgraphicsflickable_p.h b/src/declarative/graphicsitems/qmlgraphicsflickable_p.h index df6f6b1..ea07da4 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflickable_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsflickable_p.h @@ -166,6 +166,7 @@ protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void wheelEvent(QGraphicsSceneWheelEvent *event); void timerEvent(QTimerEvent *event); QmlGraphicsFlickableVisibleArea *visibleArea(); diff --git a/src/declarative/graphicsitems/qmlgraphicsgridview.cpp b/src/declarative/graphicsitems/qmlgraphicsgridview.cpp index 2fad3bb..afc2e15 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgridview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsgridview.cpp @@ -151,14 +151,14 @@ class QmlGraphicsGridViewPrivate : public QmlGraphicsFlickablePrivate public: QmlGraphicsGridViewPrivate() - : model(0), currentItem(0), flow(QmlGraphicsGridView::LeftToRight) + : currentItem(0), flow(QmlGraphicsGridView::LeftToRight) , visiblePos(0), visibleIndex(0) , currentIndex(-1) , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1) , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) , bufferMode(NoBuffer) , ownModel(false), wrap(false), autoHighlight(true) - , fixCurrentVisibility(false), lazyRelease(false) {} + , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) {} void init(); void clear(); @@ -167,6 +167,7 @@ public: void refill(qreal from, qreal to, bool doBuffer=false); void updateGrid(); + void scheduleLayout(); void layout(bool removed=false); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); @@ -306,7 +307,7 @@ public: } } - QmlGraphicsVisualModel *model; + QGuard<QmlGraphicsVisualModel> model; QVariant modelVariant; QList<FxGridItem*> visibleItems; QHash<QmlGraphicsItem*,int> unrequestedItems; @@ -335,6 +336,7 @@ public: bool autoHighlight : 1; bool fixCurrentVisibility : 1; bool lazyRelease : 1; + bool layoutScheduled : 1; }; void QmlGraphicsGridViewPrivate::init() @@ -372,6 +374,7 @@ FxGridItem *QmlGraphicsGridViewPrivate::createItem(int modelIndex) model->completeItem(); listItem->item->setZValue(1); listItem->item->setParent(q->viewport()); + unrequestedItems.remove(listItem->item); } requestedIndex = 0; return listItem; @@ -381,7 +384,7 @@ FxGridItem *QmlGraphicsGridViewPrivate::createItem(int modelIndex) void QmlGraphicsGridViewPrivate::releaseItem(FxGridItem *item) { Q_Q(QmlGraphicsGridView); - if (!item) + if (!item || !model) return; if (trackedItem == item) { QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged())); @@ -435,7 +438,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) // creating/releasing multiple items in one frame // while flicking (as much as possible). while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { - //qDebug() << "refill: append item" << modelIndex; +// qDebug() << "refill: append item" << modelIndex; if (!(item = createItem(modelIndex))) break; item->setPosition(colPos, rowPos); @@ -463,7 +466,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) } colNum = colPos / colSize(); while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){ - //qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; +// qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos; if (!(item = createItem(visibleIndex-1))) break; --visibleIndex; @@ -487,7 +490,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) && item->endRowPos() < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) { if (item->attached->delayRemove()) break; - //qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos(); +// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos(); if (item->index != -1) visibleIndex++; visibleItems.removeFirst(); @@ -499,7 +502,7 @@ void QmlGraphicsGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) { if (item->attached->delayRemove()) break; - //qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; +// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1; visibleItems.removeLast(); releaseItem(item); changed = true; @@ -528,19 +531,27 @@ void QmlGraphicsGridViewPrivate::updateGrid() } } +void QmlGraphicsGridViewPrivate::scheduleLayout() +{ + Q_Q(QmlGraphicsGridView); + if (!layoutScheduled) { + layoutScheduled = true; + QMetaObject::invokeMethod(q, "layout", Qt::QueuedConnection); + } +} + void QmlGraphicsGridViewPrivate::layout(bool removed) { Q_Q(QmlGraphicsGridView); + layoutScheduled = false; if (visibleItems.count()) { qreal rowPos = visibleItems.first()->rowPos(); qreal colPos = visibleItems.first()->colPos(); - if (visibleIndex % columns != 0) { + int col = visibleIndex % columns; + if (colPos != col * colSize()) { if (removed) rowPos -= rowSize(); - colPos = (visibleIndex % columns) * colSize(); - visibleItems.first()->setPosition(colPos, rowPos); - } else if (colPos != 0) { - colPos = 0; + colPos = col * colSize(); visibleItems.first()->setPosition(colPos, rowPos); } for (int i = 1; i < visibleItems.count(); ++i) { @@ -555,6 +566,7 @@ void QmlGraphicsGridViewPrivate::layout(bool removed) } q->refill(); updateHighlight(); + moveReason = Other; if (flow == QmlGraphicsGridView::LeftToRight) { q->setViewportHeight(endPosition() - startPosition()); fixupY(); @@ -1126,7 +1138,7 @@ void QmlGraphicsGridView::setCacheBuffer(int buffer) These properties holds the width and height of each cell in the grid - The default sell size is 100x100. + The default cell size is 100x100. */ int QmlGraphicsGridView::cellWidth() const { @@ -1406,7 +1418,7 @@ void QmlGraphicsGridView::trackedPositionChanged() Q_D(QmlGraphicsGridView); if (!d->trackedItem) return; - if (!isFlicking() && !d->moving && d->moveReason != QmlGraphicsGridViewPrivate::Mouse) { + if (!isFlicking() && !d->moving && d->moveReason == QmlGraphicsGridViewPrivate::SetIndex) { const qreal viewPos = d->position(); if (d->trackedItem->rowPos() < viewPos && d->currentItem->rowPos() < viewPos) { d->setPosition(d->currentItem->rowPos() < d->trackedItem->rowPos() ? d->trackedItem->rowPos() : d->currentItem->rowPos()); @@ -1446,12 +1458,12 @@ void QmlGraphicsGridView::itemsInserted(int modelIndex, int count) // Special case of appending an item to the model. index = d->visibleIndex + d->visibleItems.count(); } else { - if (modelIndex + count - 1 < d->visibleIndex) { + if (modelIndex <= d->visibleIndex) { // Insert before visible items d->visibleIndex += count; for (int i = 0; i < d->visibleItems.count(); ++i) { FxGridItem *listItem = d->visibleItems.at(i); - if (listItem->index != -1) + if (listItem->index != -1 && listItem->index >= modelIndex) listItem->index += count; } } @@ -1492,71 +1504,25 @@ void QmlGraphicsGridView::itemsInserted(int modelIndex, int count) } QList<FxGridItem*> added; - FxGridItem *firstItem = d->firstVisibleItem(); - if (firstItem && rowPos < firstItem->rowPos()) { - int from = d->position() - d->buffer; - int i = 0; - int insertionIdx = index; - for (i = insertCount-1; i >= 0 && rowPos > from; --i) { - int mod = (modelIndex+i) % d->columns; - while (mod++ < d->columns && modelIndex + i < d->model->count() && i < insertCount) { - FxGridItem *item = d->createItem(modelIndex + i); - d->visibleItems.insert(insertionIdx, item); - item->setPosition(colPos, rowPos); - added.append(item); - colPos -= d->colSize(); - if (colPos < 0) { - colPos = d->colSize() * (d->columns-1); - rowPos -= d->rowSize(); - } - ++index; - ++i; - } - } - if (i >= 0) { - // If we didn't insert all our new items - anything - // before the current index is not visible - remove it. - while (insertionIdx--) { - FxGridItem *item = d->visibleItems.takeFirst(); - if (item->index != -1) - d->visibleIndex++; - d->releaseItem(item); - } - } else { - // adjust pos of items before inserted items. - for (int i = insertionIdx-1; i >= 0; i--) { - FxGridItem *gridItem = d->visibleItems.at(i); - gridItem->setPosition(colPos, rowPos); - colPos -= d->colSize(); - if (colPos < 0) { - colPos = d->colSize() * (d->columns-1); - rowPos -= d->rowSize(); - } - } - } - } else { - int i = 0; - for (i = 0; i < insertCount && rowPos + d->rowSize() - 1 <= to; ++i) { - int mod = (modelIndex+i) % d->columns; - while (mod++ < d->columns && modelIndex + i < d->model->count() && i < insertCount) { - FxGridItem *item = d->createItem(modelIndex + i); - d->visibleItems.insert(index, item); - item->setPosition(colPos, rowPos); - added.append(item); - colPos += d->colSize(); - if (colPos > d->colSize() * (d->columns-1)) { - colPos = 0; - rowPos += d->rowSize(); - } - ++index; - ++i; - } + int i = 0; + while (i < insertCount && rowPos <= to + d->rowSize()*(d->columns - (colPos/d->colSize()))/qreal(d->columns)) { + FxGridItem *item = d->createItem(modelIndex + i); + d->visibleItems.insert(index, item); + item->setPosition(colPos, rowPos); + added.append(item); + colPos += d->colSize(); + if (colPos > d->colSize() * (d->columns-1)) { + colPos = 0; + rowPos += d->rowSize(); } - if (i < insertCount) { - // We didn't insert all our new items, which means anything - // beyond the current index is not visible - remove it. - while (d->visibleItems.count() > index) - d->releaseItem(d->visibleItems.takeLast()); + ++index; + ++i; + } + if (i < insertCount) { + // We didn't insert all our new items, which means anything + // beyond the current index is not visible - remove it. + while (d->visibleItems.count() > index) { + d->releaseItem(d->visibleItems.takeLast()); } } @@ -1586,32 +1552,7 @@ void QmlGraphicsGridView::itemsRemoved(int modelIndex, int count) { Q_D(QmlGraphicsGridView); bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count; - int index = d->mapFromModel(modelIndex); - if (index == -1) { - if (modelIndex + count - 1 < d->visibleIndex) { - // Items removed before our visible items. - d->visibleIndex -= count; - for (int i = 0; i < d->visibleItems.count(); ++i) { - FxGridItem *listItem = d->visibleItems.at(i); - if (listItem->index != -1) - listItem->index -= count; - } - } - if (d->currentIndex >= modelIndex + count) { - d->currentIndex -= count; - if (d->currentItem) - d->currentItem->index -= count; - } else if (currentRemoved) { - // current item has been removed. - d->releaseItem(d->currentItem); - d->currentItem = 0; - d->currentIndex = -1; - d->updateCurrent(qMin(modelIndex, d->model->count()-1)); - } - d->layout(true); - emit countChanged(); - return; - } + bool removedVisible = false; // Remove the items from the visible list, skipping anything already marked for removal QList<FxGridItem*>::Iterator it = d->visibleItems.begin(); @@ -1619,6 +1560,8 @@ void QmlGraphicsGridView::itemsRemoved(int modelIndex, int count) FxGridItem *item = *it; if (item->index == -1 || item->index < modelIndex) { // already removed, or before removed items + if (item->index < modelIndex) + removedVisible = true; ++it; } else if (item->index >= modelIndex + count) { // after removed items @@ -1626,6 +1569,7 @@ void QmlGraphicsGridView::itemsRemoved(int modelIndex, int count) ++it; } else { // removed item + removedVisible = true; item->attached->emitRemove(); if (item->attached->delayRemove()) { item->index = -1; @@ -1659,17 +1603,27 @@ void QmlGraphicsGridView::itemsRemoved(int modelIndex, int count) } } - if (d->visibleItems.isEmpty()) { - d->visibleIndex = 0; - d->setPosition(0); - refill(); - } else { - // Correct the positioning of the items - d->layout(); + if (removedVisible) { + if (d->visibleItems.isEmpty()) { + d->visibleIndex = 0; + d->setPosition(0); + refill(); + } else { + // Correct the positioning of the items + d->scheduleLayout(); + } } + emit countChanged(); } +void QmlGraphicsGridView::layout() +{ + Q_D(QmlGraphicsGridView); + if (d->layoutScheduled) + d->layout(); +} + void QmlGraphicsGridView::destroyRemoved() { Q_D(QmlGraphicsGridView); diff --git a/src/declarative/graphicsitems/qmlgraphicsgridview_p.h b/src/declarative/graphicsitems/qmlgraphicsgridview_p.h index 1615469..d2ef70e 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgridview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsgridview_p.h @@ -148,6 +148,7 @@ private Q_SLOTS: void createdItem(int index, QmlGraphicsItem *item); void destroyingItem(QmlGraphicsItem *item); void sizeChange(); + void layout(); private: void refill(); diff --git a/src/declarative/graphicsitems/qmlgraphicsimage.cpp b/src/declarative/graphicsitems/qmlgraphicsimage.cpp index ad43027..a1e8c17 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimage.cpp @@ -128,6 +128,7 @@ QML_DEFINE_TYPE(Qt,4,6,Image,QmlGraphicsImage) QmlGraphicsImage::QmlGraphicsImage(QmlGraphicsItem *parent) : QmlGraphicsImageBase(*(new QmlGraphicsImagePrivate), parent) { + connect(this, SIGNAL(sourceChanged(QUrl)), this, SLOT(updatePaintedGeometry())); } QmlGraphicsImage::QmlGraphicsImage(QmlGraphicsImagePrivate &dd, QmlGraphicsItem *parent) @@ -270,6 +271,8 @@ void QmlGraphicsImage::updatePaintedGeometry() if (d->fillMode == PreserveAspectFit) { qreal widthScale = width() / qreal(d->pix.width()); qreal heightScale = height() / qreal(d->pix.height()); + if (!d->pix.width() || !d->pix.height()) + return; if (widthScale <= heightScale) { d->paintedWidth = width(); d->paintedHeight = widthScale * qreal(d->pix.height()); diff --git a/src/declarative/graphicsitems/qmlgraphicsimage_p.h b/src/declarative/graphicsitems/qmlgraphicsimage_p.h index 36066e1..dde5d79 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimage_p.h @@ -86,6 +86,8 @@ Q_SIGNALS: protected: QmlGraphicsImage(QmlGraphicsImagePrivate &dd, QmlGraphicsItem *parent); void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + +protected Q_SLOTS: void updatePaintedGeometry(); private: diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index bd3c1ea..b03f359 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -57,6 +57,7 @@ #include <QFile> #include <QEvent> #include <QGraphicsSceneMouseEvent> +#include <QtCore/qnumeric.h> #include <QtScript/qscriptengine.h> #include <QtGui/qgraphicstransform.h> #include <QtGui/qgraphicseffect.h> @@ -2160,6 +2161,7 @@ QmlGraphicsAnchorLine QmlGraphicsItem::baseline() const \qmlproperty Item Item::anchors.fill \qmlproperty Item Item::anchors.centerIn + \qmlproperty real Item::anchors.margins \qmlproperty real Item::anchors.topMargin \qmlproperty real Item::anchors.bottomMargin \qmlproperty real Item::anchors.leftMargin @@ -2172,6 +2174,7 @@ QmlGraphicsAnchorLine QmlGraphicsItem::baseline() const relationship with other items. Margins apply to top, bottom, left, right, and fill anchors. + The margins property can be used to set all of the various margins at once, to the same value. Offsets apply for horizontal center, vertical center, and baseline anchors. @@ -2790,6 +2793,7 @@ void QmlGraphicsItem::setTransformOrigin(TransformOrigin origin) if (origin != d->origin) { d->origin = origin; QGraphicsItem::setTransformOriginPoint(d->computeTransformOrigin()); + emit transformOriginChanged(d->origin); } } @@ -2842,6 +2846,9 @@ qreal QmlGraphicsItem::width() const void QmlGraphicsItem::setWidth(qreal w) { Q_D(QmlGraphicsItem); + if (qIsNaN(w)) + return; + d->widthValid = true; if (d->width == w) return; @@ -2911,6 +2918,9 @@ qreal QmlGraphicsItem::height() const void QmlGraphicsItem::setHeight(qreal h) { Q_D(QmlGraphicsItem); + if (qIsNaN(h)) + return; + d->heightValid = true; if (d->height == h) return; diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.h b/src/declarative/graphicsitems/qmlgraphicsitem.h index df8c634..8ae2d5c 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.h +++ b/src/declarative/graphicsitems/qmlgraphicsitem.h @@ -91,7 +91,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsItem : public QGraphicsObject, public QmlP Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL) Q_PROPERTY(bool wantsFocus READ wantsFocus NOTIFY wantsFocusChanged) Q_PROPERTY(QmlList<QGraphicsTransform *>* transform READ transform DESIGNABLE false FINAL) - Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin) + Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin NOTIFY transformOriginChanged) Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) Q_PROPERTY(QGraphicsEffect *effect READ graphicsEffect WRITE setGraphicsEffect) Q_ENUMS(TransformOrigin) @@ -176,6 +176,7 @@ Q_SIGNALS: void focusChanged(); void wantsFocusChanged(); void parentChanged(); + void transformOriginChanged(TransformOrigin); protected: bool isComponentComplete() const; diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp index f75833a..8fb7c84 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslistview.cpp @@ -210,7 +210,7 @@ class QmlGraphicsListViewPrivate : public QmlGraphicsFlickablePrivate, private Q public: QmlGraphicsListViewPrivate() - : model(0), currentItem(0), orient(QmlGraphicsListView::Vertical) + : currentItem(0), orient(QmlGraphicsListView::Vertical) , visiblePos(0), visibleIndex(0) , averageSize(100.0), currentIndex(-1), requestedIndex(-1) , highlightRangeStart(0), highlightRangeEnd(0) @@ -495,7 +495,7 @@ public: virtual void flickX(qreal velocity); virtual void flickY(qreal velocity); - QmlGraphicsVisualModel *model; + QGuard<QmlGraphicsVisualModel> model; QVariant modelVariant; QList<FxListItem*> visibleItems; QHash<QmlGraphicsItem*,int> unrequestedItems; @@ -605,6 +605,7 @@ FxListItem *QmlGraphicsListViewPrivate::createItem(int modelIndex) if (listItem->attached->m_prevSection != listItem->attached->m_section) createSection(listItem); } + unrequestedItems.remove(listItem->item); } requestedIndex = -1; @@ -614,7 +615,7 @@ FxListItem *QmlGraphicsListViewPrivate::createItem(int modelIndex) void QmlGraphicsListViewPrivate::releaseItem(FxListItem *item) { Q_Q(QmlGraphicsListView); - if (!item) + if (!item || !model) return; if (trackedItem == item) { const char *notifier1 = orient == QmlGraphicsListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged()); @@ -731,6 +732,7 @@ void QmlGraphicsListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (footer) updateFooter(); updateViewport(); + updateUnrequestedPositions(); } else if (!doBuffer && buffer && bufferMode != NoBuffer) { refill(from, to, true); } @@ -765,7 +767,6 @@ void QmlGraphicsListViewPrivate::layout() updateHeader(); if (footer) updateFooter(); - updateUnrequestedPositions(); updateViewport(); } @@ -779,14 +780,20 @@ void QmlGraphicsListViewPrivate::updateUnrequestedIndexes() void QmlGraphicsListViewPrivate::updateUnrequestedPositions() { - QHash<QmlGraphicsItem*,int>::const_iterator it; - for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) { - if (visibleItem(*it)) - continue; - if (orient == QmlGraphicsListView::Vertical) - it.key()->setY(positionAt(*it)); - else - it.key()->setX(positionAt(*it)); + Q_Q(QmlGraphicsListView); + if (unrequestedItems.count()) { + qreal pos = position(); + QHash<QmlGraphicsItem*,int>::const_iterator it; + for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) { + QmlGraphicsItem *item = it.key(); + if (orient == QmlGraphicsListView::Vertical) { + if (item->y() + item->height() > pos && item->y() < pos + q->height()) + item->setY(positionAt(*it)); + } else { + if (item->x() + item->width() > pos && item->x() < pos + q->width()) + item->setX(positionAt(*it)); + } + } } } @@ -2114,12 +2121,14 @@ void QmlGraphicsListView::viewportMoved() const qreal minX = minXExtent(); if ((minX - d->_moveX.value() < height()/2 || d->flickTargetX - d->_moveX.value() < height()/2) && minX != d->flickTargetX) - d->flickX(-d->verticalVelocity.value()); + d->flickX(-d->horizontalVelocity.value()); + d->bufferMode = QmlGraphicsListViewPrivate::BufferBefore; } else if (d->velocityX < 0) { const qreal maxX = maxXExtent(); if ((d->_moveX.value() - maxX < height()/2 || d->_moveX.value() - d->flickTargetX < height()/2) && maxX != d->flickTargetX) - d->flickX(-d->verticalVelocity.value()); + d->flickX(-d->horizontalVelocity.value()); + d->bufferMode = QmlGraphicsListViewPrivate::BufferAfter; } } d->inFlickCorrection = false; @@ -2399,12 +2408,12 @@ void QmlGraphicsListView::itemsInserted(int modelIndex, int count) // Special case of appending an item to the model. modelIndex = d->visibleIndex + d->visibleItems.count(); } else { - if (modelIndex + count - 1 < d->visibleIndex) { + if (modelIndex < d->visibleIndex) { // Insert before visible items d->visibleIndex += count; for (int i = 0; i < d->visibleItems.count(); ++i) { FxListItem *listItem = d->visibleItems.at(i); - if (listItem->index != -1) + if (listItem->index != -1 && listItem->index >= modelIndex) listItem->index += count; } } @@ -2609,6 +2618,7 @@ void QmlGraphicsListView::destroyRemoved() void QmlGraphicsListView::itemsMoved(int from, int to, int count) { Q_D(QmlGraphicsListView); + d->updateUnrequestedIndexes(); if (d->visibleItems.isEmpty()) { refill(); diff --git a/src/declarative/graphicsitems/qmlgraphicsloader.cpp b/src/declarative/graphicsitems/qmlgraphicsloader.cpp index bb1020c..7cd4d1a 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsloader.cpp @@ -64,8 +64,14 @@ void QmlGraphicsLoaderPrivate::clear() } source = QUrl(); - delete item; - item = 0; + if (item) { + // We can't delete immediately because our item may have triggered + // the Loader to load a different item. + item->setVisible(false); + static_cast<QGraphicsItem*>(item)->setParentItem(0); + item->deleteLater(); + item = 0; + } } void QmlGraphicsLoaderPrivate::initResize() diff --git a/src/declarative/graphicsitems/qmlgraphicspathview.cpp b/src/declarative/graphicsitems/qmlgraphicspathview.cpp index 112eda2..85e87eb 100644 --- a/src/declarative/graphicsitems/qmlgraphicspathview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspathview.cpp @@ -71,9 +71,11 @@ inline qreal qmlMod(qreal x, qreal y) class QmlGraphicsPathViewAttached : public QObject { Q_OBJECT + + Q_PROPERTY(bool onPath READ isOnPath NOTIFY onPathChanged) public: QmlGraphicsPathViewAttached(QObject *parent) - : QObject(parent), mo(new QmlOpenMetaObject(this)) + : QObject(parent), mo(new QmlOpenMetaObject(this)), onPath(false) { } @@ -91,10 +93,49 @@ public: mo->setValue(name, val); } + bool isOnPath() const { return onPath; } + void setOnPath(bool on) { + if (on != onPath) { + onPath = on; + emit onPathChanged(); + } + } + +Q_SIGNALS: + void onPathChanged(); + private: QmlOpenMetaObject *mo; + bool onPath; }; + +QmlGraphicsItem *QmlGraphicsPathViewPrivate::getItem(int modelIndex) +{ + Q_Q(QmlGraphicsPathView); + requestedIndex = modelIndex; + QmlGraphicsItem *item = model->item(modelIndex); + if (item) { + if (QObject *obj = QmlGraphicsPathView::qmlAttachedProperties(item)) + static_cast<QmlGraphicsPathViewAttached *>(obj)->setOnPath(true); + item->setParentItem(q); + } + requestedIndex = -1; + return item; +} + +void QmlGraphicsPathViewPrivate::releaseItem(QmlGraphicsItem *item) +{ + if (!item || !model) + return; + if (QObject *obj = QmlGraphicsPathView::qmlAttachedProperties(item)) + static_cast<QmlGraphicsPathViewAttached *>(obj)->setOnPath(false); + if (model->release(item) == 0) { + if (QObject *obj = QmlGraphicsPathView::qmlAttachedProperties(item)) + static_cast<QmlGraphicsPathViewAttached *>(obj)->setOnPath(false); + } +} + /*! \qmlclass PathView QmlGraphicsPathView \brief The PathView element lays out model-provided items on a path. @@ -126,6 +167,26 @@ QmlGraphicsPathView::~QmlGraphicsPathView() } /*! + \qmlattachedproperty bool PathView::onPath + This attached property holds whether the item is currently on the path. + + If a pathItemCount has been set, it is possible that some items may + be instantiated, but not considered to be currently on the path. + Usually, these items would be set invisible, for example: + + \code + Component { + Rectangle { + visible: PathView.onPath + ... + } + } + \endcode + + It is attached to each instance of the delegate. +*/ + +/*! \qmlproperty model PathView::model This property holds the model providing data for the view. diff --git a/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h b/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h index 7ffe6ac..18cb205 100644 --- a/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h @@ -79,7 +79,7 @@ public: : path(0), currentIndex(0), startPc(0), lastDist(0) , lastElapsed(0), stealMouse(false), ownModel(false), activeItem(0) , snapPos(0), dragMargin(0), moveOffset(this, &QmlGraphicsPathViewPrivate::setOffset) - , firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1), model(0) + , firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1) , moveReason(Other) { fixupOffsetEvent = QmlTimeLineEvent::timeLineEvent<QmlGraphicsPathViewPrivate, &QmlGraphicsPathViewPrivate::fixOffset>(&moveOffset, this); @@ -95,18 +95,8 @@ public: q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); } - QmlGraphicsItem *getItem(int modelIndex) { - Q_Q(QmlGraphicsPathView); - requestedIndex = modelIndex; - QmlGraphicsItem *item = model->item(modelIndex); - if (item) - item->setParentItem(q); - requestedIndex = -1; - return item; - } - void releaseItem(QmlGraphicsItem *item) { - model->release(item); - } + QmlGraphicsItem *getItem(int modelIndex); + void releaseItem(QmlGraphicsItem *item); bool isValid() const { return model && model->count() > 0 && model->isValid() && path; @@ -143,7 +133,7 @@ public: int pathOffset; int requestedIndex; QList<QmlGraphicsItem *> items; - QmlGraphicsVisualModel *model; + QGuard<QmlGraphicsVisualModel> model; QVariant modelVariant; enum MovementReason { Other, Key, Mouse }; MovementReason moveReason; diff --git a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp index 6e14d3a..c3495b3 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp @@ -784,8 +784,17 @@ Handles the given mouse \a event. void QmlGraphicsTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QmlGraphicsTextEdit); - if (d->focusOnPress) + if (d->focusOnPress){ + QGraphicsItem *p = parentItem();//###Is there a better way to find my focus scope? + while(p) { + if(p->flags() & QGraphicsItem::ItemIsFocusScope){ + p->setFocus(); + break; + } + p = p->parentItem(); + } setFocus(true); + } d->control->processEvent(event, QPointF(0, 0)); if (!event->isAccepted()) QmlGraphicsPaintedItem::mousePressEvent(event); diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp index 6068e93..cfb93f6 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp @@ -647,9 +647,15 @@ void QmlGraphicsTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QmlGraphicsTextInput); if(d->focusOnPress){ + QGraphicsItem *p = parentItem();//###Is there a better way to find my focus scope? + while(p) { + if(p->flags() & QGraphicsItem::ItemIsFocusScope){ + p->setFocus(); + break; + } + p = p->parentItem(); + } setFocus(true); - setCursorVisible(true); - d->focused = true; } d->control->processEvent(event); } diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp index 70e3a43..2fc143d 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp @@ -462,7 +462,8 @@ int QmlGraphicsVisualDataModelDataMetaObject::createProperty(const char *name, c QmlGraphicsVisualDataModelPrivate *model = QmlGraphicsVisualDataModelPrivate::get(data->m_model); if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) { - if (model->m_listAccessor->type() == QmlListAccessor::QmlList) { + if (model->m_listAccessor->type() == QmlListAccessor::QmlList + || model->m_listAccessor->type() == QmlListAccessor::QListPtr) { model->ensureRoles(); QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>(); if (object && object->property(name).isValid()) @@ -724,7 +725,7 @@ void QmlGraphicsVisualDataModel::setModel(const QVariant &model) } d->m_listAccessor = new QmlListAccessor; d->m_listAccessor->setList(model, d->m_context?d->m_context->engine():qmlEngine(this)); - if (d->m_listAccessor->type() != QmlListAccessor::QmlList) + if (d->m_listAccessor->type() != QmlListAccessor::QmlList && d->m_listAccessor->type() != QmlListAccessor::QListPtr) d->m_metaDataCacheable = true; if (d->m_delegate && d->modelCount()) { emit itemsInserted(0, d->modelCount()); @@ -805,8 +806,12 @@ QmlGraphicsVisualDataModel::ReleaseFlags QmlGraphicsVisualDataModel::release(Qml } if (d->m_cache.releaseItem(obj)) { - if (inPackage) + if (inPackage) { emit destroyingPackage(qobject_cast<QmlPackage*>(obj)); + } else { + item->setVisible(false); + static_cast<QGraphicsItem*>(item)->setParentItem(0); + } stat |= Destroyed; obj->deleteLater(); } else if (!inPackage) { diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index bb7abf3..26ebd27 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -115,7 +115,7 @@ QList<QmlError> QmlCompiler::errors() const /*! Returns true if \a val is a legal object id, false otherwise. - Legal ids must start with a letter or underscore, and contain only + Legal ids must start with a lower-case letter or underscore, and contain only letters, numbers and underscores. */ bool QmlCompiler::isValidId(const QString &val) @@ -123,6 +123,12 @@ bool QmlCompiler::isValidId(const QString &val) if (val.isEmpty()) return false; + // TODO this will be enforced and return false + if (val.at(0).isLetter() && !val.at(0).isLower()) { + //return false; + qWarning() << "id '" + val + "' is invalid: ids cannot start with uppercase letters. This will be enforced in an upcoming version of QML."; + } + QChar u(QLatin1Char('_')); for (int ii = 0; ii < val.count(); ++ii) if (val.at(ii) != u && @@ -677,6 +683,13 @@ void QmlCompiler::compileTree(Object *tree) QmlEnginePrivate::get(engine)->registerCompositeType(output); } +static bool ValuePtrLessThan(const Value *t1, const Value *t2) +{ + return t1->location.start.line < t2->location.start.line || + (t1->location.start.line == t2->location.start.line && + t1->location.start.column < t2->location.start.column); +} + bool QmlCompiler::buildObject(Object *obj, const BindingContext &ctxt) { componentStat.objects++; @@ -736,9 +749,46 @@ bool QmlCompiler::buildObject(Object *obj, const BindingContext &ctxt) } } + // Merge + Property *defaultProperty = 0; + Property *skipProperty = 0; + if (obj->defaultProperty) { + const QMetaObject *metaObject = obj->metaObject(); + Q_ASSERT(metaObject); + QMetaProperty p = QmlMetaType::defaultProperty(metaObject); + if (p.name()) { + Property *explicitProperty = obj->getProperty(p.name(), false); + if (explicitProperty && !explicitProperty->value) { + skipProperty = explicitProperty; + + defaultProperty = new Property; + defaultProperty->parent = obj; + defaultProperty->isDefault = true; + defaultProperty->location = obj->defaultProperty->location; + defaultProperty->listValueRange = obj->defaultProperty->listValueRange; + defaultProperty->listCommaPositions = obj->defaultProperty->listCommaPositions; + + defaultProperty->values = obj->defaultProperty->values; + defaultProperty->values += explicitProperty->values; + foreach(Value *value, defaultProperty->values) + value->addref(); + qSort(defaultProperty->values.begin(), defaultProperty->values.end(), ValuePtrLessThan); + + } else { + defaultProperty = obj->defaultProperty; + defaultProperty->addref(); + } + } else { + defaultProperty = obj->defaultProperty; + defaultProperty->addref(); + } + } + // Build all explicit properties specified foreach(Property *prop, obj->properties) { + if (prop == skipProperty) + continue; if (prop->name == "id") continue; @@ -768,8 +818,8 @@ bool QmlCompiler::buildObject(Object *obj, const BindingContext &ctxt) } // Build the default property - if (obj->defaultProperty) { - Property *prop = obj->defaultProperty; + if (defaultProperty) { + Property *prop = defaultProperty; bool canDefer = false; if (isCustomParser) { @@ -791,6 +841,9 @@ bool QmlCompiler::buildObject(Object *obj, const BindingContext &ctxt) prop->isDeferred = true; } + if (defaultProperty) + defaultProperty->release(); + // Compile custom parser parts if (isCustomParser && !customProps.isEmpty()) { QmlCustomParser *cp = output->types.at(obj->type).type->customParser(); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index b3ac1bb..ea0c054 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -122,7 +122,7 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) contextClass(0), sharedContext(0), sharedScope(0), objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0), inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttacheds(0), inBeginCreate(false), - networkAccessManager(0), networkAccessManagerFactory(0), accessManagerValid(false), + networkAccessManager(0), networkAccessManagerFactory(0), typeManager(e), uniqueId(1) { globalClass = new QmlGlobalScriptClass(&scriptEngine); @@ -221,6 +221,11 @@ QScriptValue QmlScriptEngine::resolvedUrl(QScriptContext *ctxt, QScriptEngine *e return QScriptValue(r.toString()); } +QNetworkAccessManager *QmlScriptEngine::networkAccessManager() +{ + return p->getNetworkAccessManager(); +} + QmlEnginePrivate::~QmlEnginePrivate() { while (cleanup) { @@ -412,10 +417,18 @@ QmlNetworkAccessManagerFactory *QmlEngine::networkAccessManagerFactory() const return d->networkAccessManagerFactory; } -void QmlEngine::namInvalidated() +QNetworkAccessManager *QmlEnginePrivate::getNetworkAccessManager() const { - Q_D(QmlEngine); - d->accessManagerValid = false; + Q_Q(const QmlEngine); + + if (!networkAccessManager) { + if (networkAccessManagerFactory) { + networkAccessManager = networkAccessManagerFactory->create(const_cast<QmlEngine*>(q)); + } else { + networkAccessManager = new QNetworkAccessManager(const_cast<QmlEngine*>(q)); + } + } + return networkAccessManager; } /*! @@ -432,21 +445,7 @@ void QmlEngine::namInvalidated() QNetworkAccessManager *QmlEngine::networkAccessManager() const { Q_D(const QmlEngine); - if (!d->accessManagerValid) { - delete d->networkAccessManagerFactory; - d->networkAccessManagerFactory = 0; - } - if (!d->networkAccessManager) { - if (d->networkAccessManagerFactory) { - connect(d->networkAccessManagerFactory, SIGNAL(invalidated()) - , this, SLOT(namInvalidated()), Qt::UniqueConnection); - d->networkAccessManager = d->networkAccessManagerFactory->create(const_cast<QmlEngine*>(this)); - } else { - d->networkAccessManager = new QNetworkAccessManager(const_cast<QmlEngine*>(this)); - } - d->accessManagerValid = true; - } - return d->networkAccessManager; + return d->getNetworkAccessManager(); } /*! @@ -1234,8 +1233,10 @@ public: QFactoryLoader *l = loader(); QmlModuleFactoryInterface *factory = qobject_cast<QmlModuleFactoryInterface*>(l->instance(uri)); - if (factory) + if (factory) { + factory->defineModuleOnce(uri); isbuiltin = true; + } } else { url = base.resolved(QUrl(url)).toString(); } diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h index b9ec277..7ee014a 100644 --- a/src/declarative/qml/qmlengine.h +++ b/src/declarative/qml/qmlengine.h @@ -95,9 +95,6 @@ public: Q_SIGNALS: void quit (); -private Q_SLOTS: - void namInvalidated(); - private: Q_DECLARE_PRIVATE(QmlEngine) }; diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 6f62b40..6aa5d69 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -108,8 +108,7 @@ class QmlScriptEngine : public QScriptEngine { public: QmlScriptEngine(QmlEnginePrivate *priv); - - ~QmlScriptEngine(); + virtual ~QmlScriptEngine(); QUrl resolvedUrl(QScriptContext *context, const QUrl& url); // resolved against p's context, or baseUrl if no p static QScriptValue resolvedUrl(QScriptContext *ctxt, QScriptEngine *engine); @@ -127,6 +126,8 @@ public: QScriptClass *nodeListClass; QUrl baseUrl; + + virtual QNetworkAccessManager *networkAccessManager(); }; class Q_AUTOTEST_EXPORT QmlEnginePrivate : public QObjectPrivate @@ -209,9 +210,10 @@ public: QmlComponentAttached *componentAttacheds; bool inBeginCreate; + + QNetworkAccessManager *getNetworkAccessManager() const; mutable QNetworkAccessManager *networkAccessManager; mutable QmlNetworkAccessManagerFactory *networkAccessManagerFactory; - mutable bool accessManagerValid; QmlCompositeTypeManager typeManager; QStringList fileImportPath; diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 3e8d71a..ff1705b 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -184,7 +184,7 @@ QScriptValue QmlExpressionPrivate::evalInObjectScope(QmlContext *context, QObjec /*! \class QmlExpression - \brief The QmlExpression class evaluates ECMAScript in a QML context. + \brief The QmlExpression class evaluates JavaScript in a QML context. */ /*! @@ -212,7 +212,7 @@ QmlExpression::QmlExpression(QmlContext *ctxt, void *expr, /*! Create a QmlExpression object. - The \a expression ECMAScript will be executed in the \a ctxt QmlContext. + The \a expression JavaScript will be executed in the \a ctxt QmlContext. If specified, the \a scope object's properties will also be in scope during the expression's execution. */ diff --git a/src/declarative/qml/qmlmoduleplugin.cpp b/src/declarative/qml/qmlmoduleplugin.cpp index 3346ec7..2f2cb25 100644 --- a/src/declarative/qml/qmlmoduleplugin.cpp +++ b/src/declarative/qml/qmlmoduleplugin.cpp @@ -59,11 +59,12 @@ QT_BEGIN_NAMESPACE exporting the class with the Q_EXPORT_PLUGIN2() macro. See \l{How to Create Qt Plugins} for details. - The plugin should register QML types with QML_DEFINE_TYPE. - The strings returned by keys() should be the list of URIs of modules that the plugin registers. + The plugin should register QML types with qmlRegisterType() when the + defineModule() method is called. + \sa examples/declarative/plugins */ @@ -86,4 +87,25 @@ QmlModulePlugin::~QmlModulePlugin() { } +/*! + \fn void QmlModulePlugin::defineModule(const QString& uri) + + Subclasses must override this function to register types + of the module \a uri, which will be one of the strings returned by keys(). + + The plugin registers QML types with qmlRegisterType(): + + \code + qmlRegisterType<MyClass>("com.nokia.MyModule", 1, 0, "MyType", "MyClass"); + \endcode +*/ + +void QmlModulePlugin::defineModuleOnce(const QString& uri) +{ + if (!defined.contains(uri)) { + defined += uri; + defineModule(uri); + } +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlmoduleplugin.h b/src/declarative/qml/qmlmoduleplugin.h index 315209d..384e05e 100644 --- a/src/declarative/qml/qmlmoduleplugin.h +++ b/src/declarative/qml/qmlmoduleplugin.h @@ -45,6 +45,7 @@ #include <QtCore/qplugin.h> #include <QtCore/qfactoryinterface.h> #include <QtCore/qlist.h> +#include <QtCore/qset.h> #include <QtCore/qbytearray.h> QT_BEGIN_HEADER @@ -55,6 +56,7 @@ QT_MODULE(Declarative) struct Q_DECLARATIVE_EXPORT QmlModuleFactoryInterface : public QFactoryInterface { + virtual void defineModuleOnce(const QString& uri) = 0; }; #define QmlModuleFactoryInterface_iid "com.nokia.Qt.QmlModuleFactoryInterface" @@ -69,6 +71,12 @@ class Q_DECLARATIVE_EXPORT QmlModulePlugin : public QObject, public QmlModuleFac public: explicit QmlModulePlugin(QObject *parent = 0); ~QmlModulePlugin(); + + virtual void defineModule(const QString& uri) = 0; + +private: + void defineModuleOnce(const QString& uri); + QSet<QString> defined; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp b/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp index 6ae20de..76f20d8 100644 --- a/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp +++ b/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp @@ -76,18 +76,4 @@ QmlNetworkAccessManagerFactory::~QmlNetworkAccessManagerFactory() implementation of this method is reentrant. */ -/*! - Invalidates all currently created QNetworkAccessManager(s) which - will cause create() to be called for subsequent network access. -*/ -void QmlNetworkAccessManagerFactory::invalidate() -{ - emit invalidated(); -} - -/*! - \internal - \fn QmlNetworkAccessManagerFactory::invalidated() -*/ - QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlnetworkaccessmanagerfactory.h b/src/declarative/qml/qmlnetworkaccessmanagerfactory.h index f64918b..ce9860f 100644 --- a/src/declarative/qml/qmlnetworkaccessmanagerfactory.h +++ b/src/declarative/qml/qmlnetworkaccessmanagerfactory.h @@ -51,16 +51,12 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QNetworkAccessManager; -class Q_DECLARATIVE_EXPORT QmlNetworkAccessManagerFactory : public QObject +class Q_DECLARATIVE_EXPORT QmlNetworkAccessManagerFactory { - Q_OBJECT public: virtual ~QmlNetworkAccessManagerFactory(); - void invalidate(); virtual QNetworkAccessManager *create(QObject *parent) = 0; -Q_SIGNALS: - void invalidated(); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index 5fd76c6..4ff4746 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -70,7 +70,7 @@ struct ObjectData : public QScriptDeclarativeClass::Object { */ QmlObjectScriptClass::QmlObjectScriptClass(QmlEngine *bindEngine) : QmlScriptClass(QmlEnginePrivate::getScriptEngine(bindEngine)), -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) +#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) methods(bindEngine), #endif lastData(0), engine(bindEngine) @@ -231,7 +231,7 @@ QmlObjectScriptClass::property(QObject *obj, const Identifier &name) if (lastData->flags & QmlPropertyCache::Data::IsVMEFunction) { return Value(scriptEngine, ((QmlVMEMetaObject *)(obj->metaObject()))->vmeMethod(lastData->coreIndex)); } else { -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) +#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) // Uncomment to use QtScript method call logic // QScriptValue sobj = scriptEngine->newQObject(obj); // return Value(scriptEngine, sobj.property(toString(name))); @@ -444,7 +444,7 @@ QStringList QmlObjectScriptClass::propertyNames(Object *object) return cache->propertyNames(); } -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) +#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) struct MethodData : public QScriptDeclarativeClass::Object { MethodData(QObject *o, const QmlPropertyCache::Data &d) : object(o), data(d) {} diff --git a/src/declarative/qml/qmlobjectscriptclass_p.h b/src/declarative/qml/qmlobjectscriptclass_p.h index ebb2c2a..470c555 100644 --- a/src/declarative/qml/qmlobjectscriptclass_p.h +++ b/src/declarative/qml/qmlobjectscriptclass_p.h @@ -65,7 +65,7 @@ class QScriptContext; class QScriptEngine; class QmlContext; -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) +#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) class Q_AUTOTEST_EXPORT QmlObjectMethodScriptClass : public QScriptDeclarativeClass { public: @@ -118,7 +118,7 @@ protected: virtual QObject *toQObject(Object *, bool *ok = 0); private: -#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2)) +#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) QmlObjectMethodScriptClass methods; #endif diff --git a/src/declarative/qml/qmlscript.cpp b/src/declarative/qml/qmlscript.cpp index ba62898..10fc9a6 100644 --- a/src/declarative/qml/qmlscript.cpp +++ b/src/declarative/qml/qmlscript.cpp @@ -70,7 +70,7 @@ defining functions that are only executed later once the context is fully defined. - \sa {ECMAScript Blocks} + \sa {JavaScript Blocks} */ /*! diff --git a/src/declarative/qml/qmlscriptclass_p.h b/src/declarative/qml/qmlscriptclass_p.h index 7ffb2ae..847ee66 100644 --- a/src/declarative/qml/qmlscriptclass_p.h +++ b/src/declarative/qml/qmlscriptclass_p.h @@ -66,7 +66,7 @@ public: static QVariant toVariant(QmlEngine *, const QScriptValue &); -#if (QT_VERSION < QT_VERSION_CHECK(4, 6, 2)) +#if (QT_VERSION <= QT_VERSION_CHECK(4, 6, 2)) && !defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) struct Value : public QScriptValue { Value() : QScriptValue() {} Value(QScriptEngine *engine, int v) : QScriptValue(engine, v) {} diff --git a/src/declarative/qml/qmlworkerscript.cpp b/src/declarative/qml/qmlworkerscript.cpp index 75c5179..f58aa8b 100644 --- a/src/declarative/qml/qmlworkerscript.cpp +++ b/src/declarative/qml/qmlworkerscript.cpp @@ -51,6 +51,7 @@ #include <QtCore/qwaitcondition.h> #include <QtScript/qscriptvalueiterator.h> #include <QtCore/qfile.h> +#include <QtNetwork/qnetworkaccessmanager.h> #include <QtDeclarative/qmlinfo.h> QT_BEGIN_NAMESPACE @@ -107,7 +108,14 @@ public: struct ScriptEngine : public QmlScriptEngine { ScriptEngine(QmlWorkerScriptEnginePrivate *parent) : QmlScriptEngine(0), p(parent) {} + ~ScriptEngine() { delete manager; }; QmlWorkerScriptEnginePrivate *p; + QNetworkAccessManager *manager; + + virtual QNetworkAccessManager *networkAccessManager() { + if (!manager) manager = new QNetworkAccessManager; + return manager; + } }; ScriptEngine *workerEngine; static QmlWorkerScriptEnginePrivate *get(QScriptEngine *e) { @@ -128,6 +136,9 @@ public: QScriptValue callback; }; + QNetworkAccessManager *networkAccessManager; + QNetworkAccessManager *getNetworkAccessManager(); + QHash<int, WorkerScript *> workers; QScriptValue getWorker(int); @@ -224,7 +235,7 @@ private: Q_DECLARE_METATYPE(QmlWorkerListModelAgent::VariantRef); QmlWorkerScriptEnginePrivate::QmlWorkerScriptEnginePrivate() -: workerEngine(0), m_nextId(0) +: workerEngine(0), networkAccessManager(0), m_nextId(0) { } diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp index f69f254..86bec20 100644 --- a/src/declarative/qml/qmlxmlhttprequest.cpp +++ b/src/declarative/qml/qmlxmlhttprequest.cpp @@ -940,7 +940,7 @@ public: Opened = 1, HeadersReceived = 2, Loading = 3, Done = 4 }; - QmlXMLHttpRequest(); + QmlXMLHttpRequest(QNetworkAccessManager *manager); virtual ~QmlXMLHttpRequest(); QScriptValue callback() const; @@ -966,12 +966,16 @@ private slots: void finished(); private: + void requestFromUrl(const QUrl &url); + State m_state; bool m_errorFlag; bool m_sendFlag; QString m_method; QUrl m_url; QByteArray m_responseEntityBody; + QByteArray m_data; + int m_redirectCount; typedef QPair<QByteArray, QByteArray> HeaderPair; typedef QList<HeaderPair> HeadersList; @@ -989,26 +993,18 @@ private: void destroyNetwork(); QNetworkAccessManager *m_nam; - QNetworkAccessManager *networkAccessManager() - { - if (!m_nam) { - m_nam = new QNetworkAccessManager; - // XXX proxy, etc... - } - return m_nam; - } + QNetworkAccessManager *networkAccessManager() { return m_nam; } }; -QmlXMLHttpRequest::QmlXMLHttpRequest() +QmlXMLHttpRequest::QmlXMLHttpRequest(QNetworkAccessManager *manager) : m_state(Unsent), m_errorFlag(false), m_sendFlag(false), - m_network(0), m_nam(0) + m_redirectCount(0), m_network(0), m_nam(manager) { } QmlXMLHttpRequest::~QmlXMLHttpRequest() { destroyNetwork(); - delete m_nam; } QScriptValue QmlXMLHttpRequest::callback() const @@ -1109,16 +1105,10 @@ void QmlXMLHttpRequest::fillHeadersList() } } -QScriptValue QmlXMLHttpRequest::send(const QByteArray &data) +void QmlXMLHttpRequest::requestFromUrl(const QUrl &url) { - m_errorFlag = false; - m_sendFlag = true; - - QScriptValue cbv = dispatchCallback(); - if (cbv.isError()) return cbv; - - m_request.setUrl(m_url); QNetworkRequest request = m_request; + request.setUrl(url); if(m_method == QLatin1String("POST") || m_method == QLatin1String("PUT")) { QVariant var = request.header(QNetworkRequest::ContentTypeHeader); @@ -1153,9 +1143,9 @@ QScriptValue QmlXMLHttpRequest::send(const QByteArray &data) else if (m_method == QLatin1String("HEAD")) m_network = networkAccessManager()->head(request); else if(m_method == QLatin1String("POST")) - m_network = networkAccessManager()->post(request, data); + m_network = networkAccessManager()->post(request, m_data); else if(m_method == QLatin1String("PUT")) - m_network = networkAccessManager()->put(request, data); + m_network = networkAccessManager()->put(request, m_data); QObject::connect(m_network, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64))); @@ -1163,6 +1153,16 @@ QScriptValue QmlXMLHttpRequest::send(const QByteArray &data) this, SLOT(error(QNetworkReply::NetworkError))); QObject::connect(m_network, SIGNAL(finished()), this, SLOT(finished())); +} + +QScriptValue QmlXMLHttpRequest::send(const QByteArray &data) +{ + m_errorFlag = false; + m_sendFlag = true; + m_redirectCount = 0; + m_data = data; + + requestFromUrl(m_url); return QScriptValue(); } @@ -1224,6 +1224,7 @@ void QmlXMLHttpRequest::error(QNetworkReply::NetworkError error) m_responseEntityBody = QByteArray(); m_request = QNetworkRequest(); + m_data.clear(); destroyNetwork(); if (error == QNetworkReply::ContentAccessDenied || @@ -1243,9 +1244,19 @@ void QmlXMLHttpRequest::error(QNetworkReply::NetworkError error) if (cbv.isError()) printError(cbv); } +#define XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION 15 void QmlXMLHttpRequest::finished() { - // ### We need to transparently redirect as dictated by the spec + m_redirectCount++; + if (m_redirectCount < XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION) { + QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect.isValid()) { + QUrl url = redirect.toUrl(); + destroyNetwork(); + requestFromUrl(url); + return; + } + } m_status = m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); @@ -1259,6 +1270,7 @@ void QmlXMLHttpRequest::finished() if (cbv.isError()) printError(cbv); } m_responseEntityBody.append(m_network->readAll()); + m_data.clear(); destroyNetwork(); if (m_state < Loading) { m_state = Loading; @@ -1548,7 +1560,7 @@ static QScriptValue qmlxmlhttprequest_onreadystatechange(QScriptContext *context static QScriptValue qmlxmlhttprequest_new(QScriptContext *context, QScriptEngine *engine) { if (context->isCalledAsConstructor()) { - context->thisObject().setData(engine->newQObject(new QmlXMLHttpRequest(), QScriptEngine::ScriptOwnership)); + context->thisObject().setData(engine->newQObject(new QmlXMLHttpRequest(QmlScriptEngine::get(engine)->networkAccessManager()), QScriptEngine::ScriptOwnership)); } return engine->undefinedValue(); } diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index 63044bc..74f5b3a 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -1762,7 +1762,7 @@ void QmlPropertyAnimation::setTo(const QVariant &t) \table \row - \o \c easeNone + \o \c easeLinear \o Easing curve for a linear (t) function: velocity is constant. \o \inlineimage qeasingcurve-linear.png \row diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp index 8c70539..0b19574 100644 --- a/src/declarative/util/qmllistmodel.cpp +++ b/src/declarative/util/qmllistmodel.cpp @@ -161,10 +161,10 @@ static void dump(ModelNode *node, int ind); id: fruitDelegate Item { width: 200; height: 50 - Text { id: Name; text: name } + Text { id: name; text: name } Text { text: '$'+cost; anchors.right: parent.right } Row { - anchors.top: Name.bottom + anchors.top: name.bottom spacing: 5 Text { text: "Attributes:" } Repeater { diff --git a/src/declarative/util/qmlpixmapcache.cpp b/src/declarative/util/qmlpixmapcache.cpp index 5189118..755863a 100644 --- a/src/declarative/util/qmlpixmapcache.cpp +++ b/src/declarative/util/qmlpixmapcache.cpp @@ -75,6 +75,20 @@ inline uint qHash(const QUrl &uri) return qHash(uri.toEncoded(QUrl::FormattingOption(0x100))); } + +class QmlImageReaderEvent : public QEvent +{ +public: + enum ReadError { NoError, Loading, Decoding }; + + QmlImageReaderEvent(QmlImageReaderEvent::ReadError err, QImage &img) + : QEvent(QEvent::User), error(err), image(img) {} + + ReadError error; + QImage image; +}; + +class QmlImageRequestHandler; class QmlImageReader : public QThread { Q_OBJECT @@ -89,130 +103,61 @@ public: protected: void run(); - bool event(QEvent *event); - -private slots: - void networkRequestDone(); - void namInvalidated() { - accessManagerValid = false; - } private: - QNetworkAccessManager *networkAccessManager() { - if (!accessManagerValid) { - delete accessManager; - accessManager = 0; - } - if (!accessManager) { - if (engine && engine->networkAccessManagerFactory()) { - connect(engine->networkAccessManagerFactory(), SIGNAL(invalidated()) - , this, SLOT(namInvalidated()), Qt::UniqueConnection); - accessManager = engine->networkAccessManagerFactory()->create(this); - } else { - accessManager = new QNetworkAccessManager(this); - } - accessManagerValid = true; - } - return accessManager; - } - QList<QmlPixmapReply*> jobs; QList<QmlPixmapReply*> cancelled; - QHash<QNetworkReply*,QmlPixmapReply*> replies; - QNetworkAccessManager *accessManager; - bool accessManagerValid; QmlEngine *engine; + QmlImageRequestHandler *handler; QMutex mutex; + static QHash<QmlEngine *,QmlImageReader*> readers; + friend class QmlImageRequestHandler; }; QHash<QmlEngine *,QmlImageReader*> QmlImageReader::readers; -class QmlImageReaderEvent : public QEvent -{ -public: - enum ReadError { NoError, Loading, Decoding }; - - QmlImageReaderEvent(QmlImageReaderEvent::ReadError err, QImage &img) - : QEvent(QEvent::User), error(err), image(img) {} - - ReadError error; - QImage image; -}; - -QmlImageReader::QmlImageReader(QmlEngine *eng) - : QThread(eng), accessManager(0), accessManagerValid(false), engine(eng) +class QmlImageRequestHandler : public QObject { - start(QThread::LowPriority); -} - -QmlImageReader::~QmlImageReader() -{ -} - -QmlImageReader *QmlImageReader::instance(QmlEngine *engine) -{ - QmlImageReader *reader = readers.value(engine); - if (!reader) { - static QMutex rmutex; - rmutex.lock(); - reader = new QmlImageReader(engine); - readers.insert(engine, reader); - rmutex.unlock(); + Q_OBJECT +public: + QmlImageRequestHandler(QmlImageReader *read, QmlEngine *eng) + : QObject(), accessManager(0), engine(eng), reader(read) + { + QCoreApplication::postEvent(this, new QEvent(QEvent::User)); } - return reader; -} + QmlPixmapReply *getImage(const QUrl &url); + void cancel(QmlPixmapReply *reply); -QmlPixmapReply *QmlImageReader::getImage(const QUrl &url) -{ - mutex.lock(); - QmlPixmapReply *reply = new QmlPixmapReply(engine, url); - jobs.append(reply); - if (jobs.count() == 1) - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - mutex.unlock(); - return reply; -} +protected: + bool event(QEvent *event); -void QmlImageReader::cancel(QmlPixmapReply *reply) -{ - mutex.lock(); - if (reply->isLoading()) { - // Already requested. Add to cancel list to be cancelled in reader thread. - cancelled.append(reply); - if (cancelled.count() == 1) - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - } else { - // Not yet processed - just remove from waiting list - QList<QmlPixmapReply*>::iterator it = jobs.begin(); - while (it != jobs.end()) { - QmlPixmapReply *job = *it; - if (job == reply) { - jobs.erase(it); - break; +private slots: + void networkRequestDone(); + +private: + QNetworkAccessManager *networkAccessManager() { + if (!accessManager) { + if (engine && engine->networkAccessManagerFactory()) { + accessManager = engine->networkAccessManagerFactory()->create(this); + } else { + accessManager = new QNetworkAccessManager(this); } - ++it; } + return accessManager; } - mutex.unlock(); -} - -void QmlImageReader::run() -{ -#ifdef Q_OS_LINUX - struct sched_param param; - int policy; - pthread_getschedparam(pthread_self(), &policy, ¶m); - pthread_setschedparam(pthread_self(), SCHED_IDLE, ¶m); -#endif + QHash<QNetworkReply*,QmlPixmapReply*> replies; + QNetworkAccessManager *accessManager; + QmlEngine *engine; + QmlImageReader *reader; +}; - exec(); -} +//=========================================================================== -bool QmlImageReader::event(QEvent *event) +bool QmlImageRequestHandler::event(QEvent *event) { if (event->type() == QEvent::User) { static int replyDownloadProgress = -1; @@ -224,15 +169,15 @@ bool QmlImageReader::event(QEvent *event) replyDownloadProgress = QNetworkReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)"); replyFinished = QNetworkReply::staticMetaObject.indexOfSignal("finished()"); downloadProgress = QmlPixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)"); - thisNetworkRequestDone = QmlImageReader::staticMetaObject.indexOfSlot("networkRequestDone()"); + thisNetworkRequestDone = QmlImageRequestHandler::staticMetaObject.indexOfSlot("networkRequestDone()"); } while (1) { - mutex.lock(); + reader->mutex.lock(); - if (cancelled.count()) { - for (int i = 0; i < cancelled.count(); ++i) { - QmlPixmapReply *job = cancelled.at(i); + if (reader->cancelled.count()) { + for (int i = 0; i < reader->cancelled.count(); ++i) { + QmlPixmapReply *job = reader->cancelled.at(i); QNetworkReply *reply = replies.key(job, 0); if (reply && reply->isRunning()) { replies.remove(reply); @@ -240,29 +185,19 @@ bool QmlImageReader::event(QEvent *event) job->release(true); } } - cancelled.clear(); - } - - if (!accessManagerValid) { - // throw away existing requests and reschedule. - QHash<QNetworkReply*,QmlPixmapReply*>::iterator it = replies.begin(); - for (; it != replies.end(); ++it) { - delete it.key(); - jobs.prepend(*it); - } - replies.clear(); + reader->cancelled.clear(); } - if (!jobs.count() || replies.count() > maxImageRequestCount) { - mutex.unlock(); + if (!reader->jobs.count() || replies.count() > maxImageRequestCount) { + reader->mutex.unlock(); break; } - QmlPixmapReply *runningJob = jobs.takeFirst(); + QmlPixmapReply *runningJob = reader->jobs.takeFirst(); runningJob->addRef(); runningJob->setLoading(); QUrl url = runningJob->url(); - mutex.unlock(); + reader->mutex.unlock(); // fetch QNetworkRequest req(url); @@ -280,7 +215,7 @@ bool QmlImageReader::event(QEvent *event) return QObject::event(event); } -void QmlImageReader::networkRequestDone() +void QmlImageRequestHandler::networkRequestDone() { QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); QmlPixmapReply *job = replies.take(reply); @@ -306,6 +241,84 @@ void QmlImageReader::networkRequestDone() reply->deleteLater(); } +//=========================================================================== + +QmlImageReader::QmlImageReader(QmlEngine *eng) + : QThread(eng), engine(eng), handler(0) +{ + start(QThread::LowPriority); +} + +QmlImageReader::~QmlImageReader() +{ + delete handler; +} + +QmlImageReader *QmlImageReader::instance(QmlEngine *engine) +{ + QmlImageReader *reader = readers.value(engine); + if (!reader) { + static QMutex rmutex; + rmutex.lock(); + reader = new QmlImageReader(engine); + readers.insert(engine, reader); + rmutex.unlock(); + } + + return reader; +} + +QmlPixmapReply *QmlImageReader::getImage(const QUrl &url) +{ + mutex.lock(); + QmlPixmapReply *reply = new QmlPixmapReply(engine, url); + jobs.append(reply); + if (jobs.count() == 1 && handler) + QCoreApplication::postEvent(handler, new QEvent(QEvent::User)); + mutex.unlock(); + return reply; +} + +void QmlImageReader::cancel(QmlPixmapReply *reply) +{ + mutex.lock(); + if (reply->isLoading()) { + // Already requested. Add to cancel list to be cancelled in reader thread. + cancelled.append(reply); + if (cancelled.count() == 1 && handler) + QCoreApplication::postEvent(handler, new QEvent(QEvent::User)); + } else { + // Not yet processed - just remove from waiting list + QList<QmlPixmapReply*>::iterator it = jobs.begin(); + while (it != jobs.end()) { + QmlPixmapReply *job = *it; + if (job == reply) { + jobs.erase(it); + break; + } + ++it; + } + } + mutex.unlock(); +} + +void QmlImageReader::run() +{ +#if defined(Q_OS_LINUX) && defined(SCHED_IDLE) + struct sched_param param; + int policy; + + pthread_getschedparam(pthread_self(), &policy, ¶m); + pthread_setschedparam(pthread_self(), SCHED_IDLE, ¶m); +#endif + + handler = new QmlImageRequestHandler(this, engine); + + exec(); +} + +//=========================================================================== + static bool readImage(QIODevice *dev, QPixmap *pixmap) { QImageReader imgio(dev); diff --git a/src/declarative/util/qmlpixmapcache_p.h b/src/declarative/util/qmlpixmapcache_p.h index 0140352..c202ea8 100644 --- a/src/declarative/util/qmlpixmapcache_p.h +++ b/src/declarative/util/qmlpixmapcache_p.h @@ -83,6 +83,7 @@ private: private: Q_DISABLE_COPY(QmlPixmapReply) Q_DECLARE_PRIVATE(QmlPixmapReply) + friend class QmlImageRequestHandler; friend class QmlImageReader; friend class QmlPixmapCache; }; diff --git a/src/gui/dialogs/qprintdialog.h b/src/gui/dialogs/qprintdialog.h index 390a4a0..ecd50c1 100644 --- a/src/gui/dialogs/qprintdialog.h +++ b/src/gui/dialogs/qprintdialog.h @@ -97,9 +97,9 @@ public: void done(int result); #if defined (Q_OS_UNIX) && defined (QT3_SUPPORT) - void setPrinter(QPrinter *, bool = false); - QPrinter *printer() const; - void addButton(QPushButton *button); + QT3_SUPPORT void setPrinter(QPrinter *, bool = false); + QT3_SUPPORT QPrinter *printer() const; + QT3_SUPPORT void addButton(QPushButton *button); #endif void setOption(PrintDialogOption option, bool on = true); diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index ad23df3..10ef5ea 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -383,9 +383,9 @@ void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) cons { if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect && (reason == EffectRectChanged - || reason == TransformChanged - && m_cachedSystem == Qt::LogicalCoordinates)) + || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) { return; + } QPixmapCache::remove(m_cacheKey); } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c53a893..500bdd0 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -268,6 +268,17 @@ */ /*! + \variable QGraphicsItem::Type + + The type value returned by the virtual type() function in standard + graphics item classes in Qt. All such standard graphics item + classes in Qt are associated with a unique value for Type, + e.g. the value returned by QGraphicsPathItem::type() is 2. + + \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 18 +*/ + +/*! \variable QGraphicsItem::UserType The lowest permitted type value for custom items (subclasses @@ -276,6 +287,8 @@ and declaring a Type enum value. Example: \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1 + + \note UserType = 65536 */ /*! @@ -655,6 +668,7 @@ #include <QtCore/qtimer.h> #include <QtCore/qvariant.h> #include <QtCore/qvarlengtharray.h> +#include <QtCore/qnumeric.h> #include <QtGui/qapplication.h> #include <QtGui/qbitmap.h> #include <QtGui/qpainter.h> @@ -1558,17 +1572,18 @@ const QGraphicsObject *QGraphicsItem::toGraphicsObject() const } /*! - Sets this item's parent item to \a parent. If this item already has a - parent, it is first removed from the previous parent. If \a parent is 0, - this item will become a top-level item. + Sets this item's parent item to \a newParent. If this item already + has a parent, it is first removed from the previous parent. If \a + newParent is 0, this item will become a top-level item. - Note that this implicitly adds this graphics item to the scene of - the parent. You should not \l{QGraphicsScene::addItem()}{add} the - item to the scene yourself. + Note that this implicitly adds this graphics item to the scene of + the parent. You should not \l{QGraphicsScene::addItem()}{add} the + item to the scene yourself. - Calling this function on an item that is an ancestor of \a parent have undefined behaviour. + Calling this function on an item that is an ancestor of \a newParent + have undefined behaviour. - \sa parentItem(), childItems() + \sa parentItem(), childItems() */ void QGraphicsItem::setParentItem(QGraphicsItem *newParent) { @@ -3425,6 +3440,9 @@ void QGraphicsItem::setX(qreal x) if (d_ptr->inDestructor) return; + if (qIsNaN(x)) + return; + d_ptr->setPosHelper(QPointF(x, d_ptr->pos.y())); } @@ -3449,6 +3467,9 @@ void QGraphicsItem::setY(qreal y) if (d_ptr->inDestructor) return; + if (qIsNaN(y)) + return; + d_ptr->setPosHelper(QPointF(d_ptr->pos.x(), y)); } @@ -7241,7 +7262,9 @@ void QGraphicsItem::prepareGeometryChange() QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); scenePrivate->index->prepareBoundingRectChange(this); - scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true); + scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false, + /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false, + /*updateBoundingRect=*/true); // For compatibility reasons, we have to update the item's old geometry // if someone is connected to the changed signal or the scene has no views. diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9219773..54d47fa 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4832,7 +4832,8 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q } void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren, - bool force, bool ignoreOpacity, bool removingItemFromScene) + bool force, bool ignoreOpacity, bool removingItemFromScene, + bool updateBoundingRect) { Q_ASSERT(item); if (updateAll) @@ -4903,7 +4904,8 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b if (ignoreOpacity) item->d_ptr->ignoreOpacity = 1; - item->d_ptr->markParentDirty(); + if (!updateBoundingRect) + item->d_ptr->markParentDirty(); } static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item, diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 54d8130..04ffe0f 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -222,7 +222,8 @@ public: QRegion *, QWidget *, qreal, const QTransform *const, bool, bool); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, - bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); + bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false, + bool updateBoundingRect = false); void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false, qreal parentOpacity = qreal(1.0)); diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 9f90cec..18b3772 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -110,6 +110,12 @@ QT_USE_NAMESPACE } } +- (void)removeActionsFromAppMenu +{ + for (NSMenuItem *item in [appMenu itemArray]) + [item setTag:nil]; +} + - (void)dealloc { [lastAppSpecificItem release]; diff --git a/src/gui/kernel/qcocoamenuloader_mac_p.h b/src/gui/kernel/qcocoamenuloader_mac_p.h index 432a7a6..81c136e 100644 --- a/src/gui/kernel/qcocoamenuloader_mac_p.h +++ b/src/gui/kernel/qcocoamenuloader_mac_p.h @@ -70,6 +70,7 @@ } - (void)ensureAppMenuInMenu:(NSMenu *)menu; +- (void)removeActionsFromAppMenu; - (NSMenu *)applicationMenu; - (NSMenu *)menu; - (NSMenuItem *)quitMenuItem; diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index f61d2fe..d255604 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -644,6 +644,8 @@ extern "C" { - (void)mouseEntered:(NSEvent *)event { + if (qwidgetprivate->data.in_destructor) + return; QEvent enterEvent(QEvent::Enter); NSPoint windowPoint = [event locationInWindow]; NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint]; diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index eda75db..c7c7caf 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -569,7 +569,7 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags) // in cocoa. [NSApp run] should be called at least once for any cocoa app. if (NSModalSession session = d->currentModalSession()) { QBoolBlocker execGuard(d->currentExecIsNSAppRun, false); - while (!d->interrupt && [NSApp runModalSession:session] == NSRunContinuesResponse) + while ([NSApp runModalSession:session] == NSRunContinuesResponse && !d->interrupt) qt_mac_waitForMoreModalSessionEvents(); if (!d->interrupt && session == d->currentModalSessionCached) { // INVARIANT: Someone called e.g. [NSApp stopModal:] from outside the event diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index e36ab9b..e06a810 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -143,6 +143,9 @@ extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds) { +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; +#endif OSWindowRef wnd = static_cast<OSWindowRef>(window); if (wnd) { QWidget *widget; @@ -1278,4 +1281,17 @@ void qt_cocoaChangeOverrideCursor(const QCursor &cursor) } #endif +QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool() +{ +#ifndef QT_MAC_USE_COCOA + NSApplicationLoad(); +#endif + pool = (void*)[[NSAutoreleasePool alloc] init]; +} + +QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool() +{ + [(NSAutoreleasePool*)pool release]; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index ede87de..ffad38b 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -3352,7 +3352,7 @@ QPoint QWidget::pos() const \note Setting the size to \c{QSize(0, 0)} will cause the widget to not appear on screen. This also applies to windows. - \sa pos, geometry, minimumSize, maximumSize, resizeEvent() + \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize() */ /*! diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 3dbc843..78c1562 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -404,7 +404,7 @@ inline static void qt_mac_set_fullscreen_mode(bool b) return; qt_mac_app_fullscreen = b; if (b) { - SetSystemUIMode(kUIModeAllSuppressed, 0); + SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); } else { SetSystemUIMode(kUIModeNormal, 0); } @@ -3510,6 +3510,8 @@ void QWidgetPrivate::hide_sys() if (!QWidget::mouseGrabber()){ QWidget *enterWidget = QApplication::widgetAt(QCursor::pos()); + if (enterWidget && enterWidget->data->in_destructor) + enterWidget = 0; QApplicationPrivate::dispatchEnterLeave(enterWidget, qt_mouseover); qt_mouseover = enterWidget; } diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 97d69b2..7a680f2 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -667,32 +667,47 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg switch (ct) { case QStyle::CT_PushButton: { - const QPushButton *psh = static_cast<const QPushButton *>(widg); - QString buttonText = qt_mac_removeMnemonics(psh->text()); - if (buttonText.contains(QLatin1Char('\n'))) - ret = QSize(-1, -1); - else if (sz == QAquaSizeLarge) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); - else if (sz == QAquaSizeSmall) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); - else if (sz == QAquaSizeMini) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); - - if (!psh->icon().isNull()){ - // If the button got an icon, and the icon is larger than the - // button, we can't decide on a default size - ret.setWidth(-1); - if (ret.height() < psh->iconSize().height()) - ret.setHeight(-1); - } - else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){ - // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels. - // However, this doesn't work for German, therefore only do it for English, - // I suppose it would be better to do some sort of lookups for languages - // that like to have really long words. - ret.setWidth(77 - 8); - } - + const QPushButton *psh = qobject_cast<const QPushButton *>(widg); + // If this comparison is false, then the widget was not a push button. + // This is bad and there's very little we can do since we were requested to find a + // sensible size for a widget that pretends to be a QPushButton but is not. + if(psh) { + QString buttonText = qt_mac_removeMnemonics(psh->text()); + if (buttonText.contains(QLatin1Char('\n'))) + ret = QSize(-1, -1); + else if (sz == QAquaSizeLarge) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + else if (sz == QAquaSizeSmall) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); + else if (sz == QAquaSizeMini) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); + + if (!psh->icon().isNull()){ + // If the button got an icon, and the icon is larger than the + // button, we can't decide on a default size + ret.setWidth(-1); + if (ret.height() < psh->iconSize().height()) + ret.setHeight(-1); + } + else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){ + // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels. + // However, this doesn't work for German, therefore only do it for English, + // I suppose it would be better to do some sort of lookups for languages + // that like to have really long words. + ret.setWidth(77 - 8); + } + } else { + // The only sensible thing to do is to return whatever the style suggests... + if (sz == QAquaSizeLarge) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + else if (sz == QAquaSizeSmall) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); + else if (sz == QAquaSizeMini) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); + else + // Since there's no default size we return the large size... + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + } #if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam } else if (ct == QStyle::CT_RadioButton) { QRadioButton *rdo = static_cast<QRadioButton *>(widg); @@ -749,23 +764,30 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg if (sz == QAquaSizeSmall) { int width = 0, height = 0; if (szHint == QSize(-1, -1)) { //just 'guess'.. - const QToolButton *bt = static_cast<const QToolButton *>(widg); - if (!bt->icon().isNull()) { - QSize iconSize = bt->iconSize(); - QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal); - width = qMax(width, qMax(iconSize.width(), pmSize.width())); - height = qMax(height, qMax(iconSize.height(), pmSize.height())); - } - if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) { - int text_width = bt->fontMetrics().width(bt->text()), - text_height = bt->fontMetrics().height(); - if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) { - width = qMax(width, text_width); - height += text_height; - } else { - width += text_width; - width = qMax(height, text_height); + const QToolButton *bt = qobject_cast<const QToolButton *>(widg); + // If this conversion fails then the widget was not what it claimed to be. + if(bt) { + if (!bt->icon().isNull()) { + QSize iconSize = bt->iconSize(); + QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal); + width = qMax(width, qMax(iconSize.width(), pmSize.width())); + height = qMax(height, qMax(iconSize.height(), pmSize.height())); + } + if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) { + int text_width = bt->fontMetrics().width(bt->text()), + text_height = bt->fontMetrics().height(); + if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) { + width = qMax(width, text_width); + height += text_height; + } else { + width += text_width; + width = qMax(height, text_height); + } } + } else { + // Let's return the size hint... + width = szHint.width(); + height = szHint.height(); } } else { width = szHint.width(); @@ -778,37 +800,47 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg break; case QStyle::CT_Slider: { int w = -1; - const QSlider *sld = static_cast<const QSlider *>(widg); - if (sz == QAquaSizeLarge) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth); - } - } else if (sz == QAquaSizeSmall) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth); - } - } else if (sz == QAquaSizeMini) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth); + const QSlider *sld = qobject_cast<const QSlider *>(widg); + // If this conversion fails then the widget was not what it claimed to be. + if(sld) { + if (sz == QAquaSizeLarge) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth); + } + } else if (sz == QAquaSizeSmall) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth); + } + } else if (sz == QAquaSizeMini) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth); + } } + } else { + // This is tricky, we were requested to find a size for a slider which is not + // a slider. We don't know if this is vertical or horizontal or if we need to + // have tick marks or not. + // For this case we will return an horizontal slider without tick marks. + w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); + w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); } if (sld->orientation() == Qt::Horizontal) ret.setHeight(w); @@ -4309,8 +4341,6 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt, rect.setY(0); rect.setHeight(widget->height()); } - if (opt->direction == Qt::RightToLeft) - rect.adjust(15, 0, -20, 0); } break; case SE_ProgressBarGroove: diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index ecb3242..9b99161 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -985,7 +985,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom //Handle graphics const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); QS60StylePrivate::SkinElements handleElement; - if (optionSlider->state & QStyle::State_Sunken) + if (optionSlider->state & State_Sunken) handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical; else @@ -2620,29 +2620,31 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple // lets use spinbox frame here as well, as no combobox specific value available. const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize); - const int xposMod = (cmb->rect.x()) + width - buttonMargin - buttonWidth; - const int ypos = cmb->rect.y(); QSize buttonSize; buttonSize.setWidth(buttonWidth + 2 * buttonMargin); buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); switch (scontrol) { - case SC_ComboBoxArrow: + case SC_ComboBoxArrow: { + const int xposMod = cmb->rect.x() + width - buttonMargin - buttonWidth; + const int ypos = cmb->rect.y(); ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin); + } break; case SC_ComboBoxEditField: { - const int withFrameX = cmb->rect.x() + cmb->rect.width() - frameThickness - buttonSize.width(); + const int withFrameX = cmb->rect.x() + width - frameThickness - buttonSize.width(); ret = QRect( frameThickness, frameThickness, withFrameX - frameThickness, - cmb->rect.height() - 2 * frameThickness); + height - 2 * frameThickness); } break; default: break; } + ret = visualRect(cmb->direction, cmb->rect, ret); } break; case CC_GroupBox: @@ -3166,6 +3168,10 @@ bool QS60Style::eventFilter(QObject *object, QEvent *event) return QStyle::eventFilter(object, event); } +/*! + \internal + Handle the timer \a event. +*/ void QS60Style::timerEvent(QTimerEvent *event) { #ifdef Q_WS_S60 diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 2cd238f..eae2291 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -74,7 +74,6 @@ typedef struct { unsigned short width; int major_version; int minor_version; - bool mirroring; // TODO: (nice to have) Use Qt::LayoutDirection const char* layoutName; } layoutHeader; @@ -353,12 +352,12 @@ public: int timerId() const {return m_currentData->m_timerId;} int currentFrame() const {return m_currentData->m_currentFrame;} - void setFrameCount(const int &frameCount) {m_currentData->m_frames = frameCount;} - void setInterval(const int &interval) {m_currentData->m_interval = interval;} + void setFrameCount(int frameCount) {m_currentData->m_frames = frameCount;} + void setInterval(int interval) {m_currentData->m_interval = interval;} void setAnimationObject(CAknBitmapAnimation* animation); void setResourceBased(bool resourceBased) {m_currentData->m_resourceBased = resourceBased;} - void setTimerId(const int &timerId) {m_currentData->m_timerId = timerId;} - void setCurrentFrame(const int ¤tFrame) {m_currentData->m_currentFrame = currentFrame;} + void setTimerId(int timerId) {m_currentData->m_timerId = timerId;} + void setCurrentFrame(int currentFrame) {m_currentData->m_currentFrame = currentFrame;} void resetToDefaults(); diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index a3bb169..872bc2b 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -105,7 +105,7 @@ AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, i } AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval), - m_resourceBased(false), m_animation(0), m_timerId(0) + m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0) { } AnimationDataV2::~AnimationDataV2() diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 9343cb7..c000457 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -357,9 +357,6 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform ++i; } } else { - positions.resize(glyphs.numGlyphs); - glyphs_out.resize(glyphs.numGlyphs); - int i = 0; while (i < glyphs.numGlyphs) { if (!glyphs.attributes[i].dontPrint) { QFixed gpos_x = xpos + glyphs.offsets[i].x; diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index 0c8aeec..c1e254c 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -52,6 +52,9 @@ struct QTextOptionPrivate /*! Constructs a text option with default properties for text. + The text alignment property is set to Qt::AlignLeft. The + word wrap property is set to QTextOption::WordWrap. The + using of design metrics flag is set to false. */ QTextOption::QTextOption() : align(Qt::AlignLeft), @@ -67,6 +70,8 @@ QTextOption::QTextOption() /*! Constructs a text option with the given \a alignment for text. + The word wrap property is set to QTextOption::WordWrap. The using + of design metrics flag is set to false. */ QTextOption::QTextOption(Qt::Alignment alignment) : align(alignment), diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/gui/util/qsystemtrayicon_mac.mm index ae805f6..0265a83 100644 --- a/src/gui/util/qsystemtrayicon_mac.mm +++ b/src/gui/util/qsystemtrayicon_mac.mm @@ -569,16 +569,3 @@ private: } @end - -/* Done here because this is the only .mm for now! -Sam */ -QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool() -{ - NSApplicationLoad(); - pool = (void*)[[NSAutoreleasePool alloc] init]; -} - -QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool() -{ - [(NSAutoreleasePool*)pool release]; -} - diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index ee79f5a..d92168a 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -472,14 +472,20 @@ void QMainWindowLayout::removeFromMacToolbar(QToolBar *toolbar) void QMainWindowLayout::cleanUpMacToolbarItems() { - for (int i = 0; i < toolbarItemsCopy.size(); ++i) +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; +#endif + for (int i = 0; i < toolbarItemsCopy.size(); ++i) { +#ifdef QT_MAC_USE_COCOA + NSToolbarItem *item = static_cast<NSToolbarItem *>(toolbarItemsCopy.at(i)); + [item setView:0]; +#endif CFRelease(toolbarItemsCopy.at(i)); + } toolbarItemsCopy.clear(); unifiedToolbarHash.clear(); #ifdef QT_MAC_USE_COCOA - QMacCocoaAutoReleasePool pool; - OSWindowRef window = qt_mac_window_for(layoutState.mainWindow); NSToolbar *macToolbar = [window toolbar]; if (macToolbar) { diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 5031d88..8ce7cc0 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1588,10 +1588,9 @@ QAction *QMenu::insertSeparator(QAction *before) } /*! - This will set the default action to \a act. The default action may - have a visual queue depending on the current QStyle. A default - action is usually meant to indicate what will defaultly happen on a - drop, as shown in a context menu. + This sets the default action to \a act. The default action may have + a visual cue, depending on the current QStyle. A default action + usually indicates what will happen by default when a drop occurs. \sa defaultAction() */ diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index cd7f9bd..7e4bbb5 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -175,6 +175,22 @@ static quint32 constructModifierMask(quint32 accel_key) return ret; } +static void cancelAllMenuTracking() +{ +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + NSMenu *mainMenu = [NSApp mainMenu]; + [mainMenu cancelTracking]; + for (NSMenuItem *item in [mainMenu itemArray]) { + if ([item submenu]) { + [[item submenu] cancelTracking]; + } + } +#else + CancelMenuTracking(AcquireRootMenu(), true, 0); +#endif +} + static bool actualMenuItemVisibility(const QMenuBarPrivate::QMacMenuBarPrivate *mbp, const QMacMenuAction *action) { @@ -1830,6 +1846,12 @@ void QMenuBarPrivate::macDestroyMenuBar() mac_menubar = 0; if (qt_mac_current_menubar.qmenubar == q) { +#ifdef QT_MAC_USE_COCOA + QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); + [loader removeActionsFromAppMenu]; +#else + cancelAllMenuTracking(); +#endif extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp qt_event_request_menubarupdate(); } @@ -1933,20 +1955,6 @@ static bool qt_mac_should_disable_menu(QMenuBar *menuBar, QWidget *modalWidget) return qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget); } -static void cancelAllMenuTracking() -{ -#ifdef QT_MAC_USE_COCOA - QMacCocoaAutoReleasePool pool; - NSMenu *mainMenu = [NSApp mainMenu]; - [mainMenu cancelTracking]; - for (NSMenuItem *item in [mainMenu itemArray]) { - if ([item submenu]) { - [[item submenu] cancelTracking]; - } - } -#endif -} - /*! \internal diff --git a/src/network/access/qfilenetworkreply.cpp b/src/network/access/qfilenetworkreply.cpp index 8c5065c..4ac9a8c 100644 --- a/src/network/access/qfilenetworkreply.cpp +++ b/src/network/access/qfilenetworkreply.cpp @@ -49,10 +49,15 @@ QT_BEGIN_NAMESPACE QFileNetworkReplyPrivate::QFileNetworkReplyPrivate() - : QNetworkReplyPrivate(), realFileSize(0) + : QNetworkReplyPrivate(), fileEngine(0), fileSize(0), filePos(0) { } +QFileNetworkReplyPrivate::~QFileNetworkReplyPrivate() +{ + delete fileEngine; +} + QFileNetworkReply::~QFileNetworkReply() { } @@ -94,9 +99,8 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req if (fileName.isEmpty()) { fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); } - d->realFile.setFileName(fileName); - QFileInfo fi(d->realFile); + QFileInfo fi(fileName); if (fi.isDir()) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString()); setError(QNetworkReply::ContentOperationNotPermittedError, msg); @@ -106,14 +110,15 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req return; } - bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered); + d->fileEngine = QAbstractFileEngine::create(fileName); + bool opened = d->fileEngine->open(QIODevice::ReadOnly | QIODevice::Unbuffered); // could we open the file? if (!opened) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2") - .arg(d->realFile.fileName(), d->realFile.errorString()); + .arg(fileName, d->fileEngine->errorString()); - if (d->realFile.exists()) { + if (fi.exists()) { setError(QNetworkReply::ContentAccessDenied, msg); QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentAccessDenied)); @@ -126,13 +131,13 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req return; } - d->realFileSize = fi.size(); + d->fileSize = fi.size(); setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); - setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize); + setHeader(QNetworkRequest::ContentLengthHeader, d->fileSize); QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection, - Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize)); + Q_ARG(qint64, d->fileSize), Q_ARG(qint64, d->fileSize)); QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); } @@ -146,20 +151,25 @@ void QFileNetworkReply::close() { Q_D(QFileNetworkReply); QNetworkReply::close(); - d->realFile.close(); + if (d->fileEngine) + d->fileEngine->close(); } void QFileNetworkReply::abort() { Q_D(QFileNetworkReply); QNetworkReply::close(); - d->realFile.close(); + if (d->fileEngine) + d->fileEngine->close(); } qint64 QFileNetworkReply::bytesAvailable() const { Q_D(const QFileNetworkReply); - return QNetworkReply::bytesAvailable() + d->realFile.bytesAvailable(); + if (!d->fileEngine) + return 0; + + return QNetworkReply::bytesAvailable() + d->fileSize - d->filePos; } bool QFileNetworkReply::isSequential () const @@ -170,7 +180,7 @@ bool QFileNetworkReply::isSequential () const qint64 QFileNetworkReply::size() const { Q_D(const QFileNetworkReply); - return d->realFileSize; + return d->fileSize; } /*! @@ -179,11 +189,17 @@ qint64 QFileNetworkReply::size() const qint64 QFileNetworkReply::readData(char *data, qint64 maxlen) { Q_D(QFileNetworkReply); - qint64 ret = d->realFile.read(data, maxlen); - if (ret == 0 && bytesAvailable() == 0) + if (!d->fileEngine) + return -1; + + qint64 ret = d->fileEngine->read(data, maxlen); + if (ret == 0 && bytesAvailable() == 0) { return -1; // everything had been read - else - return ret; + } else if (ret > 0) { + d->filePos += ret; + } + + return ret; } diff --git a/src/network/access/qfilenetworkreply_p.h b/src/network/access/qfilenetworkreply_p.h index 125fa2e..710ec9f 100644 --- a/src/network/access/qfilenetworkreply_p.h +++ b/src/network/access/qfilenetworkreply_p.h @@ -57,6 +57,7 @@ #include "qnetworkreply_p.h" #include "qnetworkaccessmanager.h" #include <QFile> +#include <QAbstractFileEngine> QT_BEGIN_NAMESPACE @@ -85,9 +86,11 @@ class QFileNetworkReplyPrivate: public QNetworkReplyPrivate { public: QFileNetworkReplyPrivate(); + ~QFileNetworkReplyPrivate(); - QFile realFile; - qint64 realFileSize; + QAbstractFileEngine *fileEngine; + qint64 fileSize; + qint64 filePos; virtual bool isFinished() const; diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp index c2cc69c..669f9cf 100644 --- a/src/network/access/qhttpnetworkheader.cpp +++ b/src/network/access/qhttpnetworkheader.cpp @@ -80,7 +80,7 @@ QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QByteArray result; bool first = true; - foreach (QByteArray value, allValues) { + foreach (const QByteArray &value, allValues) { if (!first) result += ", "; first = false; diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 58123b2..61a95fe 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -753,7 +753,7 @@ void QNetworkAccessHttpBackend::replyHeaderChanged() QByteArray value = rawHeader(it->first); if (!value.isEmpty()) { if (qstricmp(it->first.constData(), "set-cookie") == 0) - value += "\n"; + value += '\n'; else value += ", "; } diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 6dcd05d..a2bef67 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -649,7 +649,7 @@ static QVariant parseCookieHeader(const QByteArray &raw) { QList<QNetworkCookie> result; QList<QByteArray> cookieList = raw.split(';'); - foreach (QByteArray cookie, cookieList) { + foreach (const QByteArray &cookie, cookieList) { QList<QNetworkCookie> parsed = QNetworkCookie::parseCookies(cookie.trimmed()); if (parsed.count() != 1) return QVariant(); // invalid Cookie: header diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 193a043..e4023c8 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -270,7 +270,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, break; case Ntlm: // #### extract from header - realm = QString(); + realm.clear(); break; case DigestMd5: { realm = QString::fromLatin1(options.value("realm")); @@ -281,7 +281,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, break; } default: - realm = QString(); + realm.clear(); challenge = QByteArray(); phase = Invalid; } diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index 367e3c4..1115c63 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -541,7 +541,7 @@ QList<QNetworkInterface> QNetworkInterface::allInterfaces() { QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces(); QList<QNetworkInterface> result; - foreach (QSharedDataPointer<QNetworkInterfacePrivate> p, privs) { + foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) { QNetworkInterface item; item.d = p; result << item; @@ -560,7 +560,7 @@ QList<QHostAddress> QNetworkInterface::allAddresses() { QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces(); QList<QHostAddress> result; - foreach (const QSharedDataPointer<QNetworkInterfacePrivate> p, privs) { + foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) { foreach (const QNetworkAddressEntry &entry, p->addressEntries) result += entry.ip(); } diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index ede3c89..ef7fc02 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -122,9 +122,9 @@ void QLocalServer::close() qDeleteAll(d->pendingConnections); d->pendingConnections.clear(); d->closeServer(); - d->serverName = QString(); - d->fullServerName = QString(); - d->errorString = QString(); + d->serverName.clear(); + d->fullServerName.clear(); + d->errorString.clear(); d->error = QAbstractSocket::UnknownSocketError; } @@ -226,8 +226,8 @@ bool QLocalServer::listen(const QString &name) } if (!d->listen(name)) { - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); return false; } diff --git a/src/network/socket/qlocalsocket_tcp.cpp b/src/network/socket/qlocalsocket_tcp.cpp index 9f574d4..5b5e84f 100644 --- a/src/network/socket/qlocalsocket_tcp.cpp +++ b/src/network/socket/qlocalsocket_tcp.cpp @@ -102,8 +102,8 @@ void QLocalSocketPrivate::_q_stateChanged(QAbstractSocket::SocketState newState) switch(newState) { case QAbstractSocket::UnconnectedState: state = QLocalSocket::UnconnectedState; - serverName = QString(); - fullServerName = QString(); + serverName.clear(); + fullServerName.clear(); break; case QAbstractSocket::ConnectingState: state = QLocalSocket::ConnectingState; @@ -218,7 +218,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) || state() == ConnectingState) return; - d->errorString = QString(); + d->errorString.clear(); d->state = ConnectingState; emit stateChanged(d->state); @@ -333,8 +333,8 @@ void QLocalSocket::close() { Q_D(QLocalSocket); d->tcpSocket->close(); - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); QIODevice::close(); } diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index 73c2465..1ca11d8 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -109,8 +109,8 @@ void QLocalSocketPrivate::_q_stateChanged(QAbstractSocket::SocketState newState) switch(newState) { case QAbstractSocket::UnconnectedState: state = QLocalSocket::UnconnectedState; - serverName = QString(); - fullServerName = QString(); + serverName.clear(); + fullServerName.clear(); break; case QAbstractSocket::ConnectingState: state = QLocalSocket::ConnectingState; @@ -225,7 +225,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) || state() == ConnectingState) return; - d->errorString = QString(); + d->errorString.clear(); d->unixSocket.setSocketState(QAbstractSocket::ConnectingState); d->state = ConnectingState; emit stateChanged(d->state); @@ -341,7 +341,7 @@ void QLocalSocketPrivate::_q_connectToSocket() errorOccurred(QLocalSocket::UnknownSocketError, function); } connectingSocket = -1; - connectingName = QString(); + connectingName.clear(); connectingOpenMode = 0; } @@ -438,10 +438,10 @@ void QLocalSocket::close() if (d->connectingSocket != -1) ::close(d->connectingSocket); d->connectingSocket = -1; - d->connectingName = QString(); + d->connectingName.clear(); d->connectingOpenMode = 0; - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); QIODevice::close(); } diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index 6e1df93..a890b3b 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -778,6 +778,14 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxSize) QNativeSocketEnginePrivate::RemoteHostClosedErrorString); close(); return -1; + } else if (readBytes == -1) { + if (!d->hasSetSocketError) { + d->hasSetSocketError = true; + d->socketError = QAbstractSocket::NetworkError; + d->socketErrorString = qt_error_string(); + } + close(); + return -1; } return readBytes; } diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index d3b0fe5..9a2c349 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -903,7 +903,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize) case EBADF: case EINVAL: case EIO: - setError(QAbstractSocket::NetworkError, ReadErrorString); + //error string is now set in read(), not here in nativeRead() break; #ifdef Q_OS_SYMBIAN case EPIPE: diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 7088a57..8177b4f 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1068,7 +1068,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxLength) break; case WSAEBADF: case WSAEINVAL: - setError(QAbstractSocket::NetworkError, ReadErrorString); + //error string is now set in read(), not here in nativeRead() break; case WSAECONNRESET: case WSAECONNABORTED: @@ -1199,8 +1199,10 @@ void QNativeSocketEnginePrivate::nativeClose() #if defined (QTCPSOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeClose()"); #endif - linger l = {1, 0}; - ::setsockopt(socketDescriptor, SOL_SOCKET, SO_DONTLINGER, (char*)&l, sizeof(l)); + // We were doing a setsockopt here before with SO_DONTLINGER. (However with kind of wrong + // usage of parameters, it wants a BOOL but we used a struct and pretended it to be bool). + // We don't think setting this option should be done here, if a user wants it she/he can + // do it manually with socketDescriptor()/setSocketDescriptor(); ::closesocket(socketDescriptor); } diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 9a9b1b5..fd647e2 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -634,11 +634,11 @@ QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::Encodi QByteArray tmp; for (int i = 0; i <= array.size() - 64; i += 64) { tmp += QByteArray::fromRawData(array.data() + i, 64); - tmp += "\n"; + tmp += '\n'; } if (int remainder = array.size() % 64) { tmp += QByteArray::fromRawData(array.data() + array.size() - remainder, remainder); - tmp += "\n"; + tmp += '\n'; } return BEGINCERTSTRING "\n" + tmp + ENDCERTSTRING "\n"; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 6947aa7..9623570 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1109,7 +1109,7 @@ void QSslSocket::setCiphers(const QString &ciphers) { Q_D(QSslSocket); d->configuration.ciphers.clear(); - foreach (QString cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) { + foreach (const QString &cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) { for (int i = 0; i < 3; ++i) { // ### Crude QSslCipher cipher(cipherName, QSsl::SslProtocol(i)); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 892d330..ce2aee1 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -818,7 +818,7 @@ bool QSslSocketBackendPrivate::startHandshake() QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.exactMatch(peerName)) { bool matched = false; - foreach (QString altName, configuration.peerCertificate + foreach (const QString &altName, configuration.peerCertificate .alternateSubjectNames().values(QSsl::DnsEntry)) { regexp.setPattern(altName); if (regexp.exactMatch(peerName)) { diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 48e43b2..2a60708 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4419,8 +4419,17 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, bool auto_swap = autoBufferSwap(); QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine(); - qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + QPaintEngine *engine = paintEngine(); + if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) { + qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is" + " active on the same device is not allowed."); + return; + } + + // this changes what paintEngine() returns + qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + engine = paintEngine(); QPainter *p; bool reuse_painter = false; if (engine->isActive()) { @@ -4513,8 +4522,17 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con win_y = height - win_y; // y is inverted QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine(); - qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); QPaintEngine *engine = paintEngine(); + + if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) { + qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is" + " active on the same device is not allowed."); + return; + } + + // this changes what paintEngine() returns + qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + engine = paintEngine(); QPainter *p; bool reuse_painter = false; bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST); diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 5e2f1f5..79484fa 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -106,6 +106,19 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2 + \section1 Binary shaders and programs + + Binary shaders may be specified using \c{glShaderBinary()} on + the return value from QGLShader::shaderId(). The QGLShader instance + containing the binary can then be added to the shader program with + addShader() and linked in the usual fashion with link(). + + Binary programs may be specified using \c{glProgramBinaryOES()} + on the return value from programId(). Then the application should + call link(), which will notice that the program has already been + specified and linked, allowing other operations to be performed + on the shader program. + \sa QGLShader */ @@ -632,8 +645,6 @@ bool QGLShaderProgram::addShader(QGLShader *shader) qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context."); return false; } - if (!shader->d_func()->compiled) - return false; if (!shader->d_func()->shaderGuard.id()) return false; glAttachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id()); @@ -820,8 +831,20 @@ bool QGLShaderProgram::link() GLuint program = d->programGuard.id(); if (!program) return false; + GLint value; + if (d->shaders.isEmpty()) { + // If there are no explicit shaders, then it is possible that the + // application added a program binary with glProgramBinaryOES(), + // or otherwise populated the shaders itself. Check to see if the + // program is already linked and bail out if so. + value = 0; + glGetProgramiv(program, GL_LINK_STATUS, &value); + d->linked = (value != 0); + if (d->linked) + return true; + } glLinkProgram(program); - GLint value = 0; + value = 0; glGetProgramiv(program, GL_LINK_STATUS, &value); d->linked = (value != 0); value = 0; @@ -928,6 +951,15 @@ void QGLShaderProgram::release() GLuint QGLShaderProgram::programId() const { Q_D(const QGLShaderProgram); + GLuint id = d->programGuard.id(); + if (id) + return id; + + // Create the identifier if we don't have one yet. This is for + // applications that want to create the attached shader configuration + // themselves, particularly those using program binaries. + if (!const_cast<QGLShaderProgram *>(this)->init()) + return 0; return d->programGuard.id(); } diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index 4f49476..b2351fa 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -556,7 +556,11 @@ QImage ICOReader::iconAt(int index) else // # colors used icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits; icoAttrib.w = iconEntry.bWidth; + if (icoAttrib.w == 0) + icoAttrib.w = header.biWidth; icoAttrib.h = iconEntry.bHeight; + if (icoAttrib.h == 0) + icoAttrib.h = header.biHeight/2; QImage::Format format = QImage::Format_ARGB32; if (icoAttrib.nbits == 24) diff --git a/src/s60installs/sqlite3_selfsigned.sis b/src/s60installs/sqlite3_selfsigned.sis Binary files differnew file mode 100644 index 0000000..a025ac5 --- /dev/null +++ b/src/s60installs/sqlite3_selfsigned.sis diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 1db2e1b..5bfe46a 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -1148,10 +1148,15 @@ bool QScriptValue::strictlyEquals(const QScriptValue &other) const } if (d->type != other.d_ptr->type) { - if (d->type == QScriptValuePrivate::JavaScriptCore) - return JSC::JSValue::strictEqual(d->jscValue, d->engine->scriptValueToJSCValue(other)); - else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) - return JSC::JSValue::strictEqual(other.d_ptr->engine->scriptValueToJSCValue(*this), other.d_ptr->jscValue); + if (d->type == QScriptValuePrivate::JavaScriptCore) { + QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; + if (eng_p) + return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other)); + } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) { + QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine; + if (eng_p) + return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); + } return false; } diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index 357d1d5..a0fd6d5 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -47,6 +47,7 @@ class QScriptContext; class Q_SCRIPT_EXPORT QScriptDeclarativeClass { public: +#define QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE class Q_SCRIPT_EXPORT Value { public: diff --git a/src/src.pro b/src/src.pro index 8dec49b..f2070ae 100644 --- a/src/src.pro +++ b/src/src.pro @@ -106,6 +106,7 @@ src_declarative.target = sub-declarative contains(QT_CONFIG, webkit) { src_webkit.depends = src_gui src_sql src_network src_xml contains(QT_CONFIG, phonon):src_webkit.depends += src_phonon + contains(QT_CONFIG, xmlpatterns): src_webkit.depends += src_xmlpatterns contains(QT_CONFIG, declarative):src_declarative.depends += src_webkit #exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro): src_webkit.depends += src_javascriptcore } |