summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/phonon/gstreamer/mediaobject.cpp6
-rw-r--r--src/3rdparty/webkit/WebCore/WebCore.pro34
-rw-r--r--src/corelib/global/global.pri2
-rw-r--r--src/corelib/global/qlibraryinfo.cpp5
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp8
-rw-r--r--src/corelib/plugin/qlibrary.cpp48
-rw-r--r--src/corelib/tools/qsimd_p.h7
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp12
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp20
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativepositioners.cpp48
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp15
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp8
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp103
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h6
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp63
-rw-r--r--src/declarative/qml/qdeclarativecomponent.h1
-rw-r--r--src/declarative/qml/qdeclarativecomponent_p.h12
-rw-r--r--src/declarative/qml/qdeclarativecompositetypedata_p.h161
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager.cpp778
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager_p.h120
-rw-r--r--src/declarative/qml/qdeclarativedom.cpp35
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp9
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h4
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp18
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp1
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp42
-rw-r--r--src/declarative/qml/qdeclarativescriptparser.cpp217
-rw-r--r--src/declarative/qml/qdeclarativescriptparser_p.h13
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp1070
-rw-r--r--src/declarative/qml/qdeclarativetypeloader_p.h321
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp2
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp14
-rw-r--r--src/declarative/qml/qmetaobjectbuilder.cpp4
-rw-r--r--src/declarative/qml/qml.pri5
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp2
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp16
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp36
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp10
-rw-r--r--src/gui/graphicsview/qgraphicstransform.cpp32
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp3
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h12
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp56
-rw-r--r--src/gui/kernel/qapplication_s60.cpp37
-rw-r--r--src/gui/kernel/qt_s60_p.h4
-rw-r--r--src/gui/kernel/qwidget.cpp2
-rw-r--r--src/gui/kernel/qwidget_s60.cpp6
-rw-r--r--src/gui/painting/qblendfunctions.cpp8
-rw-r--r--src/gui/painting/qdrawhelper.cpp586
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp191
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h7
-rw-r--r--src/gui/painting/qdrawhelper_p.h32
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp17
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp3
-rw-r--r--src/gui/painting/qpainter.cpp13
-rw-r--r--src/gui/styles/qcleanlooksstyle.cpp10
-rw-r--r--src/gui/styles/qs60style.cpp26
-rw-r--r--src/gui/styles/qs60style_p.h1
-rw-r--r--src/gui/styles/qs60style_s60.cpp6
-rw-r--r--src/gui/text/qfont_s60.cpp36
-rw-r--r--src/gui/text/qfontengine.cpp16
-rw-r--r--src/gui/text/qfontengine_ft.cpp13
-rw-r--r--src/gui/text/qfontengine_mac.mm17
-rw-r--r--src/gui/text/qfontengine_p.h1
-rw-r--r--src/gui/text/qfontengine_qpf.cpp2
-rw-r--r--src/gui/text/qfontengine_qws.cpp2
-rw-r--r--src/gui/text/qfontengine_s60.cpp9
-rw-r--r--src/gui/text/qfontengine_s60_p.h1
-rw-r--r--src/gui/text/qfontengine_win.cpp2
-rw-r--r--src/gui/text/qstatictext.cpp6
-rw-r--r--src/gui/text/qtextengine.cpp14
-rw-r--r--src/gui/util/qdesktopservices_s60.cpp1
-rw-r--r--src/gui/widgets/qdatetimeedit.cpp18
-rw-r--r--src/gui/widgets/qlinecontrol.cpp2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp2
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp23
-rw-r--r--src/network/kernel/qauthenticator.cpp56
-rw-r--r--src/network/ssl/qsslsocket.cpp5
-rw-r--r--src/opengl/qgl.cpp7
-rw-r--r--src/opengl/qwindowsurface_gl.cpp14
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp82
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.h11
-rw-r--r--src/plugins/bearer/symbian/symbianengine.cpp86
-rw-r--r--src/plugins/bearer/symbian/symbianengine.h17
-rw-r--r--src/script/api/qscriptengine.cpp3
-rw-r--r--src/script/api/qscriptprogram.cpp4
-rw-r--r--src/svg/qsvghandler.cpp2
90 files changed, 2825 insertions, 1967 deletions
diff --git a/src/3rdparty/phonon/gstreamer/mediaobject.cpp b/src/3rdparty/phonon/gstreamer/mediaobject.cpp
index 3e0addc..23a60c0 100644
--- a/src/3rdparty/phonon/gstreamer/mediaobject.cpp
+++ b/src/3rdparty/phonon/gstreamer/mediaobject.cpp
@@ -219,9 +219,9 @@ void MediaObject::noMorePadsAvailable ()
if ( status != GST_INSTALL_PLUGINS_STARTED_OK )
{
if( status == GST_INSTALL_PLUGINS_HELPER_MISSING )
- setError(QString(tr("Missing codec helper script assistant.")), Phonon::FatalError );
+ setError(tr("Missing codec helper script assistant."), Phonon::FatalError );
else
- setError(QString(tr("Plugin codec installation failed for codec: %0"))
+ setError(tr("Plugin codec installation failed for codec: %0")
.arg(m_missingCodecs[0].split("|")[3]), error);
}
m_missingCodecs.clear();
@@ -232,7 +232,7 @@ void MediaObject::noMorePadsAvailable ()
m_hasVideo = false;
emit hasVideoChanged(false);
}
- setError(QString(tr("A required codec is missing. You need to install the following codec(s) to play this content: %0")).arg(codecs), error);
+ setError(tr("A required codec is missing. You need to install the following codec(s) to play this content: %0").arg(codecs), error);
m_missingCodecs.clear();
#endif
}
diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro
index ac0c47c..537cdd3 100644
--- a/src/3rdparty/webkit/WebCore/WebCore.pro
+++ b/src/3rdparty/webkit/WebCore/WebCore.pro
@@ -2857,6 +2857,25 @@ contains(DEFINES, ENABLE_SYMBIAN_DIALOG_PROVIDERS) {
}
}
+!symbian {
+ modfile.files = $$moduleFile
+ modfile.path = $$[QMAKE_MKSPECS]/modules
+
+ INSTALLS += modfile
+} else {
+ # INSTALLS is not implemented in qmake's s60 generators, copy headers manually
+
+ inst_modfile.commands = $$QMAKE_COPY ${QMAKE_FILE_NAME} ${QMAKE_FILE_OUT}
+ inst_modfile.input = moduleFile
+ inst_modfile.output = $$[QMAKE_MKSPECS]/modules
+ inst_modfile.CONFIG = no_clean
+
+ QMAKE_EXTRA_COMPILERS += inst_modfile
+
+ install.depends += compiler_inst_modfile_make_all
+ QMAKE_EXTRA_TARGETS += install
+}
+
include($$PWD/../WebKit/qt/Api/headers.pri)
HEADERS += $$WEBKIT_API_HEADERS
@@ -2873,10 +2892,7 @@ HEADERS += $$WEBKIT_API_HEADERS
!isEmpty(INSTALL_LIBS): target.path = $$INSTALL_LIBS
else: target.path = $$[QT_INSTALL_LIBS]
- modfile.files = $$moduleFile
- modfile.path = $$[QMAKE_MKSPECS]/modules
-
- INSTALLS += target headers modfile
+ INSTALLS += target headers
} else {
# INSTALLS is not implemented in qmake's s60 generators, copy headers manually
inst_headers.commands = $$QMAKE_COPY ${QMAKE_FILE_NAME} ${QMAKE_FILE_OUT}
@@ -2888,15 +2904,7 @@ HEADERS += $$WEBKIT_API_HEADERS
QMAKE_EXTRA_COMPILERS += inst_headers
- inst_modfile.commands = $$inst_headers.commands
- inst_modfile.input = moduleFile
- inst_modfile.output = $$[QMAKE_MKSPECS]/modules
- inst_modfile.CONFIG = no_clean
-
- QMAKE_EXTRA_COMPILERS += inst_modfile
-
- install.depends += compiler_inst_headers_make_all compiler_inst_modfile_make_all
- QMAKE_EXTRA_TARGETS += install
+ install.depends += compiler_inst_headers_make_all
}
win32-*|wince* {
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index 2505e72..260ed59 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -19,7 +19,7 @@ INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
# Only used on platforms with CONFIG += precompile_header
PRECOMPILED_HEADER = global/qt_pch.h
-linux*:!static {
+linux*:!static:!linux-armcc:!linux-gcce {
QMAKE_LFLAGS += -Wl,-e,qt_core_boilerplate
prog=$$quote(if (/program interpreter: (.*)]/) { print $1; })
DEFINES += ELF_INTERPRETER=\\\"$$system(readelf -l /bin/ls | perl -n -e \'$$prog\')\\\"
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index a0779c9..957abbf 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -66,6 +66,8 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
+extern void qDumpCPUFeatures(); // in qsimd.cpp
+
#ifndef QT_NO_SETTINGS
struct QLibrarySettings
@@ -500,7 +502,6 @@ QT_END_NAMESPACE
extern const char qt_core_interpreter[] __attribute__((section(".interp")))
= ELF_INTERPRETER;
-extern void qDumpCPUFeatures(); // in qsimd.cpp
extern "C" void qt_core_boilerplate();
void qt_core_boilerplate()
{
@@ -526,7 +527,7 @@ void qt_core_boilerplate()
qt_configure_libraries_path_str + 12,
qt_configure_headers_path_str + 12);
-// qDumpCPUFeatures();
+ QT_PREPEND_NAMESPACE(qDumpCPUFeatures)();
#ifdef QT_EVAL
extern void qt_core_eval_init(uint);
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index 1bad8ed..5cc6ae3 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -232,8 +232,12 @@ void QTimerActiveObject::DoCancel()
void QTimerActiveObject::RunL()
{
- int error;
- QT_TRYCATCH_ERROR(error, Run());
+ int error = KErrNone;
+ if (iStatus == KErrNone) {
+ QT_TRYCATCH_ERROR(error, Run());
+ } else {
+ error = iStatus.Int();
+ }
// All Symbian error codes are negative.
if (error < 0) {
CActiveScheduler::Current()->Error(error); // stop and report here, as this timer will be deleted on scope exit
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index a9ae2ab..1874a9e 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -295,14 +295,6 @@ static bool qt_parse_pattern(const char *s, uint *version, bool *debug, QByteArr
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN) && !defined(QT_NO_PLUGIN_CHECK)
-#if defined(Q_OS_FREEBSD) || defined(Q_OS_LINUX)
-# define USE_MMAP
-QT_BEGIN_INCLUDE_NAMESPACE
-# include <sys/types.h>
-# include <sys/mman.h>
-QT_END_INCLUDE_NAMESPACE
-#endif // Q_OS_FREEBSD || Q_OS_LINUX
-
static long qt_find_pattern(const char *s, ulong s_len,
const char *pattern, ulong p_len)
{
@@ -363,34 +355,15 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
}
QByteArray data;
- char *filedata = 0;
- ulong fdlen = 0;
-
-# ifdef USE_MMAP
- char *mapaddr = 0;
- size_t maplen = file.size();
- mapaddr = (char *) mmap(mapaddr, maplen, PROT_READ, MAP_PRIVATE, file.handle(), 0);
- if (mapaddr != MAP_FAILED) {
- // mmap succeeded
- filedata = mapaddr;
- fdlen = maplen;
- } else {
- // mmap failed
- if (qt_debug_component()) {
- qWarning("mmap: %s", qPrintable(qt_error_string(errno)));
- }
- if (lib)
- lib->errorString = QLibrary::tr("Could not mmap '%1': %2")
- .arg(library)
- .arg(qt_error_string());
-# endif // USE_MMAP
+ const char *filedata = 0;
+ ulong fdlen = file.size();
+ filedata = (char *) file.map(0, fdlen);
+ if (filedata == 0) {
// try reading the data into memory instead
data = file.readAll();
- filedata = data.data();
+ filedata = data.constData();
fdlen = data.size();
-# ifdef USE_MMAP
}
-# endif // USE_MMAP
// verify that the pattern is present in the plugin
const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA";
@@ -403,17 +376,6 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
if (!ret && lib)
lib->errorString = QLibrary::tr("Plugin verification data mismatch in '%1'").arg(library);
-# ifdef USE_MMAP
- if (mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0) {
- if (qt_debug_component())
- qWarning("munmap: %s", qPrintable(qt_error_string(errno)));
- if (lib)
- lib->errorString = QLibrary::tr("Could not unmap '%1': %2")
- .arg(library)
- .arg( qt_error_string() );
- }
-# endif // USE_MMAP
-
file.close();
return ret;
}
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 2626657..664543b 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -51,8 +51,13 @@ QT_BEGIN_HEADER
#if defined(QT_NO_MAC_XARCH) || (defined(Q_OS_DARWIN) && (defined(__ppc__) || defined(__ppc64__)))
// Disable MMX and SSE on Mac/PPC builds, or if the compiler
// does not support -Xarch argument passing
-#undef QT_HAVE_SSE2
#undef QT_HAVE_SSE
+#undef QT_HAVE_SSE2
+#undef QT_HAVE_SSE3
+#undef QT_HAVE_SSSE3
+#undef QT_HAVE_SSE4_1
+#undef QT_HAVE_SSE4_2
+#undef QT_HAVE_AVX
#undef QT_HAVE_3DNOW
#undef QT_HAVE_MMX
#endif
diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp
index dca2695..1bbfcf4 100644
--- a/src/declarative/debugger/qdeclarativedebugservice.cpp
+++ b/src/declarative/debugger/qdeclarativedebugservice.cpp
@@ -128,6 +128,8 @@ void QDeclarativeDebugServer::newConnection()
if (d->connection) {
qWarning("QDeclarativeDebugServer error: another client is already connected");
+ QTcpSocket *faultyConnection = d->tcpServer->nextPendingConnection();
+ delete faultyConnection;
return;
}
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index a710190..b302393 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -1001,12 +1001,16 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry,
bool changed = false;
if (newGeometry.width() != oldGeometry.width()) {
+ if (xflick())
+ changed = true;
if (d->hData.viewSize < 0) {
d->contentItem->setWidth(width());
emit contentWidthChanged();
}
}
if (newGeometry.height() != oldGeometry.height()) {
+ if (yflick())
+ changed = true;
if (d->vData.viewSize < 0) {
d->contentItem->setHeight(height());
emit contentHeightChanged();
@@ -1254,6 +1258,7 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
d->clearDelayedPress();
d->stealMouse = false;
+ d->pressed = false;
}
return false;
}
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 1054898..aca2bb7 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -1883,6 +1883,12 @@ void QDeclarativeItem::geometryChanged(const QRectF &newGeometry,
}
}
+ for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QDeclarativeItemPrivate::Geometry)
+ change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
+ }
+
if (newGeometry.x() != oldGeometry.x())
emit xChanged();
if (newGeometry.width() != oldGeometry.width())
@@ -1891,12 +1897,6 @@ void QDeclarativeItem::geometryChanged(const QRectF &newGeometry,
emit yChanged();
if (newGeometry.height() != oldGeometry.height())
emit heightChanged();
-
- for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
- const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
- if (change.types & QDeclarativeItemPrivate::Geometry)
- change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
- }
}
void QDeclarativeItemPrivate::removeItemChangeListener(QDeclarativeItemChangeListener *listener, ChangeTypes types)
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index d3d46f7..1c634d2 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -2454,6 +2454,16 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event)
QDeclarativeFlickable::keyPressEvent(event);
}
+void QDeclarativeListView::geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
+{
+ Q_D(QDeclarativeListView);
+ d->maxExtentDirty = true;
+ d->minExtentDirty = true;
+ QDeclarativeFlickable::geometryChanged(newGeometry, oldGeometry);
+}
+
+
/*!
\qmlmethod ListView::incrementCurrentIndex()
@@ -2906,14 +2916,18 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
}
if (removedVisible && d->visibleItems.isEmpty()) {
- d->visibleIndex = 0;
- d->visiblePos = d->header ? d->header->size() : 0;
d->timeline.clear();
- d->setPosition(0);
if (d->itemCount == 0) {
+ d->visibleIndex = 0;
+ d->visiblePos = d->header ? d->header->size() : 0;
+ d->setPosition(0);
d->updateHeader();
d->updateFooter();
update();
+ } else {
+ if (modelIndex < d->visibleIndex)
+ d->visibleIndex = modelIndex+1;
+ d->visibleIndex = qMax(qMin(d->visibleIndex, d->itemCount-1), 0);
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index 8fbff49..735b248 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -246,6 +246,7 @@ protected:
virtual qreal minXExtent() const;
virtual qreal maxXExtent() const;
virtual void keyPressEvent(QKeyEvent *);
+ virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry);
virtual void componentComplete();
private Q_SLOTS:
diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
index b776b8e..77b26b9 100644
--- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
@@ -247,13 +247,13 @@ void QDeclarativeBasePositioner::prePositioning()
positionedItems.append(posItem);
item = &positionedItems[positionedItems.count()-1];
item->isNew = true;
- if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden)
+ if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height())
item->isVisible = false;
} else {
item = &oldItems[wIdx];
// Items are only omitted from positioning if they are explicitly hidden
// i.e. their positioning is not affected if an ancestor is hidden.
- if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) {
+ if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height()) {
item->isVisible = false;
} else if (!item->isVisible) {
item->isVisible = true;
@@ -321,12 +321,6 @@ void QDeclarativeBasePositioner::finishApplyTransitions()
d->moveActions.clear();
}
-static inline bool isInvisible(QGraphicsObject *child)
-{
- QGraphicsItemPrivate *childPrivate = static_cast<QGraphicsItemPrivate*>(QGraphicsItemPrivate::get(child));
- return child->opacity() == 0.0 || childPrivate->explicitlyHidden || !childPrivate->width() || !childPrivate->height();
-}
-
/*!
\qmlclass Column QDeclarativeColumn
\ingroup qml-positioning-elements
@@ -449,7 +443,7 @@ void QDeclarativeColumn::doPositioning(QSizeF *contentSize)
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
if(child.item->y() != voffset)
@@ -584,7 +578,7 @@ void QDeclarativeRow::doPositioning(QSizeF *contentSize)
for (int ii = 0; ii < positionedItems.count(); ++ii) {
const PositionedItem &child = positionedItems.at(ii);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
if(child.item->x() != hoffset)
@@ -793,9 +787,17 @@ void QDeclarativeGrid::setFlow(Flow flow)
void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
{
+
int c = m_columns;
int r = m_rows;
- int numVisible = positionedItems.count();
+ //Is allocating the extra QPODVector too much overhead?
+ QPODVector<PositionedItem, 8> visibleItems;//we aren't concerned with invisible items
+ visibleItems.reserve(positionedItems.count());
+ for(int i=0; i<positionedItems.count(); i++)
+ if(positionedItems[i].item && positionedItems[i].isVisible)
+ visibleItems.append(positionedItems[i]);
+
+ int numVisible = visibleItems.count();
if (m_columns <= 0 && m_rows <= 0){
c = 4;
r = (numVisible+3)/4;
@@ -816,11 +818,10 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
if (i==0)
maxColWidth << 0;
- if (childIndex == positionedItems.count())
- continue;
- const PositionedItem &child = positionedItems.at(childIndex++);
- if (!child.item || isInvisible(child.item))
- continue;
+ if (childIndex == visibleItems.count())
+ break;
+
+ const PositionedItem &child = visibleItems.at(childIndex++);
QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
if (childPrivate->width() > maxColWidth[j])
maxColWidth[j] = childPrivate->width();
@@ -837,10 +838,9 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
maxColWidth << 0;
if (childIndex == positionedItems.count())
- continue;
- const PositionedItem &child = positionedItems.at(childIndex++);
- if (!child.item || isInvisible(child.item))
- continue;
+ break;
+
+ const PositionedItem &child = visibleItems.at(childIndex++);
QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
if (childPrivate->width() > maxColWidth[j])
maxColWidth[j] = childPrivate->width();
@@ -854,10 +854,8 @@ void QDeclarativeGrid::doPositioning(QSizeF *contentSize)
int yoffset=0;
int curRow =0;
int curCol =0;
- for (int i = 0; i < positionedItems.count(); ++i) {
- const PositionedItem &child = positionedItems.at(i);
- if (!child.item || isInvisible(child.item))
- continue;
+ for (int i = 0; i < visibleItems.count(); ++i) {
+ const PositionedItem &child = visibleItems.at(i);
if((child.item->x()!=xoffset)||(child.item->y()!=yoffset)){
positionX(xoffset, child);
positionY(yoffset, child);
@@ -1033,7 +1031,7 @@ void QDeclarativeFlow::doPositioning(QSizeF *contentSize)
for (int i = 0; i < positionedItems.count(); ++i) {
const PositionedItem &child = positionedItems.at(i);
- if (!child.item || isInvisible(child.item))
+ if (!child.item || !child.isVisible)
continue;
QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child.item);
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index b4e8bda..a46ee73 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -1305,24 +1305,27 @@ void QDeclarativeVisualDataModel::_q_itemsMoved(int from, int to, int count)
void QDeclarativeVisualDataModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
{
- if (!parent.isValid())
+ Q_D(QDeclarativeVisualDataModel);
+ if (parent == d->m_root)
_q_itemsInserted(begin, end - begin + 1);
}
void QDeclarativeVisualDataModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
{
- if (!parent.isValid())
+ Q_D(QDeclarativeVisualDataModel);
+ if (parent == d->m_root)
_q_itemsRemoved(begin, end - begin + 1);
}
void QDeclarativeVisualDataModel::_q_rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
{
+ Q_D(QDeclarativeVisualDataModel);
const int count = sourceEnd - sourceStart + 1;
- if (!destinationParent.isValid() && !sourceParent.isValid()) {
+ if (destinationParent == d->m_root && sourceParent == d->m_root) {
_q_itemsMoved(sourceStart, destinationRow, count);
- } else if (!sourceParent.isValid()) {
+ } else if (sourceParent == d->m_root) {
_q_itemsRemoved(sourceStart, count);
- } else if (!destinationParent.isValid()) {
+ } else if (destinationParent == d->m_root) {
_q_itemsInserted(destinationRow, count);
}
}
@@ -1330,7 +1333,7 @@ void QDeclarativeVisualDataModel::_q_rowsMoved(const QModelIndex &sourceParent,
void QDeclarativeVisualDataModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end)
{
Q_D(QDeclarativeVisualDataModel);
- if (!begin.parent().isValid())
+ if (begin.parent() == d->m_root)
_q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles);
}
diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index cd08658..1eb42e4 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -677,9 +677,9 @@ int Lexer::lex()
setDone(Other);
} else
state = Start;
- if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+ if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
} else if (current == 0) {
- if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+ if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
setDone(Eof);
}
@@ -689,14 +689,14 @@ int Lexer::lex()
setDone(Bad);
err = UnclosedComment;
errmsg = QCoreApplication::translate("QDeclarativeParser", "Unclosed comment at end of file");
- if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+ if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
} else if (isLineTerminator()) {
shiftWindowsLineBreak();
yylineno++;
} else if (current == '*' && next1 == '/') {
state = Start;
shift(1);
- if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+ if (driver) driver->addComment(startpos+2, tokenLength()-3, startlineno, startcolumn+2);
}
break;
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index f044e1a..61ea9c8 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -41,7 +41,6 @@
#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "private/qdeclarativeparser_p.h"
#include "private/qdeclarativescriptparser_p.h"
#include "qdeclarativepropertyvaluesource.h"
@@ -562,7 +561,7 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data)
on a successful compiler.
*/
bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
- QDeclarativeCompositeTypeData *unit,
+ QDeclarativeTypeData *unit,
QDeclarativeCompiledData *out)
{
exceptions.clear();
@@ -573,10 +572,15 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
output = out;
// Compile types
- for (int ii = 0; ii < unit->types.count(); ++ii) {
- QDeclarativeCompositeTypeData::TypeReference &tref = unit->types[ii];
+ const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
+ QList<QDeclarativeScriptParser::TypeReference *> referencedTypes = unit->parser().referencedTypes();
+
+ for (int ii = 0; ii < resolvedTypes.count(); ++ii) {
QDeclarativeCompiledData::TypeReference ref;
- QDeclarativeScriptParser::TypeReference *parserRef = unit->data.referencedTypes().at(ii);
+
+ const QDeclarativeTypeData::TypeReference &tref = resolvedTypes.at(ii);
+ QDeclarativeScriptParser::TypeReference *parserRef = referencedTypes.at(ii);
+
if (tref.type) {
ref.type = tref.type;
if (!ref.type->isCreatable()) {
@@ -585,33 +589,16 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
err = tr( "Element is not creatable.");
COMPILE_EXCEPTION(parserRef->refObjects.first(), err);
}
- } else if (tref.unit) {
- ref.component = tref.unit->toComponent(engine);
-
- if (ref.component->isError()) {
- QDeclarativeError error;
- error.setUrl(output->url);
- error.setDescription(QLatin1String("Unable to create type ") +
- parserRef->name);
- if (!parserRef->refObjects.isEmpty()) {
- QDeclarativeParser::Object *parserObject = parserRef->refObjects.first();
- error.setLine(parserObject->location.start.line);
- error.setColumn(parserObject->location.start.column);
- }
-
- exceptions << error;
- exceptions << ref.component->errors();
- reset(out);
- return false;
- }
- ref.ref = tref.unit;
+ } else if (tref.typeData) {
+ ref.component = tref.typeData->component();
+ ref.ref = tref.typeData;
ref.ref->addref();
}
ref.className = parserRef->name.toUtf8();
out->types << ref;
}
- Object *root = unit->data.tree();
+ Object *root = unit->parser().tree();
Q_ASSERT(root);
this->engine = engine;
@@ -664,17 +651,17 @@ void QDeclarativeCompiler::compileTree(Object *tree)
QHash<QString, Object::ScriptBlock> importedScripts;
QStringList importedScriptIndexes;
- for (int ii = 0; ii < unit->scripts.count(); ++ii) {
- QString scriptCode = QString::fromUtf8(unit->scripts.at(ii).resource->data);
- Object::ScriptBlock::Pragmas pragmas = QDeclarativeScriptParser::extractPragmas(scriptCode);
+ foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
+ QString scriptCode = script.script->scriptSource();
+ Object::ScriptBlock::Pragmas pragmas = script.script->pragmas();
- Q_ASSERT(!importedScripts.contains(unit->scripts.at(ii).qualifier));
+ Q_ASSERT(!importedScripts.contains(script.qualifier));
if (!scriptCode.isEmpty()) {
- Object::ScriptBlock &scriptBlock = importedScripts[unit->scripts.at(ii).qualifier];
+ Object::ScriptBlock &scriptBlock = importedScripts[script.qualifier];
scriptBlock.code = scriptCode;
- scriptBlock.file = unit->scripts.at(ii).resource->url;
+ scriptBlock.file = script.script->finalUrl().toString();
scriptBlock.pragmas = pragmas;
}
}
@@ -704,7 +691,7 @@ void QDeclarativeCompiler::compileTree(Object *tree)
for (int ii = 0; ii < importedScriptIndexes.count(); ++ii)
output->importCache->add(importedScriptIndexes.at(ii), ii);
- unit->imports.populateCache(output->importCache, engine);
+ unit->imports().populateCache(output->importCache, engine);
Q_ASSERT(tree->metatype);
@@ -987,7 +974,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
}
// Begin the class
- if (obj->parserStatusCast != -1) {
+ if (tr.type && obj->parserStatusCast != -1) {
QDeclarativeInstruction begin;
begin.type = QDeclarativeInstruction::BeginObject;
begin.begin.castValue = obj->parserStatusCast;
@@ -1375,7 +1362,7 @@ bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop,
return p.name() != 0;
} else {
int idx = mo->indexOfProperty(prop->name.constData());
- return idx != -1;
+ return idx != -1 && mo->property(idx).isScriptable();
}
}
@@ -1404,7 +1391,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
QDeclarativeType *type = 0;
QDeclarativeImportedNamespace *typeNamespace = 0;
- unit->imports.resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
+ unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
if (typeNamespace) {
// ### We might need to indicate that this property is a namespace
@@ -1440,6 +1427,11 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
if (prop->index != -1) {
p = metaObject->property(prop->index);
Q_ASSERT(p.name());
+
+ if (!p.isScriptable()) {
+ prop->index = -1;
+ p = QMetaProperty();
+ }
}
}
@@ -1512,7 +1504,7 @@ bool QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeImportedNamespac
// Setup attached property data
QDeclarativeType *type = 0;
- unit->imports.resolveType(ns, prop->name, &type, 0, 0, 0);
+ unit->imports().resolveType(ns, prop->name, &type, 0, 0, 0);
if (!type || !type->attachedPropertiesType())
COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
@@ -1826,6 +1818,8 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
if (idx == -1)
COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
QMetaProperty p = type->metaObject()->property(idx);
+ if (!p.isScriptable())
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
prop->index = idx;
prop->type = p.userType();
prop->isValueTypeSubProperty = true;
@@ -2139,7 +2133,7 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
QString typeName = parts.at(0);
QDeclarativeType *type = 0;
- unit->imports.resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
+ unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
if (!type || obj->typeName != type->qmlTypeName())
return true;
@@ -2166,7 +2160,7 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
int dot = script.indexOf('.');
if (dot > 0) {
QDeclarativeType *type = 0;
- unit->imports.resolveType(script.left(dot), &type, 0, 0, 0, 0);
+ unit->imports().resolveType(script.left(dot), &type, 0, 0, 0, 0);
if (!type)
return -1;
const QMetaObject *mo = type->metaObject();
@@ -2184,7 +2178,7 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const
{
QDeclarativeType *qmltype = 0;
- if (!unit->imports.resolveType(name, &qmltype, 0, 0, 0, 0))
+ if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0))
return 0;
if (!qmltype)
return 0;
@@ -2342,16 +2336,18 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
QByteArray customTypeName;
QDeclarativeType *qmltype = 0;
QUrl url;
- if (!unit->imports.resolveType(p.customType, &qmltype, &url, 0, 0, 0))
+ if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0))
COMPILE_EXCEPTION(&p, tr("Invalid property type"));
if (!qmltype) {
- QDeclarativeCompositeTypeData *tdata = enginePrivate->typeManager.get(url);
+ QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(url);
Q_ASSERT(tdata);
- Q_ASSERT(tdata->status == QDeclarativeCompositeTypeData::Complete);
+ Q_ASSERT(tdata->isComplete());
- QDeclarativeCompiledData *data = tdata->toCompiledComponent(engine);
+ QDeclarativeCompiledData *data = tdata->compiledData();
customTypeName = data->root->className();
+ data->release();
+ tdata->release();
} else {
customTypeName = qmltype->typeName();
}
@@ -2417,17 +2413,20 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
builder.addSignal(p.name + "Changed()");
QMetaPropertyBuilder propBuilder =
builder.addProperty(p.name, type, builder.methodCount() - 1);
- propBuilder.setScriptable(true);
propBuilder.setWritable(!readonly);
}
- if (mode == ResolveAliases) {
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+ for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
+ const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
- if (p.type == Object::DynamicProperty::Alias) {
+ if (p.type == Object::DynamicProperty::Alias) {
+ if (mode == ResolveAliases) {
((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
compileAlias(builder, dynamicData, obj, p);
+ } else {
+ // Need a fake signal so that the metaobject remains consistent across
+ // the resolve and non-resolve alias runs
+ builder.addSignal(p.name + "Changed()");
}
}
}
@@ -2583,6 +2582,9 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
+ if (!aliasProperty.isScriptable())
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+
writable = aliasProperty.isWritable();
if (aliasProperty.isEnumType())
@@ -2619,7 +2621,6 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
builder.addSignal(prop.name + "Changed()");
QMetaPropertyBuilder propBuilder =
builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
- propBuilder.setScriptable(true);
propBuilder.setWritable(writable);
return true;
}
@@ -2746,7 +2747,7 @@ bool QDeclarativeCompiler::completeComponentBuild()
expr.context = binding.bindingContext.object;
expr.property = binding.property;
expr.expression = binding.expression;
- expr.imports = unit->imports;
+ expr.imports = unit->imports();
int index = bindingCompiler.compile(expr, enginePrivate);
if (index != -1) {
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 49dc53f..89eef09 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -56,13 +56,13 @@
#include "qdeclarative.h"
#include "qdeclarativeerror.h"
#include "private/qdeclarativeinstruction_p.h"
-#include "private/qdeclarativecompositetypemanager_p.h"
#include "private/qdeclarativeparser_p.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qbitfield_p.h"
#include "private/qdeclarativepropertycache_p.h"
#include "private/qdeclarativeintegercache_p.h"
#include "private/qdeclarativetypenamecache_p.h"
+#include "private/qdeclarativetypeloader_p.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qset.h>
@@ -152,7 +152,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeCompiler
public:
QDeclarativeCompiler();
- bool compile(QDeclarativeEngine *, QDeclarativeCompositeTypeData *, QDeclarativeCompiledData *);
+ bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *);
bool isError() const;
QList<QDeclarativeError> errors() const;
@@ -338,7 +338,7 @@ private:
QDeclarativeEngine *engine;
QDeclarativeEnginePrivate *enginePrivate;
QDeclarativeParser::Object *unitRoot;
- QDeclarativeCompositeTypeData *unit;
+ QDeclarativeTypeData *unit;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index d2d1f19..74de738 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -44,7 +44,6 @@
#include "private/qdeclarativecompiler_p.h"
#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativevme_p.h"
#include "qdeclarative.h"
@@ -197,7 +196,7 @@ class QByteArray;
\value Error An error has occurred. Call errors() to retrieve a list of \{QDeclarativeError}{errors}.
*/
-void QDeclarativeComponentPrivate::typeDataReady()
+void QDeclarativeComponentPrivate::typeDataReady(QDeclarativeTypeData *)
{
Q_Q(QDeclarativeComponent);
@@ -209,28 +208,25 @@ void QDeclarativeComponentPrivate::typeDataReady()
emit q->statusChanged(q->status());
}
-void QDeclarativeComponentPrivate::updateProgress(qreal p)
+void QDeclarativeComponentPrivate::typeDataProgress(QDeclarativeTypeData *, qreal p)
{
Q_Q(QDeclarativeComponent);
progress = p;
+
emit q->progressChanged(p);
}
-void QDeclarativeComponentPrivate::fromTypeData(QDeclarativeCompositeTypeData *data)
+void QDeclarativeComponentPrivate::fromTypeData(QDeclarativeTypeData *data)
{
- url = data->imports.baseUrl();
- QDeclarativeCompiledData *c = data->toCompiledComponent(engine);
+ url = data->finalUrl();
+ QDeclarativeCompiledData *c = data->compiledData();
if (!c) {
- Q_ASSERT(data->status == QDeclarativeCompositeTypeData::Error);
-
- state.errors = data->errors;
-
+ Q_ASSERT(data->isError());
+ state.errors = data->errors();
} else {
-
cc = c;
-
}
data->release();
@@ -239,7 +235,7 @@ void QDeclarativeComponentPrivate::fromTypeData(QDeclarativeCompositeTypeData *d
void QDeclarativeComponentPrivate::clear()
{
if (typeData) {
- typeData->remWaiter(this);
+ typeData->unregisterCallback(this);
typeData->release();
typeData = 0;
}
@@ -271,7 +267,7 @@ QDeclarativeComponent::~QDeclarativeComponent()
}
if (d->typeData) {
- d->typeData->remWaiter(d);
+ d->typeData->unregisterCallback(d);
d->typeData->release();
}
if (d->cc)
@@ -443,19 +439,13 @@ void QDeclarativeComponent::setData(const QByteArray &data, const QUrl &url)
d->url = url;
- QDeclarativeCompositeTypeData *typeData =
- QDeclarativeEnginePrivate::get(d->engine)->typeManager.getImmediate(data, url);
+ QDeclarativeTypeData *typeData = QDeclarativeEnginePrivate::get(d->engine)->typeLoader.get(data, url);
- if (typeData->status == QDeclarativeCompositeTypeData::Waiting
- || typeData->status == QDeclarativeCompositeTypeData::WaitingResources)
- {
- d->typeData = typeData;
- d->typeData->addWaiter(d);
-
- } else {
-
+ if (typeData->isCompleteOrError()) {
d->fromTypeData(typeData);
-
+ } else {
+ d->typeData = typeData;
+ d->typeData->registerCallback(d);
}
d->progress = 1.0;
@@ -501,18 +491,15 @@ void QDeclarativeComponent::loadUrl(const QUrl &url)
return;
}
- QDeclarativeCompositeTypeData *data =
- QDeclarativeEnginePrivate::get(d->engine)->typeManager.get(d->url);
+ QDeclarativeTypeData *data = QDeclarativeEnginePrivate::get(d->engine)->typeLoader.get(d->url);
- if (data->status == QDeclarativeCompositeTypeData::Waiting
- || data->status == QDeclarativeCompositeTypeData::WaitingResources)
- {
- d->typeData = data;
- d->typeData->addWaiter(d);
- d->progress = data->progress;
- } else {
+ if (data->isCompleteOrError()) {
d->fromTypeData(data);
d->progress = 1.0;
+ } else {
+ d->typeData = data;
+ d->typeData->registerCallback(d);
+ d->progress = data->progress();
}
emit statusChanged(status());
@@ -620,10 +607,11 @@ QScriptValue QDeclarativeComponent::createObject(QObject* parent)
ctxt = d->engine->rootContext();
if (!ctxt)
return QScriptValue(QScriptValue::NullValue);
- QObject* ret = create(ctxt);
- if (!ret)
+ QObject* ret = beginCreate(ctxt);
+ if (!ret) {
+ completeCreate();
return QScriptValue(QScriptValue::NullValue);
-
+ }
if (parent) {
ret->setParent(parent);
@@ -644,6 +632,7 @@ QScriptValue QDeclarativeComponent::createObject(QObject* parent)
if (needParent)
qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene.");
}
+ completeCreate();
QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine);
QDeclarativeData::get(ret, true)->setImplicitDestructible();
diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h
index 1d1fca7..fd9cb2b 100644
--- a/src/declarative/qml/qdeclarativecomponent.h
+++ b/src/declarative/qml/qdeclarativecomponent.h
@@ -117,6 +117,7 @@ private:
Q_DISABLE_COPY(QDeclarativeComponent)
friend class QDeclarativeVME;
friend class QDeclarativeCompositeTypeData;
+ friend class QDeclarativeTypeData;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h
index 2a7d633..1b1454b 100644
--- a/src/declarative/qml/qdeclarativecomponent_p.h
+++ b/src/declarative/qml/qdeclarativecomponent_p.h
@@ -56,7 +56,7 @@
#include "qdeclarativecomponent.h"
#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativecompositetypemanager_p.h"
+#include "private/qdeclarativetypeloader_p.h"
#include "private/qbitfield_p.h"
#include "qdeclarativeerror.h"
#include "qdeclarative.h"
@@ -74,7 +74,7 @@ class QDeclarativeEngine;
class QDeclarativeCompiledData;
class QDeclarativeComponentAttached;
-class QDeclarativeComponentPrivate : public QObjectPrivate
+class QDeclarativeComponentPrivate : public QObjectPrivate, public QDeclarativeTypeData::TypeDataCallback
{
Q_DECLARE_PUBLIC(QDeclarativeComponent)
@@ -85,11 +85,11 @@ public:
QObject *beginCreate(QDeclarativeContextData *, const QBitField &);
void completeCreate();
- QDeclarativeCompositeTypeData *typeData;
- void typeDataReady();
- void updateProgress(qreal);
+ QDeclarativeTypeData *typeData;
+ virtual void typeDataReady(QDeclarativeTypeData *);
+ virtual void typeDataProgress(QDeclarativeTypeData *, qreal);
- void fromTypeData(QDeclarativeCompositeTypeData *data);
+ void fromTypeData(QDeclarativeTypeData *data);
QUrl url;
qreal progress;
diff --git a/src/declarative/qml/qdeclarativecompositetypedata_p.h b/src/declarative/qml/qdeclarativecompositetypedata_p.h
deleted file mode 100644
index a0e4cc2..0000000
--- a/src/declarative/qml/qdeclarativecompositetypedata_p.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVECOMPOSITETYPEDATA_P_H
-#define QDECLARATIVECOMPOSITETYPEDATA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qdeclarativeengine_p.h"
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeCompositeTypeResource;
-class QDeclarativeCompositeTypeData : public QDeclarativeRefCount
-{
-public:
- QDeclarativeCompositeTypeData();
- virtual ~QDeclarativeCompositeTypeData();
-
- enum Status {
- Invalid,
- Complete,
- Error,
- Waiting,
- WaitingResources
- };
- Status status;
- enum ErrorType {
- NoError,
- AccessError,
- GeneralError
- };
- ErrorType errorType;
-
- QList<QDeclarativeError> errors;
-
- QDeclarativeImports imports;
-
- QList<QDeclarativeCompositeTypeData *> dependants;
-
- // Return a QDeclarativeComponent if the QDeclarativeCompositeTypeData is not in the Waiting
- // state. The QDeclarativeComponent is owned by the QDeclarativeCompositeTypeData, so a
- // reference should be kept to keep the QDeclarativeComponent alive.
- QDeclarativeComponent *toComponent(QDeclarativeEngine *);
- // Return a QDeclarativeCompiledData if possible, or 0 if an error
- // occurs
- QDeclarativeCompiledData *toCompiledComponent(QDeclarativeEngine *);
-
- struct TypeReference
- {
- TypeReference();
-
- QDeclarativeType *type;
- QDeclarativeCompositeTypeData *unit;
- };
-
- struct ScriptReference
- {
- ScriptReference();
-
- QString qualifier;
- QDeclarativeCompositeTypeResource *resource;
- };
-
- QList<TypeReference> types;
- QList<ScriptReference> scripts;
- QList<QDeclarativeCompositeTypeResource *> resources;
-
- // Add or remove p as a waiter. When the QDeclarativeCompositeTypeData becomes
- // ready, the QDeclarativeComponentPrivate::typeDataReady() method will be invoked on
- // p. The waiter is automatically removed when the typeDataReady() method
- // is invoked, so there is no need to call remWaiter() in this case.
- void addWaiter(QDeclarativeComponentPrivate *p);
- void remWaiter(QDeclarativeComponentPrivate *p);
-
- qreal progress;
-
-private:
- friend class QDeclarativeCompositeTypeManager;
- friend class QDeclarativeCompiler;
- friend class QDeclarativeDomDocument;
-
- QDeclarativeScriptParser data;
- QList<QDeclarativeComponentPrivate *> waiters;
- QDeclarativeComponent *component;
- QDeclarativeCompiledData *compiledComponent;
-};
-
-class QDeclarativeCompositeTypeResource : public QDeclarativeRefCount
-{
-public:
- QDeclarativeCompositeTypeResource();
- virtual ~QDeclarativeCompositeTypeResource();
-
- enum Status {
- Invalid,
- Complete,
- Error,
- Waiting
- };
- Status status;
-
- QList<QDeclarativeCompositeTypeData *> dependants;
-
- QString url;
- QByteArray data;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDECLARATIVECOMPOSITETYPEDATA_P_H
-
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
deleted file mode 100644
index cc8f887..0000000
--- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp
+++ /dev/null
@@ -1,778 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qdeclarativecompositetypemanager_p.h"
-
-#include "private/qdeclarativecompositetypedata_p.h"
-#include "private/qdeclarativescriptparser_p.h"
-#include "qdeclarativeengine.h"
-#include "private/qdeclarativeengine_p.h"
-#include "qdeclarativecomponent.h"
-#include "private/qdeclarativecomponent_p.h"
-#include "private/qdeclarativecompiler_p.h"
-
-#include <QtNetwork/qnetworkreply.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qfile.h>
-
-QT_BEGIN_NAMESPACE
-
-QDeclarativeCompositeTypeData::QDeclarativeCompositeTypeData()
-: status(Invalid), errorType(NoError), component(0), compiledComponent(0)
-{
-}
-
-QDeclarativeCompositeTypeData::~QDeclarativeCompositeTypeData()
-{
- for (int ii = 0; ii < dependants.count(); ++ii)
- dependants.at(ii)->release();
-
- for (int ii = 0; ii < resources.count(); ++ii)
- resources.at(ii)->release();
-
- if (compiledComponent)
- compiledComponent->release();
-
- if (component)
- delete component;
-}
-
-QDeclarativeCompositeTypeResource::QDeclarativeCompositeTypeResource()
-{
-}
-
-QDeclarativeCompositeTypeResource::~QDeclarativeCompositeTypeResource()
-{
- for (int ii = 0; ii < dependants.count(); ++ii)
- dependants.at(ii)->release();
-}
-
-void QDeclarativeCompositeTypeData::addWaiter(QDeclarativeComponentPrivate *p)
-{
- waiters << p;
-}
-
-void QDeclarativeCompositeTypeData::remWaiter(QDeclarativeComponentPrivate *p)
-{
- waiters.removeAll(p);
-}
-
-QDeclarativeComponent *QDeclarativeCompositeTypeData::toComponent(QDeclarativeEngine *engine)
-{
- if (!component) {
-
- QDeclarativeCompiledData *cc = toCompiledComponent(engine);
- if (cc) {
- component = new QDeclarativeComponent(engine, cc, -1, -1, 0);
- cc->release();
- } else {
- component = new QDeclarativeComponent(engine, 0);
- component->d_func()->url = imports.baseUrl();
- component->d_func()->state.errors = errors;
- }
-
- }
-
- return component;
-}
-
-QDeclarativeCompiledData *
-QDeclarativeCompositeTypeData::toCompiledComponent(QDeclarativeEngine *engine)
-{
- if (status == Complete && !compiledComponent) {
-
- // Build script imports
- foreach (const QDeclarativeScriptParser::Import &import, data.imports()) {
- if (import.type == QDeclarativeScriptParser::Import::Script) {
- QString url = imports.baseUrl().resolved(QUrl(import.uri)).toString();
-
- ScriptReference ref;
- ref.qualifier = import.qualifier;
-
- for (int ii = 0; ii < resources.count(); ++ii) {
- if (resources.at(ii)->url == url) {
- ref.resource = resources.at(ii);
- break;
- }
- }
-
- Q_ASSERT(ref.resource);
-
- scripts << ref;
- }
- }
-
- compiledComponent = new QDeclarativeCompiledData(engine);
- compiledComponent->url = imports.baseUrl();
- compiledComponent->name = compiledComponent->url.toString();
-
- QDeclarativeCompiler compiler;
- if (!compiler.compile(engine, this, compiledComponent)) {
- status = Error;
- errors = compiler.errors();
- compiledComponent->release();
- compiledComponent = 0;
- }
-
- // Data is no longer needed once we have a compiled component
- data.clear();
- }
-
- if (compiledComponent)
- compiledComponent->addref();
-
- return compiledComponent;
-}
-
-QDeclarativeCompositeTypeData::TypeReference::TypeReference()
-: type(0), unit(0)
-{
-}
-
-QDeclarativeCompositeTypeData::ScriptReference::ScriptReference()
-: resource(0)
-{
-}
-
-QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e)
-: engine(e), redirectCount(0)
-{
-}
-
-QDeclarativeCompositeTypeManager::~QDeclarativeCompositeTypeManager()
-{
- for (Components::Iterator iter = components.begin(); iter != components.end();) {
- (*iter)->release();
- iter = components.erase(iter);
- }
- for (Resources::Iterator iter = resources.begin(); iter != resources.end();) {
- (*iter)->release();
- iter = resources.erase(iter);
- }
-}
-
-QDeclarativeCompositeTypeData *QDeclarativeCompositeTypeManager::get(const QUrl &url)
-{
- Redirects::Iterator redir = redirects.find(url);
- if (redir != redirects.end())
- return get(*redir);
-
- QDeclarativeCompositeTypeData *unit = components.value(url);
-
- if (!unit) {
- unit = new QDeclarativeCompositeTypeData;
- unit->status = QDeclarativeCompositeTypeData::Waiting;
- unit->progress = 0.0;
- unit->imports.setBaseUrl(url);
- components.insert(url, unit);
-
- loadSource(unit);
- }
-
- unit->addref();
- return unit;
-}
-
-QDeclarativeCompositeTypeData *
-QDeclarativeCompositeTypeManager::getImmediate(const QByteArray &data, const QUrl &url)
-{
- QDeclarativeCompositeTypeData *unit = new QDeclarativeCompositeTypeData;
- unit->status = QDeclarativeCompositeTypeData::Waiting;
- unit->imports.setBaseUrl(url);
- setData(unit, data, url);
- return unit;
-}
-
-void QDeclarativeCompositeTypeManager::clearCache()
-{
- for (Components::Iterator iter = components.begin(); iter != components.end();) {
- if ((*iter)->status != QDeclarativeCompositeTypeData::Waiting) {
- (*iter)->release();
- iter = components.erase(iter);
- } else {
- ++iter;
- }
- }
-
- for (Resources::Iterator iter = resources.begin(); iter != resources.end();) {
- if ((*iter)->status != QDeclarativeCompositeTypeResource::Waiting) {
- (*iter)->release();
- iter = resources.erase(iter);
- } else {
- ++iter;
- }
- }
-}
-
-#define TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION 16
-
-void QDeclarativeCompositeTypeManager::replyFinished()
-{
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
-
- QDeclarativeCompositeTypeData *unit = components.value(reply->url());
- Q_ASSERT(unit);
-
- redirectCount++;
- if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) {
- QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (redirect.isValid()) {
- QUrl url = reply->url().resolved(redirect.toUrl());
- redirects.insert(reply->url(),url);
- unit->imports.setBaseUrl(url);
- components.remove(reply->url());
- components.insert(url, unit);
- reply->deleteLater();
- reply = engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(replyFinished()));
- QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
- return;
- }
- }
- redirectCount = 0;
-
- if (reply->error() != QNetworkReply::NoError) {
- QString errorDescription;
- // ### - Fill in error
- errorDescription = QLatin1String("Network error for URL ") +
- reply->url().toString();
-
- unit->status = QDeclarativeCompositeTypeData::Error;
- // ### FIXME
- QDeclarativeError error;
- error.setDescription(errorDescription);
- unit->errorType = QDeclarativeCompositeTypeData::AccessError;
- unit->errors << error;
- doComplete(unit);
-
- } else {
- QByteArray data = reply->readAll();
-
- setData(unit, data, reply->url());
- }
-
- reply->deleteLater();
-}
-
-void QDeclarativeCompositeTypeManager::resourceReplyFinished()
-{
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
-
- QDeclarativeCompositeTypeResource *resource = resources.value(reply->url());
- Q_ASSERT(resource);
-
- redirectCount++;
- if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) {
- QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (redirect.isValid()) {
- QUrl url = reply->url().resolved(redirect.toUrl());
- redirects.insert(reply->url(),url);
- resource->url = url.toString();
- resources.remove(reply->url());
- resources.insert(url, resource);
- reply->deleteLater();
- reply = engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(resourceReplyFinished()));
- return;
- }
- }
- redirectCount = 0;
-
- if (reply->error() != QNetworkReply::NoError) {
-
- resource->status = QDeclarativeCompositeTypeResource::Error;
-
- } else {
-
- resource->status = QDeclarativeCompositeTypeResource::Complete;
- resource->data = reply->readAll();
-
- }
-
- doComplete(resource);
- reply->deleteLater();
-}
-
-void QDeclarativeCompositeTypeManager::loadResource(QDeclarativeCompositeTypeResource *resource)
-{
- QUrl url(resource->url);
-
- QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
- if (!lf.isEmpty()) {
-
- QFile file(lf);
- if (file.open(QFile::ReadOnly)) {
- resource->data = file.readAll();
- resource->status = QDeclarativeCompositeTypeResource::Complete;
- } else {
- resource->status = QDeclarativeCompositeTypeResource::Error;
- }
- } else if (url.scheme().isEmpty()) {
-
- // We can't open this, so just declare as an error
- resource->status = QDeclarativeCompositeTypeResource::Error;
- } else {
-
- QNetworkReply *reply =
- engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(resourceReplyFinished()));
-
- }
-}
-
-void QDeclarativeCompositeTypeManager::loadSource(QDeclarativeCompositeTypeData *unit)
-{
- QUrl url(unit->imports.baseUrl());
-
- QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
- if (!lf.isEmpty()) {
-
- QFile file(lf);
- if (file.open(QFile::ReadOnly)) {
- QByteArray data = file.readAll();
- setData(unit, data, url);
- return; // success
- }
- } else if (!url.scheme().isEmpty()) {
- QNetworkReply *reply =
- engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(replyFinished()));
- QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
- return; // waiting
- }
-
- // error happened
- QString errorDescription;
- // ### - Fill in error
- errorDescription = QLatin1String("File error for URL ") + url.toString();
- unit->status = QDeclarativeCompositeTypeData::Error;
- // ### FIXME
- QDeclarativeError error;
- error.setDescription(errorDescription);
- unit->errorType = QDeclarativeCompositeTypeData::AccessError;
- unit->errors << error;
- doComplete(unit);
-}
-
-void QDeclarativeCompositeTypeManager::requestProgress(qint64 received, qint64 total)
-{
- if (total <= 0)
- return;
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
-
- QDeclarativeCompositeTypeData *unit = components.value(reply->url());
- Q_ASSERT(unit);
-
- unit->progress = qreal(received)/total;
-
- foreach (QDeclarativeComponentPrivate *comp, unit->waiters)
- comp->updateProgress(unit->progress);
-}
-
-void QDeclarativeCompositeTypeManager::setData(QDeclarativeCompositeTypeData *unit,
- const QByteArray &data,
- const QUrl &url)
-{
- bool ok = true;
- if (!unit->data.parse(data, url)) {
- ok = false;
- unit->errors << unit->data.errors();
- }
-
- if (ok) {
- compile(unit);
- } else {
- unit->status = QDeclarativeCompositeTypeData::Error;
- unit->errorType = QDeclarativeCompositeTypeData::GeneralError;
- doComplete(unit);
- }
-}
-
-void QDeclarativeCompositeTypeManager::doComplete(QDeclarativeCompositeTypeData *unit)
-{
- for (int ii = 0; ii < unit->dependants.count(); ++ii) {
- checkComplete(unit->dependants.at(ii));
- unit->dependants.at(ii)->release();
- }
- unit->dependants.clear();
-
- while(!unit->waiters.isEmpty()) {
- QDeclarativeComponentPrivate *p = unit->waiters.takeFirst();
- p->typeDataReady();
- }
-}
-
-void QDeclarativeCompositeTypeManager::doComplete(QDeclarativeCompositeTypeResource *resource)
-{
- for (int ii = 0; ii < resource->dependants.count(); ++ii) {
- checkComplete(resource->dependants.at(ii));
- resource->dependants.at(ii)->release();
- }
- resource->dependants.clear();
-}
-
-void QDeclarativeCompositeTypeManager::checkComplete(QDeclarativeCompositeTypeData *unit)
-{
- if (unit->status != QDeclarativeCompositeTypeData::Waiting
- && unit->status != QDeclarativeCompositeTypeData::WaitingResources)
- return;
-
- int waiting = 0;
- for (int ii = 0; ii < unit->resources.count(); ++ii) {
- QDeclarativeCompositeTypeResource *r = unit->resources.at(ii);
-
- if (!r)
- continue;
-
- if (r->status == QDeclarativeCompositeTypeResource::Error) {
- unit->status = QDeclarativeCompositeTypeData::Error;
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- error.setDescription(tr("Resource %1 unavailable").arg(r->url));
- unit->errors << error;
- doComplete(unit);
- return;
- } else if (r->status == QDeclarativeCompositeTypeResource::Waiting) {
- waiting++;
- }
- }
-
- if (waiting == 0) {
- if (unit->status == QDeclarativeCompositeTypeData::WaitingResources) {
- waiting += resolveTypes(unit);
- if (unit->status != QDeclarativeCompositeTypeData::Error) {
- if (waiting)
- unit->status = QDeclarativeCompositeTypeData::Waiting;
- } else {
- return;
- }
- } else {
- for (int ii = 0; ii < unit->types.count(); ++ii) {
- QDeclarativeCompositeTypeData *u = unit->types.at(ii).unit;
-
- if (!u)
- continue;
-
- if (u->status == QDeclarativeCompositeTypeData::Error) {
- unit->status = QDeclarativeCompositeTypeData::Error;
- unit->errors = u->errors;
- doComplete(unit);
- return;
- } else if (u->status == QDeclarativeCompositeTypeData::Waiting
- || u->status == QDeclarativeCompositeTypeData::WaitingResources)
- {
- waiting++;
- }
- }
- }
- }
-
- if (!waiting) {
- unit->status = QDeclarativeCompositeTypeData::Complete;
- doComplete(unit);
- }
-}
-
-int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData *unit)
-{
- // not called until all resources are loaded (they include import URLs)
- int waiting = 0;
-
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QDeclarativeImportDatabase *importDatabase = &ep->importDatabase;
-
- // For local urls, add an implicit import "." as first (most overridden) lookup.
- // This will also trigger the loading of the qmldir and the import of any native
- // types from available plugins.
- {
- QDeclarativeDirComponents qmldircomponentsnetwork;
- if (QDeclarativeCompositeTypeResource *resource
- = resources.value(unit->imports.baseUrl().resolved(QUrl(QLatin1String("./qmldir"))))) {
- QDeclarativeDirParser parser;
- parser.setSource(QString::fromUtf8(resource->data));
- parser.parse();
- qmldircomponentsnetwork = parser.components();
- }
-
- unit->imports.addImport(importDatabase,
- QLatin1String("."), QString(), -1, -1, QDeclarativeScriptParser::Import::File,
- qmldircomponentsnetwork,
- 0); // error ignored (just means no fallback)
- }
-
-
- foreach (const QDeclarativeScriptParser::Import &imp, unit->data.imports()) {
- QDeclarativeDirComponents qmldircomponentsnetwork;
- if (imp.type == QDeclarativeScriptParser::Import::Script)
- continue;
-
- if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) {
- QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString();
- for (int ii = 0; ii < unit->resources.count(); ++ii) {
- if (unit->resources.at(ii)->url == importUrl) {
- QDeclarativeDirParser parser;
- parser.setSource(QString::fromUtf8(unit->resources.at(ii)->data));
- parser.parse();
- qmldircomponentsnetwork = parser.components();
- break;
- }
- }
- }
-
-
- int vmaj = -1;
- int vmin = -1;
- if (!imp.version.isEmpty()) {
- int dot = imp.version.indexOf(QLatin1Char('.'));
- if (dot < 0) {
- vmaj = imp.version.toInt();
- vmin = 0;
- } else {
- vmaj = imp.version.left(dot).toInt();
- vmin = imp.version.mid(dot+1).toInt();
- }
- }
-
- QString errorString;
- if (!unit->imports.addImport(importDatabase,
- imp.uri, imp.qualifier, vmaj, vmin, imp.type,
- qmldircomponentsnetwork, &errorString)) {
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- error.setDescription(errorString);
- error.setLine(imp.location.start.line);
- error.setColumn(imp.location.start.column);
- unit->status = QDeclarativeCompositeTypeData::Error;
- unit->errorType = QDeclarativeCompositeTypeData::GeneralError;
- unit->errors << error;
- doComplete(unit);
- return 0;
- }
- }
-
-
- QList<QDeclarativeScriptParser::TypeReference*> types = unit->data.referencedTypes();
-
- for (int ii = 0; ii < types.count(); ++ii) {
- QDeclarativeScriptParser::TypeReference *parserRef = types.at(ii);
- QByteArray typeName = parserRef->name.toUtf8();
-
- QDeclarativeCompositeTypeData::TypeReference ref;
-
- QUrl url;
- int majorVersion;
- int minorVersion;
- QDeclarativeImportedNamespace *typeNamespace = 0;
- QString errorString;
- if (!unit->imports.resolveType(typeName, &ref.type, &url, &majorVersion, &minorVersion,
- &typeNamespace, &errorString) || typeNamespace) {
- // Known to not be a type:
- // - known to be a namespace (Namespace {})
- // - type with unknown namespace (UnknownNamespace.SomeType {})
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- QString userTypeName = QString::fromUtf8(typeName);
- userTypeName.replace(QLatin1Char('/'),QLatin1Char('.'));
- if (typeNamespace)
- error.setDescription(tr("Namespace %1 cannot be used as a type").arg(userTypeName));
- else
- error.setDescription(tr("%1 %2").arg(userTypeName).arg(errorString));
-
- if (!parserRef->refObjects.isEmpty()) {
- QDeclarativeParser::Object *obj = parserRef->refObjects.first();
- error.setLine(obj->location.start.line);
- error.setColumn(obj->location.start.column);
- }
- unit->status = QDeclarativeCompositeTypeData::Error;
- unit->errorType = QDeclarativeCompositeTypeData::GeneralError;
- unit->errors << error;
- doComplete(unit);
- return 0;
- }
-
- if (ref.type) {
- foreach (QDeclarativeParser::Object *obj, parserRef->refObjects) {
- // store namespace for DOM
- obj->majorVersion = majorVersion;
- obj->minorVersion = minorVersion;
- }
- unit->types << ref;
- continue;
- }
-
- Redirects::Iterator redir = redirects.find(url);
- if (redir != redirects.end())
- url = *redir;
-
- QDeclarativeCompositeTypeData *urlUnit = components.value(url);
-
- if (!urlUnit) {
- urlUnit = new QDeclarativeCompositeTypeData;
- urlUnit->status = QDeclarativeCompositeTypeData::Waiting;
- urlUnit->imports.setBaseUrl(url);
- components.insert(url, urlUnit);
-
- loadSource(urlUnit);
- }
-
- ref.unit = urlUnit;
- switch(urlUnit->status) {
- case QDeclarativeCompositeTypeData::Invalid:
- case QDeclarativeCompositeTypeData::Error:
- unit->status = QDeclarativeCompositeTypeData::Error;
- {
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- error.setDescription(tr("Type %1 unavailable").arg(QString::fromUtf8(typeName)));
- if (!parserRef->refObjects.isEmpty()) {
- QDeclarativeParser::Object *obj = parserRef->refObjects.first();
- error.setLine(obj->location.start.line);
- error.setColumn(obj->location.start.column);
- }
- unit->errors << error;
- }
- if (urlUnit->errorType != QDeclarativeCompositeTypeData::AccessError)
- unit->errors << urlUnit->errors;
- doComplete(unit);
- return 0;
-
- case QDeclarativeCompositeTypeData::Complete:
- break;
-
- case QDeclarativeCompositeTypeData::Waiting:
- case QDeclarativeCompositeTypeData::WaitingResources:
- unit->addref();
- ref.unit->dependants << unit;
- waiting++;
- break;
- }
-
- unit->types << ref;
- }
- return waiting;
-}
-
-// ### Check ref counting in here
-void QDeclarativeCompositeTypeManager::compile(QDeclarativeCompositeTypeData *unit)
-{
- int waiting = 0;
-
- QList<QUrl> resourceList = unit->data.referencedResources();
-
- foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) {
- if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) {
- QUrl importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir")));
- if (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty()) {
- // Import requires remote qmldir
- resourceList.prepend(importUrl);
- }
- }
- }
-
- QUrl importUrl;
- if (!unit->imports.baseUrl().scheme().isEmpty())
- importUrl = unit->imports.baseUrl().resolved(QUrl(QLatin1String("qmldir")));
- if (!importUrl.scheme().isEmpty() && QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty())
- resourceList.prepend(importUrl);
-
- for (int ii = 0; ii < resourceList.count(); ++ii) {
- QUrl url = unit->imports.baseUrl().resolved(resourceList.at(ii));
-
- QDeclarativeCompositeTypeResource *resource = resources.value(url);
-
- if (!resource) {
- resource = new QDeclarativeCompositeTypeResource;
- resource->status = QDeclarativeCompositeTypeResource::Waiting;
- resource->url = url.toString();
- resources.insert(url, resource);
-
- loadResource(resource);
- }
-
- switch(resource->status) {
- case QDeclarativeCompositeTypeResource::Invalid:
- case QDeclarativeCompositeTypeResource::Error:
- unit->status = QDeclarativeCompositeTypeData::Error;
- {
- QDeclarativeError error;
- error.setUrl(unit->imports.baseUrl());
- error.setDescription(tr("Resource %1 unavailable").arg(resource->url));
- unit->errors << error;
- }
- doComplete(unit);
- return;
-
- case QDeclarativeCompositeTypeData::Complete:
- break;
-
- case QDeclarativeCompositeTypeData::Waiting:
- unit->addref();
- resource->dependants << unit;
- waiting++;
- break;
- }
-
- resource->addref();
- unit->resources << resource;
- }
-
- if (waiting == 0) {
- waiting += resolveTypes(unit);
- if (unit->status != QDeclarativeCompositeTypeData::Error) {
- if (!waiting) {
- unit->status = QDeclarativeCompositeTypeData::Complete;
- doComplete(unit);
- } else {
- unit->status = QDeclarativeCompositeTypeData::Waiting;
- }
- }
- } else {
- unit->status = QDeclarativeCompositeTypeData::WaitingResources;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager_p.h b/src/declarative/qml/qdeclarativecompositetypemanager_p.h
deleted file mode 100644
index 5c82c4c..0000000
--- a/src/declarative/qml/qdeclarativecompositetypemanager_p.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVECOMPOSITETYPEMANAGER_P_H
-#define QDECLARATIVECOMPOSITETYPEMANAGER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qdeclarativescriptparser_p.h"
-#include "private/qdeclarativerefcount_p.h"
-#include "qdeclarativeerror.h"
-#include "qdeclarativeengine.h"
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeCompiledData;
-class QDeclarativeComponentPrivate;
-class QDeclarativeComponent;
-class QDeclarativeDomDocument;
-
-class QDeclarativeCompositeTypeData;
-class QDeclarativeCompositeTypeResource;
-
-class QDeclarativeCompositeTypeManager : public QObject
-{
- Q_OBJECT
-public:
- QDeclarativeCompositeTypeManager(QDeclarativeEngine *);
- ~QDeclarativeCompositeTypeManager();
-
- // Return a QDeclarativeCompositeTypeData for url. The QDeclarativeCompositeTypeData may be
- // cached.
- QDeclarativeCompositeTypeData *get(const QUrl &url);
- // Return a QDeclarativeCompositeTypeData for data, with the provided base url. The
- // QDeclarativeCompositeTypeData will not be cached.
- QDeclarativeCompositeTypeData *getImmediate(const QByteArray &data, const QUrl &url);
-
- // Clear cached types. Only types that aren't in the Waiting state will
- // be cleared.
- void clearCache();
-
-private Q_SLOTS:
- void replyFinished();
- void resourceReplyFinished();
- void requestProgress(qint64 received, qint64 total);
-
-private:
- void loadSource(QDeclarativeCompositeTypeData *);
- void loadResource(QDeclarativeCompositeTypeResource *);
- void compile(QDeclarativeCompositeTypeData *);
- void setData(QDeclarativeCompositeTypeData *, const QByteArray &, const QUrl &);
-
- void doComplete(QDeclarativeCompositeTypeData *);
- void doComplete(QDeclarativeCompositeTypeResource *);
- void checkComplete(QDeclarativeCompositeTypeData *);
- int resolveTypes(QDeclarativeCompositeTypeData *);
-
- QDeclarativeEngine *engine;
- typedef QHash<QUrl, QDeclarativeCompositeTypeData *> Components;
- Components components;
- typedef QHash<QUrl, QDeclarativeCompositeTypeResource *> Resources;
- Resources resources;
- typedef QHash<QUrl, QUrl> Redirects;
- Redirects redirects;
- int redirectCount;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDECLARATIVECOMPOSITETYPEMANAGER_P_H
-
diff --git a/src/declarative/qml/qdeclarativedom.cpp b/src/declarative/qml/qdeclarativedom.cpp
index 5b30bde..1a9b501 100644
--- a/src/declarative/qml/qdeclarativedom.cpp
+++ b/src/declarative/qml/qdeclarativedom.cpp
@@ -42,7 +42,6 @@
#include "private/qdeclarativedom_p.h"
#include "private/qdeclarativedom_p_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "private/qdeclarativecompiler_p.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativescriptparser_p.h"
@@ -145,37 +144,23 @@ bool QDeclarativeDomDocument::load(QDeclarativeEngine *engine, const QByteArray
d->errors.clear();
d->imports.clear();
- QDeclarativeCompiledData *component = new QDeclarativeCompiledData(engine);
- QDeclarativeCompiler compiler;
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ QDeclarativeTypeData *td = ep->typeLoader.get(data, url, QDeclarativeTypeLoader::PreserveParser);
- QDeclarativeCompositeTypeData *td = ((QDeclarativeEnginePrivate *)QDeclarativeEnginePrivate::get(engine))->typeManager.getImmediate(data, url);
-
- if(td->status == QDeclarativeCompositeTypeData::Error) {
- d->errors = td->errors;
+ if(td->isError()) {
+ d->errors = td->errors();
td->release();
- component->release();
return false;
- } else if(td->status == QDeclarativeCompositeTypeData::Waiting ||
- td->status == QDeclarativeCompositeTypeData::WaitingResources) {
+ } else if(!td->isCompleteOrError()) {
QDeclarativeError error;
error.setDescription(QLatin1String("QDeclarativeDomDocument supports local types only"));
d->errors << error;
td->release();
- component->release();
- return false;
- }
-
- compiler.compile(engine, td, component);
-
- if (compiler.isError()) {
- d->errors = compiler.errors();
- td->release();
- component->release();
return false;
}
- for (int i = 0; i < td->data.imports().size(); ++i) {
- QDeclarativeScriptParser::Import parserImport = td->data.imports().at(i);
+ for (int i = 0; i < td->parser().imports().size(); ++i) {
+ QDeclarativeScriptParser::Import parserImport = td->parser().imports().at(i);
QDeclarativeDomImport domImport;
domImport.d->type = static_cast<QDeclarativeDomImportPrivate::Type>(parserImport.type);
domImport.d->uri = parserImport.uri;
@@ -184,12 +169,12 @@ bool QDeclarativeDomDocument::load(QDeclarativeEngine *engine, const QByteArray
d->imports += domImport;
}
- if (td->data.tree()) {
- d->root = td->data.tree();
+ if (td->parser().tree()) {
+ d->root = td->parser().tree();
d->root->addref();
}
- component->release();
+ td->release();
return true;
}
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index c5a5c18..e77a53e 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -259,7 +259,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
inBeginCreate(false), networkAccessManager(0), networkAccessManagerFactory(0),
- typeManager(e), importDatabase(e), uniqueId(1)
+ typeLoader(e), importDatabase(e), uniqueId(1)
{
if (!qt_QmlQtModule_registered) {
qt_QmlQtModule_registered = true;
@@ -565,7 +565,7 @@ QDeclarativeEngine::~QDeclarativeEngine()
void QDeclarativeEngine::clearComponentCache()
{
Q_D(QDeclarativeEngine);
- d->typeManager.clearCache();
+ d->typeLoader.clearCache();
}
/*!
@@ -1716,6 +1716,9 @@ void QDeclarativeEnginePrivate::sendQuit()
{
Q_Q(QDeclarativeEngine);
emit q->quit();
+ if (q->receivers(SIGNAL(quit())) == 0) {
+ qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
+ }
}
static void dumpwarning(const QDeclarativeError &error)
@@ -2110,7 +2113,7 @@ bool QDeclarativeEnginePrivate::isQObject(int t)
QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
{
int t = v.userType();
- if (m_compositeTypes.contains(t)) {
+ if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
if (ok) *ok = true;
return *(QObject **)(v.constData());
} else {
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index db2db35..dc7315d 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -56,7 +56,7 @@
#include "qdeclarativeengine.h"
#include "private/qdeclarativeclassfactory_p.h"
-#include "private/qdeclarativecompositetypemanager_p.h"
+#include "private/qdeclarativetypeloader_p.h"
#include "private/qdeclarativeimport_p.h"
#include "private/qpodvector_p.h"
#include "qdeclarative.h"
@@ -239,7 +239,7 @@ public:
mutable QMutex mutex;
- QDeclarativeCompositeTypeManager typeManager;
+ QDeclarativeTypeLoader typeLoader;
QDeclarativeImportDatabase importDatabase;
QString offlineStoragePath;
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index 3af892d..9d74238 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -192,7 +192,7 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam
if (!(hints & ImplicitObject)) {
local.coreIndex = -1;
lastData = &local;
- return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess;
+ return QScriptClass::HandlesWriteAccess;
}
return 0;
@@ -625,11 +625,12 @@ private:
char data[4 * sizeof(void *)];
int type;
+ bool isObjectType;
};
}
MetaCallArgument::MetaCallArgument()
-: type(QVariant::Invalid)
+: type(QVariant::Invalid), isObjectType(false)
{
}
@@ -744,12 +745,23 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine,
new (&data) QVariant();
type = -1;
- QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
+ QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine);
+ QVariant v = priv->scriptValueToVariant(value);
if (v.userType() == callType) {
*((QVariant *)&data) = v;
} else if (v.canConvert((QVariant::Type)callType)) {
*((QVariant *)&data) = v;
((QVariant *)&data)->convert((QVariant::Type)callType);
+ } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) {
+ QObject *obj = priv->toQObject(v);
+
+ if (obj) {
+ const QMetaObject *objMo = obj->metaObject();
+ while (objMo && objMo != mo) objMo = objMo->superClass();
+ if (!objMo) obj = 0;
+ }
+
+ *((QVariant *)&data) = QVariant(callType, &obj);
} else {
*((QVariant *)&data) = QVariant(callType, (void *)0);
}
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 515c4d6..d0dd2e8 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -42,7 +42,6 @@
#include "qdeclarativeproperty.h"
#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "qdeclarative.h"
#include "private/qdeclarativebinding_p.h"
#include "qdeclarativecontext.h"
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index 839d79f..08503c2 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -134,8 +134,9 @@ QDeclarativePropertyCache::~QDeclarativePropertyCache()
void QDeclarativePropertyCache::clear()
{
- for (int ii = 0; ii < indexCache.count(); ++ii)
- indexCache.at(ii)->release();
+ for (int ii = 0; ii < indexCache.count(); ++ii) {
+ if (indexCache.at(ii)) indexCache.at(ii)->release();
+ }
for (StringCache::ConstIterator iter = stringCache.begin();
iter != stringCache.end(); ++iter)
@@ -156,14 +157,27 @@ QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObj
Q_ASSERT(metaObject);
QDeclarativePropertyCache::Data rv;
- int idx = metaObject->indexOfProperty(property.toUtf8());
- if (idx != -1) {
- rv.load(metaObject->property(idx));
- return rv;
+ {
+ const QMetaObject *cmo = metaObject;
+ while (cmo) {
+ int idx = metaObject->indexOfProperty(property.toUtf8());
+ if (idx != -1) {
+ QMetaProperty p = metaObject->property(idx);
+ if (p.isScriptable()) {
+ rv.load(metaObject->property(idx));
+ return rv;
+ } else {
+ while (cmo && cmo->propertyOffset() >= idx)
+ cmo = cmo->superClass();
+ }
+ } else {
+ cmo = 0;
+ }
+ }
}
int methodCount = metaObject->methodCount();
- for (int ii = methodCount - 1; ii >= 2; --ii) { // >=2 to block the destroyed signal
+ for (int ii = methodCount - 1; ii >= 3; --ii) { // >=3 to block the destroyed signal and deleteLater() slot
QMetaMethod m = metaObject->method(ii);
if (m.access() == QMetaMethod::Private)
continue;
@@ -189,8 +203,9 @@ QDeclarativePropertyCache *QDeclarativePropertyCache::copy() const
cache->stringCache = stringCache;
cache->identifierCache = identifierCache;
- for (int ii = 0; ii < indexCache.count(); ++ii)
- indexCache.at(ii)->addref();
+ for (int ii = 0; ii < indexCache.count(); ++ii) {
+ if (indexCache.at(ii)) indexCache.at(ii)->addref();
+ }
for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter)
(*iter)->addref();
for (IdentifierCache::ConstIterator iter = identifierCache.begin(); iter != identifierCache.end(); ++iter)
@@ -210,6 +225,9 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
indexCache.resize(propCount);
for (int ii = propOffset; ii < propCount; ++ii) {
QMetaProperty p = metaObject->property(ii);
+ if (!p.isScriptable())
+ continue;
+
QString propName = QString::fromUtf8(p.name());
RData *data = new RData;
@@ -275,6 +293,10 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb
indexCache.resize(propCount);
for (int ii = propCount - 1; ii >= 0; --ii) {
QMetaProperty p = metaObject->property(ii);
+ if (!p.isScriptable()) {
+ indexCache[ii] = 0;
+ continue;
+ }
QString propName = QString::fromUtf8(p.name());
RData *data = new RData;
@@ -294,7 +316,7 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb
}
int methodCount = metaObject->methodCount();
- for (int ii = methodCount - 1; ii >= 2; --ii) { // >=2 to block the destroyed signal
+ for (int ii = methodCount - 1; ii >= 3; --ii) { // >=3 to block the destroyed signal and deleteLater() slot
QMetaMethod m = metaObject->method(ii);
if (m.access() == QMetaMethod::Private)
continue;
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp
index 0b3b35f..c956051 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescriptparser.cpp
@@ -387,7 +387,6 @@ bool ProcessAST::visit(AST::UiImport *node)
if (uri.endsWith(QLatin1String(".js"))) {
import.type = QDeclarativeScriptParser::Import::Script;
- _parser->_refUrls << QUrl(uri);
} else {
import.type = QDeclarativeScriptParser::Import::File;
}
@@ -878,11 +877,6 @@ QList<QDeclarativeScriptParser::TypeReference*> QDeclarativeScriptParser::refere
return _refTypes;
}
-QList<QUrl> QDeclarativeScriptParser::referencedResources() const
-{
- return _refUrls;
-}
-
Object *QDeclarativeScriptParser::tree() const
{
return root;
@@ -960,6 +954,217 @@ QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extra
return rv;
}
+#define CHECK_LINE if(l.currentLineNo() != startLine) return rv;
+#define CHECK_TOKEN(t) if (token != QDeclarativeJSGrammar:: t) return rv;
+
+static const int uriTokens[] = {
+ QDeclarativeJSGrammar::T_IDENTIFIER,
+ QDeclarativeJSGrammar::T_PROPERTY,
+ QDeclarativeJSGrammar::T_SIGNAL,
+ QDeclarativeJSGrammar::T_READONLY,
+ QDeclarativeJSGrammar::T_ON,
+ QDeclarativeJSGrammar::T_BREAK,
+ QDeclarativeJSGrammar::T_CASE,
+ QDeclarativeJSGrammar::T_CATCH,
+ QDeclarativeJSGrammar::T_CONTINUE,
+ QDeclarativeJSGrammar::T_DEFAULT,
+ QDeclarativeJSGrammar::T_DELETE,
+ QDeclarativeJSGrammar::T_DO,
+ QDeclarativeJSGrammar::T_ELSE,
+ QDeclarativeJSGrammar::T_FALSE,
+ QDeclarativeJSGrammar::T_FINALLY,
+ QDeclarativeJSGrammar::T_FOR,
+ QDeclarativeJSGrammar::T_FUNCTION,
+ QDeclarativeJSGrammar::T_IF,
+ QDeclarativeJSGrammar::T_IN,
+ QDeclarativeJSGrammar::T_INSTANCEOF,
+ QDeclarativeJSGrammar::T_NEW,
+ QDeclarativeJSGrammar::T_NULL,
+ QDeclarativeJSGrammar::T_RETURN,
+ QDeclarativeJSGrammar::T_SWITCH,
+ QDeclarativeJSGrammar::T_THIS,
+ QDeclarativeJSGrammar::T_THROW,
+ QDeclarativeJSGrammar::T_TRUE,
+ QDeclarativeJSGrammar::T_TRY,
+ QDeclarativeJSGrammar::T_TYPEOF,
+ QDeclarativeJSGrammar::T_VAR,
+ QDeclarativeJSGrammar::T_VOID,
+ QDeclarativeJSGrammar::T_WHILE,
+ QDeclarativeJSGrammar::T_CONST,
+ QDeclarativeJSGrammar::T_DEBUGGER,
+ QDeclarativeJSGrammar::T_RESERVED_WORD,
+ QDeclarativeJSGrammar::T_WITH,
+
+ QDeclarativeJSGrammar::EOF_SYMBOL
+};
+static inline bool isUriToken(int token)
+{
+ const int *current = uriTokens;
+ while (*current != QDeclarativeJSGrammar::EOF_SYMBOL) {
+ if (*current == token)
+ return true;
+ ++current;
+ }
+ return false;
+}
+
+QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMetaData(QString &script)
+{
+ JavaScriptMetaData rv;
+
+ QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = rv.pragmas;
+
+ const QString pragma(QLatin1String("pragma"));
+ const QString js(QLatin1String(".js"));
+ const QString library(QLatin1String("library"));
+
+ QDeclarativeJS::Lexer l(0);
+ l.setCode(script, 0);
+
+ int token = l.lex();
+
+ while (true) {
+ if (token != QDeclarativeJSGrammar::T_DOT)
+ return rv;
+
+ int startOffset = l.tokenOffset();
+ int startLine = l.currentLineNo();
+
+ token = l.lex();
+
+ CHECK_LINE;
+
+ if (token == QDeclarativeJSGrammar::T_IMPORT) {
+
+ // .import <URI> <Version> as <Identifier>
+ // .import <file.js> as <Identifier>
+
+ token = l.lex();
+
+ CHECK_LINE;
+
+ if (token == QDeclarativeJSGrammar::T_STRING_LITERAL) {
+
+ QString file(l.characterBuffer(), l.characterCount());
+ if (!file.endsWith(js))
+ return rv;
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_AS);
+ CHECK_LINE;
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_IDENTIFIER);
+ CHECK_LINE;
+
+ int endOffset = l.tokenLength() + l.tokenOffset();
+
+ QString importId = script.mid(l.tokenOffset(), l.tokenLength());
+
+ if (!importId.at(0).isUpper())
+ return rv;
+
+ token = l.lex();
+ if (l.currentLineNo() == startLine)
+ return rv;
+
+ replaceWithSpace(script, startOffset, endOffset - startOffset);
+
+ Import import;
+ import.type = Import::Script;
+ import.uri = file;
+ import.qualifier = importId;
+
+ rv.imports << import;
+
+ } else {
+ // URI
+ QString uri;
+ QString version;
+
+ while (true) {
+ if (!isUriToken(token))
+ return rv;
+
+ uri.append(QString(l.characterBuffer(), l.characterCount()));
+
+ token = l.lex();
+ CHECK_LINE;
+ if (token != QDeclarativeJSGrammar::T_DOT)
+ break;
+
+ uri.append(QLatin1Char('.'));
+
+ token = l.lex();
+ CHECK_LINE;
+ }
+
+ CHECK_TOKEN(T_NUMERIC_LITERAL);
+ version = script.mid(l.tokenOffset(), l.tokenLength());
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_AS);
+ CHECK_LINE;
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_IDENTIFIER);
+ CHECK_LINE;
+
+ int endOffset = l.tokenLength() + l.tokenOffset();
+
+ QString importId = script.mid(l.tokenOffset(), l.tokenLength());
+
+ if (!importId.at(0).isUpper())
+ return rv;
+
+ token = l.lex();
+ if (l.currentLineNo() == startLine)
+ return rv;
+
+ replaceWithSpace(script, startOffset, endOffset - startOffset);
+
+ Import import;
+ import.type = Import::Library;
+ import.uri = uri;
+ import.version = version;
+ import.qualifier = importId;
+
+ rv.imports << import;
+ }
+
+ } else if (token == QDeclarativeJSGrammar::T_IDENTIFIER &&
+ script.mid(l.tokenOffset(), l.tokenLength()) == pragma) {
+
+ token = l.lex();
+
+ CHECK_TOKEN(T_IDENTIFIER);
+ CHECK_LINE;
+
+ QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
+ int endOffset = l.tokenLength() + l.tokenOffset();
+
+ if (pragmaValue == QLatin1String("library")) {
+ pragmas |= QDeclarativeParser::Object::ScriptBlock::Shared;
+ replaceWithSpace(script, startOffset, endOffset - startOffset);
+ } else {
+ return rv;
+ }
+
+ token = l.lex();
+ if (l.currentLineNo() == startLine)
+ return rv;
+
+ } else {
+ return rv;
+ }
+ }
+ return rv;
+}
+
void QDeclarativeScriptParser::clear()
{
if (root) {
diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h
index 28e960b..6319e11 100644
--- a/src/declarative/qml/qdeclarativescriptparser_p.h
+++ b/src/declarative/qml/qdeclarativescriptparser_p.h
@@ -103,7 +103,6 @@ public:
bool parse(const QByteArray &data, const QUrl &url = QUrl());
QList<TypeReference*> referencedTypes() const;
- QList<QUrl> referencedResources() const;
QDeclarativeParser::Object *tree() const;
QList<Import> imports() const;
@@ -112,7 +111,18 @@ public:
QList<QDeclarativeError> errors() const;
+ class JavaScriptMetaData {
+ public:
+ JavaScriptMetaData()
+ : pragmas(QDeclarativeParser::Object::ScriptBlock::None) {}
+
+ QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas;
+ QList<Import> imports;
+ };
+
static QDeclarativeParser::Object::ScriptBlock::Pragmas extractPragmas(QString &);
+ static JavaScriptMetaData extractMetaData(QString &);
+
// ### private:
TypeReference *findOrCreateType(const QString &name);
@@ -127,7 +137,6 @@ public:
QDeclarativeParser::Object *root;
QList<Import> _imports;
QList<TypeReference*> _refTypes;
- QList<QUrl> _refUrls;
QString _scriptFile;
QDeclarativeScriptParserJsASTData *data;
};
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
new file mode 100644
index 0000000..8c291f2
--- /dev/null
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -0,0 +1,1070 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativetypeloader_p.h"
+
+#include <private/qdeclarativeengine_p.h>
+#include <private/qdeclarativecompiler_p.h>
+#include <private/qdeclarativecomponent_p.h>
+
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qfile.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+\class QDeclarativeDataBlob
+\brief The QDeclarativeDataBlob encapsulates a data request that can be issued to a QDeclarativeDataLoader.
+\internal
+
+QDeclarativeDataBlob's are loaded by a QDeclarativeDataLoader. The user creates the QDeclarativeDataBlob
+and then calls QDeclarativeDataLoader::load() or QDeclarativeDataLoader::loadWithStaticData() to load it.
+The QDeclarativeDataLoader invokes callbacks on the QDeclarativeDataBlob as data becomes available.
+*/
+
+/*!
+\enum QDeclarativeDataBlob::Status
+
+\o Null The blob has not yet been loaded by a QDeclarativeDataLoader
+\o Loading The blob is loading network data. The QDeclarativeDataBlob::setData() callback has not yet been
+invoked or has not yet returned.
+\o WaitingForDependencies The blob is waiting for dependencies to be done before continueing. This status
+only occurs after the QDeclarativeDataBlob::setData() callback has been made, and when the blob has outstanding
+dependencies.
+\o Complete The blob's data has been loaded and all dependencies are done.
+\o Error An error has been set on this blob.
+*/
+
+/*!
+\enum QDeclarativeDataBlob::Type
+\o QmlFile This is a QDeclarativeTypeData
+\o JavaScriptFile This is a QDeclarativeScriptData
+\o QmldirFile This is a QDeclarativeQmldirData
+*/
+
+/*!
+Create a new QDeclarativeDataBlob for \a url and of the provided \a type.
+*/
+QDeclarativeDataBlob::QDeclarativeDataBlob(const QUrl &url, Type type)
+: m_type(type), m_status(Null), m_progress(0), m_url(url), m_finalUrl(url), m_manager(0),
+ m_redirectCount(0), m_inCallback(false), m_isDone(false)
+{
+}
+
+/*! \internal */
+QDeclarativeDataBlob::~QDeclarativeDataBlob()
+{
+ Q_ASSERT(m_waitingOnMe.isEmpty());
+
+ cancelAllWaitingFor();
+}
+
+/*!
+Returns the type provided to the constructor.
+*/
+QDeclarativeDataBlob::Type QDeclarativeDataBlob::type() const
+{
+ return m_type;
+}
+
+/*!
+Returns the blob's status.
+*/
+QDeclarativeDataBlob::Status QDeclarativeDataBlob::status() const
+{
+ return m_status;
+}
+
+/*!
+Returns true if the status is Null.
+*/
+bool QDeclarativeDataBlob::isNull() const
+{
+ return m_status == Null;
+}
+
+/*!
+Returns true if the status is Loading.
+*/
+bool QDeclarativeDataBlob::isLoading() const
+{
+ return m_status == Loading;
+}
+
+/*!
+Returns true if the status is WaitingForDependencies.
+*/
+bool QDeclarativeDataBlob::isWaiting() const
+{
+ return m_status == WaitingForDependencies;
+}
+
+/*!
+Returns true if the status is Complete.
+*/
+bool QDeclarativeDataBlob::isComplete() const
+{
+ return m_status == Complete;
+}
+
+/*!
+Returns true if the status is Error.
+*/
+bool QDeclarativeDataBlob::isError() const
+{
+ return m_status == Error;
+}
+
+/*!
+Returns true if the status is Complete or Error.
+*/
+bool QDeclarativeDataBlob::isCompleteOrError() const
+{
+ return isComplete() || isError();
+}
+
+/*!
+Returns the data download progress from 0 to 1.
+*/
+qreal QDeclarativeDataBlob::progress() const
+{
+ return m_progress;
+}
+
+/*!
+Returns the blob url passed to the constructor. If a network redirect
+happens while fetching the data, this url remains the same.
+
+\sa finalUrl()
+*/
+QUrl QDeclarativeDataBlob::url() const
+{
+ return m_url;
+}
+
+/*!
+Returns the final url of the data. Initially this is the same as
+url(), but if a network redirect happens while fetching the data, this url
+is updated to reflect the new location.
+*/
+QUrl QDeclarativeDataBlob::finalUrl() const
+{
+ return m_finalUrl;
+}
+
+/*!
+Return the errors on this blob.
+*/
+QList<QDeclarativeError> QDeclarativeDataBlob::errors() const
+{
+ return m_errors;
+}
+
+/*!
+Mark this blob as having \a errors.
+
+All outstanding dependencies will be cancelled. Requests to add new dependencies
+will be ignored. Entry into the Error state is irreversable, although you can change the
+specific errors by additional calls to setError.
+*/
+void QDeclarativeDataBlob::setError(const QDeclarativeError &errors)
+{
+ QList<QDeclarativeError> l;
+ l << errors;
+ setError(l);
+}
+
+/*!
+\override
+*/
+void QDeclarativeDataBlob::setError(const QList<QDeclarativeError> &errors)
+{
+ m_status = Error;
+ m_errors = errors;
+
+ cancelAllWaitingFor();
+
+ if (!m_inCallback)
+ tryDone();
+}
+
+/*!
+Wait for \a blob to become complete or to error. If \a blob is already
+complete or in error, or this blob is already complete, this has no effect.
+*/
+void QDeclarativeDataBlob::addDependency(QDeclarativeDataBlob *blob)
+{
+ Q_ASSERT(status() != Null);
+
+ if (!blob ||
+ blob->status() == Error || blob->status() == Complete ||
+ status() == Error || status() == Complete ||
+ m_waitingFor.contains(blob))
+ return;
+
+ blob->addref();
+ m_status = WaitingForDependencies;
+ m_waitingFor.append(blob);
+ blob->m_waitingOnMe.append(this);
+}
+
+/*!
+\fn void QDeclarativeDataBlob::dataReceived(const QByteArray &data)
+
+Invoked when data for the blob is received. Implementors should use this callback
+to determine a blob's dependencies. Within this callback you may call setError()
+or addDependency().
+*/
+
+/*!
+Invoked once data has either been received or a network error occurred, and all
+dependencies are complete.
+
+You can set an error in this method, but you cannot add new dependencies. Implementors
+should use this callback to finalize processing of data.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::done()
+{
+}
+
+/*!
+Invoked if there is a network error while fetching this blob.
+
+The default implementation sets an appropriate QDeclarativeError.
+*/
+void QDeclarativeDataBlob::networkError(QNetworkReply::NetworkError networkError)
+{
+ Q_UNUSED(networkError);
+
+ QDeclarativeError error;
+ error.setUrl(m_finalUrl);
+
+ const char *errorString = 0;
+ switch (networkError) {
+ default:
+ errorString = "Network error";
+ break;
+ case QNetworkReply::ConnectionRefusedError:
+ errorString = "Connection refused";
+ break;
+ case QNetworkReply::RemoteHostClosedError:
+ errorString = "Remote host closed the connection";
+ break;
+ case QNetworkReply::HostNotFoundError:
+ errorString = "Host not found";
+ break;
+ case QNetworkReply::TimeoutError:
+ errorString = "Timeout";
+ break;
+ case QNetworkReply::ProxyConnectionRefusedError:
+ case QNetworkReply::ProxyConnectionClosedError:
+ case QNetworkReply::ProxyNotFoundError:
+ case QNetworkReply::ProxyTimeoutError:
+ case QNetworkReply::ProxyAuthenticationRequiredError:
+ case QNetworkReply::UnknownProxyError:
+ errorString = "Proxy error";
+ break;
+ case QNetworkReply::ContentAccessDenied:
+ errorString = "Access denied";
+ break;
+ case QNetworkReply::ContentNotFoundError:
+ errorString = "File not found";
+ break;
+ case QNetworkReply::AuthenticationRequiredError:
+ errorString = "Authentication required";
+ break;
+ };
+
+ error.setDescription(QLatin1String(errorString));
+
+ setError(error);
+}
+
+/*!
+Called if \a blob, which was previously waited for, has an error.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::dependencyError(QDeclarativeDataBlob *blob)
+{
+ Q_UNUSED(blob);
+}
+
+/*!
+Called if \a blob, which was previously waited for, has completed.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::dependencyComplete(QDeclarativeDataBlob *blob)
+{
+ Q_UNUSED(blob);
+}
+
+/*!
+Called when all blobs waited for have completed. This occurs regardless of
+whether they are in error, or complete state.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::allDependenciesDone()
+{
+}
+
+/*!
+Called when the download progress of this blob changes. \a progress goes
+from 0 to 1.
+*/
+void QDeclarativeDataBlob::downloadProgressChanged(qreal progress)
+{
+ Q_UNUSED(progress);
+}
+
+void QDeclarativeDataBlob::tryDone()
+{
+ if (status() != Loading && m_waitingFor.isEmpty() && !m_isDone) {
+ if (status() != Error)
+ m_status = Complete;
+
+ m_isDone = true;
+ done();
+ notifyAllWaitingOnMe();
+ }
+}
+
+void QDeclarativeDataBlob::cancelAllWaitingFor()
+{
+ while (m_waitingFor.count()) {
+ QDeclarativeDataBlob *blob = m_waitingFor.takeLast();
+
+ Q_ASSERT(blob->m_waitingOnMe.contains(this));
+
+ blob->m_waitingOnMe.removeOne(this);
+
+ blob->release();
+ }
+}
+
+void QDeclarativeDataBlob::notifyAllWaitingOnMe()
+{
+ while (m_waitingOnMe.count()) {
+ QDeclarativeDataBlob *blob = m_waitingOnMe.takeLast();
+
+ Q_ASSERT(blob->m_waitingFor.contains(this));
+
+ blob->notifyComplete(this);
+ }
+}
+
+void QDeclarativeDataBlob::notifyComplete(QDeclarativeDataBlob *blob)
+{
+ Q_ASSERT(m_waitingFor.contains(blob));
+ Q_ASSERT(blob->status() == Error || blob->status() == Complete);
+
+ m_inCallback = true;
+
+ if (blob->status() == Error) {
+ dependencyError(blob);
+ } else if (blob->status() == Complete) {
+ dependencyComplete(blob);
+ }
+
+ m_waitingFor.removeOne(blob);
+ blob->release();
+
+ if (!isError() && m_waitingFor.isEmpty())
+ allDependenciesDone();
+
+ m_inCallback = false;
+
+ tryDone();
+}
+
+/*!
+\class QDeclarativeDataLoader
+\brief The QDeclarativeDataLoader class abstracts loading files and their dependecies over the network.
+\internal
+
+The QDeclarativeDataLoader class is provided for the exclusive use of the QDeclarativeTypeLoader class.
+
+Clients create QDeclarativeDataBlob instances and submit them to the QDeclarativeDataLoader class
+through the QDeclarativeDataLoader::load() or QDeclarativeDataLoader::loadWithStaticData() methods.
+The loader then fetches the data over the network or from the local file system in an efficient way.
+QDeclarativeDataBlob is an abstract class, so should always be specialized.
+
+Once data is received, the QDeclarativeDataBlob::dataReceived() method is invoked on the blob. The
+derived class should use this callback to process the received data. Processing of the data can
+result in an error being set (QDeclarativeDataBlob::setError()), or one or more dependencies being
+created (QDeclarativeDataBlob::addDependency()). Dependencies are other QDeclarativeDataBlob's that
+are required before processing can fully complete.
+
+To complete processing, the QDeclarativeDataBlob::done() callback is invoked. done() is called when
+one of these three preconditions are met.
+
+1. The QDeclarativeDataBlob has no dependencies.
+2. The QDeclarativeDataBlob has an error set.
+3. All the QDeclarativeDataBlob's dependencies are themselves "done()".
+
+Thus QDeclarativeDataBlob::done() will always eventually be called, even if the blob has an error set.
+*/
+
+/*!
+Create a new QDeclarativeDataLoader for \a engine.
+*/
+QDeclarativeDataLoader::QDeclarativeDataLoader(QDeclarativeEngine *engine)
+: m_engine(engine)
+{
+}
+
+/*! \internal */
+QDeclarativeDataLoader::~QDeclarativeDataLoader()
+{
+ for (NetworkReplies::Iterator iter = m_networkReplies.begin(); iter != m_networkReplies.end(); ++iter)
+ (*iter)->release();
+}
+
+/*!
+Load the provided \a blob from the network or filesystem.
+*/
+void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob)
+{
+ Q_ASSERT(blob->status() == QDeclarativeDataBlob::Null);
+ Q_ASSERT(blob->m_manager == 0);
+
+ blob->m_status = QDeclarativeDataBlob::Loading;
+
+ if (blob->m_url.isEmpty()) {
+ QDeclarativeError error;
+ error.setDescription(QLatin1String("Invalid null URL"));
+ blob->setError(error);
+ return;
+ }
+
+ QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(blob->m_url);
+
+ if (!lf.isEmpty()) {
+ QFile file(lf);
+ if (file.open(QFile::ReadOnly)) {
+ QByteArray data = file.readAll();
+
+ blob->m_progress = 1.;
+ blob->downloadProgressChanged(1.);
+
+ setData(blob, data);
+ } else {
+ blob->networkError(QNetworkReply::ContentNotFoundError);
+ }
+
+ } else {
+
+ blob->m_manager = this;
+ QNetworkReply *reply = m_engine->networkAccessManager()->get(QNetworkRequest(blob->m_url));
+ QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
+ this, SLOT(networkReplyProgress(qint64,qint64)));
+ QObject::connect(reply, SIGNAL(finished()),
+ this, SLOT(networkReplyFinished()));
+ m_networkReplies.insert(reply, blob);
+
+ blob->addref();
+ }
+}
+
+#define DATALOADER_MAXIMUM_REDIRECT_RECURSION 16
+
+void QDeclarativeDataLoader::networkReplyFinished()
+{
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ reply->deleteLater();
+
+ QDeclarativeDataBlob *blob = m_networkReplies.take(reply);
+
+ Q_ASSERT(blob);
+
+ blob->m_redirectCount++;
+
+ if (blob->m_redirectCount < DATALOADER_MAXIMUM_REDIRECT_RECURSION) {
+ QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = reply->url().resolved(redirect.toUrl());
+ blob->m_finalUrl = url;
+
+ QNetworkReply *reply = m_engine->networkAccessManager()->get(QNetworkRequest(url));
+ QObject::connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ m_networkReplies.insert(reply, blob);
+ return;
+ }
+ }
+
+ if (reply->error()) {
+ blob->networkError(reply->error());
+ } else {
+ QByteArray data = reply->readAll();
+ setData(blob, data);
+ }
+
+ blob->release();
+}
+
+void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ QDeclarativeDataBlob *blob = m_networkReplies.value(reply);
+
+ Q_ASSERT(blob);
+
+ if (bytesTotal != 0) {
+ blob->m_progress = bytesReceived / bytesTotal;
+ blob->downloadProgressChanged(blob->m_progress);
+ }
+}
+
+/*!
+Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case.
+*/
+void QDeclarativeDataLoader::loadWithStaticData(QDeclarativeDataBlob *blob, const QByteArray &data)
+{
+ Q_ASSERT(blob->status() == QDeclarativeDataBlob::Null);
+ Q_ASSERT(blob->m_manager == 0);
+
+ blob->m_status = QDeclarativeDataBlob::Loading;
+
+ setData(blob, data);
+}
+
+/*!
+Return the QDeclarativeEngine associated with this loader
+*/
+QDeclarativeEngine *QDeclarativeDataLoader::engine() const
+{
+ return m_engine;
+}
+
+void QDeclarativeDataLoader::setData(QDeclarativeDataBlob *blob, const QByteArray &data)
+{
+ blob->m_inCallback = true;
+
+ blob->dataReceived(data);
+
+ if (!blob->isError() && !blob->isWaiting())
+ blob->allDependenciesDone();
+
+ if (blob->status() != QDeclarativeDataBlob::Error)
+ blob->m_status = QDeclarativeDataBlob::WaitingForDependencies;
+
+ blob->m_inCallback = false;
+
+ blob->tryDone();
+}
+
+/*!
+\class QDeclarativeTypeLoader
+*/
+QDeclarativeTypeLoader::QDeclarativeTypeLoader(QDeclarativeEngine *engine)
+: QDeclarativeDataLoader(engine)
+{
+}
+
+QDeclarativeTypeLoader::~QDeclarativeTypeLoader()
+{
+ clearCache();
+}
+
+/*!
+Return a QDeclarativeTypeData for \a url. The QDeclarativeTypeData may be cached.
+*/
+QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QUrl &url)
+{
+ Q_ASSERT(!url.isRelative() &&
+ (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
+ !QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+
+ QDeclarativeTypeData *typeData = m_typeCache.value(url);
+
+ if (!typeData) {
+ typeData = new QDeclarativeTypeData(url, None, this);
+ m_typeCache.insert(url, typeData);
+ QDeclarativeDataLoader::load(typeData);
+ }
+
+ typeData->addref();
+ return typeData;
+}
+
+/*!
+Return a QDeclarativeTypeData for \a data with the provided base \a url. The
+QDeclarativeTypeData will not be cached.
+*/
+QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QByteArray &data, const QUrl &url, Options options)
+{
+ QDeclarativeTypeData *typeData = new QDeclarativeTypeData(url, options, this);
+ QDeclarativeDataLoader::loadWithStaticData(typeData, data);
+ return typeData;
+}
+
+/*!
+Return a QDeclarativeScriptData for \a url. The QDeclarativeScriptData may be cached.
+*/
+QDeclarativeScriptData *QDeclarativeTypeLoader::getScript(const QUrl &url)
+{
+ Q_ASSERT(!url.isRelative() &&
+ (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
+ !QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+
+ QDeclarativeScriptData *scriptData = m_scriptCache.value(url);
+
+ if (!scriptData) {
+ scriptData = new QDeclarativeScriptData(url);
+ m_scriptCache.insert(url, scriptData);
+ QDeclarativeDataLoader::load(scriptData);
+ }
+
+ scriptData->addref();
+ return scriptData;
+}
+
+/*!
+Return a QDeclarativeQmldirData for \a url. The QDeclarativeQmldirData may be cached.
+*/
+QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url)
+{
+ Q_ASSERT(!url.isRelative() &&
+ (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
+ !QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+
+ QDeclarativeQmldirData *qmldirData = m_qmldirCache.value(url);
+
+ if (!qmldirData) {
+ qmldirData = new QDeclarativeQmldirData(url);
+ m_qmldirCache.insert(url, qmldirData);
+ QDeclarativeDataLoader::load(qmldirData);
+ }
+
+ qmldirData->addref();
+ return qmldirData;
+}
+
+void QDeclarativeTypeLoader::clearCache()
+{
+ for (TypeCache::Iterator iter = m_typeCache.begin(); iter != m_typeCache.end(); ++iter)
+ (*iter)->release();
+ for (ScriptCache::Iterator iter = m_scriptCache.begin(); iter != m_scriptCache.end(); ++iter)
+ (*iter)->release();
+ for (QmldirCache::Iterator iter = m_qmldirCache.begin(); iter != m_qmldirCache.end(); ++iter)
+ (*iter)->release();
+
+ m_typeCache.clear();
+ m_scriptCache.clear();
+ m_qmldirCache.clear();
+}
+
+
+QDeclarativeTypeData::QDeclarativeTypeData(const QUrl &url, QDeclarativeTypeLoader::Options options,
+ QDeclarativeTypeLoader *manager)
+: QDeclarativeDataBlob(url, QmlFile), m_options(options), m_typesResolved(false),
+ m_compiledData(0), m_component(0), m_typeLoader(manager)
+{
+}
+
+QDeclarativeTypeData::~QDeclarativeTypeData()
+{
+ for (int ii = 0; ii < m_scripts.count(); ++ii)
+ m_scripts.at(ii).script->release();
+ for (int ii = 0; ii < m_qmldirs.count(); ++ii)
+ m_qmldirs.at(ii)->release();
+ for (int ii = 0; ii < m_types.count(); ++ii)
+ if (m_types.at(ii).typeData) m_types.at(ii).typeData->release();
+ if (m_compiledData)
+ m_compiledData->release();
+}
+
+QDeclarativeTypeLoader *QDeclarativeTypeData::typeLoader() const
+{
+ return m_typeLoader;
+}
+
+const QDeclarativeImports &QDeclarativeTypeData::imports() const
+{
+ return m_imports;
+}
+
+const QDeclarativeScriptParser &QDeclarativeTypeData::parser() const
+{
+ return scriptParser;
+}
+
+const QList<QDeclarativeTypeData::TypeReference> &QDeclarativeTypeData::resolvedTypes() const
+{
+ return m_types;
+}
+
+const QList<QDeclarativeTypeData::ScriptReference> &QDeclarativeTypeData::resolvedScripts() const
+{
+ return m_scripts;
+}
+
+QDeclarativeCompiledData *QDeclarativeTypeData::compiledData() const
+{
+ if (m_compiledData)
+ m_compiledData->addref();
+
+ return m_compiledData;
+}
+
+QDeclarativeComponent *QDeclarativeTypeData::component() const
+{
+ if (!m_component) {
+
+ if (m_compiledData) {
+ m_component = new QDeclarativeComponent(typeLoader()->engine(), m_compiledData, -1, -1, 0);
+ } else {
+ m_component = new QDeclarativeComponent(typeLoader()->engine());
+ QDeclarativeComponentPrivate::get(m_component)->url = finalUrl();
+ QDeclarativeComponentPrivate::get(m_component)->state.errors = errors();
+ }
+
+ }
+
+ return m_component;
+}
+
+void QDeclarativeTypeData::registerCallback(TypeDataCallback *callback)
+{
+ Q_ASSERT(!m_callbacks.contains(callback));
+ m_callbacks.append(callback);
+}
+
+void QDeclarativeTypeData::unregisterCallback(TypeDataCallback *callback)
+{
+ Q_ASSERT(m_callbacks.contains(callback));
+ m_callbacks.removeOne(callback);
+ Q_ASSERT(!m_callbacks.contains(callback));
+}
+
+void QDeclarativeTypeData::done()
+{
+ addref();
+
+ // Check all script dependencies for errors
+ for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) {
+ const ScriptReference &script = m_scripts.at(ii);
+ Q_ASSERT(script.script->isCompleteOrError());
+ if (script.script->isError()) {
+ QList<QDeclarativeError> errors = script.script->errors();
+ QDeclarativeError error;
+ error.setUrl(finalUrl());
+ error.setLine(script.location.line);
+ error.setColumn(script.location.column);
+ error.setDescription(typeLoader()->tr("Script %1 unavailable").arg(script.script->url().toString()));
+ errors.prepend(error);
+ setError(errors);
+ }
+ }
+
+ // Check all type dependencies for errors
+ for (int ii = 0; !isError() && ii < m_types.count(); ++ii) {
+ const TypeReference &type = m_types.at(ii);
+ Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError());
+ if (type.typeData && type.typeData->isError()) {
+ QString typeName = scriptParser.referencedTypes().at(ii)->name;
+
+ QList<QDeclarativeError> errors = type.typeData->errors();
+ QDeclarativeError error;
+ error.setUrl(finalUrl());
+ error.setLine(type.location.line);
+ error.setColumn(type.location.column);
+ error.setDescription(typeLoader()->tr("Type %1 unavailable").arg(typeName));
+ errors.prepend(error);
+ setError(errors);
+ }
+ }
+
+ // Compile component
+ if (!isError())
+ compile();
+
+ if (!(m_options & QDeclarativeTypeLoader::PreserveParser))
+ scriptParser.clear();
+
+ // Notify callbacks
+ while (!m_callbacks.isEmpty()) {
+ TypeDataCallback *callback = m_callbacks.takeFirst();
+ callback->typeDataReady(this);
+ }
+
+ release();
+}
+
+void QDeclarativeTypeData::dataReceived(const QByteArray &data)
+{
+ if (!scriptParser.parse(data, finalUrl())) {
+ setError(scriptParser.errors());
+ return;
+ }
+
+ m_imports.setBaseUrl(finalUrl());
+
+ foreach (const QDeclarativeScriptParser::Import &import, scriptParser.imports()) {
+ if (import.type == QDeclarativeScriptParser::Import::File && import.qualifier.isEmpty()) {
+ QUrl importUrl = finalUrl().resolved(QUrl(import.uri + QLatin1String("/qmldir")));
+ if (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty()) {
+ QDeclarativeQmldirData *data = typeLoader()->getQmldir(importUrl);
+ addDependency(data);
+ m_qmldirs << data;
+ }
+ } else if (import.type == QDeclarativeScriptParser::Import::Script) {
+ QUrl scriptUrl = finalUrl().resolved(QUrl(import.uri));
+ QDeclarativeScriptData *data = typeLoader()->getScript(scriptUrl);
+ addDependency(data);
+
+ ScriptReference ref;
+ ref.location = import.location.start;
+ ref.qualifier = import.qualifier;
+ ref.script = data;
+ m_scripts << ref;
+
+ }
+ }
+
+ if (!finalUrl().scheme().isEmpty()) {
+ QUrl importUrl = finalUrl().resolved(QUrl(QLatin1String("qmldir")));
+ if (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty()) {
+ QDeclarativeQmldirData *data = typeLoader()->getQmldir(importUrl);
+ addDependency(data);
+ m_qmldirs << data;
+ }
+ }
+}
+
+void QDeclarativeTypeData::allDependenciesDone()
+{
+ if (!m_typesResolved) {
+ resolveTypes();
+ m_typesResolved = true;
+ }
+}
+
+void QDeclarativeTypeData::downloadProgressChanged(qreal p)
+{
+ for (int ii = 0; ii < m_callbacks.count(); ++ii) {
+ TypeDataCallback *callback = m_callbacks.at(ii);
+ callback->typeDataProgress(this, p);
+ }
+}
+
+void QDeclarativeTypeData::compile()
+{
+ Q_ASSERT(m_compiledData == 0);
+
+ m_compiledData = new QDeclarativeCompiledData(typeLoader()->engine());
+ m_compiledData->url = m_imports.baseUrl();
+ m_compiledData->name = m_compiledData->url.toString();
+
+ QDeclarativeCompiler compiler;
+ if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
+ setError(compiler.errors());
+ m_compiledData->release();
+ m_compiledData = 0;
+ }
+}
+
+void QDeclarativeTypeData::resolveTypes()
+{
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_typeLoader->engine());
+ QDeclarativeImportDatabase *importDatabase = &ep->importDatabase;
+
+ // For local urls, add an implicit import "." as first (most overridden) lookup.
+ // This will also trigger the loading of the qmldir and the import of any native
+ // types from available plugins.
+ if (QDeclarativeQmldirData *qmldir = qmldirForUrl(finalUrl().resolved(QUrl(QLatin1String("./qmldir"))))) {
+ m_imports.addImport(importDatabase, QLatin1String("."),
+ QString(), -1, -1, QDeclarativeScriptParser::Import::File,
+ qmldir->dirComponents(), 0);
+ } else {
+ m_imports.addImport(importDatabase, QLatin1String("."),
+ QString(), -1, -1, QDeclarativeScriptParser::Import::File,
+ QDeclarativeDirComponents(), 0);
+ }
+
+ foreach (const QDeclarativeScriptParser::Import &import, scriptParser.imports()) {
+ QDeclarativeDirComponents qmldircomponentsnetwork;
+ if (import.type == QDeclarativeScriptParser::Import::Script)
+ continue;
+
+ if (import.type == QDeclarativeScriptParser::Import::File && import.qualifier.isEmpty()) {
+ QUrl qmldirUrl = finalUrl().resolved(QUrl(import.uri + QLatin1String("/qmldir")));
+ if (QDeclarativeQmldirData *qmldir = qmldirForUrl(qmldirUrl))
+ qmldircomponentsnetwork = qmldir->dirComponents();
+ }
+
+ int vmaj = -1;
+ int vmin = -1;
+
+ if (!import.version.isEmpty()) {
+ int dot = import.version.indexOf(QLatin1Char('.'));
+ if (dot < 0) {
+ vmaj = import.version.toInt();
+ vmin = 0;
+ } else {
+ vmaj = import.version.left(dot).toInt();
+ vmin = import.version.mid(dot+1).toInt();
+ }
+ }
+
+ QString errorString;
+ if (!m_imports.addImport(importDatabase, import.uri, import.qualifier,
+ vmaj, vmin, import.type, qmldircomponentsnetwork, &errorString)) {
+ QDeclarativeError error;
+ error.setUrl(m_imports.baseUrl());
+ error.setDescription(errorString);
+ error.setLine(import.location.start.line);
+ error.setColumn(import.location.start.column);
+
+ setError(error);
+ return;
+ }
+ }
+
+ foreach (QDeclarativeScriptParser::TypeReference *parserRef, scriptParser.referencedTypes()) {
+ QByteArray typeName = parserRef->name.toUtf8();
+
+ TypeReference ref;
+
+ QUrl url;
+ int majorVersion;
+ int minorVersion;
+ QDeclarativeImportedNamespace *typeNamespace = 0;
+ QString errorString;
+
+ if (!m_imports.resolveType(typeName, &ref.type, &url, &majorVersion, &minorVersion,
+ &typeNamespace, &errorString) || typeNamespace) {
+ // Known to not be a type:
+ // - known to be a namespace (Namespace {})
+ // - type with unknown namespace (UnknownNamespace.SomeType {})
+ QDeclarativeError error;
+ error.setUrl(m_imports.baseUrl());
+ QString userTypeName = parserRef->name;
+ userTypeName.replace(QLatin1Char('/'),QLatin1Char('.'));
+ if (typeNamespace)
+ error.setDescription(typeLoader()->tr("Namespace %1 cannot be used as a type").arg(userTypeName));
+ else
+ error.setDescription(typeLoader()->tr("%1 %2").arg(userTypeName).arg(errorString));
+
+ if (!parserRef->refObjects.isEmpty()) {
+ QDeclarativeParser::Object *obj = parserRef->refObjects.first();
+ error.setLine(obj->location.start.line);
+ error.setColumn(obj->location.start.column);
+ }
+
+ setError(error);
+ return;
+ }
+
+ if (ref.type) {
+ foreach (QDeclarativeParser::Object *obj, parserRef->refObjects) {
+ // store namespace for DOM
+ obj->majorVersion = majorVersion;
+ obj->minorVersion = minorVersion;
+ }
+ } else {
+ ref.typeData = typeLoader()->get(url);
+ addDependency(ref.typeData);
+ }
+
+ if (parserRef->refObjects.count())
+ ref.location = parserRef->refObjects.first()->location.start;
+
+ m_types << ref;
+ }
+}
+
+QDeclarativeQmldirData *QDeclarativeTypeData::qmldirForUrl(const QUrl &url)
+{
+ for (int ii = 0; ii < m_qmldirs.count(); ++ii) {
+ if (m_qmldirs.at(ii)->url() == url)
+ return m_qmldirs.at(ii);
+ }
+ return 0;
+}
+
+QDeclarativeScriptData::QDeclarativeScriptData(const QUrl &url)
+: QDeclarativeDataBlob(url, JavaScriptFile), m_pragmas(QDeclarativeParser::Object::ScriptBlock::None)
+{
+}
+
+QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptData::pragmas() const
+{
+ return m_pragmas;
+}
+
+QString QDeclarativeScriptData::scriptSource() const
+{
+ return m_source;
+}
+
+void QDeclarativeScriptData::dataReceived(const QByteArray &data)
+{
+ m_source = QString::fromUtf8(data);
+ m_pragmas = QDeclarativeScriptParser::extractPragmas(m_source);
+}
+
+QDeclarativeQmldirData::QDeclarativeQmldirData(const QUrl &url)
+: QDeclarativeDataBlob(url, QmldirFile)
+{
+}
+
+const QDeclarativeDirComponents &QDeclarativeQmldirData::dirComponents() const
+{
+ return m_components;
+}
+
+void QDeclarativeQmldirData::dataReceived(const QByteArray &data)
+{
+ QDeclarativeDirParser parser;
+ parser.setSource(QString::fromUtf8(data));
+ parser.parse();
+ m_components = parser.components();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h
new file mode 100644
index 0000000..7381f28
--- /dev/null
+++ b/src/declarative/qml/qdeclarativetypeloader_p.h
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVETYPELOADER_P_H
+#define QDECLARATIVETYPELOADER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qobject.h>
+#include <QtNetwork/qnetworkreply.h>
+#include <QtDeclarative/qdeclarativeerror.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <private/qdeclarativescriptparser_p.h>
+#include <private/qdeclarativedirparser_p.h>
+#include <private/qdeclarativeimport_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeScriptData;
+class QDeclarativeQmldirData;
+class QDeclarativeTypeLoader;
+class QDeclarativeCompiledData;
+class QDeclarativeComponentPrivate;
+class QDeclarativeTypeData;
+class QDeclarativeDataLoader;
+
+class Q_AUTOTEST_EXPORT QDeclarativeDataBlob : public QDeclarativeRefCount
+{
+public:
+ enum Status {
+ Null, // Prior to QDeclarativeDataLoader::load()
+ Loading, // Prior to data being received and dataReceived() being called
+ WaitingForDependencies, // While there are outstanding addDependency()s
+ Complete, // Finished
+ Error, // Error
+ };
+
+ enum Type {
+ QmlFile,
+ JavaScriptFile,
+ QmldirFile
+ };
+
+ QDeclarativeDataBlob(const QUrl &, Type);
+ virtual ~QDeclarativeDataBlob();
+
+ Type type() const;
+
+ Status status() const;
+ bool isNull() const;
+ bool isLoading() const;
+ bool isWaiting() const;
+ bool isComplete() const;
+ bool isError() const;
+ bool isCompleteOrError() const;
+
+ qreal progress() const;
+
+ QUrl url() const;
+ QUrl finalUrl() const;
+
+ QList<QDeclarativeError> errors() const;
+
+ void setError(const QDeclarativeError &);
+ void setError(const QList<QDeclarativeError> &errors);
+
+ void addDependency(QDeclarativeDataBlob *);
+
+protected:
+ virtual void dataReceived(const QByteArray &) = 0;
+
+ virtual void done();
+ virtual void networkError(QNetworkReply::NetworkError);
+
+ virtual void dependencyError(QDeclarativeDataBlob *);
+ virtual void dependencyComplete(QDeclarativeDataBlob *);
+ virtual void allDependenciesDone();
+
+ virtual void downloadProgressChanged(qreal);
+
+private:
+ friend class QDeclarativeDataLoader;
+ void tryDone();
+ void cancelAllWaitingFor();
+ void notifyAllWaitingOnMe();
+ void notifyComplete(QDeclarativeDataBlob *);
+
+ Type m_type;
+ Status m_status;
+ qreal m_progress;
+
+ QUrl m_url;
+ QUrl m_finalUrl;
+
+ // List of QDeclarativeDataBlob's that are waiting for me to complete.
+ QList<QDeclarativeDataBlob *> m_waitingOnMe;
+
+ // List of QDeclarativeDataBlob's that I am waiting for to complete.
+ QList<QDeclarativeDataBlob *> m_waitingFor;
+
+ // Manager that is currently fetching data for me
+ QDeclarativeDataLoader *m_manager;
+ int m_redirectCount:30;
+ bool m_inCallback:1;
+ bool m_isDone:1;
+
+ QList<QDeclarativeError> m_errors;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativeDataLoader : public QObject
+{
+ Q_OBJECT
+public:
+ QDeclarativeDataLoader(QDeclarativeEngine *);
+ ~QDeclarativeDataLoader();
+
+ void load(QDeclarativeDataBlob *);
+ void loadWithStaticData(QDeclarativeDataBlob *, const QByteArray &);
+
+ QDeclarativeEngine *engine() const;
+
+private slots:
+ void networkReplyFinished();
+ void networkReplyProgress(qint64,qint64);
+
+private:
+ void setData(QDeclarativeDataBlob *, const QByteArray &);
+
+ QDeclarativeEngine *m_engine;
+ typedef QHash<QNetworkReply *, QDeclarativeDataBlob *> NetworkReplies;
+ NetworkReplies m_networkReplies;
+};
+
+
+class Q_AUTOTEST_EXPORT QDeclarativeTypeLoader : public QDeclarativeDataLoader
+{
+ Q_OBJECT
+public:
+ QDeclarativeTypeLoader(QDeclarativeEngine *);
+ ~QDeclarativeTypeLoader();
+
+ enum Option {
+ None,
+ PreserveParser
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
+ QDeclarativeTypeData *get(const QUrl &url);
+ QDeclarativeTypeData *get(const QByteArray &, const QUrl &url, Options = None);
+ void clearCache();
+
+ QDeclarativeScriptData *getScript(const QUrl &);
+ QDeclarativeQmldirData *getQmldir(const QUrl &);
+private:
+ typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache;
+ typedef QHash<QUrl, QDeclarativeScriptData *> ScriptCache;
+ typedef QHash<QUrl, QDeclarativeQmldirData *> QmldirCache;
+
+ TypeCache m_typeCache;
+ ScriptCache m_scriptCache;
+ QmldirCache m_qmldirCache;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeTypeLoader::Options)
+
+class Q_AUTOTEST_EXPORT QDeclarativeTypeData : public QDeclarativeDataBlob
+{
+public:
+ struct TypeReference
+ {
+ TypeReference() : type(0), typeData(0) {}
+
+ QDeclarativeParser::Location location;
+ QDeclarativeType *type;
+ QDeclarativeTypeData *typeData;
+ };
+
+ struct ScriptReference
+ {
+ ScriptReference() : script(0) {}
+
+ QDeclarativeParser::Location location;
+ QString qualifier;
+ QDeclarativeScriptData *script;
+ };
+
+ QDeclarativeTypeData(const QUrl &, QDeclarativeTypeLoader::Options, QDeclarativeTypeLoader *);
+ ~QDeclarativeTypeData();
+
+ QDeclarativeTypeLoader *typeLoader() const;
+
+ const QDeclarativeImports &imports() const;
+ const QDeclarativeScriptParser &parser() const;
+
+ const QList<TypeReference> &resolvedTypes() const;
+ const QList<ScriptReference> &resolvedScripts() const;
+
+ QDeclarativeCompiledData *compiledData() const;
+ QDeclarativeComponent *component() const;
+
+ // Used by QDeclarativeComponent to get notifications
+ struct TypeDataCallback {
+ ~TypeDataCallback() {}
+ virtual void typeDataProgress(QDeclarativeTypeData *, qreal) {}
+ virtual void typeDataReady(QDeclarativeTypeData *) {}
+ };
+ void registerCallback(TypeDataCallback *);
+ void unregisterCallback(TypeDataCallback *);
+
+protected:
+ virtual void done();
+ virtual void dataReceived(const QByteArray &);
+ virtual void allDependenciesDone();
+ virtual void downloadProgressChanged(qreal);
+
+private:
+ void resolveTypes();
+ void compile();
+
+ QDeclarativeTypeLoader::Options m_options;
+
+ QDeclarativeQmldirData *qmldirForUrl(const QUrl &);
+
+ QDeclarativeScriptParser scriptParser;
+ QDeclarativeImports m_imports;
+
+ QList<ScriptReference> m_scripts;
+ QList<QDeclarativeQmldirData *> m_qmldirs;
+
+ QList<TypeReference> m_types;
+ bool m_typesResolved:1;
+
+ QDeclarativeCompiledData *m_compiledData;
+ mutable QDeclarativeComponent *m_component;
+
+ QList<TypeDataCallback *> m_callbacks;
+
+ QDeclarativeTypeLoader *m_typeLoader;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativeScriptData : public QDeclarativeDataBlob
+{
+public:
+ QDeclarativeScriptData(const QUrl &);
+
+ QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas() const;
+ QString scriptSource() const;
+
+protected:
+ virtual void dataReceived(const QByteArray &);
+
+private:
+ QDeclarativeParser::Object::ScriptBlock::Pragmas m_pragmas;
+ QString m_source;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativeQmldirData : public QDeclarativeDataBlob
+{
+public:
+ QDeclarativeQmldirData(const QUrl &);
+
+ const QDeclarativeDirComponents &dirComponents() const;
+
+protected:
+ virtual void dataReceived(const QByteArray &);
+
+private:
+ QDeclarativeDirComponents m_components;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVETYPELOADER_P_H
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index f06d6ae..60f2cb3 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -168,7 +168,7 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier
ref->type->read(ref->object, ref->property);
QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);
- if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::QReal)
+ if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
v = v.toInt();
p.write(ref->type, v);
ref->type->write(ref->object, ref->property, 0);
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index 689ed92..3e32006 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -707,11 +707,19 @@ void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QScriptValue &val
void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QVariant &value)
{
- if (value.userType() == QMetaType::QObjectStar)
+ bool needActivate = false;
+ if (value.userType() == QMetaType::QObjectStar) {
+ QObject *o = qvariant_cast<QObject *>(value);
+ needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o);
data[id].setValue(qvariant_cast<QObject *>(value));
- else
+ } else {
+ needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() ||
+ data[id].asQVariant().userType() != value.userType() ||
+ data[id].asQVariant() != value);
data[id].setValue(value);
- activate(object, methodOffset + id, 0);
+ }
+ if (needActivate)
+ activate(object, methodOffset + id, 0);
}
void QDeclarativeVMEMetaObject::listChanged(int id)
diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp
index 0954248..58f8811 100644
--- a/src/declarative/qml/qmetaobjectbuilder.cpp
+++ b/src/declarative/qml/qmetaobjectbuilder.cpp
@@ -205,7 +205,7 @@ public:
(const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1)
: name(_name),
type(QMetaObject::normalizedType(_type.constData())),
- flags(Readable | Writable), notifySignal(-1)
+ flags(Readable | Writable | Scriptable), notifySignal(-1)
{
if (notifierIdx >= 0) {
flags |= Notify;
@@ -2187,7 +2187,7 @@ bool QMetaPropertyBuilder::isDesignable() const
/*!
Returns true if the property is scriptable; otherwise returns false.
- This default value is false.
+ This default value is true.
\sa setScriptable(), isDesignable(), isStored()
*/
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 12f9794..687ff52 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -24,7 +24,7 @@ SOURCES += \
$$PWD/qdeclarativestringconverters.cpp \
$$PWD/qdeclarativeclassfactory.cpp \
$$PWD/qdeclarativeparserstatus.cpp \
- $$PWD/qdeclarativecompositetypemanager.cpp \
+ $$PWD/qdeclarativetypeloader.cpp \
$$PWD/qdeclarativeinfo.cpp \
$$PWD/qdeclarativeerror.cpp \
$$PWD/qdeclarativescriptparser.cpp \
@@ -94,8 +94,7 @@ HEADERS += \
$$PWD/qdeclarativeproperty_p.h \
$$PWD/qdeclarativecontext_p.h \
$$PWD/qdeclarativeinclude_p.h \
- $$PWD/qdeclarativecompositetypedata_p.h \
- $$PWD/qdeclarativecompositetypemanager_p.h \
+ $$PWD/qdeclarativetypeloader_p.h \
$$PWD/qdeclarativelist.h \
$$PWD/qdeclarativelist_p.h \
$$PWD/qdeclarativedata_p.h \
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 267642d..3c09747 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -332,7 +332,7 @@ void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f)
stopped - either by setting the \c running property to false, or by calling
the \c stop() method.
- In the following example, the rectangle will spin indefinately.
+ In the following example, the rectangle will spin indefinitely.
\code
Rectangle {
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index de2de21..4fc52f5 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -155,7 +155,7 @@ protected:
private:
friend class QDeclarativePixmapReaderThreadObject;
void processJobs();
- void processJob(QDeclarativePixmapReply *);
+ void processJob(QDeclarativePixmapReply *, const QUrl &, const QSize &);
void networkRequestDone(QNetworkReply *);
QList<QDeclarativePixmapReply*> jobs;
@@ -434,23 +434,24 @@ void QDeclarativePixmapReader::processJobs()
QDeclarativePixmapReply *runningJob = jobs.takeLast();
runningJob->loading = true;
+ QUrl url = runningJob->data->url;
+ QSize requestSize = runningJob->data->requestSize;
locker.unlock();
- processJob(runningJob);
+ processJob(runningJob, url, requestSize);
locker.relock();
}
}
}
-void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob)
+void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob, const QUrl &url,
+ const QSize &requestSize)
{
- QUrl url = runningJob->data->url;
-
// fetch
if (url.scheme() == QLatin1String("image")) {
// Use QmlImageProvider
QSize readSize;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QImage image = ep->getImageFromProvider(url, &readSize, runningJob->data->requestSize);
+ QImage image = ep->getImageFromProvider(url, &readSize, requestSize);
QDeclarativePixmapReply::ReadError errorCode = QDeclarativePixmapReply::NoError;
QString errorStr;
@@ -472,7 +473,7 @@ void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob)
QFile f(lf);
QSize readSize;
if (f.open(QIODevice::ReadOnly)) {
- if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->data->requestSize))
+ if (!readImage(url, &f, &image, &errorStr, &readSize, requestSize))
errorCode = QDeclarativePixmapReply::Loading;
} else {
errorStr = QDeclarativePixmap::tr("Cannot open: %1").arg(url.toString());
@@ -663,6 +664,7 @@ void QDeclarativePixmapStore::shrinkCache(int remove)
data->prevUnreferenced = 0;
remove -= data->cost();
+ m_unreferencedCost -= data->cost();
data->removeFromCache();
delete data;
}
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 0b3b164..fc122d2 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -5666,9 +5666,6 @@ void QGraphicsItem::update(const QRectF &rect)
return;
}
- if (d_ptr->discardUpdateRequest())
- return;
-
if (d_ptr->scene)
d_ptr->scene->d_func()->markDirty(this, rect);
}
@@ -7758,18 +7755,21 @@ void QGraphicsItemPrivate::resetHeight()
}
/*!
- \property QGraphicsObject::children
- \internal
+ \property QGraphicsObject::children
+ \since 4.7
+ \internal
*/
/*!
- \property QGraphicsObject::width
- \internal
+ \property QGraphicsObject::width
+ \since 4.7
+ \internal
*/
/*!
- \property QGraphicsObject::height
- \internal
+ \property QGraphicsObject::height
+ \since 4.7
+ \internal
*/
/*!
@@ -7985,24 +7985,6 @@ void QGraphicsItemPrivate::resetHeight()
*/
/*!
- \property QGraphicsObject::children
- \since 4.7
- \internal
-*/
-
-/*!
- \property QGraphicsObject::width
- \since 4.7
- \internal
-*/
-
-/*!
- \property QGraphicsObject::height
- \since 4.7
- \internal
-*/
-
-/*!
\class QAbstractGraphicsShapeItem
\brief The QAbstractGraphicsShapeItem class provides a common base for
all path items.
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 4c03d33..539685a 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -1074,7 +1074,7 @@ void QGraphicsScenePrivate::enableMouseTrackingOnViews()
/*!
Returns all items for the screen position in \a event.
*/
-QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &screenPos,
+QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &/*screenPos*/,
const QPointF &scenePos,
QWidget *widget) const
{
@@ -1083,16 +1083,12 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &scre
if (!view)
return q->items(scenePos, Qt::IntersectsItemShape, Qt::DescendingOrder, QTransform());
- const QRectF pointRect(QPointF(widget->mapFromGlobal(screenPos)), QSizeF(1, 1));
+ const QRectF pointRect(scenePos, QSizeF(1, 1));
if (!view->isTransformed())
return q->items(pointRect, Qt::IntersectsItemShape, Qt::DescendingOrder);
const QTransform viewTransform = view->viewportTransform();
- if (viewTransform.type() <= QTransform::TxScale) {
- return q->items(viewTransform.inverted().mapRect(pointRect), Qt::IntersectsItemShape,
- Qt::DescendingOrder, viewTransform);
- }
- return q->items(viewTransform.inverted().map(pointRect), Qt::IntersectsItemShape,
+ return q->items(pointRect, Qt::IntersectsItemShape,
Qt::DescendingOrder, viewTransform);
}
diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp
index bd3f2ef..1f155c6 100644
--- a/src/gui/graphicsview/qgraphicstransform.cpp
+++ b/src/gui/graphicsview/qgraphicstransform.cpp
@@ -346,21 +346,24 @@ void QGraphicsScale::applyTo(QMatrix4x4 *matrix) const
/*!
\fn QGraphicsScale::xScaleChanged()
+ \since 4.7
- QGraphicsScale emits this signal when its xScale changes.
+ This signal is emitted whenever the \l xScale property changes.
*/
/*!
\fn QGraphicsScale::yScaleChanged()
+ \since 4.7
- QGraphicsScale emits this signal when its yScale changes.
+ This signal is emitted whenever the \l yScale property changes.
*/
/*!
\fn QGraphicsScale::zScaleChanged()
+ \since 4.7
- QGraphicsScale emits this signal when its zScale changes.
-*/
+ This signal is emitted whenever the \l zScale property changes.
+*/
/*!
\fn QGraphicsScale::scaleChanged()
@@ -583,27 +586,6 @@ void QGraphicsRotation::applyTo(QMatrix4x4 *matrix) const
\sa QGraphicsRotation::axis
*/
-/*!
- \fn QGraphicsScale::xScaleChanged()
- \since 4.7
-
- This signal is emitted whenever the \l xScale property changes.
-*/
-
-/*!
- \fn QGraphicsScale::yScaleChanged()
- \since 4.7
-
- This signal is emitted whenever the \l yScale property changes.
-*/
-
-/*!
- \fn QGraphicsScale::zScaleChanged()
- \since 4.7
-
- This signal is emitted whenever the \l zScale property changes.
-*/
-
#include "moc_qgraphicstransform.cpp"
QT_END_NAMESPACE
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 0fabd18..1bfe266 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -937,7 +937,9 @@ void QGraphicsWidget::setStyle(QStyle *style)
QFont QGraphicsWidget::font() const
{
Q_D(const QGraphicsWidget);
- return d->font;
+ QFont fnt = d->font;
+ fnt.resolve(fnt.resolve() | d->inheritedFontResolveMask);
+ return fnt;
}
void QGraphicsWidget::setFont(const QFont &font)
{
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index f7850ca..3466733 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -254,7 +254,10 @@ void QGraphicsWidgetPrivate::setFont_helper(const QFont &font)
void QGraphicsWidgetPrivate::resolveFont(uint inheritedMask)
{
+ Q_Q(QGraphicsWidget);
inheritedFontResolveMask = inheritedMask;
+ if (QGraphicsWidget *p = q->parentWidget())
+ inheritedFontResolveMask |= p->d_func()->inheritedFontResolveMask;
QFont naturalFont = naturalWidgetFont();
QFont resolvedFont = font.resolve(naturalFont);
updateFont(resolvedFont);
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index d5243c3..ac40bba 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -66,10 +66,10 @@
QT_BEGIN_NAMESPACE
-class QCoeFepInputContext : public QInputContext,
- public MCoeFepAwareTextEditor,
- public MCoeFepAwareTextEditor_Extension1,
- public MObjectProvider
+class Q_AUTOTEST_EXPORT QCoeFepInputContext : public QInputContext,
+ public MCoeFepAwareTextEditor,
+ public MCoeFepAwareTextEditor_Extension1,
+ public MObjectProvider
{
Q_OBJECT
@@ -84,6 +84,7 @@ public:
void update();
bool filterEvent(const QEvent *event);
+ bool symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event);
void mouseHandler( int x, QMouseEvent *event);
bool isComposing() const { return !m_preeditString.isEmpty(); }
@@ -151,9 +152,10 @@ private:
int m_inlinePosition;
MFepInlineTextFormatRetriever *m_formatRetriever;
MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
- int m_cursorPos;
QBasicTimer m_tempPreeditStringTimeout;
bool m_hasTempPreeditString;
+
+ friend class tst_QInputContext;
};
QT_END_NAMESPACE
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index c4d60a5..b08b9a9 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -47,6 +47,7 @@
#include <qgraphicsview.h>
#include <qgraphicsscene.h>
#include <qgraphicswidget.h>
+#include <qsymbianevent.h>
#include <private/qcore_symbian_p.h>
#include <fepitfr.h>
@@ -79,7 +80,6 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_inlinePosition(0),
m_formatRetriever(0),
m_pointerHandler(0),
- m_cursorPos(0),
m_hasTempPreeditString(false)
{
m_fepState->SetObjectProvider(this);
@@ -237,11 +237,17 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
break;
}
+ QString widgetText = focusWidget()->inputMethodQuery(Qt::ImSurroundingText).toString();
+ int maxLength = focusWidget()->inputMethodQuery(Qt::ImMaximumTextLength).toInt();
+ if (!keyEvent->text().isEmpty() && widgetText.size() + m_preeditString.size() >= maxLength) {
+ // Don't send key events with string content if the widget is "full".
+ return true;
+ }
+
if (keyEvent->type() == QEvent::KeyPress
&& focusWidget()->inputMethodHints() & Qt::ImhHiddenText
&& !keyEvent->text().isEmpty()) {
// Send some temporary preedit text in order to make text visible for a moment.
- m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
m_preeditString = keyEvent->text();
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent imEvent(m_preeditString, attributes);
@@ -282,6 +288,18 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
return false;
}
+bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event)
+{
+ Q_UNUSED(keyWidget);
+ if (event->type() == QSymbianEvent::CommandEvent)
+ // A command basically means the same as a button being pushed. With Qt buttons
+ // that would normally result in a reset of the input method due to the focus change.
+ // This should also happen for commands.
+ reset();
+
+ return false;
+}
+
void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent)
{
if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId())
@@ -297,10 +315,6 @@ void QCoeFepInputContext::commitTemporaryPreeditString()
return;
commitCurrentString(false);
-
- //update cursor position, now this pre-edit text has been committed.
- //this prevents next keypress overwriting it (QTBUG-11673)
- m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
}
void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
@@ -596,8 +610,6 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
commitTemporaryPreeditString();
- m_cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
-
QList<QInputMethodEvent::Attribute> attributes;
m_cursorVisibility = aCursorVisibility ? 1 : 0;
@@ -612,9 +624,10 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
// Let's remove the selected text if aInitialInlineText is empty and there is selected text
if (m_preeditString.isEmpty()) {
int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt();
- int replacementLength = qAbs(m_cursorPos-anchor);
+ int cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
+ int replacementLength = qAbs(cursorPos-anchor);
if (replacementLength > 0) {
- int replacementStart = m_cursorPos < anchor ? 0 : -replacementLength;
+ int replacementStart = cursorPos < anchor ? 0 : -replacementLength;
QList<QInputMethodEvent::Attribute> clearSelectionAttributes;
QInputMethodEvent clearSelectionEvent(QLatin1String(""), clearSelectionAttributes);
clearSelectionEvent.setCommitString(QLatin1String(""), replacementStart, replacementLength);
@@ -647,8 +660,13 @@ void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText,
m_inlinePosition,
m_cursorVisibility,
QVariant()));
- m_preeditString = qt_TDesC2QString(aNewInlineText);
- QInputMethodEvent event(m_preeditString, attributes);
+ QString newPreeditString = qt_TDesC2QString(aNewInlineText);
+ QInputMethodEvent event(newPreeditString, attributes);
+ if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
+ // In Symbian world this means "erase last character".
+ event.setCommitString(QLatin1String(""), -1, 1);
+ }
+ m_preeditString = newPreeditString;
sendEvent(event);
}
@@ -818,25 +836,13 @@ void QCoeFepInputContext::DoCommitFepInlineEditL()
void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
{
- int longPress = 0;
-
- if (m_preeditString.size() == 0) {
- QWidget *w = focusWidget();
- if (!cancelFepTransaction && w) {
- // We must replace the last character only if the input box has already accepted one
- if (w->inputMethodQuery(Qt::ImCursorPosition).toInt() != m_cursorPos)
- longPress = 1;
- }
- }
-
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_preeditString, 0-longPress, longPress);
+ event.setCommitString(m_preeditString, 0, 0);
m_preeditString.clear();
sendEvent(event);
m_hasTempPreeditString = false;
- longPress = 0;
if (cancelFepTransaction) {
CCoeFep* fep = CCoeEnv::Static()->Fep();
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index e197dc5..e937918 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -129,7 +129,13 @@ void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, boo
statusPaneVisibilityChanged = (s->IsVisible() != statusPaneVisible);
s->MakeVisible(statusPaneVisible);
}
- if (buttonGroupVisibilityChanged && !statusPaneVisibilityChanged)
+ if (buttonGroupVisibilityChanged || statusPaneVisibilityChanged) {
+ const QSize size = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()).size();
+ const QSize oldSize; // note that QDesktopWidget::resizeEvent ignores the QResizeEvent contents
+ QResizeEvent event(size, oldSize);
+ QApplication::instance()->sendEvent(QApplication::desktop(), &event);
+ }
+ if (buttonGroupVisibilityChanged && !statusPaneVisibilityChanged && QApplication::activeWindow())
// Ensure that control rectangle is updated
static_cast<QSymbianControl *>(QApplication::activeWindow()->winId())->handleClientAreaChange();
}
@@ -1242,17 +1248,28 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility);
#endif
} else if (QApplication::activeWindow() == qwidget->window()) {
- if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
- QWidget *fw = QApplication::focusWidget();
- if (fw) {
- QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
- QCoreApplication::sendEvent(fw, &event);
- }
- m_symbianPopupIsOpen = true;
- return;
+ bool focusedControlFound = false;
+ WId winId = 0;
+ for (QWidget *w = qwidget->parentWidget(); w && (winId = w->internalWinId()); w = w->parentWidget()) {
+ if (winId->IsFocused() && winId->IsVisible()) {
+ focusedControlFound = true;
+ break;
+ } else if (w->isWindow())
+ break;
}
+ if (!focusedControlFound) {
+ if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
+ QWidget *fw = QApplication::focusWidget();
+ if (fw) {
+ QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
+ QCoreApplication::sendEvent(fw, &event);
+ }
+ m_symbianPopupIsOpen = true;
+ return;
+ }
- QApplication::setActiveWindow(0);
+ QApplication::setActiveWindow(0);
+ }
}
// else { We don't touch the active window unless we were explicitly activated or deactivated }
}
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index eb1aa18..7fd2baa 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -87,7 +87,7 @@ const TInt KInternalStatusPaneChange = 0x50000000;
//this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2
#define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13)
-class QS60ThreadLocalData
+class Q_AUTOTEST_EXPORT QS60ThreadLocalData
{
public:
QS60ThreadLocalData();
@@ -171,7 +171,7 @@ public:
#endif
};
-QS60Data* qGlobalS60Data();
+Q_AUTOTEST_EXPORT QS60Data* qGlobalS60Data();
#define S60 qGlobalS60Data()
class QAbstractLongTapObserver
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 3d2bfe2..ea3dcab 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -4864,6 +4864,8 @@ void QWidgetPrivate::resolveLayoutDirection()
has been called for the parent do not inherit the parent's layout
direction.
+ This method no longer affects text layout direction since Qt 4.7.
+
\sa QApplication::layoutDirection
*/
void QWidget::setLayoutDirection(Qt::LayoutDirection direction)
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index fc13c93..c98c05a 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -503,8 +503,10 @@ void QWidgetPrivate::show_sys()
// Can't use AppUi directly because it privately inherits from MEikStatusPaneObserver.
QSymbianControl *desktopControl = static_cast<QSymbianControl *>(QApplication::desktop()->winId());
S60->statusPane()->SetObserver(desktopControl);
- if (isFullscreen)
- S60->statusPane()->MakeVisible(false);
+ if (isFullscreen) {
+ const bool cbaVisible = S60->buttonGroupContainer() && S60->buttonGroupContainer()->IsVisible();
+ S60->setStatusPaneAndButtonGroupVisibility(false, cbaVisible);
+ }
}
}
}
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 24908ce..0edf256 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -254,10 +254,10 @@ void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
}
}
-static void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
- const uchar *src, int sbpl,
- int w, int h,
- int const_alpha)
+void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
+ const uchar *src, int sbpl,
+ int w, int h,
+ int const_alpha)
{
#ifdef QT_DEBUG_DRAW
printf("qt_blend_rgb16_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 276da93..cf487b5 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -46,7 +46,6 @@
#include <private/qdrawhelper_armv6_p.h>
#include <private/qdrawhelper_neon_p.h>
#include <private/qmath_p.h>
-#include <private/qsimd_p.h>
#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -656,6 +655,46 @@ const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const
return buffer;
}
+/** \internal
+ interpolate 4 argb pixels with the distx and disty factor.
+ distx and disty bust be between 0 and 16
+ */
+static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, int distx, int disty, int idistx, int idisty)
+{
+ uint tlrb = ((tl & 0x00ff00ff) * idistx * idisty);
+ uint tlag = (((tl & 0xff00ff00) >> 8) * idistx * idisty);
+ uint trrb = ((tr & 0x00ff00ff) * distx * idisty);
+ uint trag = (((tr & 0xff00ff00) >> 8) * distx * idisty);
+ uint blrb = ((bl & 0x00ff00ff) * idistx * disty);
+ uint blag = (((bl & 0xff00ff00) >> 8) * idistx * disty);
+ uint brrb = ((br & 0x00ff00ff) * distx * disty);
+ uint brag = (((br & 0xff00ff00) >> 8) * distx * disty);
+ return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00);
+}
+
+
+template<TextureBlendType blendType>
+Q_STATIC_TEMPLATE_FUNCTION inline void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2)
+{
+ if (blendType == BlendTransformedBilinearTiled) {
+ v1 %= max;
+ if (v1 < 0) v1 += max;
+ v2 = v1 + 1;
+ v2 %= max;
+ } else {
+ if (v1 < l1) {
+ v2 = v1 = l1;
+ } else if (v1 >= l2) {
+ v2 = v1 = l2;
+ } else {
+ v2 = v1 + 1;
+ }
+ }
+
+ Q_ASSERT(v1 >= 0 && v1 < max);
+ Q_ASSERT(v2 >= 0 && v2 < max);
+}
+
template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */
Q_STATIC_TEMPLATE_FUNCTION
const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data,
@@ -676,8 +715,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
int image_x1 = data->texture.x1;
int image_y1 = data->texture.y1;
- int image_x2 = data->texture.x2;
- int image_y2 = data->texture.y2;
+ int image_x2 = data->texture.x2 - 1;
+ int image_y2 = data->texture.y2 - 1;
const qreal cx = x + 0.5;
const qreal cy = y + 0.5;
@@ -696,64 +735,230 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
fx -= half_point;
fy -= half_point;
- while (b < end) {
- int x1 = (fx >> 16);
- int x2;
+
+ if (fdy == 0) { //simple scale, no rotation
int y1 = (fy >> 16);
int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
- if (blendType == BlendTransformedBilinearTiled) {
- x1 %= image_width;
- if (x1 < 0) x1 += image_width;
- x2 = x1 + 1;
- x2 %= image_width;
-
- y1 %= image_height;
- if (y1 < 0) y1 += image_height;
- y2 = y1 + 1;
- y2 %= image_height;
- } else {
- if (x1 < image_x1) {
- x2 = x1 = image_x1;
- } else if (x1 >= image_x2 - 1) {
- x2 = x1 = image_x2 - 1;
+ if (fdx <= fixed_scale && fdx > 0) { // scale up on X
+ int disty = (fy & 0x0000ffff) >> 8;
+ int idisty = 256 - disty;
+ int x = fx >> 16;
+
+ // The idea is first to do the interpolation between the row s1 and the row s2
+ // into an intermediate buffer, then we interpolate between two pixel of this buffer.
+
+ // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
+ // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG
+ quint32 intermediate_buffer[2][buffer_size + 2];
+ // count is the size used in the intermediate_buffer.
+ int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors.
+ Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
+ int f = 0;
+ int lim = count;
+ if (blendType == BlendTransformedBilinearTiled) {
+ x %= image_width;
+ if (x < 0) x += image_width;
} else {
- x2 = x1 + 1;
+ lim = qMin(count, image_x2-x+1);
+ if (x < image_x1) {
+ Q_ASSERT(x <= image_x2);
+ uint t = fetch(s1, image_x1, data->texture.colorTable);
+ uint b = fetch(s2, image_x1, data->texture.colorTable);
+ quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ do {
+ intermediate_buffer[0][f] = rb;
+ intermediate_buffer[1][f] = ag;
+ f++;
+ x++;
+ } while (x < image_x1 && f < lim);
+ }
}
- if (y1 < image_y1) {
- y2 = y1 = image_y1;
- } else if (y1 >= image_y2 - 1) {
- y2 = y1 = image_y2 - 1;
- } else {
- y2 = y1 + 1;
+
+#if defined(QT_ALWAYS_HAVE_SSE2)
+ if (blendType != BlendTransformedBilinearTiled &&
+ (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) {
+
+ const __m128i disty_ = _mm_set1_epi16(disty);
+ const __m128i idisty_ = _mm_set1_epi16(idisty);
+ const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+
+ lim -= 3;
+ for (; f < lim; x += 4, f += 4) {
+ // Load 4 pixels from s1, and split the alpha-green and red-blue component
+ __m128i top = _mm_loadu_si128((__m128i*)((const uint *)(s1)+x));
+ __m128i topAG = _mm_srli_epi16(top, 8);
+ __m128i topRB = _mm_and_si128(top, colorMask);
+ // Multiplies each colour component by idisty
+ topAG = _mm_mullo_epi16 (topAG, idisty_);
+ topRB = _mm_mullo_epi16 (topRB, idisty_);
+
+ // Same for the s2 vector
+ __m128i bottom = _mm_loadu_si128((__m128i*)((const uint *)(s2)+x));
+ __m128i bottomAG = _mm_srli_epi16(bottom, 8);
+ __m128i bottomRB = _mm_and_si128(bottom, colorMask);
+ bottomAG = _mm_mullo_epi16 (bottomAG, disty_);
+ bottomRB = _mm_mullo_epi16 (bottomRB, disty_);
+
+ // Add the values, and shift to only keep 8 significant bits per colors
+ __m128i rAG =_mm_add_epi16(topAG, bottomAG);
+ rAG = _mm_srli_epi16(rAG, 8);
+ _mm_storeu_si128((__m128i*)(&intermediate_buffer[1][f]), rAG);
+ __m128i rRB =_mm_add_epi16(topRB, bottomRB);
+ rRB = _mm_srli_epi16(rRB, 8);
+ _mm_storeu_si128((__m128i*)(&intermediate_buffer[0][f]), rRB);
+ }
+ }
+#endif
+ for (; f < count; f++) { // Same as above but without sse2
+ if (blendType == BlendTransformedBilinearTiled) {
+ if (x >= image_width) x -= image_width;
+ } else {
+ x = qMin(x, image_x2);
+ }
+
+ uint t = fetch(s1, x, data->texture.colorTable);
+ uint b = fetch(s2, x, data->texture.colorTable);
+
+ intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ x++;
+ }
+ // Now interpolate the values from the intermediate_buffer to get the final result.
+ fx &= fixed_scale - 1;
+ Q_ASSERT((fx >> 16) == 0);
+ while (b < end) {
+ register int x1 = (fx >> 16);
+ register int x2 = x1 + 1;
+ Q_ASSERT(x1 >= 0);
+ Q_ASSERT(x2 < count);
+
+ register int distx = (fx & 0x0000ffff) >> 8;
+ register int idistx = 256 - distx;
+ int rb = ((intermediate_buffer[0][x1] * idistx + intermediate_buffer[0][x2] * distx) >> 8) & 0xff00ff;
+ int ag = (intermediate_buffer[1][x1] * idistx + intermediate_buffer[1][x2] * distx) & 0xff00ff00;
+ *b = rb | ag;
+ b++;
+ fx += fdx;
+ }
+ } else if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+ int disty = (fy & 0x0000ffff) >> 8;
+ int idisty = 256 - disty;
+ while (b < end) {
+ int x1 = (fx >> 16);
+ int x2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ uint tl = fetch(s1, x1, data->texture.colorTable);
+ uint tr = fetch(s1, x2, data->texture.colorTable);
+ uint bl = fetch(s2, x1, data->texture.colorTable);
+ uint br = fetch(s2, x2, data->texture.colorTable);
+
+ int distx = (fx & 0x0000ffff) >> 8;
+ int idistx = 256 - distx;
+
+ uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
+ uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
+ *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+
+ fx += fdx;
+ ++b;
+ }
+ } else { //scale down
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+ int disty = (fy & 0x0000ffff) >> 12;
+ int idisty = 16 - disty;
+ while (b < end) {
+ int x1 = (fx >> 16);
+ int x2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ uint tl = fetch(s1, x1, data->texture.colorTable);
+ uint tr = fetch(s1, x2, data->texture.colorTable);
+ uint bl = fetch(s2, x1, data->texture.colorTable);
+ uint br = fetch(s2, x2, data->texture.colorTable);
+ int distx = (fx & 0x0000ffff) >> 12;
+ int idistx = 16 - distx;
+ *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty, idistx, idisty);
+ fx += fdx;
+ ++b;
}
}
+ } else { //rotation
+ if (fabs(data->m11) > 8 || fabs(data->m22) > 8) {
+ //if we are zooming more than 8 times, we use 8bit precision for the position.
+ while (b < end) {
+ int x1 = (fx >> 16);
+ int x2;
+ int y1 = (fy >> 16);
+ int y2;
- Q_ASSERT(x1 >= 0 && x1 < image_width);
- Q_ASSERT(x2 >= 0 && x2 < image_width);
- Q_ASSERT(y1 >= 0 && y1 < image_height);
- Q_ASSERT(y2 >= 0 && y2 < image_height);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
- uint tl = fetch(s1, x1, data->texture.colorTable);
- uint tr = fetch(s1, x2, data->texture.colorTable);
- uint bl = fetch(s2, x1, data->texture.colorTable);
- uint br = fetch(s2, x2, data->texture.colorTable);
+ uint tl = fetch(s1, x1, data->texture.colorTable);
+ uint tr = fetch(s1, x2, data->texture.colorTable);
+ uint bl = fetch(s2, x1, data->texture.colorTable);
+ uint br = fetch(s2, x2, data->texture.colorTable);
- int distx = (fx & 0x0000ffff) >> 8;
- int disty = (fy & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int idisty = 256 - disty;
+ int distx = (fx & 0x0000ffff) >> 8;
+ int disty = (fy & 0x0000ffff) >> 8;
+ int idistx = 256 - distx;
+ int idisty = 256 - disty;
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
+ uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
+ *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
- fx += fdx;
- fy += fdy;
- ++b;
+ fx += fdx;
+ fy += fdy;
+ ++b;
+ }
+ } else {
+ //we are zooming less than 8x, use 4bit precision
+ while (b < end) {
+ int x1 = (fx >> 16);
+ int x2;
+ int y1 = (fy >> 16);
+ int y2;
+
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+
+ uint tl = fetch(s1, x1, data->texture.colorTable);
+ uint tr = fetch(s1, x2, data->texture.colorTable);
+ uint bl = fetch(s2, x1, data->texture.colorTable);
+ uint br = fetch(s2, x2, data->texture.colorTable);
+
+ int distx = (fx & 0x0000ffff) >> 12;
+ int disty = (fy & 0x0000ffff) >> 12;
+ int idistx = 16 - distx;
+ int idisty = 16 - disty;
+
+ *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty, idistx, idisty);
+
+ fx += fdx;
+ fy += fdy;
+ ++b;
+ }
+ }
}
} else {
const qreal fdx = data->m11;
@@ -779,37 +984,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
int idistx = 256 - distx;
int idisty = 256 - disty;
- if (blendType == BlendTransformedBilinearTiled) {
- x1 %= image_width;
- if (x1 < 0) x1 += image_width;
- x2 = x1 + 1;
- x2 %= image_width;
-
- y1 %= image_height;
- if (y1 < 0) y1 += image_height;
- y2 = y1 + 1;
- y2 %= image_height;
- } else {
- if (x1 < 0) {
- x2 = x1 = 0;
- } else if (x1 >= image_width - 1) {
- x2 = x1 = image_width - 1;
- } else {
- x2 = x1 + 1;
- }
- if (y1 < 0) {
- y2 = y1 = 0;
- } else if (y1 >= image_height - 1) {
- y2 = y1 = image_height - 1;
- } else {
- y2 = y1 + 1;
- }
- }
-
- Q_ASSERT(x1 >= 0 && x1 < image_width);
- Q_ASSERT(x2 >= 0 && x2 < image_width);
- Q_ASSERT(y1 >= 0 && y1 < image_height);
- Q_ASSERT(y2 >= 0 && y2 < image_height);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
const uchar *s1 = data->texture.scanLine(y1);
const uchar *s2 = data->texture.scanLine(y2);
@@ -1757,9 +1933,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl(uint *dest, int
for (int i = 0; i < length; ++i) {
PRELOAD_COND(dest)
uint d = dest[i];
-#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
- d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
-#undef MIX
+ d = comp_func_Plus_one_pixel(d, s);
coverage.store(&dest[i], d);
}
}
@@ -1781,9 +1955,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *dest, const uin
uint d = dest[i];
uint s = src[i];
-#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
- d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
-#undef MIX
+ d = comp_func_Plus_one_pixel(d, s);
coverage.store(&dest[i], d);
}
@@ -5163,239 +5335,6 @@ static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData)
blend_tiled_generic<RegularSpans>(count, spans, userData);
}
-
-template <SpanMethod spanMethod, TextureBlendType blendType> /* blendType must be either BlendTransformedBilinear or BlendTransformedBilinearTiled */
-Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- if (data->texture.format != QImage::Format_ARGB32_Premultiplied
- && data->texture.format != QImage::Format_RGB32) {
- blend_src_generic<spanMethod>(count, spans, userData);
- return;
- }
-
- CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];
- uint buffer[buffer_size];
-
- const int image_x1 = data->texture.x1;
- const int image_y1 = data->texture.y1;
- const int image_x2 = data->texture.x2;
- const int image_y2 = data->texture.y2;
- const int image_width = data->texture.width;
- const int image_height = data->texture.height;
- const int scanline_offset = data->texture.bytesPerLine / 4;
-
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- int fdx = (int)(data->m11 * fixed_scale);
- int fdy = (int)(data->m12 * fixed_scale);
-
- while (count--) {
- void *t = data->rasterBuffer->scanLine(spans->y);
-
- uint *target = ((uint *)t) + spans->x;
- uint *image_bits = (uint *)data->texture.imageData;
-
- const qreal cx = spans->x + 0.5;
- const qreal cy = spans->y + 0.5;
-
- int x = int((data->m21 * cy
- + data->m11 * cx + data->dx) * fixed_scale) - half_point;
- int y = int((data->m22 * cy
- + data->m12 * cx + data->dy) * fixed_scale) - half_point;
-
- int length = spans->len;
- const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- while (length) {
- int l = qMin(length, buffer_size);
- const uint *end = buffer + l;
- uint *b = buffer;
- while (b < end) {
- int x1 = (x >> 16);
- int x2;
- int y1 = (y >> 16);
- int y2;
-
- if (blendType == BlendTransformedBilinearTiled) {
- x1 %= image_width;
- if (x1 < 0) x1 += image_width;
- x2 = x1 + 1;
- x2 %= image_width;
-
- y1 %= image_height;
- if (y1 < 0) y1 += image_height;
- y2 = y1 + 1;
- y2 %= image_height;
-
- Q_ASSERT(x1 >= 0 && x1 < image_width);
- Q_ASSERT(x2 >= 0 && x2 < image_width);
- Q_ASSERT(y1 >= 0 && y1 < image_height);
- Q_ASSERT(y2 >= 0 && y2 < image_height);
- } else {
- if (x1 < image_x1) {
- x2 = x1 = image_x1;
- } else if (x1 >= image_x2 - 1) {
- x2 = x1 = image_x2 - 1;
- } else {
- x2 = x1 + 1;
- }
- if (y1 < image_y1) {
- y2 = y1 = image_y1;
- } else if (y1 >= image_y2 - 1) {
- y2 = y1 = image_y2 - 1;
- } else {
- y2 = y1 + 1;
- }
- }
-
- int y1_offset = y1 * scanline_offset;
- int y2_offset = y2 * scanline_offset;
-
-#if defined(Q_IRIX_GCC3_3_WORKAROUND)
- uint tl = gccBug(image_bits[y1_offset + x1]);
- uint tr = gccBug(image_bits[y1_offset + x2]);
- uint bl = gccBug(image_bits[y2_offset + x1]);
- uint br = gccBug(image_bits[y2_offset + x2]);
-#else
- uint tl = image_bits[y1_offset + x1];
- uint tr = image_bits[y1_offset + x2];
- uint bl = image_bits[y2_offset + x1];
- uint br = image_bits[y2_offset + x2];
-#endif
-
- int distx = (x & 0x0000ffff) >> 8;
- int disty = (y & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int idisty = 256 - disty;
-
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
- ++b;
-
- x += fdx;
- y += fdy;
- }
- if (spanMethod == RegularSpans)
- func(target, buffer, l, coverage);
- else
- drawBufferSpan(data, buffer, buffer_size,
- spans->x + spans->len - length,
- spans->y, l, coverage);
- target += l;
- length -= l;
- }
- ++spans;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
-
- while (count--) {
- void *t = data->rasterBuffer->scanLine(spans->y);
-
- uint *target = ((uint *)t) + spans->x;
- uint *image_bits = (uint *)data->texture.imageData;
-
- const qreal cx = spans->x + 0.5;
- const qreal cy = spans->y + 0.5;
-
- qreal x = data->m21 * cy + data->m11 * cx + data->dx;
- qreal y = data->m22 * cy + data->m12 * cx + data->dy;
- qreal w = data->m23 * cy + data->m13 * cx + data->m33;
-
- int length = spans->len;
- const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- while (length) {
- int l = qMin(length, buffer_size);
- const uint *end = buffer + l;
- uint *b = buffer;
- while (b < end) {
- const qreal iw = w == 0 ? 1 : 1 / w;
- const qreal px = x * iw - 0.5;
- const qreal py = y * iw - 0.5;
-
- int x1 = int(px) - (px < 0);
- int x2;
- int y1 = int(py) - (py < 0);
- int y2;
-
- int distx = int((px - x1) * 256);
- int disty = int((py - y1) * 256);
- int idistx = 256 - distx;
- int idisty = 256 - disty;
-
- if (blendType == BlendTransformedBilinearTiled) {
- x1 %= image_width;
- if (x1 < 0) x1 += image_width;
- x2 = x1 + 1;
- x2 %= image_width;
-
- y1 %= image_height;
- if (y1 < 0) y1 += image_height;
- y2 = y1 + 1;
- y2 %= image_height;
-
- Q_ASSERT(x1 >= 0 && x1 < image_width);
- Q_ASSERT(x2 >= 0 && x2 < image_width);
- Q_ASSERT(y1 >= 0 && y1 < image_height);
- Q_ASSERT(y2 >= 0 && y2 < image_height);
- } else {
- if (x1 < image_x1) {
- x2 = x1 = image_x1;
- } else if (x1 >= image_x2 - 1) {
- x2 = x1 = image_x2 - 1;
- } else {
- x2 = x1 + 1;
- }
- if (y1 < image_y1) {
- y2 = y1 = image_y1;
- } else if (y1 >= image_y2 - 1) {
- y2 = y1 = image_y2 - 1;
- } else {
- y2 = y1 + 1;
- }
- }
-
- int y1_offset = y1 * scanline_offset;
- int y2_offset = y2 * scanline_offset;
-
-#if defined(Q_IRIX_GCC3_3_WORKAROUND)
- uint tl = gccBug(image_bits[y1_offset + x1]);
- uint tr = gccBug(image_bits[y1_offset + x2]);
- uint bl = gccBug(image_bits[y2_offset + x1]);
- uint br = gccBug(image_bits[y2_offset + x2]);
-#else
- uint tl = image_bits[y1_offset + x1];
- uint tr = image_bits[y1_offset + x2];
- uint bl = image_bits[y2_offset + x1];
- uint br = image_bits[y2_offset + x2];
-#endif
-
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
- ++b;
-
- x += fdx;
- y += fdy;
- w += fdw;
- }
- if (spanMethod == RegularSpans)
- func(target, buffer, l, coverage);
- else
- drawBufferSpan(data, buffer, buffer_size,
- spans->x + spans->len - length,
- spans->y, l, coverage);
- target += l;
- length -= l;
- }
- ++spans;
- }
- }
-}
-
template <class DST, class SRC>
Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan *spans,
void *userData)
@@ -6646,7 +6585,7 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
- blend_transformed_bilinear_argb<RegularSpans, BlendTransformedBilinear>, // ARGB32_Premultiplied
+ SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied
blend_transformed_bilinear_rgb565,
blend_transformed_bilinear_argb8565,
blend_transformed_bilinear_rgb666,
@@ -6665,7 +6604,7 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
- blend_transformed_bilinear_argb<RegularSpans, BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
+ SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied
SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB666
@@ -6764,7 +6703,7 @@ static const ProcessSpans processTextureSpansCallback[NBlendTypes][QImage::NImag
blend_src_generic<CallbackSpans>, // Indexed8
blend_src_generic<CallbackSpans>, // RGB32
blend_src_generic<CallbackSpans>, // ARGB32
- blend_transformed_bilinear_argb<CallbackSpans, BlendTransformedBilinear>, // ARGB32_Premultiplied
+ blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied
blend_src_generic<CallbackSpans>, // RGB16
blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied
blend_src_generic<CallbackSpans>, // RGB666
@@ -6783,7 +6722,7 @@ static const ProcessSpans processTextureSpansCallback[NBlendTypes][QImage::NImag
blend_src_generic<CallbackSpans>, // Indexed8
blend_src_generic<CallbackSpans>, // RGB32
blend_src_generic<CallbackSpans>, // ARGB32
- blend_transformed_bilinear_argb<CallbackSpans, BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
+ blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied
blend_src_generic<CallbackSpans>, // RGB16
blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied
blend_src_generic<CallbackSpans>, // RGB666
@@ -7900,6 +7839,7 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
@@ -7911,11 +7851,13 @@ void qInitDrawhelperAsm()
functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
+ functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
+ qt_memfill32 = qt_memfill32_neon;
}
#endif
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 03fe075..0afd077 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -51,6 +51,44 @@
QT_BEGIN_NAMESPACE
+void qt_memfill32_neon(quint32 *dest, quint32 value, int count)
+{
+ const int epilogueSize = count % 16;
+ if (count >= 16) {
+ quint32 *const neonEnd = dest + count - epilogueSize;
+ register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value);
+ register uint32x4_t valueVector2 asm ("q1") = valueVector1;
+ while (dest != neonEnd) {
+ asm volatile (
+ "vst2.32 { d0, d1, d2, d3 }, [%[DST]] !\n\t"
+ "vst2.32 { d0, d1, d2, d3 }, [%[DST]] !\n\t"
+ : [DST]"+r" (dest)
+ : [VALUE1]"w"(valueVector1), [VALUE2]"w"(valueVector2)
+ : "memory"
+ );
+ }
+ }
+
+ switch (epilogueSize)
+ {
+ case 15: *dest++ = value;
+ case 14: *dest++ = value;
+ case 13: *dest++ = value;
+ case 12: *dest++ = value;
+ case 11: *dest++ = value;
+ case 10: *dest++ = value;
+ case 9: *dest++ = value;
+ case 8: *dest++ = value;
+ case 7: *dest++ = value;
+ case 6: *dest++ = value;
+ case 5: *dest++ = value;
+ case 4: *dest++ = value;
+ case 3: *dest++ = value;
+ case 2: *dest++ = value;
+ case 1: *dest++ = value;
+ }
+}
+
static inline uint16x8_t qvdiv_255_u16(uint16x8_t x, uint16x8_t half)
{
// result = (x + (x >> 8) + 0x80) >> 8
@@ -129,6 +167,14 @@ pixman_composite_scanline_over_asm_neon (int32_t w,
const uint32_t *dst,
const uint32_t *src);
+extern "C" void
+pixman_composite_src_0565_0565_asm_neon (int32_t w,
+ int32_t h,
+ uint16_t *dst,
+ int32_t dst_stride,
+ uint16_t *src,
+ int32_t src_stride);
+
// qblendfunctions.cpp
void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
@@ -162,6 +208,96 @@ void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl,
pixman_composite_src_0565_8888_asm_neon(w, h, dst, dbpl, src, sbpl);
}
+// qblendfunctions.cpp
+void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
+ const uchar *src, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+template <int N>
+static inline void scanLineBlit16(quint16 *dst, quint16 *src, int dstride)
+{
+ if (N >= 2) {
+ ((quint32 *)dst)[0] = ((quint32 *)src)[0];
+ __builtin_prefetch(dst + dstride, 1, 0);
+ }
+ for (int i = 1; i < N/2; ++i)
+ ((quint32 *)dst)[i] = ((quint32 *)src)[i];
+ if (N & 1)
+ dst[N-1] = src[N-1];
+}
+
+template <int Width>
+static inline void blockBlit16(quint16 *dst, quint16 *src, int dstride, int sstride, int h)
+{
+ union {
+ quintptr address;
+ quint16 *pointer;
+ } u;
+
+ u.pointer = dst;
+
+ if (u.address & 2) {
+ while (h--) {
+ // align dst
+ dst[0] = src[0];
+ if (Width > 1)
+ scanLineBlit16<Width-1>(dst + 1, src + 1, dstride);
+ dst += dstride;
+ src += sstride;
+ }
+ } else {
+ while (h--) {
+ scanLineBlit16<Width>(dst, src, dstride);
+
+ dst += dstride;
+ src += sstride;
+ }
+ }
+}
+
+void qt_blend_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ // testing show that the default memcpy is faster for widths 150 and up
+ if (const_alpha != 256 || w >= 150) {
+ qt_blend_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
+ return;
+ }
+
+ int dstride = dbpl / 2;
+ int sstride = sbpl / 2;
+
+ quint16 *dst = (quint16 *) destPixels;
+ quint16 *src = (quint16 *) srcPixels;
+
+ switch (w) {
+#define BLOCKBLIT(n) case n: blockBlit16<n>(dst, src, dstride, sstride, h); return;
+ BLOCKBLIT(1);
+ BLOCKBLIT(2);
+ BLOCKBLIT(3);
+ BLOCKBLIT(4);
+ BLOCKBLIT(5);
+ BLOCKBLIT(6);
+ BLOCKBLIT(7);
+ BLOCKBLIT(8);
+ BLOCKBLIT(9);
+ BLOCKBLIT(10);
+ BLOCKBLIT(11);
+ BLOCKBLIT(12);
+ BLOCKBLIT(13);
+ BLOCKBLIT(14);
+ BLOCKBLIT(15);
+#undef BLOCKBLIT
+ default:
+ break;
+ }
+
+ pixman_composite_src_0565_0565_asm_neon (w, h, dst, dstride, src, sstride);
+}
+
extern "C" void blend_8_pixels_argb32_on_rgb16_neon(quint16 *dst, const quint32 *src, int const_alpha);
void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl,
@@ -622,6 +758,61 @@ void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, u
}
}
+void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ uint *const end = dst + length;
+ uint *const neonEnd = end - 3;
+
+ while (dst < neonEnd) {
+ asm volatile (
+ "vld2.8 { d0, d1 }, [%[SRC]] !\n\t"
+ "vld2.8 { d2, d3 }, [%[DST]]\n\t"
+ "vqadd.u8 q0, q0, q1\n\t"
+ "vst2.8 { d0, d1 }, [%[DST]] !\n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ :
+ : "memory", "d0", "d1", "d2", "d3", "q0", "q1"
+ );
+ }
+
+ while (dst != end) {
+ *dst = comp_func_Plus_one_pixel(*dst, *src);
+ ++dst;
+ ++src;
+ }
+ } else {
+ int x = 0;
+ const int one_minus_const_alpha = 255 - const_alpha;
+ const uint16x8_t constAlphaVector = vdupq_n_u16(const_alpha);
+ const uint16x8_t oneMinusconstAlphaVector = vdupq_n_u16(one_minus_const_alpha);
+
+ const uint16x8_t half = vdupq_n_u16(0x80);
+ for (; x < length - 3; x += 4) {
+ const uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]);
+ const uint8x16_t src8 = vreinterpretq_u8_u32(src32);
+ uint8x16_t dst8 = vld1q_u8((uint8_t *)&dst[x]);
+ uint8x16_t result = vqaddq_u8(dst8, src8);
+
+ uint16x8_t result_low = vmovl_u8(vget_low_u8(result));
+ uint16x8_t result_high = vmovl_u8(vget_high_u8(result));
+
+ uint16x8_t dst_low = vmovl_u8(vget_low_u8(dst8));
+ uint16x8_t dst_high = vmovl_u8(vget_high_u8(dst8));
+
+ result_low = qvinterpolate_pixel_255(result_low, constAlphaVector, dst_low, oneMinusconstAlphaVector, half);
+ result_high = qvinterpolate_pixel_255(result_high, constAlphaVector, dst_high, oneMinusconstAlphaVector, half);
+
+ const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result_low));
+ const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result_high));
+ vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high));
+ }
+
+ for (; x < length; ++x)
+ dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha);
+ }
+}
+
static const int tileSize = 32;
extern "C" void qt_rotate90_16_neon(quint16 *dst, const quint16 *src, int sstride, int dstride, int count);
diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h
index cd2dbfc..d25b7ec 100644
--- a/src/gui/painting/qdrawhelper_neon_p.h
+++ b/src/gui/painting/qdrawhelper_neon_p.h
@@ -84,6 +84,11 @@ void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl,
int w, int h,
int const_alpha);
+void qt_blend_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer,
int x, int y, quint32 color,
const uchar *bitmap,
@@ -120,6 +125,7 @@ void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
const QTransform &targetRectTransform,
int const_alpha);
+void qt_memfill32_neon(quint32 *dest, quint32 value, int count);
void qt_memrotate90_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl);
void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl);
@@ -131,6 +137,7 @@ void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer,
int x, int y, const uint *buffer, int length);
void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha);
+void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uint const_alpha);
#endif // QT_HAVE_NEON
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index d04c70d..5747da5 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -62,6 +62,7 @@
#define QT_FT_END_HEADER
#endif
#include "private/qrasterdefs_p.h"
+#include <private/qsimd_p.h>
#ifdef Q_WS_QWS
#include "QtGui/qscreen_qws.h"
@@ -69,13 +70,6 @@
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_MAC) && (defined(__ppc__) || defined(__ppc64__))
-#undef QT_HAVE_MMX
-#undef QT_HAVE_SSE
-#undef QT_HAVE_SSE2
-#undef QT_HAVE_3DNOW
-#endif
-
#if defined(Q_CC_MSVC) && _MSCVER <= 1300 && !defined(Q_CC_INTEL)
#define Q_STATIC_TEMPLATE_SPECIALIZATION static
#else
@@ -1944,6 +1938,30 @@ const uint qt_bayer_matrix[16][16] = {
((((argb >> 24) * alpha) >> 8) << 24) | (argb & 0x00ffffff)
+#if QT_POINTER_SIZE == 8 // 64-bit versions
+#define AMIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
+#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
+#else // 32 bits
+// The mask for alpha can overflow over 32 bits
+#define AMIX(mask) quint32(qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
+#define MIX(mask) (qMin(((quint32(s)&mask) + (quint32(d)&mask)), quint32(mask)))
+#endif
+
+inline int comp_func_Plus_one_pixel_const_alpha(uint d, const uint s, const uint const_alpha, const uint one_minus_const_alpha)
+{
+ const int result = (AMIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
+ return INTERPOLATE_PIXEL_255(result, const_alpha, d, one_minus_const_alpha);
+}
+
+inline int comp_func_Plus_one_pixel(uint d, const uint s)
+{
+ const int result = (AMIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
+ return result;
+}
+
+#undef MIX
+#undef AMIX
+
// prototypes of all the composition functions
void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha);
void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha);
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index 22c0384..5b674b5 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -43,7 +43,6 @@
#ifdef QT_HAVE_SSE2
-#include <private/qsimd_p.h>
#include <private/qdrawingprimitive_sse2_p.h>
#include <private/qpaintengine_raster_p.h>
@@ -161,22 +160,6 @@ void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixe
}
}
-inline int comp_func_Plus_one_pixel_const_alpha(uint d, const uint s, const uint const_alpha, const uint one_minus_const_alpha)
-{
-#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
- const int result = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
-#undef MIX
- return INTERPOLATE_PIXEL_255(result, const_alpha, d, one_minus_const_alpha);
-}
-
-inline int comp_func_Plus_one_pixel(uint d, const uint s)
-{
-#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask)))
- const int result = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
-#undef MIX
- return result;
-}
-
void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha)
{
int x = 0;
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index 9c02009..4cb4089 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -39,11 +39,10 @@
**
****************************************************************************/
+#include <private/qdrawhelper_x86_p.h>
#ifdef QT_HAVE_SSSE3
-#include <private/qsimd_p.h>
-#include <private/qdrawhelper_x86_p.h>
#include <private/qdrawingprimitive_sse2_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index be90006..c6046ac 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -696,9 +696,9 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s)
skip = false;
- QBrush penBrush = s->pen.brush();
- Qt::BrushStyle brushStyle = s->brush.style();
- Qt::BrushStyle penBrushStyle = penBrush.style();
+ QBrush penBrush = (qpen_style(s->pen) == Qt::NoPen) ? QBrush(Qt::NoBrush) : qpen_brush(s->pen);
+ Qt::BrushStyle brushStyle = qbrush_style(s->brush);
+ Qt::BrushStyle penBrushStyle = qbrush_style(penBrush);
alpha = (penBrushStyle != Qt::NoBrush
&& (penBrushStyle < Qt::LinearGradientPattern && penBrush.color().alpha() != 255)
&& !penBrush.isOpaque())
@@ -5863,7 +5863,8 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
}
bool paintEngineSupportsTransformations = d->extended->type() == QPaintEngine::OpenGL2
- || d->extended->type() == QPaintEngine::OpenVG;
+ || d->extended->type() == QPaintEngine::OpenVG
+ || d->extended->type() == QPaintEngine::OpenGL;
if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) {
staticText_d->untransformedCoordinates = true;
@@ -5907,7 +5908,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
// Recreate the layout of the static text because the matrix or font has changed
if (staticTextNeedsReinit)
- staticText_d->init();
+ staticText_d->init();
if (transformedPosition != staticText_d->position) { // Translate to actual position
QFixed fx = QFixed::fromReal(transformedPosition.x());
@@ -9027,7 +9028,7 @@ void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragment
{
Q_D(QPainter);
- if (!d->engine)
+ if (!d->engine || pixmap.isNull())
return;
#ifndef QT_NO_DEBUG
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp
index ada5293..306219d 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/gui/styles/qcleanlooksstyle.cpp
@@ -2157,7 +2157,7 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o
}
if (button->features & QStyleOptionButton::HasMenu)
- ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
+ ir = ir.adjusted(0, 0, -proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
proxy()->drawItemText(painter, ir, tf, button->palette, (button->state & State_Enabled),
button->text, QPalette::ButtonText);
}
@@ -4014,8 +4014,8 @@ QRect QCleanlooksStyle::subControlRect(ComplexControl control, const QStyleOptio
switch (subControl) {
case SC_SliderHandle: {
if (slider->orientation == Qt::Horizontal) {
- rect.setHeight(pixelMetric(PM_SliderThickness));
- rect.setWidth(pixelMetric(PM_SliderLength));
+ rect.setHeight(proxy()->pixelMetric(PM_SliderThickness));
+ rect.setWidth(proxy()->pixelMetric(PM_SliderLength));
int centerY = slider->rect.center().y() - rect.height() / 2;
if (slider->tickPosition & QSlider::TicksAbove)
centerY += tickSize;
@@ -4023,8 +4023,8 @@ QRect QCleanlooksStyle::subControlRect(ComplexControl control, const QStyleOptio
centerY -= tickSize;
rect.moveTop(centerY);
} else {
- rect.setWidth(pixelMetric(PM_SliderThickness));
- rect.setHeight(pixelMetric(PM_SliderLength));
+ rect.setWidth(proxy()->pixelMetric(PM_SliderThickness));
+ rect.setHeight(proxy()->pixelMetric(PM_SliderLength));
int centerX = slider->rect.center().x() - rect.width() / 2;
if (slider->tickPosition & QSlider::TicksAbove)
centerX += tickSize;
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index e28403b..358c6aa 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -154,6 +154,9 @@ QS60StylePrivate::~QS60StylePrivate()
{
clearCaches(); //deletes also background image
deleteThemePalette();
+#ifdef Q_WS_S60
+ removeAnimations();
+#endif
}
void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter,
@@ -1097,8 +1100,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
}
State mflags = bflags;
if (toolBtn->state & State_Sunken) {
- if (toolBtn->activeSubControls & SC_ToolButton)
- bflags |= State_Sunken;
+ bflags |= State_Sunken;
mflags |= State_Sunken;
}
@@ -1114,11 +1116,6 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
if (bflags & (State_Sunken | State_On | State_Raised | State_Enabled)) {
tool.rect = button.unite(menuRect);
tool.state = bflags;
- const QToolButton *toolButtonWidget = qobject_cast<const QToolButton *>(widget);
- const QS60StylePrivate::SkinElements element =
- ((toolButtonWidget && toolButtonWidget->isDown()) || (option->state & State_Sunken)) ?
- QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;
- QS60StylePrivate::drawSkinElement(element, painter, tool.rect, flags);
drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
}
if (toolBtn->subControls & SC_ToolButtonMenu) {
@@ -2174,9 +2171,12 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_PanelButtonBevel:
case PE_FrameButtonBevel:
if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)) {
- const bool isPressed = option->state & State_Sunken;
- const QS60StylePrivate::SkinElements skinElement =
- isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
+ const bool isPressed = (option->state & State_Sunken) || (option->state & State_On);
+ QS60StylePrivate::SkinElements skinElement;
+ if (element == PE_PanelButtonTool)
+ skinElement = isPressed ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;
+ else
+ skinElement = isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
} else {
commonStyleDraws = true;
@@ -2340,16 +2340,20 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
tableView = true;
QS60StylePrivate::SkinElements element;
+ bool themeGraphicDefined = false;
QRect elementRect = option->rect;
//draw item is drawn as pressed, if it already has focus.
if (isPressed && (hasFocus || isSelected)) {
+ themeGraphicDefined = true;
element = tableView ? QS60StylePrivate::SE_TableItemPressed : QS60StylePrivate::SE_ListItemPressed;
} else if (hasFocus || (isSelected && selectionBehavior != QAbstractItemView::SelectItems)) {
element = QS60StylePrivate::SE_ListHighlight;
elementRect = highlightRect;
+ themeGraphicDefined = true;
}
- QS60StylePrivate::drawSkinElement(element, painter, elementRect, flags);
+ if (themeGraphicDefined)
+ QS60StylePrivate::drawSkinElement(element, painter, elementRect, flags);
} else {
QCommonStyle::drawPrimitive(element, option, painter, widget);
}
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index 836969a..51ced96 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -571,6 +571,7 @@ public:
void startAnimation(QS60StyleEnums::SkinParts animation);
void stopAnimation(QS60StyleEnums::SkinParts animation);
static QS60StyleAnimation* animationDefinition(QS60StyleEnums::SkinParts part);
+ static void removeAnimations();
#endif
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index f44b85e..5dda42e 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -1152,6 +1152,12 @@ QS60StylePrivate::QS60StylePrivate()
setActiveLayout();
}
+void QS60StylePrivate::removeAnimations()
+{
+ //currently only one animation in the list.
+ m_animations()->removeFirst();
+}
+
QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list,
int index, const QStyleOption *option)
{
diff --git a/src/gui/text/qfont_s60.cpp b/src/gui/text/qfont_s60.cpp
index ccd17a2..2d547a9 100644
--- a/src/gui/text/qfont_s60.cpp
+++ b/src/gui/text/qfont_s60.cpp
@@ -40,15 +40,26 @@
****************************************************************************/
#include "qfont.h"
+#include "qfont_p.h"
#include <private/qt_s60_p.h>
#include <private/qpixmap_s60_p.h>
#include "qmutex.h"
QT_BEGIN_NAMESPACE
-#if 1
#ifdef QT_NO_FREETYPE
Q_GLOBAL_STATIC(QMutex, lastResortFamilyMutex);
+Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, fontFamiliesOnFontServer, {
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+ const int numTypeFaces = S60->screenDevice()->NumTypefaces();
+ for (int i = 0; i < numTypeFaces; i++) {
+ TTypefaceSupport typefaceSupport;
+ S60->screenDevice()->TypefaceSupport(typefaceSupport, i);
+ const QString familyName((const QChar *)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length());
+ x->append(familyName);
+ }
+ lock.relock();
+});
#endif // QT_NO_FREETYPE
QString QFont::lastResortFamily() const
@@ -70,7 +81,7 @@ QString QFont::lastResortFamily() const
lock.relock();
}
return family;
-#else
+#else // QT_NO_FREETYPE
// For the FreeType case we just hard code the face name, since otherwise on
// East Asian systems we may get a name for a stroke based (non-ttf) font.
@@ -82,15 +93,24 @@ QString QFont::lastResortFamily() const
return QLatin1String(isJapaneseOrChineseSystem?"Heisei Kaku Gothic S60":"Series 60 Sans");
#endif // QT_NO_FREETYPE
}
-#else // 0
-QString QFont::lastResortFamily() const
-{
- return QLatin1String("Series 60 Sans");
-}
-#endif // 0
QString QFont::defaultFamily() const
{
+#ifdef QT_NO_FREETYPE
+ switch(d->request.styleHint) {
+ case QFont::SansSerif: {
+ static const char* const preferredSansSerif[] = {"Nokia Sans S60", "Series 60 Sans"};
+ for (int i = 0; i < sizeof preferredSansSerif / sizeof preferredSansSerif[0]; ++i) {
+ const QString sansSerif = QLatin1String(preferredSansSerif[i]);
+ if (fontFamiliesOnFontServer()->contains(sansSerif))
+ return sansSerif;
+ }
+ }
+ // No break. Intentional fall through.
+ default:
+ return lastResortFamily();
+ }
+#endif // QT_NO_FREETYPE
return lastResortFamily();
}
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 194c5f3..1e8461f 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -874,8 +874,8 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
enum {
Invalid,
- Symbol,
AppleRoman,
+ Symbol,
Unicode11,
Unicode,
MicrosoftUnicode,
@@ -939,7 +939,7 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
return 0;
resolveTable:
- *isSymbolFont = (score == Symbol);
+ *isSymbolFont = (symbolTable > -1);
unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4);
@@ -1093,6 +1093,18 @@ const QVector<QRgb> &QFontEngine::grayPalette()
return *qt_grayPalette();
}
+QFixed QFontEngine::lastRightBearing(const QGlyphLayout &glyphs, bool round)
+{
+ if (glyphs.numGlyphs >= 1) {
+ glyph_t glyph = glyphs.glyphs[glyphs.numGlyphs - 1];
+ glyph_metrics_t gi = boundingBox(glyph);
+ if (gi.isValid())
+ return round ? QFixed(qRound(gi.xoff - gi.x - gi.width))
+ : QFixed(gi.xoff - gi.x - gi.width);
+ }
+ return 0;
+}
+
// ------------------------------------------------------------------
// The box font engine
// ------------------------------------------------------------------
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 2c4fbab..a9b25f5 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -94,6 +94,13 @@ QT_BEGIN_NAMESPACE
#define Y_SIZE(face,i) ((face)->available_sizes[i].height << 6)
#endif
+/* FreeType 2.1.10 starts to provide FT_GlyphSlot_Embolden */
+#if (FREETYPE_MAJOR*10000+FREETYPE_MINOR*100+FREETYPE_PATCH) >= 20110
+#define Q_FT_GLYPHSLOT_EMBOLDEN(slot) FT_GlyphSlot_Embolden(slot)
+#else
+#define Q_FT_GLYPHSLOT_EMBOLDEN(slot)
+#endif
+
#define FLOOR(x) ((x) & -64)
#define CEIL(x) (((x)+63) & -64)
#define TRUNC(x) ((x) >> 6)
@@ -794,7 +801,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph
}
FT_GlyphSlot slot = face->glyph;
- if (embolden) FT_GlyphSlot_Embolden(slot);
+ if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot);
int left = slot->metrics.horiBearingX;
int right = slot->metrics.horiBearingX + slot->metrics.width;
int top = slot->metrics.horiBearingY;
@@ -940,7 +947,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph
return 0;
FT_GlyphSlot slot = face->glyph;
- if (embolden) FT_GlyphSlot_Embolden(slot);
+ if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot);
FT_Library library = qt_getFreetype();
info.xOff = TRUNC(ROUND(slot->advance.x));
@@ -1558,8 +1565,6 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
FT_Face face = freetype->face;
for ( int i = 0; i < len; ++i ) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
if ( !glyphs->glyphs[glyph_pos] ) {
glyph_t glyph;
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 91b6082..bdf3848 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -455,12 +455,13 @@ bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *
glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
{
QFixed w;
+ bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
+
for (int i = 0; i < glyphs.numGlyphs; ++i) {
- w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? glyphs.effectiveAdvance(i).round()
- : glyphs.effectiveAdvance(i);
+ w += round ? glyphs.effectiveAdvance(i).round()
+ : glyphs.effectiveAdvance(i);
}
- return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
+ return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0);
}
glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
{
@@ -1480,12 +1481,12 @@ void QFontEngineMac::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla
glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs)
{
QFixed w;
+ bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
for (int i = 0; i < glyphs.numGlyphs; ++i) {
- w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? glyphs.effectiveAdvance(i).round()
- : glyphs.effectiveAdvance(i);
+ w += round ? glyphs.effectiveAdvance(i).round()
+ : glyphs.effectiveAdvance(i);
}
- return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
+ return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0);
}
glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph)
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 922acfb..3b91cd8 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -253,6 +253,7 @@ public:
protected:
static const QVector<QRgb> &grayPalette();
+ QFixed lastRightBearing(const QGlyphLayout &glyphs, bool round = false);
private:
struct GlyphCacheEntry {
diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
index a0593cc..53b6910 100644
--- a/src/gui/text/qfontengine_qpf.cpp
+++ b/src/gui/text/qfontengine_qpf.cpp
@@ -578,8 +578,6 @@ bool QFontEngineQPF::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
if (symbol) {
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp
index a7a95d0..decc89c 100644
--- a/src/gui/text/qfontengine_qws.cpp
+++ b/src/gui/text/qfontengine_qws.cpp
@@ -557,7 +557,7 @@ glyph_metrics_t QFontEngineQPF1::boundingBox(const QGlyphLayout &glyphs)
QFixed w = 0;
for (int i = 0; i < glyphs.numGlyphs; ++i)
w += glyphs.effectiveAdvance(i);
- return glyph_metrics_t(0, -ascent(), w, ascent()+descent()+1, w, 0);
+ return glyph_metrics_t(0, -ascent(), w - lastRightBearing(glyphs), ascent()+descent()+1, w, 0);
}
glyph_metrics_t QFontEngineQPF1::boundingBox(glyph_t glyph)
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
index 52a1fe7..5980f20 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/gui/text/qfontengine_s60.cpp
@@ -166,6 +166,11 @@ const uchar *QSymbianTypeFaceExtras::cmap() const
return reinterpret_cast<const uchar *>(m_cmapTable.constData());
}
+bool QSymbianTypeFaceExtras::isSymbolCMap() const
+{
+ return m_symbolCMap;
+}
+
CFont *QSymbianTypeFaceExtras::fontOwner() const
{
return m_cFont;
@@ -256,7 +261,7 @@ bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout
for (int i = 0; i < len; ++i) {
const unsigned int uc = getChar(characters, i, len);
*g++ = QFontEngine::getTrueTypeGlyphIndex(cmap,
- isRtl ? QChar::mirroredChar(uc) : uc);
+ (isRtl && !m_extras->isSymbolCMap()) ? QChar::mirroredChar(uc) : uc);
}
glyphs->numGlyphs = g - glyphs->glyphs;
@@ -345,7 +350,7 @@ glyph_metrics_t QFontEngineS60::boundingBox(const QGlyphLayout &glyphs)
for (int i = 0; i < glyphs.numGlyphs; ++i)
w += glyphs.effectiveAdvance(i);
- return glyph_metrics_t(0, -ascent(), w, ascent()+descent()+1, w, 0);
+ return glyph_metrics_t(0, -ascent(), w - lastRightBearing(glyphs), ascent()+descent()+1, w, 0);
}
glyph_metrics_t QFontEngineS60::boundingBox_const(glyph_t glyph) const
diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h
index d65f13b..d05c23c 100644
--- a/src/gui/text/qfontengine_s60_p.h
+++ b/src/gui/text/qfontengine_s60_p.h
@@ -81,6 +81,7 @@ public:
bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
const uchar *cmap() const;
CFont *fontOwner() const;
+ bool isSymbolCMap() const;
private:
CFont* m_cFont;
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index a805612..4bed2b5 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -487,7 +487,7 @@ glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs)
for (int i = 0; i < glyphs.numGlyphs; ++i)
w += glyphs.effectiveAdvance(i);
- return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0);
+ return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0);
}
#ifndef Q_WS_WINCE
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 21c2e02..b950b13 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -400,9 +400,9 @@ QStaticTextPrivate::QStaticTextPrivate()
QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other)
: text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix),
- items(0), itemCount(0), glyphPool(0), positionPool(0), charPool(0), needsRelayout(true),
- useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat),
- untransformedCoordinates(other.untransformedCoordinates)
+ items(0), itemCount(0), glyphPool(0), positionPool(0), charPool(0), textOption(other.textOption),
+ needsRelayout(true), useBackendOptimizations(other.useBackendOptimizations),
+ textFormat(other.textFormat), untransformedCoordinates(other.untransformedCoordinates)
{
}
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 8d6dd6c..119217a 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1646,7 +1646,6 @@ glyph_metrics_t QTextEngine::boundingBox(int from, int len) const
for (int i = 0; i < layoutData->items.size(); i++) {
const QScriptItem *si = layoutData->items.constData() + i;
- QFontEngine *fe = fontEngine(*si);
int pos = si->position;
int ilen = length(i);
@@ -1676,6 +1675,7 @@ glyph_metrics_t QTextEngine::boundingBox(int from, int len) const
while (charFrom < ilen && logClusters[charFrom] == glyphStart)
charFrom++;
if (charFrom < ilen) {
+ QFontEngine *fe = fontEngine(*si);
glyphStart = logClusters[charFrom];
int charEnd = from + len - 1 - pos;
if (charEnd >= ilen)
@@ -1694,11 +1694,6 @@ glyph_metrics_t QTextEngine::boundingBox(int from, int len) const
gm.yoff += m.yoff;
}
}
-
- glyph_t glyph = glyphs.glyphs[logClusters[ilen - 1]];
- glyph_metrics_t gi = fe->boundingBox(glyph);
- if (gi.isValid())
- gm.width -= qRound(gi.xoff - gi.x - gi.width);
}
}
return gm;
@@ -2144,8 +2139,11 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
void **newMem = memory;
newMem = (void **)::realloc(memory_on_stack ? 0 : memory, newAllocated*sizeof(void *));
- Q_CHECK_PTR(newMem);
- if (memory_on_stack && newMem)
+ if (!newMem) {
+ layoutState = LayoutFailed;
+ return false;
+ }
+ if (memory_on_stack)
memcpy(newMem, memory, allocated*sizeof(void *));
memory = newMem;
memory_on_stack = false;
diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp
index 24f6ccf..cd023cb 100644
--- a/src/gui/util/qdesktopservices_s60.cpp
+++ b/src/gui/util/qdesktopservices_s60.cpp
@@ -223,6 +223,7 @@ static void handleOtherSchemesL(const TDesC& aUrl)
TApaTask task = taskList.FindApp(KUidBrowser);
if (task.Exists()){
// Switch to existing browser instance
+ task.BringToForeground();
HBufC8* param8 = HBufC8::NewLC(buf16->Length());
param8->Des().Append(buf16->Des());
task.SendMessage(TUid::Uid( 0 ), *param8); // Uid is not used
diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp
index 7a61dc7..bd6c577 100644
--- a/src/gui/widgets/qdatetimeedit.cpp
+++ b/src/gui/widgets/qdatetimeedit.cpp
@@ -248,7 +248,7 @@ void QDateTimeEdit::setDateTime(const QDateTime &datetime)
/*!
\property QDateTimeEdit::date
- \brief the QDate that is set in the QDateTimeEdit
+ \brief the QDate that is set in the widget
By default, this property contains a date that refers to January 1, 2000.
@@ -279,7 +279,7 @@ void QDateTimeEdit::setDate(const QDate &date)
/*!
\property QDateTimeEdit::time
- \brief the QTime that is set in the QDateTimeEdit
+ \brief the QTime that is set in the widget
By default, this property contains a time of 00:00:00 and 0 milliseconds.
@@ -1555,13 +1555,6 @@ QTimeEdit::QTimeEdit(const QTime &time, QWidget *parent)
{
}
-/*!
- \property QTimeEdit::time
- \brief the QTime that is shown in the widget
-
- By default, this property contains a time of 00:00:00 and 0 milliseconds.
-*/
-
/*!
\class QDateEdit
@@ -1616,13 +1609,6 @@ QDateEdit::QDateEdit(const QDate &date, QWidget *parent)
{
}
-/*!
- \property QDateEdit::date
- \brief the QDate that is shown in the widget
-
- By default, this property contains a date referring to January 1, 2000.
-*/
-
// --- QDateTimeEditPrivate ---
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index d027b91..b6dfd13 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -419,7 +419,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
int c = m_cursor; // cursor position after insertion of commit string
- if (event->replacementStart() == 0)
+ if (event->replacementStart() <= 0)
c += event->commitString().length() + qMin(-event->replacementStart(), event->replacementLength());
m_cursor += event->replacementStart();
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 837cf66..b35c318 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -201,7 +201,7 @@ static void ensureInitialized()
deleteResource())
\value CustomOperation custom operation (created with
- sendCustomRequest())
+ sendCustomRequest()) \since 4.7
\omitvalue UnknownOperation
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 65014a6..23d7800 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -45,12 +45,33 @@
#include "qbearerengine_p.h"
#include <QtCore/qstringlist.h>
+#include <QtCore/qcoreapplication.h>
#ifndef QT_NO_BEARERMANAGEMENT
QT_BEGIN_NAMESPACE
-Q_GLOBAL_STATIC(QNetworkConfigurationManagerPrivate, connManager);
+#define Q_GLOBAL_STATIC_QAPP_DESTRUCTION(TYPE, NAME) \
+ Q_GLOBAL_STATIC_INIT(TYPE, NAME); \
+ static void NAME##_cleanup() \
+ { \
+ delete this_##NAME.pointer; \
+ this_##NAME.pointer = 0; \
+ this_##NAME.destroyed = true; \
+ } \
+ static TYPE *NAME() \
+ { \
+ if (!this_##NAME.pointer && !this_##NAME.destroyed) { \
+ TYPE *x = new TYPE; \
+ if (!this_##NAME.pointer.testAndSetOrdered(0, x)) \
+ delete x; \
+ else \
+ qAddPostRoutine(NAME##_cleanup); \
+ } \
+ return this_##NAME.pointer; \
+ }
+
+Q_GLOBAL_STATIC_QAPP_DESTRUCTION(QNetworkConfigurationManagerPrivate, connManager);
QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate()
{
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index d61c686..18cc14e 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -52,10 +52,13 @@
#include <qstring.h>
#include <qdatetime.h>
+//#define NTLMV1_CLIENT
QT_BEGIN_NAMESPACE
+#ifdef NTLMV1_CLIENT
#include "../../3rdparty/des/des.cpp"
+#endif
static QByteArray qNtlmPhase1();
static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
@@ -203,17 +206,29 @@ QString QAuthenticator::user() const
void QAuthenticator::setUser(const QString &user)
{
detach();
-
int separatorPosn = 0;
- separatorPosn = user.indexOf(QLatin1String("\\"));
- if (separatorPosn == -1) {
- //No domain name present
+ switch(d->method) {
+ case QAuthenticatorPrivate::DigestMd5:
+ case QAuthenticatorPrivate::Ntlm:
+ if((separatorPosn = user.indexOf(QLatin1String("\\"))) != -1)
+ {
+ //domain name is present
+ d->realm = user.left(separatorPosn);
+ d->user = user.mid(separatorPosn + 1);
+ } else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) {
+ //domain name is present
+ d->realm = user.mid(separatorPosn + 1);
+ d->user = user.left(separatorPosn);
+ } else {
+ d->user = user;
+ d->realm.clear();
+ }
+ break;
+ // For other auth mechanisms, domain name will be part of username
+ default:
d->user = user;
- } else {
- //domain name is present
- d->realm = user.left(separatorPosn);
- d->user = user.mid(separatorPosn+1);
+ break;
}
}
@@ -1178,11 +1193,9 @@ static QByteArray clientChallenge(const QAuthenticatorPrivate *ctx)
}
// caller has to ensure a valid targetInfoBuff
-static bool qExtractServerTime(const QByteArray& targetInfoBuff,
- quint64 *serverTime)
+static QByteArray qExtractServerTime(const QByteArray& targetInfoBuff)
{
- Q_ASSERT(serverTime != 0);
- bool retValue = false;
+ QByteArray timeArray;
QDataStream ds(targetInfoBuff);
ds.setByteOrder(QDataStream::LittleEndian);
@@ -1193,19 +1206,16 @@ static bool qExtractServerTime(const QByteArray& targetInfoBuff,
ds >> avLen;
while(avId != 0) {
if(avId == AVTIMESTAMP) {
- QByteArray timeArray(avLen, 0);
+ timeArray.resize(avLen);
//avLen size of QByteArray is allocated
ds.readRawData(timeArray.data(), avLen);
- bool ok;
- *serverTime = timeArray.toHex().toLongLong(&ok, 16);
- retValue = true;
break;
}
ds.skipRawData(avLen);
ds >> avId;
ds >> avLen;
}
- return retValue;
+ return timeArray;
}
static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,
@@ -1228,9 +1238,17 @@ static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,
ds.writeRawData(reserved1.constData(), reserved1.size());
quint64 time = 0;
+ QByteArray timeArray;
+
+ if(ch.targetInfo.len)
+ {
+ timeArray = qExtractServerTime(ch.targetInfoBuff);
+ }
//if server sends time, use it instead of current time
- if(!(ch.targetInfo.len && qExtractServerTime(ch.targetInfoBuff, &time))) {
+ if(timeArray.size()) {
+ ds.writeRawData(timeArray.constData(), timeArray.size());
+ } else {
QDateTime currentTime(QDate::currentDate(),
QTime::currentTime(), Qt::UTC);
@@ -1242,8 +1260,8 @@ static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,
// represented as 100 nano seconds
time = Q_UINT64_C(time * 10000000);
+ ds << time;
}
- ds << time;
//8 byte client challenge
QByteArray clientCh = clientChallenge(ctx);
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 91265f3..f18c629 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1966,6 +1966,11 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri
QMutexLocker locker(&globalData()->mutex);
const QSslConfigurationPrivate *global = globalData()->config.constData();
+ if (!global) {
+ ptr = 0;
+ return;
+ }
+
ptr->ref = 1;
ptr->peerCertificate = global->peerCertificate;
ptr->peerCertificateChain = global->peerCertificateChain;
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 943a195..c49dba4 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2103,11 +2103,8 @@ void QGLContextPrivate::syncGlState()
#ifdef QT_NO_EGL
void QGLContextPrivate::swapRegion(const QRegion *)
{
- static bool firstWarning = true;
- if (firstWarning) {
- qWarning() << "::swapRegion called but not supported!";
- firstWarning = false;
- }
+ Q_Q(QGLContext);
+ q->swapBuffers();
}
#endif
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index b86fb78..d602000 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -426,6 +426,20 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize,
void QGLWindowSurface::beginPaint(const QRegion &)
{
+ if (! context())
+ return;
+
+ int clearFlags = 0;
+
+ if (context()->d_func()->workaround_needsFullClearOnEveryFrame)
+ clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
+ else if (context()->format().alpha())
+ clearFlags = GL_COLOR_BUFFER_BIT;
+
+ if (clearFlags) {
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(clearFlags);
+ }
}
void QGLWindowSurface::endPaint(const QRegion &rgn)
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
index 32eb61a..19f13c2 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -48,6 +48,14 @@
#include <stdapis/sys/socket.h>
#include <stdapis/net/if.h>
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+#include <cmmanager.h>
+#endif
+
+#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+#include <extendedconnpref.h>
+#endif
+
#ifndef QT_NO_BEARERMANAGEMENT
QT_BEGIN_NAMESPACE
@@ -113,7 +121,7 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
#endif
}
-void QNetworkSessionPrivateImpl::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState)
+void QNetworkSessionPrivateImpl::configurationStateChanged(quint32 accessPointId, quint32 connMonId, QNetworkSession::State newState)
{
if (iHandleStateNotificationsFromManager) {
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
@@ -170,8 +178,10 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface()
return;
if (iFirstSync) {
- QObject::connect(engine, SIGNAL(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)),
- this, SLOT(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)));
+ QObject::connect(engine,
+ SIGNAL(configurationStateChanged(quint32,quint32,QNetworkSession::State)),
+ this,
+ SLOT(configurationStateChanged(quint32,quint32,QNetworkSession::State)));
// Listen to configuration removals, so that in case the configuration
// this session is based on is removed, session knows to enter Invalid -state.
QObject::connect(engine, SIGNAL(configurationRemoved(QNetworkConfigurationPrivatePointer)),
@@ -902,13 +912,13 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
if (iapId == 0) {
_LIT(KSetting, "IAP\\Id");
iConnection.GetIntSetting(KSetting, iapId);
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
// Check if this is an Easy WLAN configuration. On Symbian^3 RConnection may report
// the used configuration as 'EasyWLAN' IAP ID if someone has just opened the configuration
// from WLAN Scan dialog, _and_ that connection is still up. We need to find the
// real matching configuration. Function alters the Easy WLAN ID to real IAP ID (only if
// easy WLAN):
- engine->easyWlanTrueIapId(iapId);
+ easyWlanTrueIapId(iapId);
#endif
}
@@ -948,7 +958,7 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
}
}
} else {
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
// On Symbian^3 (only, not earlier or Symbian^4) if the SNAP was not reachable, it triggers
// user choice type of activity (EasyWLAN). As a result, a new IAP may be created, and
// hence if was not found yet. Therefore update configurations and see if there is something new.
@@ -1319,7 +1329,7 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
}
}
}
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
// If the retVal is not true here, it means that the status update may apply to an IAP outside of
// SNAP (session is based on SNAP but follows IAP outside of it), which may occur on Symbian^3 EasyWlan.
if (retVal == false && activeConfig.isValid() &&
@@ -1472,6 +1482,64 @@ void QNetworkSessionPrivateImpl::restoreDefaultIf()
setdefaultif(&ifr);
}
+#if defined(SNAP_FUNCTIONALITY_AVAILABLE)
+bool QNetworkSessionPrivateImpl::easyWlanTrueIapId(TUint32 &trueIapId) const
+{
+ RCmManager iCmManager;
+ TRAPD(err, iCmManager.OpenL());
+ if (err != KErrNone)
+ return false;
+
+ // Check if this is easy wlan id in the first place
+ if (trueIapId != iCmManager.EasyWlanIdL()) {
+ iCmManager.Close();
+ return false;
+ }
+
+ iCmManager.Close();
+
+ // Loop through all connections that connection monitor is aware
+ // and check for IAPs based on easy WLAN
+ TRequestStatus status;
+ TUint connectionCount;
+ iConnectionMonitor.GetConnectionCount(connectionCount, status);
+ User::WaitForRequest(status);
+ TUint connectionId;
+ TUint subConnectionCount;
+ TUint apId;
+ if (status.Int() == KErrNone) {
+ for (TUint i = 1; i <= connectionCount; i++) {
+ iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount,
+ KIAPId, apId, status);
+ User::WaitForRequest(status);
+ if (apId == trueIapId) {
+ TBuf<50>easyWlanNetworkName;
+ iConnectionMonitor.GetStringAttribute(connectionId, 0, KNetworkName,
+ easyWlanNetworkName, status);
+ User::WaitForRequest(status);
+ if (status.Int() != KErrNone)
+ continue;
+
+ const QString ssid = QString::fromUtf16(easyWlanNetworkName.Ptr(),
+ easyWlanNetworkName.Length());
+
+ QNetworkConfigurationPrivatePointer ptr = engine->configurationFromSsid(ssid);
+ if (ptr) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM easyWlanTrueIapId(), found true IAP ID: "
+ << toSymbianConfig(ptr)->numericIdentifier();
+#endif
+ trueIapId = toSymbianConfig(ptr)->numericIdentifier();
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+#endif
+
ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivateImpl& owner, RConnection& connection)
: CActive(CActive::EPriorityUserInput), iOwner(owner), iConnection(connection)
{
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h
index 1b0e968..51f2e70 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.h
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.h
@@ -64,9 +64,6 @@
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
#include <comms-infras/cs_mobility_apiext.h>
#endif
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
- #include <extendedconnpref.h>
-#endif
QT_BEGIN_NAMESPACE
@@ -132,7 +129,8 @@ protected: // From CActive
void DoCancel();
private Q_SLOTS:
- void configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState);
+ void configurationStateChanged(quint32 accessPointId, quint32 connMonId,
+ QNetworkSession::State newState);
void configurationRemoved(QNetworkConfigurationPrivatePointer config);
void configurationAdded(QNetworkConfigurationPrivatePointer config);
@@ -148,6 +146,11 @@ private:
QNetworkInterface interface(TUint iapId) const;
#endif
+#if defined(SNAP_FUNCTIONALITY_AVAILABLE)
+ bool easyWlanTrueIapId(TUint32 &trueIapId) const;
+#endif
+
+
private: // data
SymbianEngine *engine;
diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp
index 9593461..2e2b671 100644
--- a/src/plugins/bearer/symbian/symbianengine.cpp
+++ b/src/plugins/bearer/symbian/symbianengine.cpp
@@ -692,7 +692,7 @@ void SymbianEngine::updateActiveAccessPoints()
User::WaitForRequest(status);
QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
if (!ptr) {
// If IAP was not found, check if the update was about EasyWLAN
ptr = configurationFromEasyWlan(apId, connectionId);
@@ -1054,7 +1054,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
if (!ptr) {
// Check if status was regarding EasyWLAN
ptr = configurationFromEasyWlan(apId, connectionId);
@@ -1079,7 +1079,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
User::WaitForRequest(status);
QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
if (!ptr) {
// Check for EasyWLAN
ptr = configurationFromEasyWlan(apId, connectionId);
@@ -1189,7 +1189,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
User::WaitForRequest(status);
QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(apId));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
if (!ptr) {
// If IAP was not found, check if the update was about EasyWLAN
ptr = configurationFromEasyWlan(apId, connectionId);
@@ -1210,11 +1210,39 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
}
}
-#if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE)
+/*
+ Returns the network configuration that matches the given SSID.
+*/
+QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromSsid(const QString &ssid)
+{
+ QMutexLocker locker(&mutex);
+
+ // Browser through all items and check their name for match
+ QHash<QString, QNetworkConfigurationPrivatePointer>::ConstIterator i =
+ accessPointConfigurations.constBegin();
+ while (i != accessPointConfigurations.constEnd()) {
+ QNetworkConfigurationPrivatePointer ptr = i.value();
+
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if (ptr->name == ssid) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM EasyWlan uses real SSID: " << ssid;
+#endif
+ return ptr;
+ }
+ ++i;
+ }
+
+ return QNetworkConfigurationPrivatePointer();
+}
+
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
// Tries to derive configuration from EasyWLAN.
// First checks if the interface brought up was EasyWLAN, then derives the real SSID,
// and looks up configuration based on that one.
-QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUint32 apId, TUint connectionId)
+QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUint32 apId,
+ TUint connectionId)
{
if (apId == iCmManager.EasyWlanIdL()) {
TRequestStatus status;
@@ -1223,11 +1251,12 @@ QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUi
easyWlanNetworkName, status );
User::WaitForRequest(status);
if (status.Int() == KErrNone) {
- QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(), easyWlanNetworkName.Length());
+ const QString realSSID = QString::fromUtf16(easyWlanNetworkName.Ptr(),
+ easyWlanNetworkName.Length());
// Browser through all items and check their name for match
- QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i =
- accessPointConfigurations.constBegin();
+ QHash<QString, QNetworkConfigurationPrivatePointer>::ConstIterator i =
+ accessPointConfigurations.constBegin();
while (i != accessPointConfigurations.constEnd()) {
QNetworkConfigurationPrivatePointer ptr = i.value();
@@ -1245,45 +1274,6 @@ QNetworkConfigurationPrivatePointer SymbianEngine::configurationFromEasyWlan(TUi
}
return QNetworkConfigurationPrivatePointer();
}
-
-bool SymbianEngine::easyWlanTrueIapId(TUint32& trueIapId)
-{
- // Check if this is easy wlan id in the first place
- if (trueIapId != iCmManager.EasyWlanIdL())
- return false;
-
- // Loop through all connections that connection monitor is aware
- // and check for IAPs based on easy WLAN
- TRequestStatus status;
- TUint connectionCount;
- iConnectionMonitor.GetConnectionCount(connectionCount, status);
- User::WaitForRequest(status);
- TUint connectionId;
- TUint subConnectionCount;
- TUint apId;
- if (status.Int() == KErrNone) {
- for (TUint i = 1; i <= connectionCount; i++) {
- iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
- iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount,
- KIAPId, apId, status);
- User::WaitForRequest(status);
- if (apId == trueIapId) {
- QNetworkConfigurationPrivatePointer ptr =
- configurationFromEasyWlan(apId, connectionId);
- if (ptr) {
-#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
- qDebug() << "QNCM easyWlanTrueIapId(), found true IAP ID: "
- << toSymbianConfig(ptr)->numericIdentifier();
-#endif
- trueIapId = toSymbianConfig(ptr)->numericIdentifier();
- return true;
- }
- }
- }
- }
- return false;
-}
-
#endif
// Sessions may use this function to report configuration state changes,
diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h
index 1fe6395..7c1076e 100644
--- a/src/plugins/bearer/symbian/symbianengine.h
+++ b/src/plugins/bearer/symbian/symbianengine.h
@@ -138,10 +138,15 @@ public:
QStringList accessPointConfigurationIdentifiers();
+ QNetworkConfigurationPrivatePointer configurationFromSsid(const QString &ssid);
+
+ // For QNetworkSessionPrivateImpl to indicate about state changes
+ void configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState);
+
Q_SIGNALS:
void onlineStateChanged(bool isOnline);
- void configurationStateChanged(TUint32 accessPointId, TUint32 connMonId,
+ void configurationStateChanged(quint32 accessPointId, quint32 connMonId,
QNetworkSession::State newState);
public Q_SLOTS:
@@ -187,12 +192,9 @@ protected:
private:
// MConnectionMonitorObserver
void EventL(const CConnMonEventBase& aEvent);
- // For QNetworkSessionPrivate to indicate about state changes
- void configurationStateChangeReport(TUint32 accessPointId,
- QNetworkSession::State newState);
-#ifdef OCC_FUNCTIONALITY_AVAILABLE
- QNetworkConfigurationPrivatePointer configurationFromEasyWlan(TUint32 apId, TUint connectionId);
- bool easyWlanTrueIapId(TUint32& trueIapId);
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ QNetworkConfigurationPrivatePointer configurationFromEasyWlan(TUint32 apId,
+ TUint connectionId);
#endif
private: // Data
@@ -212,7 +214,6 @@ private: // Data
friend class QNetworkSessionPrivate;
friend class AccessPointsAvailabilityScanner;
- friend class QNetworkSessionPrivateImpl;
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
RCmManager iCmManager;
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 8347626..07aced4 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -2626,8 +2626,7 @@ QScriptValue QScriptEngine::evaluate(const QString &program, const QString &file
}
/*!
- \internal
- \since 4.6
+ \since 4.7
Evaluates the given \a program and returns the result of the
evaluation.
diff --git a/src/script/api/qscriptprogram.cpp b/src/script/api/qscriptprogram.cpp
index 02beba4..3857b75 100644
--- a/src/script/api/qscriptprogram.cpp
+++ b/src/script/api/qscriptprogram.cpp
@@ -32,9 +32,7 @@
QT_BEGIN_NAMESPACE
/*!
- \internal
-
- \since 4.6
+ \since 4.7
\class QScriptProgram
\brief The QScriptProgram class encapsulates a Qt Script program.
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index d545440..bf19a88 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
static const char *qt_inherit_text = "inherit";
#define QT_INHERIT QLatin1String(qt_inherit_text)
-Q_DECL_IMPORT double qstrtod(const char *s00, char const **se, bool *ok);
+Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
// ======== duplicated from qcolor_p