Merge "Merge remote-tracking branch 'origin/4.8' into 4.9" into 4.9

This commit is contained in:
Eike Ziller
2019-02-28 13:32:06 +00:00
committed by The Qt Project
13 changed files with 265 additions and 77 deletions

13
dist/changes-4.8.2.md vendored
View File

@@ -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 clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline origin/v4.8.1..v4.8.2 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 Editing
* Fixed highlighting of search results of regular expression search * Fixed highlighting of search results of regular expression search
@@ -20,6 +24,10 @@ Autotools Projects
C++ Support C++ Support
* Fixed crash when expanding macros (QTCREATORBUG-21642) * 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 QML Support
@@ -38,6 +46,7 @@ Debugging
Qt Quick Designer Qt Quick Designer
* Added support for more JavaScript functions in `.ui.qml` files * Added support for more JavaScript functions in `.ui.qml` files
* Fixed crash with gradients and Qt Quick 5.12 (QDS-472)
Test Integration Test Integration
@@ -55,16 +64,20 @@ macOS
Android Android
* Fixed upload of GDB server on some devices (QTCREATORBUG-21317) * Fixed upload of GDB server on some devices (QTCREATORBUG-21317)
* Fixed crash on exiting debugger (QTCREATORBUG-21684)
Credits for these changes go to: Credits for these changes go to:
Andre Hartmann
André Pönitz André Pönitz
Christian Kandeler Christian Kandeler
Christian Stenger Christian Stenger
David Schulz David Schulz
Eike Ziller Eike Ziller
Ivan Donchevskii Ivan Donchevskii
Kirill Burtsev
Leena Miettinen Leena Miettinen
Liang Qi Liang Qi
Nikolai Kosjar
Oliver Wolff Oliver Wolff
Raoul Hecky Raoul Hecky
Robert Löhning Robert Löhning

View File

@@ -267,13 +267,13 @@ static bool isList(const QQmlProperty &property)
static bool isQJSValue(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) static bool isObject(const QQmlProperty &property)
{ {
/* QVariant and QJSValue can also store QObjects. Lets trust our model. */ /* 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") || !strcmp(property.propertyTypeName(), "QVariant")
|| isQJSValue(property)); || isQJSValue(property));
} }

View File

@@ -764,7 +764,7 @@ QByteArray Preprocessor::run(const QString &fileName,
preprocessed.reserve(source.size() * 2); // multiply by 2 because we insert #gen lines. preprocessed.reserve(source.size() * 2); // multiply by 2 because we insert #gen lines.
preprocess(fileName, source, &preprocessed, &includeGuardMacroName, noLines, preprocess(fileName, source, &preprocessed, &includeGuardMacroName, noLines,
markGeneratedTokens, false); markGeneratedTokens, false);
if (!includeGuardMacroName.isEmpty()) if (m_client && !includeGuardMacroName.isEmpty())
m_client->markAsIncludeGuard(includeGuardMacroName); m_client->markAsIncludeGuard(includeGuardMacroName);
return preprocessed; return preprocessed;
} }
@@ -986,10 +986,12 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
if (!expandFunctionlikeMacros() if (!expandFunctionlikeMacros()
// Still expand if this originally started with an object-like macro. // Still expand if this originally started with an object-like macro.
&& m_state.m_expansionStatus != Expanding) { && m_state.m_expansionStatus != Expanding) {
if (m_client) {
m_client->notifyMacroReference(m_state.m_bytesOffsetRef + idTk.byteOffset, m_client->notifyMacroReference(m_state.m_bytesOffsetRef + idTk.byteOffset,
m_state.m_utf16charsOffsetRef + idTk.utf16charOffset, m_state.m_utf16charsOffsetRef + idTk.utf16charOffset,
idTk.lineno, idTk.lineno,
*macro); *macro);
}
return false; return false;
} }
@@ -1793,7 +1795,7 @@ void Preprocessor::handleDefineDirective(PPToken *tk)
} }
} }
} else if (macroReference) { } else if (macroReference) {
if (tk->is(T_LPAREN)) { if (m_client && tk->is(T_LPAREN)) {
m_client->notifyMacroReference(previousBytesOffset, previousUtf16charsOffset, m_client->notifyMacroReference(previousBytesOffset, previousUtf16charsOffset,
previousLine, *macroReference); previousLine, *macroReference);
} }

View File

@@ -86,7 +86,7 @@ static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterf
const QString &name) const QString &name)
{ {
auto *item = static_cast<ClangAssistProposalItem *>(sameItem); auto *item = static_cast<ClangAssistProposalItem *>(sameItem);
item->setHasOverloadsWithParameters(true); item->setHasOverloadsWithParameters(codeCompletion.hasParameters);
if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind) { if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind) {
// It's the constructor, currently constructor definitions do not lead here. // It's the constructor, currently constructor definitions do not lead here.
// CLANG-UPGRADE-CHECK: Can we get here with constructor definition? // CLANG-UPGRADE-CHECK: Can we get here with constructor definition?

View File

@@ -49,7 +49,7 @@ private:
void filterFixits(); void filterFixits();
private: private:
const QString &m_filePath; const QString m_filePath;
QVector<ClangBackEnd::DiagnosticContainer> m_warningDiagnostics; QVector<ClangBackEnd::DiagnosticContainer> m_warningDiagnostics;
QVector<ClangBackEnd::DiagnosticContainer> m_errorDiagnostics; QVector<ClangBackEnd::DiagnosticContainer> m_errorDiagnostics;

View File

@@ -372,24 +372,16 @@ void DebuggerMainWindowPrivate::fixupLayoutIfNeeded()
{ {
// Evil workaround for QTCREATORBUG-21455: In some so far unknown situation // Evil workaround for QTCREATORBUG-21455: In some so far unknown situation
// the saveLayout/restoreLayout process leads to a situation where some docks // 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. // initially, leading to an awkward dock layout.
// This here tries to detect the situation (no other dock directly below the // This here tries to detect the situation (sonmething else in the bottom
// toolbar) and "corrects" that by restoring the default layout. // area is at the right of the toolbar) "corrects" that by restoring the
const QRect toolbarRect = m_toolBarDock->geometry(); // default layout.
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;
}
if (m_toolBarDock->width() != q->width()) {
qDebug() << "Scrambled dock layout found. Resetting it."; qDebug() << "Scrambled dock layout found. Resetting it.";
resetCurrentPerspective(); resetCurrentPerspective();
}
} }
void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective) void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective)

View File

@@ -28,6 +28,7 @@
#include "qmlanchorbindingproxy.h" #include "qmlanchorbindingproxy.h"
#include "propertyeditorview.h" #include "propertyeditorview.h"
#include <exception.h>
#include <nodeproperty.h> #include <nodeproperty.h>
#include <nodelistproperty.h> #include <nodelistproperty.h>
#include <variantproperty.h> #include <variantproperty.h>
@@ -35,8 +36,11 @@
#include <nodemetainfo.h> #include <nodemetainfo.h>
#include <rewritertransaction.h> #include <rewritertransaction.h>
#include <utils/qtcassert.h>
GradientModel::GradientModel(QObject *parent) : GradientModel::GradientModel(QObject *parent) :
QAbstractListModel(parent), m_locked(false) QAbstractListModel(parent), m_locked(false)
,m_gradientTypeName("Gradient")
{ {
} }
@@ -101,21 +105,19 @@ int GradientModel::addStop(qreal position, const QColor &color)
return -1; return -1;
if (m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) { if (m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) {
//QmlDesigner::RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(); int properPos = 0;
//### TODO does not work try {
QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode();
QmlDesigner::ModelNode gradientStopNode = QmlDesigner::ModelNode gradientStopNode = createGradientStopNode();
m_itemNode.modelNode().view()->createModelNode("QtQuick.GradientStop",
m_itemNode.modelNode().view()->majorQtQuickVersion(), 0);
gradientStopNode.variantProperty("position").setValue(position); gradientStopNode.variantProperty("position").setValue(position);
gradientStopNode.variantProperty("color").setValue(color); gradientStopNode.variantProperty("color").setValue(color);
gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
const QList<QmlDesigner::ModelNode> stopNodes = gradientNode.nodeListProperty("stops").toModelNodeList(); const QList<QmlDesigner::ModelNode> stopNodes = gradientNode.nodeListProperty("stops").toModelNodeList();
int properPos = 0;
for (int i = 0; i < stopNodes.count(); i++) { for (int i = 0; i < stopNodes.count(); i++) {
if (QmlDesigner::QmlObjectNode(stopNodes.at(i)).modelValue("position").toReal() < position) if (QmlDesigner::QmlObjectNode(stopNodes.at(i)).modelValue("position").toReal() < position)
properPos = i + 1; properPos = i + 1;
@@ -123,6 +125,9 @@ int GradientModel::addStop(qreal position, const QColor &color)
gradientNode.nodeListProperty("stops").slide(stopNodes.count() - 1, properPos); gradientNode.nodeListProperty("stops").slide(stopNodes.count() - 1, properPos);
setupModel(); setupModel();
} catch (const QmlDesigner::Exception &e) {
e.showException();
}
return properPos; return properPos;
} }
@@ -139,38 +144,38 @@ void GradientModel::addGradient()
return; return;
if (!m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) { 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()) if (!color.isValid())
color = QColor(Qt::white); color = QColor(Qt::white);
QmlDesigner::RewriterTransaction transaction = m_itemNode.modelNode().view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::addGradient")); QmlDesigner::RewriterTransaction transaction = 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();
QmlDesigner::ModelNode gradientStopNode =
m_itemNode.modelNode().view()->createModelNode("QtQuick.GradientStop",
m_itemNode.modelNode().view()->majorQtQuickVersion(), 0);
gradientStopNode.variantProperty("position").setValue(0.0); gradientStopNode.variantProperty("position").setValue(0.0);
gradientStopNode.variantProperty("color").setValue(color); gradientStopNode.variantProperty("color").setValue(color);
gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
gradientStopNode = m_itemNode.modelNode().view()->createModelNode( gradientStopNode = createGradientStopNode();
"QtQuick.GradientStop",
m_itemNode.modelNode().view()->majorQtQuickVersion(), 0);
gradientStopNode.variantProperty("position").setValue(1.0); gradientStopNode.variantProperty("position").setValue(1.0);
gradientStopNode.variantProperty("color").setValue(QColor(Qt::black)); gradientStopNode.variantProperty("color").setValue(QColor(Qt::black));
gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
} catch (const QmlDesigner::Exception &e) {
e.showException();
}
} }
setupModel(); setupModel();
emit hasGradientChanged(); emit hasGradientChanged();
emit gradientTypeChanged();
} }
void GradientModel::setColor(int index, const QColor &color) void GradientModel::setColor(int index, const QColor &color)
@@ -231,7 +236,7 @@ qreal GradientModel::getPosition(int index) const
void GradientModel::removeStop(int index) void GradientModel::removeStop(int index)
{ {
if (index < rowCount() - 1 && index != 0) { 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::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode();
QmlDesigner::QmlObjectNode stop = gradientNode.nodeListProperty("stops").at(index); QmlDesigner::QmlObjectNode stop = gradientNode.nodeListProperty("stops").at(index);
if (stop.isValid()) { if (stop.isValid()) {
@@ -255,7 +260,7 @@ void GradientModel::deleteGradient()
if (m_itemNode.isInBaseState()) { if (m_itemNode.isInBaseState()) {
if (modelNode.hasProperty(gradientPropertyName().toUtf8())) { 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(); QmlDesigner::ModelNode gradientNode = modelNode.nodeProperty(gradientPropertyName().toUtf8()).modelNode();
if (QmlDesigner::QmlObjectNode(gradientNode).isValid()) if (QmlDesigner::QmlObjectNode(gradientNode).isValid())
QmlDesigner::QmlObjectNode(gradientNode).destroy(); QmlDesigner::QmlObjectNode(gradientNode).destroy();
@@ -263,6 +268,7 @@ void GradientModel::deleteGradient()
} }
emit hasGradientChanged(); emit hasGradientChanged();
emit gradientTypeChanged();
} }
void GradientModel::lock() void GradientModel::lock()
@@ -280,6 +286,22 @@ void GradientModel::registerDeclarativeType()
qmlRegisterType<GradientModel>("HelperWidgets",2,0,"GradientModel"); 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() void GradientModel::setupModel()
{ {
m_locked = true; m_locked = true;
@@ -299,12 +321,17 @@ void GradientModel::setAnchorBackend(const QVariant &anchorBackend)
if (backendCasted) if (backendCasted)
m_itemNode = backendCasted->getItemNode(); 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(); setupModel();
m_locked = true; m_locked = true;
emit anchorBackendChanged(); emit anchorBackendChanged();
emit hasGradientChanged(); emit hasGradientChanged();
emit gradientTypeChanged();
m_locked = false; m_locked = false;
} }
@@ -319,6 +346,16 @@ void GradientModel::setGradientPropertyName(const QString &name)
m_gradientPropertyName = name; m_gradientPropertyName = name;
} }
QString GradientModel::gradientTypeName() const
{
return m_gradientTypeName;
}
void GradientModel::setGradientTypeName(const QString &name)
{
m_gradientTypeName = name;
}
bool GradientModel::hasGradient() const bool GradientModel::hasGradient() const
{ {
return m_itemNode.isValid() return m_itemNode.isValid()
@@ -330,10 +367,125 @@ bool GradientModel::locked() const
if (m_locked) if (m_locked)
return true; return true;
auto view = qobject_cast<QmlDesigner::PropertyEditorView*>(m_itemNode.view()); auto editorView = qobject_cast<QmlDesigner::PropertyEditorView*>(view());
if (view && view->locked()) return editorView && editorView->locked();
return true; }
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; 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();
}
}

View File

@@ -37,6 +37,7 @@ class GradientModel : public QAbstractListModel
Q_PROPERTY(QVariant anchorBackendProperty READ anchorBackend WRITE setAnchorBackend NOTIFY anchorBackendChanged) Q_PROPERTY(QVariant anchorBackendProperty READ anchorBackend WRITE setAnchorBackend NOTIFY anchorBackendChanged)
Q_PROPERTY(QString gradientPropertyName READ gradientPropertyName WRITE setGradientPropertyName) 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(int count READ rowCount)
Q_PROPERTY(bool hasGradient READ hasGradient NOTIFY hasGradientChanged) Q_PROPERTY(bool hasGradient READ hasGradient NOTIFY hasGradientChanged)
@@ -65,9 +66,14 @@ public:
static void registerDeclarativeType(); static void registerDeclarativeType();
Q_INVOKABLE qreal readGradientProperty(const QString &property) const;
Q_INVOKABLE void setGradientProperty(const QString &propertyName, qreal value);
signals: signals:
void anchorBackendChanged(); void anchorBackendChanged();
void hasGradientChanged(); void hasGradientChanged();
void gradientTypeChanged();
private: private:
void setupModel(); void setupModel();
@@ -75,14 +81,23 @@ private:
QVariant anchorBackend() const {return QVariant(); } QVariant anchorBackend() const {return QVariant(); }
QString gradientPropertyName() const; QString gradientPropertyName() const;
void setGradientPropertyName(const QString &name); void setGradientPropertyName(const QString &name);
QString gradientTypeName() const;
void setGradientTypeName(const QString &name);
bool hasGradient() const; bool hasGradient() const;
bool locked() const; bool locked() const;
QmlDesigner::ModelNode createGradientNode();
QmlDesigner::ModelNode createGradientStopNode();
private: private:
QmlDesigner::QmlItemNode m_itemNode; QmlDesigner::QmlItemNode m_itemNode;
QString m_gradientPropertyName; QString m_gradientPropertyName;
QString m_gradientTypeName;
bool m_locked; 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) QML_DECLARE_TYPE(GradientModel)

View File

@@ -486,6 +486,8 @@ QString RewriterView::auxiliaryDataAsQML() const
QString str = "Designer {\n "; QString str = "Designer {\n ";
QTC_ASSERT(!m_canonicalIntModelNode.isEmpty(), return {});
int columnCount = 0; int columnCount = 0;
for (const auto &node : allModelNodes()) { for (const auto &node : allModelNodes()) {
QHash<PropertyName, QVariant> data = node.auxiliaryData(); QHash<PropertyName, QVariant> data = node.auxiliaryData();
@@ -727,8 +729,11 @@ void RewriterView::setupCanonicalHashes() const
using myPair = std::pair<ModelNode,int>; using myPair = std::pair<ModelNode,int>;
std::vector<myPair> data; std::vector<myPair> data;
for (const ModelNode &node : allModelNodes()) for (const ModelNode &node : allModelNodes()) {
data.emplace_back(std::make_pair(node, nodeOffset(node))); 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) { std::sort(data.begin(), data.end(), [](myPair a, myPair b) {
return a.second < b.second; return a.second < b.second;
@@ -1066,6 +1071,8 @@ void RewriterView::restoreAuxiliaryData()
setupCanonicalHashes(); setupCanonicalHashes();
QTC_ASSERT(!m_canonicalIntModelNode.isEmpty(), return);
const QString text = m_textModifier->text(); const QString text = m_textModifier->text();
int startIndex = text.indexOf(annotationsStart()); int startIndex = text.indexOf(annotationsStart());

View File

@@ -106,8 +106,8 @@ QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName)
return QDir::cleanPath(fileName); return QDir::cleanPath(fileName);
#ifdef Q_OS_WIN // Add drive to otherwise-absolute path: #ifdef Q_OS_WIN // Add drive to otherwise-absolute path:
if (fileName.at(0).unicode() == '/' || fileName.at(0).unicode() == '\\') { if (fileName.at(0).unicode() == '/' || fileName.at(0).unicode() == '\\') {
Q_ASSERT(isAbsolutePath(baseDir)); return isAbsolutePath(baseDir) ? QDir::cleanPath(baseDir.left(2) + fileName)
return QDir::cleanPath(baseDir.left(2) + fileName); : QDir::cleanPath(fileName);
} }
#endif // Q_OS_WIN #endif // Q_OS_WIN
return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName); return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);

View File

@@ -36,6 +36,7 @@
#include <clangsupport/sourcerangecontainer.h> #include <clangsupport/sourcerangecontainer.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/textfileformat.h> #include <utils/textfileformat.h>
#include <utils/qtcassert.h>
#include <utf8string.h> #include <utf8string.h>
@@ -392,7 +393,7 @@ static bool isBuiltinOrPointerToBuiltin(const Type &type)
// TODO: Simplify // TODO: Simplify
// TODO: Test with ** // TODO: Test with **
while (theType.pointeeType().isValid()) { while (theType.pointeeType().isValid() && theType != theType.pointeeType()) {
theType = theType.pointeeType(); theType = theType.pointeeType();
if (theType.isBuiltinType()) if (theType.isBuiltinType())
return true; return true;
@@ -436,7 +437,7 @@ ToolTipInfo ToolTipInfoCollector::qDocInfo(const Cursor &cursor) const
} }
Type type = cursor.type(); Type type = cursor.type();
while (type.pointeeType().isValid()) while (type.pointeeType().isValid() && type != type.pointeeType())
type = type.pointeeType(); type = type.pointeeType();
const Cursor typeCursor = type.declaration(); const Cursor typeCursor = type.declaration();

View File

@@ -245,6 +245,11 @@ bool operator==(Type first, Type second)
return clang_equalTypes(first.m_cxType, second.m_cxType); 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) std::ostream &operator<<(std::ostream &os, CXTypeKind typeKind)
{ {
ClangString typeKindSpelling(clang_getTypeKindSpelling(typeKind)); ClangString typeKindSpelling(clang_getTypeKindSpelling(typeKind));

View File

@@ -81,6 +81,7 @@ private:
}; };
bool operator==(Type first, Type second); 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, CXTypeKind typeKind);
std::ostream &operator<<(std::ostream &os, const Type &type); std::ostream &operator<<(std::ostream &os, const Type &type);