diff options
Diffstat (limited to 'src/qml')
19 files changed, 308 insertions, 110 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 9731f3bc12..61b538e726 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1622,7 +1622,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases() QQmlPropertyData *targetProperty = resolver.property(property.toString()); if (!targetProperty || targetProperty->coreIndex > 0x0000FFFF) { - recordError(p->aliasLocation, tr("Invalid alias location")); + recordError(p->aliasLocation, tr("Invalid alias target location: %1").arg(property.toString())); return false; } @@ -1636,7 +1636,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases() if (!subProperty.isEmpty()) { const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(type); if (!valueTypeMetaObject) { - recordError(p->aliasLocation, tr("Invalid alias location")); + recordError(p->aliasLocation, tr("Invalid alias target location: %1").arg(subProperty.toString())); return false; } @@ -1645,7 +1645,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases() int valueTypeIndex = valueTypeMetaObject->indexOfProperty(subProperty.toString().toUtf8().constData()); if (valueTypeIndex == -1) { - recordError(p->aliasLocation, tr("Invalid alias location")); + recordError(p->aliasLocation, tr("Invalid alias target location: %1").arg(subProperty.toString())); return false; } Q_ASSERT(valueTypeIndex <= 0x0000FFFF); diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index a0ed77ffc1..e61a602e64 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -81,16 +81,129 @@ static void showMeTheCode(IR::Function *function, const char *marker) } } -class ProcessedBlocks +#if !defined(BROKEN_STD_VECTOR_BOOL_OR_BROKEN_STD_FIND) +// Sanity: +class BitVector { - QBitArray processed; + std::vector<bool> bits; public: - ProcessedBlocks(IR::Function *function) + BitVector(int size = 0, bool value = false) + : bits(size, value) + {} + + void reserve(int size) + { bits.reserve(size); } + + int size() const { - processed = QBitArray(function->basicBlockCount(), false); + Q_ASSERT(bits.size() < INT_MAX); + return static_cast<int>(bits.size()); } + void resize(int newSize) + { bits.resize(newSize); } + + void assign(int newSize, bool value) + { bits.assign(newSize, value); } + + int findNext(int start, bool value, bool wrapAround) const + { + // The ++operator of std::vector<bool>::iterator in libc++ has a bug when using it on an + // iterator pointing to the last element. It will not be set to ::end(), but beyond + // that. (It will be set to the first multiple of the native word size that is bigger + // than size().) + // + // See http://llvm.org/bugs/show_bug.cgi?id=19663 + // + // The work-around is to calculate the distance, and compare it to the size() to see if it's + // beyond the end, or take the minimum of the distance and the size. + + size_t pos = std::distance(bits.begin(), + std::find(bits.begin() + start, bits.end(), value)); + if (wrapAround && pos >= static_cast<size_t>(size())) + pos = std::distance(bits.begin(), + std::find(bits.begin(), bits.begin() + start, value)); + + pos = qMin(pos, static_cast<size_t>(size())); + + Q_ASSERT(pos <= static_cast<size_t>(size())); + Q_ASSERT(pos < INT_MAX); + + return static_cast<int>(pos); + } + + bool at(int idx) const + { return bits.at(idx); } + + void setBit(int idx) + { bits[idx] = true; } + + void clearBit(int idx) + { bits[idx] = false; } +}; +#else // Insanity: +class BitVector +{ + QBitArray bits; + +public: + BitVector(int size = 0, bool value = false) + : bits(size, value) + {} + + void reserve(int size) + { Q_UNUSED(size); } + + int size() const + { return bits.size(); } + + void resize(int newSize) + { bits.resize(newSize); } + + void assign(int newSize, bool value) + { + bits.resize(newSize); + bits.fill(value); + } + + int findNext(int start, bool value, bool wrapAround) const + { + for (int i = start, ei = size(); i < ei; ++i) { + if (at(i) == value) + return i; + } + + if (wrapAround) { + for (int i = 0, ei = start; i < ei; ++i) { + if (at(i) == value) + return i; + } + } + + return size(); + } + + bool at(int idx) const + { return bits.at(idx); } + + void setBit(int idx) + { bits[idx] = true; } + + void clearBit(int idx) + { bits[idx] = false; } +}; +#endif + +class ProcessedBlocks +{ + BitVector processed; + +public: + ProcessedBlocks(IR::Function *function) + : processed(function->basicBlockCount(), false) + {} + bool alreadyProcessed(BasicBlock *bb) const { Q_ASSERT(bb); @@ -106,7 +219,7 @@ public: class BasicBlockSet { - typedef std::vector<bool> Flags; + typedef BitVector Flags; QVarLengthArray<int, 8> blockNumbers; Flags *blockFlags; @@ -119,7 +232,7 @@ public: const BasicBlockSet &set; // ### These two members could go into a union, but clang won't compile (https://codereview.qt-project.org/#change,74259) QVarLengthArray<int, 8>::const_iterator numberIt; - size_t flagIt; + int flagIt; friend class BasicBlockSet; const_iterator(const BasicBlockSet &set, bool end) @@ -138,24 +251,9 @@ public: } } - void findNextWithFlags(size_t start) + void findNextWithFlags(int start) { - flagIt = std::distance(set.blockFlags->begin(), - std::find(set.blockFlags->begin() + start, - set.blockFlags->end(), - true)); - - // The ++operator of std::vector<bool>::iterator in libc++ has a bug when using it on an - // iterator pointing to the last element. It will not be set to ::end(), but beyond - // that. (It will be set to the first multiple of the native word size that is bigger - // than size().) - // - // See http://llvm.org/bugs/show_bug.cgi?id=19663 - // - // As we use the size to for our end() iterator, take the minimum of the size and the - // distance for the flagIt: - flagIt = qMin(flagIt, set.blockFlags->size()); - + flagIt = set.blockFlags->findNext(start, true, /*wrapAround = */false); Q_ASSERT(flagIt <= set.blockFlags->size()); } @@ -165,8 +263,8 @@ public: if (!set.blockFlags) { return set.function->basicBlock(*numberIt); } else { - Q_ASSERT(flagIt <= static_cast<size_t>(set.function->basicBlockCount())); - return set.function->basicBlock(static_cast<int>(flagIt)); + Q_ASSERT(flagIt <= set.function->basicBlockCount()); + return set.function->basicBlock(flagIt); } } @@ -256,7 +354,7 @@ public: Q_ASSERT(function); if (blockFlags) { - (*blockFlags)[bb->index()] = true; + blockFlags->setBit(bb->index()); return; } @@ -268,10 +366,10 @@ public: if (blockNumbers.size() == MaxVectorCapacity) { blockFlags = new Flags(function->basicBlockCount(), false); for (int i = 0; i < blockNumbers.size(); ++i) { - blockFlags->operator[](blockNumbers[i]) = true; + blockFlags->setBit(blockNumbers[i]); } blockNumbers.clear(); - blockFlags->operator[](bb->index()) = true; + blockFlags->setBit(bb->index()); } else { blockNumbers.append(bb->index()); } @@ -282,7 +380,7 @@ public: Q_ASSERT(function); if (blockFlags) { - (*blockFlags)[bb->index()] = false; + blockFlags->clearBit(bb->index()); return; } @@ -310,7 +408,7 @@ public: Q_ASSERT(function); if (blockFlags) - return (*blockFlags)[bb->index()]; + return blockFlags->at(bb->index()); for (int i = 0; i < blockNumbers.size(); ++i) { if (blockNumbers[i] == bb->index()) @@ -539,12 +637,12 @@ public: np.todo = children[nodeIndex]; } - std::vector<bool> DF_done(function->basicBlockCount(), false); + BitVector DF_done(function->basicBlockCount(), false); while (!worklist.empty()) { BasicBlockIndex node = worklist.back(); - if (DF_done[node]) { + if (DF_done.at(node)) { worklist.pop_back(); continue; } @@ -552,7 +650,7 @@ public: NodeProgress &np = nodeStatus[node]; std::vector<BasicBlockIndex>::iterator it = np.todo.begin(); while (it != np.todo.end()) { - if (DF_done[*it]) { + if (DF_done.at(*it)) { it = np.todo.erase(it); } else { worklist.push_back(*it); @@ -575,7 +673,7 @@ public: S.insert(w); } } - DF_done[node] = true; + DF_done.setBit(node); worklist.pop_back(); } } @@ -914,8 +1012,8 @@ class VariableCollector: public StmtVisitor, ExprVisitor { std::vector<Temp> _allTemps; std::vector<BasicBlockSet> _defsites; std::vector<std::vector<int> > A_orig; - std::vector<bool> nonLocals; - std::vector<bool> killed; + BitVector nonLocals; + BitVector killed; BasicBlock *currentBB; bool isCollectable(Temp *t) const @@ -979,8 +1077,8 @@ public: bool isNonLocal(const Temp &var) const { Q_ASSERT(!var.isInvalid()); - Q_ASSERT(var.index < nonLocals.size()); - return nonLocals[var.index]; + Q_ASSERT(static_cast<int>(var.index) < nonLocals.size()); + return nonLocals.at(var.index); } protected: @@ -1025,7 +1123,7 @@ protected: addDefInCurrentBlock(t); // For semi-pruned SSA: - killed[t->index] = true; + killed.setBit(t->index); } } else { s->target->accept(this); @@ -1037,8 +1135,8 @@ protected: addTemp(t); if (isCollectable(t)) - if (!killed[t->index]) - nonLocals[t->index] = true; + if (!killed.at(t->index)) + nonLocals.setBit(t->index); } }; @@ -1619,7 +1717,7 @@ void convertToSSA(IR::Function *function, const DominatorTree &df, DefUses &defU VariableCollector variables(function); // Prepare for phi node insertion: - std::vector<std::vector<bool> > A_phi; + std::vector<BitVector > A_phi; const size_t ei = function->basicBlockCount(); A_phi.resize(ei); for (size_t i = 0; i != ei; ++i) @@ -1646,7 +1744,7 @@ void convertToSSA(IR::Function *function, const DominatorTree &df, DefUses &defU BasicBlock *y = *it; if (!A_phi.at(y->index()).at(a.index)) { insertPhiNode(a, y, function); - A_phi[y->index()].at(a.index) = true; + A_phi[y->index()].setBit(a.index); const std::vector<int> &varsInBlockY = variables.inBlock(y); if (std::find(varsInBlockY.begin(), varsInBlockY.end(), a.index) == varsInBlockY.end()) W.push_back(y); @@ -1723,10 +1821,10 @@ class StatementWorklist { IR::Function *theFunction; std::vector<Stmt *> stmts; - std::vector<bool> worklist; + BitVector worklist; unsigned worklistSize; std::vector<int> replaced; - std::vector<bool> removed; + BitVector removed; Q_DISABLE_COPY(StatementWorklist) @@ -1750,7 +1848,7 @@ public: continue; stmts[s->id()] = s; - worklist[s->id()] = true; + worklist.setBit(s->id()); ++worklistSize; } } @@ -1765,7 +1863,7 @@ public: if (!s) continue; - worklist[s->id()] = true; + worklist.setBit(s->id()); ++worklistSize; } @@ -1776,10 +1874,9 @@ public: void remove(Stmt *stmt) { replaced[stmt->id()] = Stmt::InvalidId; - removed[stmt->id()] = true; - std::vector<bool>::reference inWorklist = worklist[stmt->id()]; - if (inWorklist) { - inWorklist = false; + removed.setBit(stmt->id()); + if (worklist.at(stmt->id())) { + worklist.clearBit(stmt->id()); Q_ASSERT(worklistSize > 0); --worklistSize; } @@ -1789,15 +1886,15 @@ public: { Q_ASSERT(oldStmt); Q_ASSERT(replaced[oldStmt->id()] == Stmt::InvalidId); - Q_ASSERT(removed[oldStmt->id()] == false); + Q_ASSERT(removed.at(oldStmt->id()) == false); Q_ASSERT(newStmt); registerNewStatement(newStmt); Q_ASSERT(replaced[newStmt->id()] == Stmt::InvalidId); - Q_ASSERT(removed[newStmt->id()] == false); + Q_ASSERT(removed.at(newStmt->id()) == false); replaced[oldStmt->id()] = newStmt->id(); - worklist[oldStmt->id()] = false; + worklist.clearBit(oldStmt->id()); } void applyToFunction() @@ -1818,7 +1915,7 @@ public: Q_ASSERT(id != Stmt::InvalidId); Q_ASSERT(static_cast<unsigned>(stmt->id()) < stmts.size()); - if (removed[id]) { + if (removed.at(id)) { bb->removeStatement(i); } else { if (id != stmt->id()) @@ -1847,10 +1944,10 @@ public: return *this; Q_ASSERT(s->id() >= 0); - Q_ASSERT(static_cast<unsigned>(s->id()) < worklist.size()); + Q_ASSERT(s->id() < worklist.size()); - if (!worklist[s->id()]) { - worklist[s->id()] = true; + if (!worklist.at(s->id())) { + worklist.setBit(s->id()); ++worklistSize; } @@ -1860,11 +1957,10 @@ public: StatementWorklist &operator-=(Stmt *s) { Q_ASSERT(s->id() >= 0); - Q_ASSERT(static_cast<unsigned>(s->id()) < worklist.size()); + Q_ASSERT(s->id() < worklist.size()); - std::vector<bool>::reference inWorklist = worklist[s->id()]; - if (inWorklist) { - inWorklist = false; + if (worklist.at(s->id())) { + worklist.clearBit(s->id()); Q_ASSERT(worklistSize > 0); --worklistSize; } @@ -1884,18 +1980,13 @@ public: const int startAt = last ? last->id() + 1 : 0; Q_ASSERT(startAt >= 0); - Q_ASSERT(static_cast<unsigned>(startAt) <= worklist.size()); + Q_ASSERT(startAt <= worklist.size()); - Q_ASSERT(worklist.size() == stmts.size()); + Q_ASSERT(static_cast<size_t>(worklist.size()) == stmts.size()); - // Do not compare the result of find with the end iterator, because some libc++ versions - // have a bug where the result of the ++operator is past-the-end of the vector, but unequal - // to end(). - size_t pos = std::find(worklist.begin() + startAt, worklist.end(), true) - worklist.begin(); - if (pos >= worklist.size()) - pos = std::find(worklist.begin(), worklist.begin() + startAt, true) - worklist.begin(); + int pos = worklist.findNext(startAt, true, /*wrapAround = */true); - worklist[pos] = false; + worklist.clearBit(pos); Q_ASSERT(worklistSize > 0); --worklistSize; Stmt *s = stmts.at(pos); @@ -1917,9 +2008,9 @@ public: int newSize = s->id() + 1; stmts.resize(newSize, 0); - worklist.resize(newSize, false); + worklist.resize(newSize); replaced.resize(newSize, Stmt::InvalidId); - removed.resize(newSize, false); + removed.resize(newSize); } stmts[s->id()] = s; @@ -1928,7 +2019,8 @@ public: private: void grow() { - size_t newCapacity = ((stmts.capacity() + 1) * 3) / 2; + Q_ASSERT(stmts.capacity() < INT_MAX / 2); + int newCapacity = ((static_cast<int>(stmts.capacity()) + 1) * 3) / 2; stmts.reserve(newCapacity); worklist.reserve(newCapacity); replaced.reserve(newCapacity); diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h index 421c6968b9..58afa004a0 100644 --- a/src/qml/debugger/qqmldebug.h +++ b/src/qml/debugger/qqmldebug.h @@ -42,8 +42,13 @@ QT_BEGIN_NAMESPACE struct Q_QML_EXPORT QQmlDebuggingEnabler { + enum StartMode { + DoNotWaitForClient, + WaitForClient + }; + QQmlDebuggingEnabler(bool printWarning = true); - static bool startTcpDebugServer(int port, bool block = false, + static bool startTcpDebugServer(int port, StartMode mode = DoNotWaitForClient, const QString &hostName = QString()); static bool connectToLocalDebugger(const QString &socketFileName, bool block = false); }; diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp index 7323d3bf46..0e6a182b1a 100644 --- a/src/qml/debugger/qqmldebugserver.cpp +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -835,18 +835,29 @@ bool QQmlDebugServerPrivate::enable(Action action) } /*! + * \enum QQmlDebuggingEnabler::StartMode + * + * Defines the debug server's start behavior. You can interrupt QML engines starting while a debug + * client is connecting, in order to set breakpoints in or profile startup code. + * + * \value DoNotWaitForClient Run any QML engines as usual while the debug services are connecting. + * \value WaitForClient If a QML engine starts while the debug services are connecting, + * interrupt it until they are done. + */ + +/*! * Enables debugging for QML engines created after calling this function. The debug server will * listen on \a port at \a hostName and block the QML engine until it receives a connection if - * \a block is true. If \a block is not specified it won't block and if \a hostName isn't specified - * it will listen on all available interfaces. You can only start one debug server at a time. A - * debug server may have already been started if the -qmljsdebugger= command line argument was - * given. This method returns \c true if a new debug server was successfully started, or \c false - * otherwise. + * \a mode is \c WaitForClient. If \a mode is not specified it won't block and if \a hostName is not + * specified it will listen on all available interfaces. You can only start one debug server at a + * time. A debug server may have already been started if the -qmljsdebugger= command line argument + * was given. This method returns \c true if a new debug server was successfully started, or + * \c false otherwise. */ -bool QQmlDebuggingEnabler::startTcpDebugServer(int port, bool block, const QString &hostName) +bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const QString &hostName) { #ifndef QQML_NO_DEBUG_PROTOCOL - return QQmlDebugServerPrivate::enable(StartTcpServerAction(port, port, block, hostName)); + return QQmlDebugServerPrivate::enable(StartTcpServerAction(port, port, mode == WaitForClient, hostName)); #else Q_UNUSED(port); Q_UNUSED(block); diff --git a/src/qml/doc/snippets/qml/createQmlObject.qml b/src/qml/doc/snippets/qml/createQmlObject.qml index a6753823b9..b12c6c2ea5 100644 --- a/src/qml/doc/snippets/qml/createQmlObject.qml +++ b/src/qml/doc/snippets/qml/createQmlObject.qml @@ -49,7 +49,8 @@ Rectangle { function createIt() { //![0] var newObject = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20}', - parentItem, "dynamicSnippet1"); + parentItem, + "dynamicSnippet1"); //![0] //![destroy] diff --git a/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.js b/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.js index 0073e4df8f..814e0b444f 100644 --- a/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.js +++ b/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.js @@ -42,7 +42,8 @@ Qt.include("factorial.js") function showCalculations(value) { - console.log("Call factorial() from script.js:", + console.log( + "Call factorial() from script.js:", factorial(value)); } //![0] diff --git a/src/qml/doc/src/cppintegration/contextproperties.qdoc b/src/qml/doc/src/cppintegration/contextproperties.qdoc index 48532ccae2..83f49bdcf0 100644 --- a/src/qml/doc/src/cppintegration/contextproperties.qdoc +++ b/src/qml/doc/src/cppintegration/contextproperties.qdoc @@ -65,10 +65,13 @@ QML code invokes a method on the object instance: \table \row +\li C++ \li \snippet qml/qtbinding/context-advanced/applicationdata.h 0 \codeline \snippet qml/qtbinding/context-advanced/main.cpp 0 +\row +\li QML \li \snippet qml/qtbinding/context-advanced/MyItem.qml 0 \endtable diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index a11d8ba510..e153ca3d8b 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -176,7 +176,10 @@ converted to JavaScript array and object values, repectively: \table \header \row +\li QML \li \snippet qml/qtbinding/variantlistmap/MyItem.qml 0 +\row +\li C++ \li \snippet qml/qtbinding/variantlistmap/main.cpp 0 \endtable @@ -223,7 +226,7 @@ Item { } } \endqml - +\row \li \code // C++ diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc index 0d81930592..e1db5c9d57 100644 --- a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc +++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc @@ -395,6 +395,7 @@ methods, as shown below right: \table \row +\li C++ \li \code int main(int argc, char *argv[]) { @@ -409,6 +410,8 @@ methods, as shown below right: return app.exec(); } \endcode +\row +\li QML \li \qml // MyItem.qml diff --git a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc index 25d98dbc0d..2a644cafff 100644 --- a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc +++ b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc @@ -170,7 +170,10 @@ QMetaObject::invokeMethod(): \table \row +\li QML \li \snippet qml/qtbinding/functions-qml/MyItem.qml 0 +\row +\li C++ \li \snippet qml/qtbinding/functions-qml/main.cpp 0 \endtable @@ -195,6 +198,7 @@ QObject::connect(), so that the \c cppSlot() method is called whenever the \row \li \snippet qml/qtbinding/signals-qml/MyItem.qml 0 +\row \li \snippet qml/qtbinding/signals-qml/myclass.h 0 \codeline @@ -235,8 +239,10 @@ QVariant type: void cppSlot(const QVariant &v) { qDebug() << "Called the C++ slot with value:" << v; - QQuickItem *item = qobject_cast<QQuickItem*>(v.value<QObject*>()); - qDebug() << "Item dimensions:" << item->width() << item->height(); + QQuickItem *item = + qobject_cast<QQuickItem*>(v.value<QObject*>()); + qDebug() << "Item dimensions:" << item->width() + << item->height(); } }; diff --git a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc index 2988f3a684..acd7188db7 100644 --- a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc +++ b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc @@ -143,6 +143,15 @@ If the string of QML imports files using relative paths, the path should be relative to the file in which the parent object (the second argument to the method) is defined. +\important When building static QML applications, which is enforced on platforms like iOS, +QML files are scanned to detect import dependencies. That way, all +necessary plugins and resources are resolved at compile time. +However, only explicit import statements are considered (those found at +the top of a QML file), and not import statements enclosed within string literals. +To support static builds, you therefore need to ensure that QML files +using \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}, +explicitly contain all necessary imports at the top of the file in addition +to inside the string literals. \section1 Maintaining Dynamically Created Objects @@ -191,10 +200,10 @@ destroy itself: \table \row \li \c application.qml -\li \c SelfDestroyingRect.qml +\li \snippet qml/dynamicObjects-destroy.qml 0 \row -\li \snippet qml/dynamicObjects-destroy.qml 0 +\li \c SelfDestroyingRect.qml \li \snippet qml/SelfDestroyingRect.qml 0 \endtable diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc index ed73a2b9ba..201cee16e6 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc @@ -46,7 +46,7 @@ documentation about A \c qmldir file is a plain-text file that contains the following commands: -\table +\table 70% \header \li Syntax \li Usage diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc index 48f7ba1bae..31133c862f 100644 --- a/src/qml/doc/src/qmltypereference.qdoc +++ b/src/qml/doc/src/qmltypereference.qdoc @@ -208,6 +208,9 @@ Or use the \l{QtQml::Qt::rect()}{Qt.rect()} function: CustomObject { myRectProperty: Qt.rect(50, 50, 100, 100) } \endqml +The \c rect type also exposes read-only \c left, \c right, \c top and \c bottom +attributes. These are the same as their \l {QRectF}{C++ counterparts}. + When integrating with C++, note that any QRect or QRectF value \l{qtqml-cppintegration-data.html}{passed into QML from C++} is automatically converted into a \c rect value, and vice-versa. When a \c rect value is passed to C++, it diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index 49b284b979..a90e8e3689 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -199,10 +199,7 @@ InternalClass *InternalClass::nonExtensible() if (!extensible) return this; - Transition temp; - temp.lookup = 0; - temp.flags = Transition::NotExtensible; - + Transition temp = { Q_NULLPTR, Q_NULLPTR, Transition::NotExtensible}; Transition &t = lookupOrInsertTransition(temp); if (t.lookup) return t.lookup; diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 425c5e507c..d46f612e40 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -246,9 +246,9 @@ V4_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension); \table \row \li MyItem.qml - \li main.qml - \row \li \snippet qml/component/MyItem.qml 0 + \row + \li main.qml \li \snippet qml/component/main.qml 0 \endtable */ diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index cc4a9bebc5..7ebfcd64b7 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -388,6 +388,26 @@ void QQmlRectFValueType::setHeight(qreal h) v.setHeight(h); } +qreal QQmlRectFValueType::left() const +{ + return v.left(); +} + +qreal QQmlRectFValueType::right() const +{ + return v.right(); +} + +qreal QQmlRectFValueType::top() const +{ + return v.top(); +} + +qreal QQmlRectFValueType::bottom() const +{ + return v.bottom(); +} + int QQmlRectValueType::x() const { return v.x(); @@ -428,6 +448,25 @@ void QQmlRectValueType::setHeight(int h) v.setHeight(h); } +int QQmlRectValueType::left() const +{ + return v.left(); +} + +int QQmlRectValueType::right() const +{ + return v.right(); +} + +int QQmlRectValueType::top() const +{ + return v.top(); +} + +int QQmlRectValueType::bottom() const +{ + return v.bottom(); +} QQmlEasingValueType::Type QQmlEasingValueType::type() const { diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index 0dcf78c519..abd73d7f35 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -153,6 +153,10 @@ struct QQmlRectFValueType Q_PROPERTY(qreal y READ y WRITE setY FINAL) Q_PROPERTY(qreal width READ width WRITE setWidth FINAL) Q_PROPERTY(qreal height READ height WRITE setHeight FINAL) + Q_PROPERTY(qreal left READ left DESIGNABLE false FINAL) + Q_PROPERTY(qreal right READ right DESIGNABLE false FINAL) + Q_PROPERTY(qreal top READ top DESIGNABLE false FINAL) + Q_PROPERTY(qreal bottom READ bottom DESIGNABLE false FINAL) Q_GADGET public: Q_INVOKABLE QString toString() const; @@ -165,6 +169,11 @@ public: qreal height() const; void setWidth(qreal); void setHeight(qreal); + + qreal left() const; + qreal right() const; + qreal top() const; + qreal bottom() const; }; struct QQmlRectValueType @@ -174,6 +183,10 @@ struct QQmlRectValueType Q_PROPERTY(int y READ y WRITE setY FINAL) Q_PROPERTY(int width READ width WRITE setWidth FINAL) Q_PROPERTY(int height READ height WRITE setHeight FINAL) + Q_PROPERTY(int left READ left DESIGNABLE false FINAL) + Q_PROPERTY(int right READ right DESIGNABLE false FINAL) + Q_PROPERTY(int top READ top DESIGNABLE false FINAL) + Q_PROPERTY(int bottom READ bottom DESIGNABLE false FINAL) Q_GADGET public: int x() const; @@ -185,6 +198,11 @@ public: int height() const; void setWidth(int); void setHeight(int); + + int left() const; + int right() const; + int top() const; + int bottom() const; }; struct QQmlEasingValueType diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 58b6937432..b0ab85199d 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -314,10 +314,12 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) const QMetaObject *mo = w->d()->propertyCache->metaObject(); const int propCount = mo->propertyCount(); for (int i = 0; i < propCount; ++i) { - QVariant value = mo->property(i).readOnGadget(w->d()->gadgetPtr); - result += value.toString(); - if (i < propCount - 1) - result += QStringLiteral(", "); + if (mo->property(i).isDesignable()) { + QVariant value = mo->property(i).readOnGadget(w->d()->gadgetPtr); + if (i > 0) + result += QLatin1String(", "); + result += value.toString(); + } } result += QLatin1Char(')'); } diff --git a/src/qml/types/qqmlitemselectionmodel.qdoc b/src/qml/types/qqmlitemselectionmodel.qdoc index 7a61416153..185ffb5fa4 100644 --- a/src/qml/types/qqmlitemselectionmodel.qdoc +++ b/src/qml/types/qqmlitemselectionmodel.qdoc @@ -50,22 +50,31 @@ /*! \qmlproperty bool ItemSelectionModel::hasSelection + \readonly - Read-only property. It will trigger property binding updates every time - \l selectionChanged() is emitted, even though its value hasn't changed. + It will trigger property binding updates every time \l selectionChanged() + is emitted, even though its value hasn't changed. \sa selection(), selectedIndexes(), select(), selectionChanged() */ /*! \qmlproperty QModelIndex ItemSelectionModel::currentIndex + \readonly - Read-only property. Use \l setCurrentIndex() to set its value. + Use \l setCurrentIndex() to set its value. \sa setCurrentIndex(), currentChanged() */ /*! + \qmlproperty QModelIndexList ItemSelectionModel::selectedIndexes + \readonly + + Contains the list of all the indexes in the selection model. +*/ + +/*! \qmlmethod bool ItemSelectionModel::isSelected(QModelIndex index) */ @@ -86,10 +95,6 @@ */ /*! - \qmlmethod QModelIndexList ItemSelectionModel::selectedIndexes() -*/ - -/*! \qmlmethod QModelIndexList ItemSelectionModel::selectedRows(int column) */ |