diff options
author | Eike Ziller <eike.ziller@qt.io> | 2019-02-28 12:39:09 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2019-02-28 12:39:09 +0100 |
commit | eeaa02bc2726141ff71cc63d7ab4112461adbcd5 (patch) | |
tree | c5b451826704fee90f399b614c4a5d56ca2b660d | |
parent | b9e26fcd376e0002e8f24abbd0baa94642025a1b (diff) | |
parent | 04aac85e2623395d4c6ed4d88a5dc1b8a1103649 (diff) | |
download | qt-creator-eeaa02bc2726141ff71cc63d7ab4112461adbcd5.tar.gz |
Merge remote-tracking branch 'origin/4.8' into 4.9
Conflicts:
src/plugins/android/androidbuildapkstep.cpp
Change-Id: Id6dfda480c23706089ab38aa6277cd37599b5167
-rw-r--r-- | dist/changes-4.8.2.md | 13 | ||||
-rw-r--r-- | share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp | 4 | ||||
-rw-r--r-- | src/libs/cplusplus/pp-engine.cpp | 14 | ||||
-rw-r--r-- | src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp | 2 | ||||
-rw-r--r-- | src/plugins/clangcodemodel/clangdiagnosticfilter.h | 2 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermainwindow.cpp | 24 | ||||
-rw-r--r-- | src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp | 236 | ||||
-rw-r--r-- | src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h | 17 | ||||
-rw-r--r-- | src/plugins/qmldesigner/designercore/model/rewriterview.cpp | 11 | ||||
-rw-r--r-- | src/shared/proparser/ioutils.cpp | 4 | ||||
-rw-r--r-- | src/tools/clangbackend/source/clangtooltipinfocollector.cpp | 5 | ||||
-rw-r--r-- | src/tools/clangbackend/source/clangtype.cpp | 5 | ||||
-rw-r--r-- | src/tools/clangbackend/source/clangtype.h | 1 |
13 files changed, 263 insertions, 75 deletions
diff --git a/dist/changes-4.8.2.md b/dist/changes-4.8.2.md index 22a930d9a4..ef7316c7c7 100644 --- a/dist/changes-4.8.2.md +++ b/dist/changes-4.8.2.md @@ -7,6 +7,10 @@ you can check out from the public Git repository. For example: git clone git://code.qt.io/qt-creator/qt-creator.git git log --cherry-pick --pretty=oneline origin/v4.8.1..v4.8.2 +General + +* Fixed UI for choosing executable for external tools (QTCREATORBUG-21937) + Editing * Fixed highlighting of search results of regular expression search @@ -20,6 +24,10 @@ Autotools Projects C++ Support * Fixed crash when expanding macros (QTCREATORBUG-21642) +* Fixed crash in preprocessor (QTCREATORBUG-21981) +* Fixed infinite loop when resolving pointer types (QTCREATORBUG-22010) +* Fixed cursor position after completion of functions without arguments + (QTCREATORBUG-21841) QML Support @@ -38,6 +46,7 @@ Debugging Qt Quick Designer * Added support for more JavaScript functions in `.ui.qml` files +* Fixed crash with gradients and Qt Quick 5.12 (QDS-472) Test Integration @@ -55,16 +64,20 @@ macOS Android * Fixed upload of GDB server on some devices (QTCREATORBUG-21317) +* Fixed crash on exiting debugger (QTCREATORBUG-21684) Credits for these changes go to: +Andre Hartmann André Pönitz Christian Kandeler Christian Stenger David Schulz Eike Ziller Ivan Donchevskii +Kirill Burtsev Leena Miettinen Liang Qi +Nikolai Kosjar Oliver Wolff Raoul Hecky Robert Löhning diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp index c13781558c..dd4a0adbd1 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -267,13 +267,13 @@ static bool isList(const QQmlProperty &property) static bool isQJSValue(const QQmlProperty &property) { - return !strcmp(property.propertyTypeName(), "QJSValue"); + return property.isValid() && !strcmp(property.propertyTypeName(), "QJSValue"); } static bool isObject(const QQmlProperty &property) { /* QVariant and QJSValue can also store QObjects. Lets trust our model. */ - return (property.propertyTypeCategory() == QQmlProperty::Object + return property.isValid() && (property.propertyTypeCategory() == QQmlProperty::Object || !strcmp(property.propertyTypeName(), "QVariant") || isQJSValue(property)); } diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index a4bfea10b4..f8874101fe 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -764,7 +764,7 @@ QByteArray Preprocessor::run(const QString &fileName, preprocessed.reserve(source.size() * 2); // multiply by 2 because we insert #gen lines. preprocess(fileName, source, &preprocessed, &includeGuardMacroName, noLines, markGeneratedTokens, false); - if (!includeGuardMacroName.isEmpty()) + if (m_client && !includeGuardMacroName.isEmpty()) m_client->markAsIncludeGuard(includeGuardMacroName); return preprocessed; } @@ -986,10 +986,12 @@ bool Preprocessor::handleIdentifier(PPToken *tk) if (!expandFunctionlikeMacros() // Still expand if this originally started with an object-like macro. && m_state.m_expansionStatus != Expanding) { - m_client->notifyMacroReference(m_state.m_bytesOffsetRef + idTk.byteOffset, - m_state.m_utf16charsOffsetRef + idTk.utf16charOffset, - idTk.lineno, - *macro); + if (m_client) { + m_client->notifyMacroReference(m_state.m_bytesOffsetRef + idTk.byteOffset, + m_state.m_utf16charsOffsetRef + idTk.utf16charOffset, + idTk.lineno, + *macro); + } return false; } @@ -1793,7 +1795,7 @@ void Preprocessor::handleDefineDirective(PPToken *tk) } } } else if (macroReference) { - if (tk->is(T_LPAREN)) { + if (m_client && tk->is(T_LPAREN)) { m_client->notifyMacroReference(previousBytesOffset, previousUtf16charsOffset, previousLine, *macroReference); } diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index d00d488586..db34c904d4 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -86,7 +86,7 @@ static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterf const QString &name) { auto *item = static_cast<ClangAssistProposalItem *>(sameItem); - item->setHasOverloadsWithParameters(true); + item->setHasOverloadsWithParameters(codeCompletion.hasParameters); if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind) { // It's the constructor, currently constructor definitions do not lead here. // CLANG-UPGRADE-CHECK: Can we get here with constructor definition? diff --git a/src/plugins/clangcodemodel/clangdiagnosticfilter.h b/src/plugins/clangcodemodel/clangdiagnosticfilter.h index 0fe164ecf0..a61734718e 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticfilter.h +++ b/src/plugins/clangcodemodel/clangdiagnosticfilter.h @@ -49,7 +49,7 @@ private: void filterFixits(); private: - const QString &m_filePath; + const QString m_filePath; QVector<ClangBackEnd::DiagnosticContainer> m_warningDiagnostics; QVector<ClangBackEnd::DiagnosticContainer> m_errorDiagnostics; diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index 12371975f8..a5da08055b 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -372,24 +372,16 @@ void DebuggerMainWindowPrivate::fixupLayoutIfNeeded() { // Evil workaround for QTCREATORBUG-21455: In some so far unknown situation // the saveLayout/restoreLayout process leads to a situation where some docks - // does not end up below the perspective toolbar even though they were there + // do not end up below the perspective toolbar even though they were there // initially, leading to an awkward dock layout. - // This here tries to detect the situation (no other dock directly below the - // toolbar) and "corrects" that by restoring the default layout. - const QRect toolbarRect = m_toolBarDock->geometry(); - const int targetX = toolbarRect.left(); - const int targetY = toolbarRect.bottom(); - - const QList<QDockWidget *> docks = q->dockWidgets(); - for (QDockWidget *dock : docks) { - const QRect dockRect = dock->geometry(); - // 10 for some decoration wiggle room. Found something below? Good. - if (targetX == dockRect.left() && qAbs(targetY - dockRect.top()) < 10) - return; - } + // This here tries to detect the situation (sonmething else in the bottom + // area is at the right of the toolbar) "corrects" that by restoring the + // default layout. - qDebug() << "Scrambled dock layout found. Resetting it."; - resetCurrentPerspective(); + if (m_toolBarDock->width() != q->width()) { + qDebug() << "Scrambled dock layout found. Resetting it."; + resetCurrentPerspective(); + } } void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective) diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp index aa7cfe1bb0..b2e25fa6d6 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp @@ -28,6 +28,7 @@ #include "qmlanchorbindingproxy.h" #include "propertyeditorview.h" +#include <exception.h> #include <nodeproperty.h> #include <nodelistproperty.h> #include <variantproperty.h> @@ -35,8 +36,11 @@ #include <nodemetainfo.h> #include <rewritertransaction.h> +#include <utils/qtcassert.h> + GradientModel::GradientModel(QObject *parent) : QAbstractListModel(parent), m_locked(false) + ,m_gradientTypeName("Gradient") { } @@ -101,28 +105,29 @@ int GradientModel::addStop(qreal position, const QColor &color) return -1; if (m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) { - //QmlDesigner::RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(); - //### TODO does not work + int properPos = 0; + try { - QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); + QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); - QmlDesigner::ModelNode gradientStopNode = - m_itemNode.modelNode().view()->createModelNode("QtQuick.GradientStop", - m_itemNode.modelNode().view()->majorQtQuickVersion(), 0); - gradientStopNode.variantProperty("position").setValue(position); - gradientStopNode.variantProperty("color").setValue(color); - gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); + QmlDesigner::ModelNode gradientStopNode = createGradientStopNode(); - const QList<QmlDesigner::ModelNode> stopNodes = gradientNode.nodeListProperty("stops").toModelNodeList(); + gradientStopNode.variantProperty("position").setValue(position); + gradientStopNode.variantProperty("color").setValue(color); + gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); - int properPos = 0; - for (int i = 0; i < stopNodes.count(); i++) { - if (QmlDesigner::QmlObjectNode(stopNodes.at(i)).modelValue("position").toReal() < position) - properPos = i + 1; - } - gradientNode.nodeListProperty("stops").slide(stopNodes.count() - 1, properPos); + const QList<QmlDesigner::ModelNode> stopNodes = gradientNode.nodeListProperty("stops").toModelNodeList(); - setupModel(); + for (int i = 0; i < stopNodes.count(); i++) { + if (QmlDesigner::QmlObjectNode(stopNodes.at(i)).modelValue("position").toReal() < position) + properPos = i + 1; + } + gradientNode.nodeListProperty("stops").slide(stopNodes.count() - 1, properPos); + + setupModel(); + } catch (const QmlDesigner::Exception &e) { + e.showException(); + } return properPos; } @@ -139,38 +144,38 @@ void GradientModel::addGradient() return; if (!m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) { + try { + + QColor color = m_itemNode.instanceValue("color").value<QColor>(); - QColor color = m_itemNode.instanceValue("color").value<QColor>(); + if (!color.isValid()) + color = QColor(Qt::white); - if (!color.isValid()) - color = QColor(Qt::white); + QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::addGradient")); - QmlDesigner::RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::addGradient")); + QmlDesigner::ModelNode gradientNode = createGradientNode(); - QmlDesigner::ModelNode gradientNode = - m_itemNode.modelNode().view()->createModelNode("QtQuick.Gradient", - m_itemNode.modelNode().view()->majorQtQuickVersion(), 0); - m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).reparentHere(gradientNode); + m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).reparentHere(gradientNode); + QmlDesigner::ModelNode gradientStopNode = createGradientStopNode(); + gradientStopNode.variantProperty("position").setValue(0.0); + gradientStopNode.variantProperty("color").setValue(color); + gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); - QmlDesigner::ModelNode gradientStopNode = - m_itemNode.modelNode().view()->createModelNode("QtQuick.GradientStop", - m_itemNode.modelNode().view()->majorQtQuickVersion(), 0); - gradientStopNode.variantProperty("position").setValue(0.0); - gradientStopNode.variantProperty("color").setValue(color); - gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); + gradientStopNode = createGradientStopNode(); + gradientStopNode.variantProperty("position").setValue(1.0); + gradientStopNode.variantProperty("color").setValue(QColor(Qt::black)); + gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); - gradientStopNode = m_itemNode.modelNode().view()->createModelNode( - "QtQuick.GradientStop", - m_itemNode.modelNode().view()->majorQtQuickVersion(), 0); - gradientStopNode.variantProperty("position").setValue(1.0); - gradientStopNode.variantProperty("color").setValue(QColor(Qt::black)); - gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); + } catch (const QmlDesigner::Exception &e) { + e.showException(); + } } setupModel(); emit hasGradientChanged(); + emit gradientTypeChanged(); } void GradientModel::setColor(int index, const QColor &color) @@ -231,7 +236,7 @@ qreal GradientModel::getPosition(int index) const void GradientModel::removeStop(int index) { if (index < rowCount() - 1 && index != 0) { - QmlDesigner::RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::removeStop")); + QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::removeStop")); QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); QmlDesigner::QmlObjectNode stop = gradientNode.nodeListProperty("stops").at(index); if (stop.isValid()) { @@ -255,7 +260,7 @@ void GradientModel::deleteGradient() if (m_itemNode.isInBaseState()) { if (modelNode.hasProperty(gradientPropertyName().toUtf8())) { - QmlDesigner::RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::deleteGradient")); + QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::deleteGradient")); QmlDesigner::ModelNode gradientNode = modelNode.nodeProperty(gradientPropertyName().toUtf8()).modelNode(); if (QmlDesigner::QmlObjectNode(gradientNode).isValid()) QmlDesigner::QmlObjectNode(gradientNode).destroy(); @@ -263,6 +268,7 @@ void GradientModel::deleteGradient() } emit hasGradientChanged(); + emit gradientTypeChanged(); } void GradientModel::lock() @@ -280,6 +286,22 @@ void GradientModel::registerDeclarativeType() qmlRegisterType<GradientModel>("HelperWidgets",2,0,"GradientModel"); } +qreal GradientModel::readGradientProperty(const QString &propertyName) const +{ + if (!m_itemNode.isValid()) + return 0; + + QmlDesigner::QmlObjectNode gradient; + + if (m_itemNode.modelNode().hasProperty(gradientPropertyName().toUtf8())) + gradient = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); + + if (!gradient.isValid()) + return 0; + + return gradient.modelValue(propertyName.toUtf8()).toReal(); +} + void GradientModel::setupModel() { m_locked = true; @@ -299,12 +321,17 @@ void GradientModel::setAnchorBackend(const QVariant &anchorBackend) if (backendCasted) m_itemNode = backendCasted->getItemNode(); + if (m_itemNode.isValid() + && m_itemNode.modelNode().hasProperty(gradientPropertyName().toUtf8())) + m_gradientTypeName = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode().simplifiedTypeName(); + setupModel(); m_locked = true; emit anchorBackendChanged(); emit hasGradientChanged(); + emit gradientTypeChanged(); m_locked = false; } @@ -319,6 +346,16 @@ void GradientModel::setGradientPropertyName(const QString &name) m_gradientPropertyName = name; } +QString GradientModel::gradientTypeName() const +{ + return m_gradientTypeName; +} + +void GradientModel::setGradientTypeName(const QString &name) +{ + m_gradientTypeName = name; +} + bool GradientModel::hasGradient() const { return m_itemNode.isValid() @@ -330,10 +367,125 @@ bool GradientModel::locked() const if (m_locked) return true; - auto view = qobject_cast<QmlDesigner::PropertyEditorView*>(m_itemNode.view()); + auto editorView = qobject_cast<QmlDesigner::PropertyEditorView*>(view()); - if (view && view->locked()) - return true; + return editorView && editorView->locked(); +} + +bool GradientModel::hasShapesImport() const +{ + if (m_itemNode.isValid()) { + QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick.Shapes", "1.0"); + return model()->hasImport(import, true, true); + } return false; } + +void GradientModel::ensureShapesImport() +{ + if (!hasShapesImport()) { + QmlDesigner::Import timelineImport = QmlDesigner::Import::createLibraryImport("QtQuick.Shapes", "1.0"); + model()->changeImports({timelineImport}, {}); + } +} + +void GradientModel::setupGradientProperties(const QmlDesigner::ModelNode &gradient) +{ + QTC_ASSERT(m_itemNode.isValid(), return); + + QTC_ASSERT(gradient.isValid(), return); + + if (m_gradientTypeName == "Gradient") { + } else if (m_gradientTypeName == "LinearGradient") { + gradient.variantProperty("x1").setValue(0); + gradient.variantProperty("x2").setValue(m_itemNode.instanceValue("width")); + gradient.variantProperty("y1").setValue(0); + gradient.variantProperty("y2").setValue(m_itemNode.instanceValue("height")); + } else if (m_gradientTypeName == "RadialGradient") { + qreal width = m_itemNode.instanceValue("width").toReal(); + qreal height = m_itemNode.instanceValue("height").toReal(); + gradient.variantProperty("centerX").setValue(width / 2.0); + gradient.variantProperty("centerY").setValue(height / 2.0); + + gradient.variantProperty("focalX").setValue(width / 2.0); + gradient.variantProperty("focalY").setValue(height / 2.0); + + qreal radius = qMin(width, height) / 2; + + gradient.variantProperty("centerRadius").setValue(radius); + gradient.variantProperty("focalRadius").setValue(0); + + } else if (m_gradientTypeName == "ConicalGradient") { + qreal width = m_itemNode.instanceValue("width").toReal(); + qreal height = m_itemNode.instanceValue("height").toReal(); + gradient.variantProperty("centerX").setValue(width / 2.0); + gradient.variantProperty("centerY").setValue(height / 2.0); + + gradient.variantProperty("angle").setValue(0); + } +} + +QmlDesigner::Model *GradientModel::model() const +{ + QTC_ASSERT(m_itemNode.isValid(), return nullptr); + return m_itemNode.view()->model(); +} + +QmlDesigner::AbstractView *GradientModel::view() const +{ + QTC_ASSERT(m_itemNode.isValid(), return nullptr); + return m_itemNode.view(); +} + +QmlDesigner::ModelNode GradientModel::createGradientNode() +{ + QByteArray fullTypeName = m_gradientTypeName.toUtf8(); + + if (m_gradientTypeName == "Gradient") { + fullTypeName.prepend("QtQuick."); + } else { + fullTypeName.prepend("QtQuick.Shapes."); + ensureShapesImport(); + } + + auto metaInfo = model()->metaInfo(fullTypeName); + + int minorVersion = metaInfo.minorVersion(); + int majorVersion = metaInfo.majorVersion(); + + auto gradientNode = view()->createModelNode(fullTypeName, majorVersion, minorVersion); + + setupGradientProperties(gradientNode); + + return gradientNode; +} + +QmlDesigner::ModelNode GradientModel::createGradientStopNode() +{ + QByteArray fullTypeName = "QtQuick.GradientStop"; + auto metaInfo = model()->metaInfo(fullTypeName); + + int minorVersion = metaInfo.minorVersion(); + int majorVersion = metaInfo.majorVersion(); + + return view()->createModelNode(fullTypeName, majorVersion, minorVersion); +} + +void GradientModel::setGradientProperty(const QString &propertyName, qreal value) +{ + QTC_ASSERT(m_itemNode.isValid(), return); + + QmlDesigner::QmlObjectNode gradient; + + if (m_itemNode.modelNode().hasProperty(gradientPropertyName().toUtf8())) + gradient = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); + + QTC_ASSERT(gradient.isValid(), return); + + try { + gradient.setVariantProperty(propertyName.toUtf8(), value); + } catch (const QmlDesigner::Exception &e) { + e.showException(); + } +} diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h index 2ca8b93c42..48514ae688 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h +++ b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h @@ -37,6 +37,7 @@ class GradientModel : public QAbstractListModel Q_PROPERTY(QVariant anchorBackendProperty READ anchorBackend WRITE setAnchorBackend NOTIFY anchorBackendChanged) Q_PROPERTY(QString gradientPropertyName READ gradientPropertyName WRITE setGradientPropertyName) + Q_PROPERTY(QString gradientTypeName READ gradientTypeName WRITE setGradientTypeName NOTIFY gradientTypeChanged) Q_PROPERTY(int count READ rowCount) Q_PROPERTY(bool hasGradient READ hasGradient NOTIFY hasGradientChanged) @@ -65,9 +66,14 @@ public: static void registerDeclarativeType(); + Q_INVOKABLE qreal readGradientProperty(const QString &property) const; + + Q_INVOKABLE void setGradientProperty(const QString &propertyName, qreal value); + signals: void anchorBackendChanged(); void hasGradientChanged(); + void gradientTypeChanged(); private: void setupModel(); @@ -75,14 +81,23 @@ private: QVariant anchorBackend() const {return QVariant(); } QString gradientPropertyName() const; void setGradientPropertyName(const QString &name); + QString gradientTypeName() const; + void setGradientTypeName(const QString &name); bool hasGradient() const; bool locked() const; + QmlDesigner::ModelNode createGradientNode(); + QmlDesigner::ModelNode createGradientStopNode(); private: QmlDesigner::QmlItemNode m_itemNode; QString m_gradientPropertyName; + QString m_gradientTypeName; bool m_locked; - + bool hasShapesImport() const; + void ensureShapesImport(); + void setupGradientProperties(const QmlDesigner::ModelNode &gradient); + QmlDesigner::Model *model() const; + QmlDesigner::AbstractView *view() const; }; QML_DECLARE_TYPE(GradientModel) diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index f4cd9c7e79..2b22844bb9 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -486,6 +486,8 @@ QString RewriterView::auxiliaryDataAsQML() const QString str = "Designer {\n "; + QTC_ASSERT(!m_canonicalIntModelNode.isEmpty(), return {}); + int columnCount = 0; for (const auto &node : allModelNodes()) { QHash<PropertyName, QVariant> data = node.auxiliaryData(); @@ -727,8 +729,11 @@ void RewriterView::setupCanonicalHashes() const using myPair = std::pair<ModelNode,int>; std::vector<myPair> data; - for (const ModelNode &node : allModelNodes()) - data.emplace_back(std::make_pair(node, nodeOffset(node))); + for (const ModelNode &node : allModelNodes()) { + int offset = nodeOffset(node); + QTC_ASSERT(offset > 0, qDebug() << Q_FUNC_INFO << "no offset" << node; return); + data.emplace_back(std::make_pair(node, offset)); + } std::sort(data.begin(), data.end(), [](myPair a, myPair b) { return a.second < b.second; @@ -1066,6 +1071,8 @@ void RewriterView::restoreAuxiliaryData() setupCanonicalHashes(); + QTC_ASSERT(!m_canonicalIntModelNode.isEmpty(), return); + const QString text = m_textModifier->text(); int startIndex = text.indexOf(annotationsStart()); diff --git a/src/shared/proparser/ioutils.cpp b/src/shared/proparser/ioutils.cpp index f678ea9fb0..302811cac4 100644 --- a/src/shared/proparser/ioutils.cpp +++ b/src/shared/proparser/ioutils.cpp @@ -106,8 +106,8 @@ QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName) return QDir::cleanPath(fileName); #ifdef Q_OS_WIN // Add drive to otherwise-absolute path: if (fileName.at(0).unicode() == '/' || fileName.at(0).unicode() == '\\') { - Q_ASSERT(isAbsolutePath(baseDir)); - return QDir::cleanPath(baseDir.left(2) + fileName); + return isAbsolutePath(baseDir) ? QDir::cleanPath(baseDir.left(2) + fileName) + : QDir::cleanPath(fileName); } #endif // Q_OS_WIN return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName); diff --git a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp index 8eb15eb89e..beecf63bb6 100644 --- a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp +++ b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp @@ -36,6 +36,7 @@ #include <clangsupport/sourcerangecontainer.h> #include <utils/qtcassert.h> #include <utils/textfileformat.h> +#include <utils/qtcassert.h> #include <utf8string.h> @@ -392,7 +393,7 @@ static bool isBuiltinOrPointerToBuiltin(const Type &type) // TODO: Simplify // TODO: Test with ** - while (theType.pointeeType().isValid()) { + while (theType.pointeeType().isValid() && theType != theType.pointeeType()) { theType = theType.pointeeType(); if (theType.isBuiltinType()) return true; @@ -436,7 +437,7 @@ ToolTipInfo ToolTipInfoCollector::qDocInfo(const Cursor &cursor) const } Type type = cursor.type(); - while (type.pointeeType().isValid()) + while (type.pointeeType().isValid() && type != type.pointeeType()) type = type.pointeeType(); const Cursor typeCursor = type.declaration(); diff --git a/src/tools/clangbackend/source/clangtype.cpp b/src/tools/clangbackend/source/clangtype.cpp index 46ed23d54c..af58f71595 100644 --- a/src/tools/clangbackend/source/clangtype.cpp +++ b/src/tools/clangbackend/source/clangtype.cpp @@ -245,6 +245,11 @@ bool operator==(Type first, Type second) return clang_equalTypes(first.m_cxType, second.m_cxType); } +bool operator!=(Type first, Type second) +{ + return !operator==(first, second); +} + std::ostream &operator<<(std::ostream &os, CXTypeKind typeKind) { ClangString typeKindSpelling(clang_getTypeKindSpelling(typeKind)); diff --git a/src/tools/clangbackend/source/clangtype.h b/src/tools/clangbackend/source/clangtype.h index ed6977ee73..53953392e3 100644 --- a/src/tools/clangbackend/source/clangtype.h +++ b/src/tools/clangbackend/source/clangtype.h @@ -81,6 +81,7 @@ private: }; bool operator==(Type first, Type second); +bool operator!=(Type first, Type second); std::ostream &operator<<(std::ostream &os, CXTypeKind typeKind); std::ostream &operator<<(std::ostream &os, const Type &type); |