aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/qml/doc/src/qml-extending.qdoc19
-rw-r--r--examples/quick/scenegraph/sgengine/window.cpp8
-rw-r--r--src/3rdparty/masm/wtf/PrintStream.cpp8
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.cpp2
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp2
-rw-r--r--src/qml/compiler/qv4ssa.cpp26
-rw-r--r--src/qml/doc/snippets/qml/statemachine/statemachine-button-history.qml1
-rw-r--r--src/qml/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml1
-rw-r--r--src/qml/doc/snippets/qml/statemachine/statemachine-button-nested.qml1
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc46
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc24
-rw-r--r--src/qml/jsruntime/qv4context.cpp16
-rw-r--r--src/qml/jsruntime/qv4context_p.h14
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp18
-rw-r--r--src/qml/jsruntime/qv4engine.cpp15
-rw-r--r--src/qml/jsruntime/qv4global_p.h4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp14
-rw-r--r--src/quick/doc/snippets/qml/itemGrab.qml2
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp30
-rw-r--r--src/quick/items/qquickanimatedimage.cpp9
-rw-r--r--src/quick/items/qquicktext.cpp19
-rw-r--r--src/quick/items/qquicktext_p_p.h1
-rw-r--r--src/quick/items/qquicktextedit.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp5
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp2
-rw-r--r--src/quick/scenegraph/shaders/visualization.frag2
-rw-r--r--src/quickwidgets/qquickwidget.cpp8
-rw-r--r--src/quickwidgets/qquickwidget_p.h2
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp11
-rw-r--r--tests/auto/qml/qqmlecmascript/data/date.qml6
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp3
-rw-r--r--tests/auto/qml/qv4debugger/tst_qv4debugger.cpp38
-rw-r--r--tests/auto/quick/nokeywords/tst_nokeywords.cpp8
-rw-r--r--tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp2
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp12
-rw-r--r--tests/testapplications/elements/content/BugPanel.qml2
-rw-r--r--tools/qmljs/qmljs.cpp2
38 files changed, 325 insertions, 64 deletions
diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc
index 8f44e4f506..f25b75ed29 100644
--- a/examples/qml/doc/src/qml-extending.qdoc
+++ b/examples/qml/doc/src/qml-extending.qdoc
@@ -63,6 +63,25 @@ loads and runs the QML snippet shown at the beginning of this page.
*/
/*!
+\example referenceexamples/extended
+\title Extending QML - Extension Objects Example
+\brief Extension Objects
+\ingroup qmlextendingexamples
+
+This example builds on:
+\list
+\li \l {Extending QML - Adding Types Example}
+\endlist
+
+Shows how to use \l qmlRegisterExtendedType() to provide an \l {Registering
+Extension Objects}{extension object} to a \l QLineEdit without modifying or
+subclassing. The QML engine instantiates a \l QLineEdit and sets a property that
+only exists on the extension type. The extension type performs calls on the \l
+QLineEdit that otherwise will not be accessible to the QML engine.
+
+*/
+
+/*!
\example referenceexamples/properties
\title Extending QML - Object and List Property Types Example
\brief Exporting C++ Properties
diff --git a/examples/quick/scenegraph/sgengine/window.cpp b/examples/quick/scenegraph/sgengine/window.cpp
index 9af4029165..bc371a38f6 100644
--- a/examples/quick/scenegraph/sgengine/window.cpp
+++ b/examples/quick/scenegraph/sgengine/window.cpp
@@ -47,6 +47,7 @@
#include <QSGTransformNode>
#include <QScreen>
#include <QVariantAnimation>
+#include <QOpenGLFunctions>
class Item {
public:
@@ -213,13 +214,14 @@ void Window::initialize()
m_sgRenderer->setClearColor(QColor(32, 32, 32));
// With QSGEngine::createTextureFromId
+ QOpenGLFunctions glFuncs(m_context.data());
GLuint glTexture;
- glGenTextures(1, &glTexture);
- glBindTexture(GL_TEXTURE_2D, glTexture);
+ glFuncs.glGenTextures(1, &glTexture);
+ glFuncs.glBindTexture(GL_TEXTURE_2D, glTexture);
QImage smile = QImage(":/scenegraph/sgengine/face-smile.png").scaled(48, 48, Qt::KeepAspectRatio, Qt::SmoothTransformation);
smile = smile.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
Q_ASSERT(!smile.isNull());
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smile.width(), smile.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, smile.constBits());
+ glFuncs.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smile.width(), smile.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, smile.constBits());
m_smileTexture.reset(m_sgEngine->createTextureFromId(glTexture, smile.size(), QFlag(QSGEngine::TextureOwnsGLTexture | QSGEngine::TextureHasAlphaChannel)));
// With QSGEngine::createTextureFromImage
diff --git a/src/3rdparty/masm/wtf/PrintStream.cpp b/src/3rdparty/masm/wtf/PrintStream.cpp
index 3bf362e281..02dfb11b4f 100644
--- a/src/3rdparty/masm/wtf/PrintStream.cpp
+++ b/src/3rdparty/masm/wtf/PrintStream.cpp
@@ -82,12 +82,20 @@ void printInternal(PrintStream& out, unsigned long value)
void printInternal(PrintStream& out, long long value)
{
+#if OS(WINDOWS)
+ out.printf("%I64d", value);
+#else
out.printf("%lld", value);
+#endif
}
void printInternal(PrintStream& out, unsigned long long value)
{
+#if OS(WINDOWS)
+ out.printf("%I64u", value);
+#else
out.printf("%llu", value);
+#endif
}
void printInternal(PrintStream& out, float value)
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
index 2026cb83d8..3f7b0fc072 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
@@ -541,7 +541,7 @@ void QQuickFolderListModel::componentComplete()
\list
\li Unsorted - no sorting is applied.
\li Name - sort by filename
- \li LastModified - sort by time modified
+ \li Time - sort by time modified
\li Size - sort by file size
\li Type - sort by file type (extension)
\endlist
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index c2d123c96f..84e6c76cc4 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1138,7 +1138,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
if (!prop->isWritable() && !(binding->flags & QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration))
COMPILE_EXCEPTION(binding, tr("Invalid property assignment: \"%1\" is a read-only property").arg(stringAt(binding->propertyNameIndex)));
- Q_ASSERT(binding->type = QV4::CompiledData::Binding::Type_Script);
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script);
const QString string = compiler->bindingAsString(obj, binding->value.compiledScriptIndex);
if (!string.constData()->isUpper())
return true;
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index d89ea07087..c0a14a5c80 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -2543,17 +2543,21 @@ public:
} else if (m->source->asConvert()) {
break;
} else if (Binop *b = m->source->asBinop()) {
+ bool iterateOnOperands = true;
+
switch (b->op) {
+ case OpSub:
+ case OpMul:
case OpAdd:
- if (b->left->type & NumberType || b->right->type & NumberType)
+ if (b->left->type == SInt32Type && b->right->type == SInt32Type) {
+ iterateOnOperands = false;
break;
- else
+ } else {
continue;
+ }
case OpBitAnd:
case OpBitOr:
case OpBitXor:
- case OpSub:
- case OpMul:
case OpLShift:
case OpRShift:
case OpURShift:
@@ -2561,10 +2565,13 @@ public:
default:
continue;
}
- if (Temp *lt = b->left->asTemp())
- candidates.append(*lt);
- if (Temp *rt = b->right->asTemp())
- candidates.append(*rt);
+
+ if (iterateOnOperands) {
+ if (Temp *lt = b->left->asTemp())
+ candidates.append(*lt);
+ if (Temp *rt = b->right->asTemp())
+ candidates.append(*rt);
+ }
} else if (Unop *u = m->source->asUnop()) {
if (u->op == OpCompl || u->op == OpUPlus) {
if (Temp *t = u->expr->asTemp())
@@ -4033,8 +4040,7 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df)
default:
break;
}
- if (casted) {
- Q_ASSERT(casted->type == SInt32Type);
+ if (casted && casted->type == SInt32Type) {
m->source = casted;
W += m;
continue;
diff --git a/src/qml/doc/snippets/qml/statemachine/statemachine-button-history.qml b/src/qml/doc/snippets/qml/statemachine/statemachine-button-history.qml
index 8f628232c1..c161a10610 100644
--- a/src/qml/doc/snippets/qml/statemachine/statemachine-button-history.qml
+++ b/src/qml/doc/snippets/qml/statemachine/statemachine-button-history.qml
@@ -58,7 +58,6 @@ Rectangle {
}
Button {
id: quitButton
- // change the button label to the active state id
text: "quit"
}
}
diff --git a/src/qml/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml b/src/qml/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml
index bf84b4cc90..5bbd9ca9df 100644
--- a/src/qml/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml
+++ b/src/qml/doc/snippets/qml/statemachine/statemachine-button-nested-ignore-quit.qml
@@ -53,7 +53,6 @@ Rectangle {
}
Button {
id: quitButton
- // change the button label to the active state id
text: "quit"
}
}
diff --git a/src/qml/doc/snippets/qml/statemachine/statemachine-button-nested.qml b/src/qml/doc/snippets/qml/statemachine/statemachine-button-nested.qml
index dfa093716f..932a9249d3 100644
--- a/src/qml/doc/snippets/qml/statemachine/statemachine-button-nested.qml
+++ b/src/qml/doc/snippets/qml/statemachine/statemachine-button-nested.qml
@@ -54,7 +54,6 @@ Rectangle {
}
Button {
id: quitButton
- // change the button label to the active state id
text: "quit"
}
}
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 03607df2e5..2f780503b2 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -294,6 +294,52 @@ This is useful when deriving from base classes provided by other authors,
e.g. when extending classes from the Qt Quick module.
+\section2 Registering Extension Objects
+
+When integrating existing classes and technology into QML, APIs will
+often need tweaking to fit better into the declarative environment.
+Although the best results are usually obtained by modifying the original
+classes directly, if this is either not possible or is complicated by some
+other concerns, extension objects allow limited extension possibilities
+without direct modifications.
+
+\e{Extension objects} add additional properties to an existing type. Extension
+objects can only add properties, not signals or methods. An extended type
+definition allows the programmer to supply an additional type, known as the
+\e{extension type}, when registering the class. The properties are transparently
+merged with the original target class when used from within QML. For example:
+
+\snippet referenceexamples/extended/example.qml 0
+
+The \c leftMargin property is a new property added to an existing C++ type, \l
+QLineEdit, without modifying its source code.
+
+The \l qmlRegisterExtendedType() function is for registering extended types.
+Note that it has two forms.
+
+\code
+template<typename T, typename ExtendedT>
+int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
+
+template<typename T, typename ExtendedT>
+int qmlRegisterExtendedType()
+\endcode
+
+This functions should be used instead of the regular \c qmlRegisterType()
+variations. The arguments are identical to the corresponding non-extension
+registration functions, except for the ExtendedT parameter which is the type of
+the extension object.
+
+An extension class is a regular QObject, with a constructor that takes a QObject
+pointer. However, the extension class creation is delayed until the first
+extended property is accessed. The extension class is created and the target
+object is passed in as the parent. When the property on the original is
+accessed, the corresponding property on the extension object is used instead.
+
+The \l{Extending QML - Extension Objects Example}{Extension Objects Example}
+demonstrates a usage of extension objects.
+
+
\section1 Defining QML-Specific Types and Attributes
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index e95784dc5c..108b99277f 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -157,8 +157,25 @@
*/
/*!
- \fn int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message)
- \relates QQmlEgine
+ \fn int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
+ \relates QQmlEngine
+
+ This template function registers the C++ type and its extension object in the
+ QML system with the name \a qmlName in the library imported from \a uri having
+ version number composed from \a versionMajor and \a versionMinor. Properties
+ not available in the main type will be searched for in the extension object.
+
+ Returns the QML type id.
+
+ #include <QtQml> to use this function.
+
+ \sa qmlRegisterType(), {Registering Extension Objects}
+*/
+
+
+/*!
+ \fn int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
+ \relates QQmlEngine
This template function registers the C++ type and its extension
in the QML system with the name \a qmlName in the library imported
@@ -180,7 +197,8 @@
/*!
\fn int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, QQmlCustomParser *parser)
- \relates QQmlEgine
+ \relates QQmlEngine
+ \internal
This template function registers the C++ type and its extension
in the QML system with the name \a qmlName in the library imported
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 85bcadd8d2..40c02ef4ee 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -475,3 +475,19 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Heap::Object **
ScopedValue n(scope, name);
return engine()->throwReferenceError(n);
}
+
+Heap::FunctionObject *ExecutionContext::getFunctionObject() const
+{
+ Scope scope(d()->engine);
+ ScopedContext it(scope, this->d());
+ for (; it; it = it->d()->parent) {
+ if (const CallContext *callCtx = it->asCallContext())
+ return callCtx->d()->function;
+ else if (it->asCatchContext() || it->asWithContext())
+ continue; // look in the parent context for a FunctionObject
+ else
+ break;
+ }
+
+ return 0;
+}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index ea2d266146..48319c7444 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -154,6 +154,10 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
inline CallContext *asCallContext();
inline const CallContext *asCallContext() const;
+ inline const CatchContext *asCatchContext() const;
+ inline const WithContext *asWithContext() const;
+
+ Heap::FunctionObject *getFunctionObject() const;
static void markObjects(Heap::Base *m, ExecutionEngine *e);
};
@@ -202,6 +206,16 @@ inline const CallContext *ExecutionContext::asCallContext() const
return d()->type >= Heap::ExecutionContext::Type_SimpleCallContext ? static_cast<const CallContext *>(this) : 0;
}
+inline const CatchContext *ExecutionContext::asCatchContext() const
+{
+ return d()->type == Heap::ExecutionContext::Type_CatchContext ? static_cast<const CatchContext *>(this) : 0;
+}
+
+inline const WithContext *ExecutionContext::asWithContext() const
+{
+ return d()->type == Heap::ExecutionContext::Type_WithContext ? static_cast<const WithContext *>(this) : 0;
+}
+
/* Function *f, int argc */
#define requiredMemoryForExecutionContect(f, argc) \
((sizeof(CallContext::Data) + 7) & ~7) + sizeof(Value) * (f->varCount() + qMax((uint)argc, f->formalParameterCount())) + sizeof(CallData)
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 7f79de3035..4379e3ff94 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -482,6 +482,8 @@ static inline double ParseString(const QString &s)
QDateTime dt = QDateTime::fromString(s, Qt::TextDate);
if (!dt.isValid())
dt = QDateTime::fromString(s, Qt::ISODate);
+ if (!dt.isValid())
+ dt = QDateTime::fromString(s, Qt::RFC2822Date);
if (!dt.isValid()) {
QStringList formats;
formats << QStringLiteral("M/d/yyyy")
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 9361fa1a23..01ee9585c3 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -523,7 +523,6 @@ void Debugger::maybeBreakAtInstruction()
return;
QMutexLocker locker(&m_lock);
- int lineNumber = engine()->currentContext()->lineNumber;
if (m_gatherSources) {
m_gatherSources->run();
@@ -547,8 +546,12 @@ void Debugger::maybeBreakAtInstruction()
if (m_pauseRequested) { // Serve debugging requests from the agent
m_pauseRequested = false;
pauseAndWait(PauseRequest);
- } else if (m_haveBreakPoints && reallyHitTheBreakPoint(getFunction()->sourceFile(), lineNumber)) {
- pauseAndWait(BreakPoint);
+ } else if (m_haveBreakPoints) {
+ if (Function *f = getFunction()) {
+ const int lineNumber = engine()->currentContext()->lineNumber;
+ if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber))
+ pauseAndWait(BreakPoint);
+ }
}
}
@@ -594,12 +597,11 @@ Function *Debugger::getFunction() const
{
Scope scope(m_engine);
ScopedContext context(scope, m_engine->currentContext());
- if (CallContext *callCtx = context->asCallContext())
- return callCtx->d()->function->function;
- else {
- Q_ASSERT(context->d()->type == QV4::Heap::ExecutionContext::Type_GlobalContext);
+ ScopedFunctionObject function(scope, context->getFunctionObject());
+ if (function)
+ return function->function();
+ else
return context->d()->engine->globalCode;
- }
}
void Debugger::pauseAndWait(PauseReason reason)
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 4f8f329e2b..a51ea36351 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -762,21 +762,21 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
QVector<StackFrame> stack;
ScopedContext c(scope, currentContext());
+ ScopedFunctionObject function(scope);
while (c && frameLimit) {
- CallContext *callCtx = c->asCallContext();
- if (callCtx && callCtx->d()->function) {
+ function = c->getFunctionObject();
+ if (function) {
StackFrame frame;
- ScopedFunctionObject function(scope, callCtx->d()->function);
- if (function->function())
- frame.source = function->function()->sourceFile();
+ if (const Function *f = function->function())
+ frame.source = f->sourceFile();
name = function->name();
frame.function = name->toQString();
frame.line = -1;
frame.column = -1;
- if (callCtx->d()->function->function)
+ if (function->function())
// line numbers can be negative for places where you can't set a real breakpoint
- frame.line = qAbs(callCtx->d()->lineNumber);
+ frame.line = qAbs(c->d()->lineNumber);
stack.append(frame);
--frameLimit;
@@ -791,7 +791,6 @@ QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
frame.line = rootContext()->lineNumber;
frame.column = -1;
-
stack.append(frame);
}
return stack;
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 61cd53cd61..687ff19be4 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -69,9 +69,9 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
//
// NOTE: This should match the logic in qv4targetplatform_p.h!
-#if defined(Q_PROCESSOR_X86) && (defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD))
+#if defined(Q_PROCESSOR_X86) && (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD))
#define V4_ENABLE_JIT
-#elif defined(Q_PROCESSOR_X86_64) && (defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD))
+#elif defined(Q_PROCESSOR_X86_64) && (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD))
#define V4_ENABLE_JIT
#elif defined(Q_PROCESSOR_ARM_32)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 7ec66dd0e5..1248991789 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -814,13 +814,17 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
f->call(callData);
if (scope.hasException()) {
+ QQmlError error = v4->catchExceptionAsQmlError();
+ if (error.description().isEmpty()) {
+ QV4::ScopedString name(scope, f->name());
+ error.setDescription(QString::fromLatin1("Unknown exception occurred during evaluation of connected function: %1").arg(name->toQString()));
+ }
if (QQmlEngine *qmlEngine = v4->qmlEngine()) {
- QQmlError error = v4->catchExceptionAsQmlError();
- if (error.description().isEmpty()) {
- QV4::ScopedString name(scope, f->name());
- error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(name->toQString()));
- }
QQmlEnginePrivate::get(qmlEngine)->warning(error);
+ } else {
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).warning().noquote()
+ << error.toString();
}
}
}
diff --git a/src/quick/doc/snippets/qml/itemGrab.qml b/src/quick/doc/snippets/qml/itemGrab.qml
index 4ceaea6133..c8ffd30edc 100644
--- a/src/quick/doc/snippets/qml/itemGrab.qml
+++ b/src/quick/doc/snippets/qml/itemGrab.qml
@@ -70,7 +70,7 @@ Image {
// ...
source.grabToImage(function(result) {
- result.save("something.png");
+ result.saveToFile("something.png");
});
//! [grab-to-file]
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index da4212e5b1..bc5fd8504f 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -4170,13 +4170,35 @@ QQuickContext2DTexture *QQuickContext2D::texture() const
QImage QQuickContext2D::toImage(const QRectF& bounds)
{
- flush();
- if (m_texture->thread() == QThread::currentThread())
- m_texture->grabImage(bounds);
- else if (m_renderStrategy == QQuickCanvasItem::Cooperative) {
+ if (m_texture->thread() == QThread::currentThread()) {
+ // if we're either not rendering to an fbo or we have a separate opengl context we can just
+ // flush. Otherwise we have to make sure the shared opengl context is current before we do
+ // so. It may or may not be current already, depending on how this method is called.
+ if (m_renderTarget != QQuickCanvasItem::FramebufferObject || m_glContext) {
+ flush();
+ m_texture->grabImage(bounds);
+ } else {
+ QQuickWindow *window = m_canvas->window();
+ QOpenGLContext *ctx = window ? window->openglContext() : 0;
+ if (ctx && ctx->isValid()) {
+ if (ctx == QOpenGLContext::currentContext()) {
+ flush();
+ } else {
+ ctx->makeCurrent(window);
+ flush();
+ ctx->doneCurrent();
+ }
+ m_texture->grabImage(bounds);
+ } else {
+ qWarning() << "Cannot read pixels from canvas before opengl context is valid";
+ return QImage();
+ }
+ }
+ } else if (m_renderStrategy == QQuickCanvasItem::Cooperative) {
qWarning() << "Pixel readback is not supported in Cooperative mode, please try Threaded or Immediate mode";
return QImage();
} else {
+ flush();
QCoreApplication::postEvent(m_texture, new QEvent(QEvent::Type(QEvent::User + 10)));
QMetaObject::invokeMethod(m_texture,
"grabImage",
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index 342394a74c..2fc00ad1d7 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -36,6 +36,7 @@
#ifndef QT_NO_MOVIE
+#include <QtGui/qguiapplication.h>
#include <QtQml/qqmlinfo.h>
#include <QtQml/qqmlfile.h>
#include <QtQml/qqmlengine.h>
@@ -293,7 +294,13 @@ void QQuickAnimatedImage::load()
if (isPlaying() != d->oldPlaying)
emit playingChanged();
} else {
- QString lf = QQmlFile::urlToLocalFileOrQrc(d->url);
+ const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio());
+ d->devicePixelRatio = 1.0;
+
+ QUrl loadUrl = d->url;
+ resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
+ QString lf = QQmlFile::urlToLocalFileOrQrc(loadUrl);
+
if (!lf.isEmpty()) {
d->_movie = new QMovie(lf);
movieRequestFinished();
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 87255f4bd9..be86b2976b 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -1166,6 +1166,17 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
}
/*!
+ Returns the y offset when aligning text with a non-1.0 lineHeight
+*/
+int QQuickTextPrivate::lineHeightOffset() const
+{
+ QFontMetricsF fm(font);
+ qreal fontHeight = qCeil(fm.height()); // QScriptLine and therefore QTextLine rounds up
+ return lineHeightMode() == QQuickText::FixedHeight ? fontHeight - lineHeight()
+ : (1.0 - lineHeight()) * fontHeight;
+}
+
+/*!
Ensures the QQuickTextPrivate::doc variable is set to a valid text document
*/
void QQuickTextPrivate::ensureDoc()
@@ -2090,7 +2101,7 @@ QRectF QQuickText::boundingRect() const
QRectF rect = d->layedOutTextRect;
rect.moveLeft(QQuickTextUtil::alignedX(rect.width(), width(), effectiveHAlign()));
- rect.moveTop(QQuickTextUtil::alignedY(rect.height(), height(), d->vAlign));
+ rect.moveTop(QQuickTextUtil::alignedY(rect.height() + d->lineHeightOffset(), height(), d->vAlign));
if (d->style != Normal)
rect.adjust(-1, 0, 1, 2);
@@ -2209,7 +2220,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
d->updateType = QQuickTextPrivate::UpdateNone;
- const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height(), height(), d->vAlign);
+ const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height() + d->lineHeightOffset(), height(), d->vAlign);
QQuickTextNode *node = 0;
if (!oldNode)
@@ -2513,7 +2524,7 @@ QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const
{
Q_Q(const QQuickText);
QPointF translatedMousePos = mousePos;
- translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect.height(), q->height(), vAlign);
+ translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect.height() + lineHeightOffset(), q->height(), vAlign);
if (styledText) {
QString link = anchorAt(&layout, translatedMousePos);
if (link.isEmpty() && elideLayout)
@@ -2597,7 +2608,7 @@ bool QQuickTextPrivate::isLinkHoveredConnected()
\qmlproperty string QtQuick::Text::hoveredLink
\since 5.2
- This property contains the link string when user hovers a link
+ This property contains the link string when the user hovers a link
embedded in the text. The link must be in rich text or HTML format
and the \a hoveredLink string provides access to the particular link.
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 3b83d37899..0acd77aab8 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -76,6 +76,7 @@ public:
bool isLineLaidOutConnected();
void setLineGeometry(QTextLine &line, qreal lineWidth, qreal &height);
+ int lineHeightOffset() const;
QString elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine = 0) const;
void elideFormats(int start, int length, int offset, QList<QTextLayout::FormatRange> *elidedFormats);
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index c46df8f1b0..3446f65c19 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -175,7 +175,7 @@ QQuickTextEdit::QQuickTextEdit(QQuickItem *parent)
QString QQuickTextEdit::text() const
{
Q_D(const QQuickTextEdit);
- if (!d->textCached) {
+ if (!d->textCached && isComponentComplete()) {
QQuickTextEditPrivate *d = const_cast<QQuickTextEditPrivate *>(d_func());
#ifndef QT_NO_TEXTHTMLPARSER
if (d->richText)
@@ -2578,7 +2578,7 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
\qmlproperty string QtQuick::TextEdit::hoveredLink
\since 5.2
- This property contains the link string when user hovers a link
+ This property contains the link string when the user hovers a link
embedded in the text. The link must be in rich text or HTML format
and the link string provides access to the particular link.
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index aef5b4ee79..fd9b2a4480 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -2828,7 +2828,10 @@ void Renderer::visualizeBatch(Batch *b)
g = gn->geometry();
shader->setUniformValue(shader->matrix, matrix * *gn->matrix());
glVertexAttribPointer(a.position, a.tupleSize, a.type, false, g->sizeOfVertex(), (void *) (qintptr) offset);
- glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), g->indexData());
+ if (g->indexCount())
+ glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), g->indexData());
+ else
+ glDrawArrays(g->drawingMode(), 0, g->vertexCount());
offset += g->sizeOfVertex() * g->vertexCount();
e = e->nextInBatch;
}
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 58d618a049..9f74e259e3 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -437,7 +437,7 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
d->fireFrameSwapped();
qCDebug(QSG_LOG_TIME_RENDERLOOP()).nospace()
- << "Frame rendered with 'windows' renderloop in: " << time_swapped << "ms"
+ << "Frame rendered with 'windows' renderloop in: " << (time_swapped - time_start) / 1000000 << "ms"
<< ", polish=" << (time_polished - time_start) / 1000000
<< ", sync=" << (time_synced - time_polished) / 1000000
<< ", render=" << (time_rendered - time_synced) / 1000000
diff --git a/src/quick/scenegraph/shaders/visualization.frag b/src/quick/scenegraph/shaders/visualization.frag
index 6cfeac1985..458d9dde14 100644
--- a/src/quick/scenegraph/shaders/visualization.frag
+++ b/src/quick/scenegraph/shaders/visualization.frag
@@ -6,6 +6,6 @@ varying mediump vec2 pos;
void main(void)
{
lowp vec4 c = color;
- c.xyz += pow(max(sin(pos.x + pos.y), 0.0), 2.0) * pattern * 0.1;
+ c.xyz += pow(max(sin(pos.x + pos.y), 0.0), 2.0) * pattern * 0.25;
gl_FragColor = c;
}
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 83fe586cb8..6143e4ef0d 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -246,6 +246,11 @@ QImage QQuickWidgetPrivate::grabFramebuffer()
return renderControl->grab();
}
+QObject *QQuickWidgetPrivate::focusObject()
+{
+ return offscreenWindow ? offscreenWindow->focusObject() : 0;
+}
+
/*!
\module QtQuickWidgets
\title Qt Quick Widgets C++ Classes
@@ -1086,6 +1091,9 @@ bool QQuickWidget::event(QEvent *e)
e->accept();
return true;
#endif
+ case QEvent::InputMethod:
+ case QEvent::InputMethodQuery:
+
case QEvent::TouchBegin:
case QEvent::TouchEnd:
case QEvent::TouchUpdate:
diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h
index 2ff9601f77..57782a6492 100644
--- a/src/quickwidgets/qquickwidget_p.h
+++ b/src/quickwidgets/qquickwidget_p.h
@@ -81,6 +81,8 @@ public:
void destroyContext();
void handleContextCreationFailure(const QSurfaceFormat &format, bool isEs);
+ QObject *focusObject() Q_DECL_OVERRIDE;
+
GLuint textureId() const Q_DECL_OVERRIDE;
QImage grabFramebuffer() Q_DECL_OVERRIDE;
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 13e60fefd9..9f86c8e4e1 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -175,6 +175,7 @@ private slots:
void privateMethods();
void engineForObject();
+ void intConversion_QTBUG43309();
signals:
void testSignal();
@@ -3639,6 +3640,16 @@ void tst_QJSEngine::engineForObject()
QVERIFY(!qjsEngine(&object));
}
+void tst_QJSEngine::intConversion_QTBUG43309()
+{
+ // This failed in the interpreter:
+ QJSEngine engine;
+ QString jsCode = "var n = 0.1; var m = (n*255) | 0; m";
+ QJSValue result = engine.evaluate( jsCode );
+ QVERIFY(result.isNumber());
+ QCOMPARE(result.toNumber(), 25.0);
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
diff --git a/tests/auto/qml/qqmlecmascript/data/date.qml b/tests/auto/qml/qqmlecmascript/data/date.qml
index 0dcba71ae3..41dcaafa33 100644
--- a/tests/auto/qml/qqmlecmascript/data/date.qml
+++ b/tests/auto/qml/qqmlecmascript/data/date.qml
@@ -17,4 +17,10 @@ Item {
var dt = new Date("");
return isNaN(dt);
}
+
+ function test_rfc2822_date()
+ {
+ var dt = new Date("Wed, 18 Sep 2013 07:00:51 -0700");
+ return dt.getTime();
+ }
}
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index e137f6b042..8b95770312 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -7360,7 +7360,8 @@ void tst_qqmlecmascript::dateParse()
QMetaObject::invokeMethod(object, "test_is_invalid_qtDateTime", Q_RETURN_ARG(QVariant, q));
QVERIFY(q.toBool() == true);
-
+ QMetaObject::invokeMethod(object, "test_rfc2822_date", Q_RETURN_ARG(QVariant, q));
+ QCOMPARE(q.toLongLong(), 1379512851000LL);
}
void tst_qqmlecmascript::utcDate()
diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
index 70e6739aff..628cd143cf 100644
--- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
@@ -287,6 +287,8 @@ private slots:
// exceptions:
void pauseOnThrow();
+ void breakInCatch();
+ void breakInWith();
void evaluateExpression();
@@ -613,6 +615,42 @@ void tst_qv4debugger::pauseOnThrow()
QCOMPARE(m_debuggerAgent->m_thrownValue.toString(), QString("hard"));
}
+void tst_qv4debugger::breakInCatch()
+{
+ QString script =
+ "try {\n"
+ " throw 'catch...'\n"
+ "} catch (e) {\n"
+ " console.log(e, 'me');\n"
+ "}\n";
+
+ m_debuggerAgent->addBreakPoint("breakInCatch", 4);
+ evaluateJavaScript(script, "breakInCatch");
+ QVERIFY(m_debuggerAgent->m_wasPaused);
+ QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint);
+ QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1);
+ QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
+ QCOMPARE(state.fileName, QString("breakInCatch"));
+ QCOMPARE(state.lineNumber, 4);
+}
+
+void tst_qv4debugger::breakInWith()
+{
+ QString script =
+ "with (42) {\n"
+ " console.log('give the answer');\n"
+ "}\n";
+
+ m_debuggerAgent->addBreakPoint("breakInWith", 2);
+ evaluateJavaScript(script, "breakInWith");
+ QVERIFY(m_debuggerAgent->m_wasPaused);
+ QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint);
+ QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1);
+ QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first();
+ QCOMPARE(state.fileName, QString("breakInWith"));
+ QCOMPARE(state.lineNumber, 2);
+}
+
void tst_qv4debugger::evaluateExpression()
{
QString script =
diff --git a/tests/auto/quick/nokeywords/tst_nokeywords.cpp b/tests/auto/quick/nokeywords/tst_nokeywords.cpp
index 1a20649b2d..ddd9dccf4f 100644
--- a/tests/auto/quick/nokeywords/tst_nokeywords.cpp
+++ b/tests/auto/quick/nokeywords/tst_nokeywords.cpp
@@ -87,7 +87,13 @@ Q_SIGNALS:
void mySignal();
public Q_SLOTS:
- inline void mySlot() { mySignal(); }
+ inline void mySlot()
+ {
+ Q_UNUSED(signals);
+ Q_UNUSED(slots);
+
+ mySignal();
+ }
private:
int signals;
diff --git a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
index db69020589..83c678214d 100644
--- a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
+++ b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
@@ -113,7 +113,7 @@ void tst_qquickpixmapcache::initTestCase()
// This avoids a race condition/deadlock bug in network config
// manager when it is accessed by the HTTP server thread before
// anything else. Bug report can be found at:
- // https://bugreports.qt-project.org/browse/QTBUG-26355
+ // QTBUG-26355
QNetworkConfigurationManager cm;
cm.updateConfigurations();
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index 4f10b4ce82..c61504ef99 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -201,6 +201,7 @@ private slots:
void emptytags_QTBUG_22058();
void cursorRectangle_QTBUG_38947();
+ void textCached_QTBUG_41583();
private:
void simulateKeys(QWindow *window, const QList<Key> &keys);
@@ -5302,6 +5303,17 @@ void tst_qquicktextedit::cursorRectangle_QTBUG_38947()
QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, to);
}
+void tst_qquicktextedit::textCached_QTBUG_41583()
+{
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nTextEdit { property int margin: 10; text: \"TextEdit\"; textMargin: margin; property bool empty: !text; }", QUrl());
+ QQuickTextEdit *textedit = qobject_cast<QQuickTextEdit*>(component.create());
+ QVERIFY(textedit);
+ QCOMPARE(textedit->textMargin(), qreal(10.0));
+ QCOMPARE(textedit->text(), QString("TextEdit"));
+ QVERIFY(!textedit->property("empty").toBool());
+}
+
QTEST_MAIN(tst_qquicktextedit)
#include "tst_qquicktextedit.moc"
diff --git a/tests/testapplications/elements/content/BugPanel.qml b/tests/testapplications/elements/content/BugPanel.qml
index 48de12ab15..fcbdd941bc 100644
--- a/tests/testapplications/elements/content/BugPanel.qml
+++ b/tests/testapplications/elements/content/BugPanel.qml
@@ -37,7 +37,7 @@ Rectangle {
property string urltext
urltext: "<a href=\"" + bugreports + bugnumber + "\">QTBUG-" + bugnumber + "</a>"
property string bugnumber: ""
- property string bugreports: "http://bugreports.qt-project.org/browse/QTBUG-"
+ property string bugreports: "http://bugreports.qt.io/browse/QTBUG-"
visible: opacity != 0
opacity: bugnumber == "" ? 0 : 1
Behavior on opacity { NumberAnimation { duration: 1500 } }
diff --git a/tools/qmljs/qmljs.cpp b/tools/qmljs/qmljs.cpp
index c9765c57df..f4a561fac6 100644
--- a/tools/qmljs/qmljs.cpp
+++ b/tools/qmljs/qmljs.cpp
@@ -166,7 +166,7 @@ int main(int argc, char *argv[])
}
if (args.first() == QLatin1String("--help")) {
- std::cerr << "Usage: qmljs [|--debug|-d] [|--jit|--interpret|--compile|--aot|--llvm-jit] file..." << std::endl;
+ std::cerr << "Usage: qmljs [|--jit|--interpret|--qml] file..." << std::endl;
return EXIT_SUCCESS;
}
}