Merge remote-tracking branch 'origin/4.12'

Change-Id: Ia8254720b2ba6e3e7b859017e1c2b6e289bed771
This commit is contained in:
Eike Ziller
2020-03-20 08:16:19 +01:00
26 changed files with 174 additions and 101 deletions

View File

@@ -1,9 +1,9 @@
#BINARY_ARTIFACTS_BRANCH = master #BINARY_ARTIFACTS_BRANCH = master
#PROJECT_USER_FILE_EXTENSION = .user #PROJECT_USER_FILE_EXTENSION = .user
set(IDE_VERSION "4.11.83") # The IDE version. set(IDE_VERSION "4.11.84") # The IDE version.
set(IDE_VERSION_COMPAT "4.11.83") # The IDE Compatibility version. set(IDE_VERSION_COMPAT "4.11.84") # The IDE Compatibility version.
set(IDE_VERSION_DISPLAY "4.12.0-beta2") # The IDE display version. set(IDE_VERSION_DISPLAY "4.12.0-rc1") # The IDE display version.
set(IDE_COPYRIGHT_YEAR "2020") # The IDE current copyright year. set(IDE_COPYRIGHT_YEAR "2020") # The IDE current copyright year.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.

View File

@@ -381,7 +381,7 @@
Copyright (C) 2010-2015 three.js authors\br Copyright (C) 2010-2015 three.js authors\br
share/qtcreator/templates/wizards/projects/qmake/qtcanvas3dapplication share/qtcreator/templates/wizards/projects/qmake/qtcanvas3dapplication
\li \b{OpenSSL toolkit. Version 1.0.2j} \li \b{OpenSSL toolkit}
The OpenSSL toolkit stays under a double license, i.e. both the conditions of The OpenSSL toolkit stays under a double license, i.e. both the conditions of
the OpenSSL License and the original SSLeay license apply to the toolkit. the OpenSSL License and the original SSLeay license apply to the toolkit.
@@ -391,7 +391,7 @@
OpenSSL License OpenSSL License
==================================================================== ====================================================================
Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -4,16 +4,16 @@ import qbs.FileInfo
import "qtc.js" as HelperFunctions import "qtc.js" as HelperFunctions
Module { Module {
property string qtcreator_display_version: '4.12.0-beta2' property string qtcreator_display_version: '4.12.0-rc1'
property string ide_version_major: '4' property string ide_version_major: '4'
property string ide_version_minor: '11' property string ide_version_minor: '11'
property string ide_version_release: '83' property string ide_version_release: '84'
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.'
+ ide_version_release + ide_version_release
property string ide_compat_version_major: '4' property string ide_compat_version_major: '4'
property string ide_compat_version_minor: '11' property string ide_compat_version_minor: '11'
property string ide_compat_version_release: '83' property string ide_compat_version_release: '84'
property string qtcreator_compat_version: ide_compat_version_major + '.' property string qtcreator_compat_version: ide_compat_version_major + '.'
+ ide_compat_version_minor + '.' + ide_compat_version_release + ide_compat_version_minor + '.' + ide_compat_version_release

View File

@@ -1,8 +1,8 @@
QTCREATOR_VERSION = 4.11.83 QTCREATOR_VERSION = 4.11.84
QTCREATOR_COMPAT_VERSION = 4.11.83 QTCREATOR_COMPAT_VERSION = 4.11.84
QTCREATOR_DISPLAY_VERSION = 4.12.0-beta2 QTCREATOR_DISPLAY_VERSION = 4.12.0-rc1
QTCREATOR_COPYRIGHT_YEAR = 2020 QTCREATOR_COPYRIGHT_YEAR = 2020
BINARY_ARTIFACTS_BRANCH = master BINARY_ARTIFACTS_BRANCH = 4.12
IDE_DISPLAY_NAME = Qt Creator IDE_DISPLAY_NAME = Qt Creator
IDE_ID = qtcreator IDE_ID = qtcreator

View File

@@ -180,7 +180,10 @@ void AndroidPlugin::kitsRestored()
AndroidConfigurations::registerNewToolChains(); AndroidConfigurations::registerNewToolChains();
AndroidConfigurations::updateAutomaticKitList(); AndroidConfigurations::updateAutomaticKitList();
connect(QtSupport::QtVersionManager::instance(), &QtSupport::QtVersionManager::qtVersionsChanged, connect(QtSupport::QtVersionManager::instance(), &QtSupport::QtVersionManager::qtVersionsChanged,
AndroidConfigurations::instance(), &AndroidConfigurations::updateAutomaticKitList); AndroidConfigurations::instance(), []() {
AndroidConfigurations::registerNewToolChains();
AndroidConfigurations::updateAutomaticKitList();
});
disconnect(KitManager::instance(), &KitManager::kitsLoaded, disconnect(KitManager::instance(), &KitManager::kitsLoaded,
this, &AndroidPlugin::kitsRestored); this, &AndroidPlugin::kitsRestored);
} }

View File

@@ -169,11 +169,6 @@ AndroidToolChainFactory::AndroidToolChainFactory()
setToolchainConstructor([] { return new AndroidToolChain; }); setToolchainConstructor([] { return new AndroidToolChain; });
} }
ToolChainList AndroidToolChainFactory::autoDetect(const ToolChainList &alreadyKnown)
{
return autodetectToolChains(alreadyKnown);
}
static FilePath clangPlusPlusPath(const FilePath &clangPath) static FilePath clangPlusPlusPath(const FilePath &clangPath)
{ {
return clangPath.parentDir().pathAppended( return clangPath.parentDir().pathAppended(

View File

@@ -67,8 +67,6 @@ class AndroidToolChainFactory : public ProjectExplorer::ToolChainFactory
public: public:
AndroidToolChainFactory(); AndroidToolChainFactory();
ToolChainList autoDetect(const ToolChainList &alreadyKnown) override;
class AndroidToolChainInformation class AndroidToolChainInformation
{ {
public: public:

View File

@@ -1793,8 +1793,8 @@ void BreakpointItem::destroyMarker()
FilePath BreakpointItem::markerFileName() const FilePath BreakpointItem::markerFileName() const
{ {
// Some heuristics to find a "good" file name. // Some heuristics to find a "good" file name.
if (!m_parameters.fileName.exists()) if (m_parameters.fileName.exists())
return FilePath::fromString(m_parameters.fileName.toFileInfo().absolutePath()); return FilePath::fromString(m_parameters.fileName.toFileInfo().absoluteFilePath());
const FilePath origFileName = requestedParameters().fileName; const FilePath origFileName = requestedParameters().fileName;
if (m_parameters.fileName.endsWith(origFileName.fileName())) if (m_parameters.fileName.endsWith(origFileName.fileName()))
@@ -2268,7 +2268,7 @@ void GlobalBreakpointItem::updateFileName(const FilePath &fileName)
FilePath GlobalBreakpointItem::markerFileName() const FilePath GlobalBreakpointItem::markerFileName() const
{ {
// Some heuristics to find a "good" file name. // Some heuristics to find a "good" file name.
if (!m_params.fileName.exists()) if (m_params.fileName.exists())
return FilePath::fromString(m_params.fileName.toFileInfo().absoluteFilePath()); return FilePath::fromString(m_params.fileName.toFileInfo().absoluteFilePath());
return m_params.fileName; return m_params.fileName;
} }

View File

@@ -378,6 +378,7 @@ void BreakpointParameters::updateFromGdbOutput(const GdbMi &bkpt)
QString name; QString name;
if (!fullName.isEmpty()) { if (!fullName.isEmpty()) {
name = cleanupFullName(fullName); name = cleanupFullName(fullName);
fileName = Utils::FilePath::fromString(name);
//if (data->markerFileName().isEmpty()) //if (data->markerFileName().isEmpty())
// data->setMarkerFileName(name); // data->setMarkerFileName(name);
} else { } else {

View File

@@ -440,11 +440,12 @@ void CdbEngine::setupEngine()
inferiorEnvironment.set(qtLoggingToConsoleKey, "0"); inferiorEnvironment.set(qtLoggingToConsoleKey, "0");
static const char cdbExtensionPathVariableC[] = "_NT_DEBUGGER_EXTENSION_PATH"; static const char cdbExtensionPathVariableC[] = "_NT_DEBUGGER_EXTENSION_PATH";
inferiorEnvironment.prependOrSet(cdbExtensionPathVariableC, extensionFi.absolutePath()); inferiorEnvironment.prependOrSet(cdbExtensionPathVariableC, extensionFi.absolutePath(), {";"});
const QByteArray oldCdbExtensionPath = qgetenv(cdbExtensionPathVariableC); const QByteArray oldCdbExtensionPath = qgetenv(cdbExtensionPathVariableC);
if (!oldCdbExtensionPath.isEmpty()) { if (!oldCdbExtensionPath.isEmpty()) {
inferiorEnvironment.appendOrSet(cdbExtensionPathVariableC, inferiorEnvironment.appendOrSet(cdbExtensionPathVariableC,
QString::fromLocal8Bit(oldCdbExtensionPath)); QString::fromLocal8Bit(oldCdbExtensionPath),
{";"});
} }
m_process.setEnvironment(inferiorEnvironment); m_process.setEnvironment(inferiorEnvironment);

View File

@@ -334,16 +334,22 @@ McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent) : QObject(parent)
, qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage()) , qtForMCUsSdkPackage(Sdk::createQtForMCUsPackage())
{ {
Sdk::hardcodedTargetsAndPackages(qtForMCUsSdkPackage, &packages, &mcuTargets); connect(qtForMCUsSdkPackage, &McuPackage::changed,
this, &McuSupportOptions::populatePackagesAndTargets);
packages.append(qtForMCUsSdkPackage);
for (auto package : packages)
connect(package, &McuPackage::changed, [this](){
emit changed();
});
} }
McuSupportOptions::~McuSupportOptions() McuSupportOptions::~McuSupportOptions()
{
deletePackagesAndTargets();
delete qtForMCUsSdkPackage;
}
void McuSupportOptions::populatePackagesAndTargets()
{
setQulDir(Utils::FilePath::fromUserInput(qtForMCUsSdkPackage->path()));
}
void McuSupportOptions::deletePackagesAndTargets()
{ {
qDeleteAll(packages); qDeleteAll(packages);
packages.clear(); packages.clear();
@@ -351,6 +357,19 @@ McuSupportOptions::~McuSupportOptions()
mcuTargets.clear(); mcuTargets.clear();
} }
void McuSupportOptions::setQulDir(const Utils::FilePath &dir)
{
deletePackagesAndTargets();
Sdk::hardcodedTargetsAndPackages(dir, &packages, &mcuTargets);
//packages.append(qtForMCUsSdkPackage);
for (auto package : packages) {
connect(package, &McuPackage::changed, [this](){
emit changed();
});
}
emit changed();
}
static bool mcuTargetIsDesktop(const McuTarget* mcuTarget) static bool mcuTargetIsDesktop(const McuTarget* mcuTarget)
{ {
return mcuTarget->qulPlatform() == "Qt"; return mcuTarget->qulPlatform() == "Qt";

View File

@@ -35,6 +35,7 @@ class Id;
} }
namespace Utils { namespace Utils {
class FilePath;
class PathChooser; class PathChooser;
class InfoLabel; class InfoLabel;
} }
@@ -158,10 +159,16 @@ public:
QVector<McuTarget*> mcuTargets; QVector<McuTarget*> mcuTargets;
McuPackage *qtForMCUsSdkPackage = nullptr; McuPackage *qtForMCUsSdkPackage = nullptr;
void setQulDir(const Utils::FilePath &dir);
QString kitName(const McuTarget* mcuTarget) const; QString kitName(const McuTarget* mcuTarget) const;
QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTargt); QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTargt);
ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget); ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget);
void populatePackagesAndTargets();
private:
void deletePackagesAndTargets();
signals: signals:
void changed(); void changed();

View File

@@ -62,6 +62,7 @@ public:
private: private:
void apply() final; void apply() final;
void populateMcuTargetsComboBox();
void showEvent(QShowEvent *event) final; void showEvent(QShowEvent *event) final;
QString m_armGccPath; QString m_armGccPath;
@@ -108,14 +109,12 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
m_mcuTargetsGroupBox->setFlat(true); m_mcuTargetsGroupBox->setFlat(true);
mainLayout->addWidget(m_mcuTargetsGroupBox); mainLayout->addWidget(m_mcuTargetsGroupBox);
m_mcuTargetsComboBox = new QComboBox; m_mcuTargetsComboBox = new QComboBox;
m_mcuTargetsComboBox->addItems(
Utils::transform<QStringList>(m_options.mcuTargets, [this](McuTarget *t){
return m_options.kitName(t);
}));
auto layout = new QVBoxLayout(m_mcuTargetsGroupBox); auto layout = new QVBoxLayout(m_mcuTargetsGroupBox);
layout->addWidget(m_mcuTargetsComboBox); layout->addWidget(m_mcuTargetsComboBox);
connect(m_mcuTargetsComboBox, &QComboBox::currentTextChanged, connect(m_mcuTargetsComboBox, &QComboBox::currentTextChanged,
this, &McuSupportOptionsWidget::showMcuTargetPackages); this, &McuSupportOptionsWidget::showMcuTargetPackages);
connect(m_options.qtForMCUsSdkPackage, &McuPackage::changed,
this, &McuSupportOptionsWidget::populateMcuTargetsComboBox);
} }
{ {
@@ -147,15 +146,13 @@ McuSupportOptionsWidget::McuSupportOptionsWidget()
void McuSupportOptionsWidget::updateStatus() void McuSupportOptionsWidget::updateStatus()
{ {
const McuTarget *mcuTarget = currentMcuTarget(); const McuTarget *mcuTarget = currentMcuTarget();
if (!mcuTarget)
return;
const bool cMakeAvailable = !CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty(); const bool cMakeAvailable = !CMakeProjectManager::CMakeToolManager::cmakeTools().isEmpty();
// Page elements // Page elements
{ {
m_qtForMCUsSdkGroupBox->setVisible(cMakeAvailable); m_qtForMCUsSdkGroupBox->setVisible(cMakeAvailable);
const bool ready = cMakeAvailable && const bool ready = cMakeAvailable && mcuTarget &&
m_options.qtForMCUsSdkPackage->status() == McuPackage::ValidPackage; m_options.qtForMCUsSdkPackage->status() == McuPackage::ValidPackage;
m_mcuTargetsGroupBox->setVisible(ready); m_mcuTargetsGroupBox->setVisible(ready);
m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty()); m_packagesGroupBox->setVisible(ready && !mcuTarget->packages().isEmpty());
@@ -163,7 +160,7 @@ void McuSupportOptionsWidget::updateStatus()
} }
// Kit creation status // Kit creation status
{ if (mcuTarget) {
const bool mcuTargetValid = mcuTarget->isValid(); const bool mcuTargetValid = mcuTarget->isValid();
m_kitCreationInfoLabel->setType(mcuTargetValid ? Utils::InfoLabel::Ok m_kitCreationInfoLabel->setType(mcuTargetValid ? Utils::InfoLabel::Ok
: Utils::InfoLabel::NotOk); : Utils::InfoLabel::NotOk);
@@ -213,13 +210,15 @@ void McuSupportOptionsWidget::showMcuTargetPackages()
McuTarget *McuSupportOptionsWidget::currentMcuTarget() const McuTarget *McuSupportOptionsWidget::currentMcuTarget() const
{ {
const int mcuTargetIndex = m_mcuTargetsComboBox->currentIndex(); const int mcuTargetIndex = m_mcuTargetsComboBox->currentIndex();
return m_options.mcuTargets.isEmpty() ? nullptr : m_options.mcuTargets.at(mcuTargetIndex); return (mcuTargetIndex == -1 || m_options.mcuTargets.isEmpty())
? nullptr
: m_options.mcuTargets.at(mcuTargetIndex);
} }
void McuSupportOptionsWidget::showEvent(QShowEvent *event) void McuSupportOptionsWidget::showEvent(QShowEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
updateStatus(); populateMcuTargetsComboBox();
} }
void McuSupportOptionsWidget::apply() void McuSupportOptionsWidget::apply()
@@ -241,6 +240,17 @@ void McuSupportOptionsWidget::apply()
m_options.newKit(mcuTarget); m_options.newKit(mcuTarget);
} }
void McuSupportOptionsWidget::populateMcuTargetsComboBox()
{
m_options.populatePackagesAndTargets();
m_mcuTargetsComboBox->clear();
m_mcuTargetsComboBox->addItems(
Utils::transform<QStringList>(m_options.mcuTargets, [this](McuTarget *t){
return m_options.kitName(t);
}));
updateStatus();
}
McuSupportOptionsPage::McuSupportOptionsPage() McuSupportOptionsPage::McuSupportOptionsPage()
{ {
setId(Core::Id(Constants::SETTINGS_ID)); setId(Core::Id(Constants::SETTINGS_ID));

View File

@@ -158,8 +158,8 @@ static McuPackage *createSeggerJLinkPackage()
return result; return result;
} }
void hardcodedTargetsAndPackages(const McuPackage* qtForMCUsSdkPackage, void hardcodedTargetsAndPackages(const Utils::FilePath &dir, QVector<McuPackage *> *packages,
QVector<McuPackage *> *packages, QVector<McuTarget *> *mcuTargets) QVector<McuTarget *> *mcuTargets)
{ {
McuToolChainPackage* armGccPackage = Sdk::createArmGccPackage(); McuToolChainPackage* armGccPackage = Sdk::createArmGccPackage();
McuPackage* stm32CubeFwF7SdkPackage = Sdk::createStm32CubeFwF7SdkPackage(); McuPackage* stm32CubeFwF7SdkPackage = Sdk::createStm32CubeFwF7SdkPackage();
@@ -171,6 +171,8 @@ void hardcodedTargetsAndPackages(const McuPackage* qtForMCUsSdkPackage,
armGccPackage, stm32CubeProgrammerPackage}; armGccPackage, stm32CubeProgrammerPackage};
QVector<McuPackage*> nxpEvalPackages = { QVector<McuPackage*> nxpEvalPackages = {
armGccPackage, seggerJLinkPackage}; armGccPackage, seggerJLinkPackage};
QVector<McuPackage*> renesasEvalPackages = {
armGccPackage, seggerJLinkPackage};
QVector<McuPackage*> desktopPackages = {}; QVector<McuPackage*> desktopPackages = {};
*packages = { *packages = {
armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage, evkbImxrt1050SdkPackage, armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage, evkbImxrt1050SdkPackage,
@@ -179,28 +181,42 @@ void hardcodedTargetsAndPackages(const McuPackage* qtForMCUsSdkPackage,
const QString vendorStm = "STM"; const QString vendorStm = "STM";
const QString vendorNxp = "NXP"; const QString vendorNxp = "NXP";
const QString vendorQt = "Qt"; const QString vendorQt = "Qt";
const QString vendorRenesas = "Renesas";
// STM const struct {
auto mcuTarget = new McuTarget(vendorStm, "STM32F7508-DISCOVERY", stmEvalPackages, const QString &vendor;
armGccPackage); const QString qulPlatform;
mcuTarget->setColorDepth(32); const QVector<McuPackage*> &packages;
mcuTargets->append(mcuTarget); McuToolChainPackage *toolchainPackage;
const QVector<int> colorDepths;
} targets[] = {
{vendorNxp, {"MIMXRT1050-EVK"}, nxpEvalPackages, armGccPackage, {16}},
{vendorNxp, {"MIMXRT1064-EVK"}, nxpEvalPackages, armGccPackage, {16}},
{vendorQt, {"Qt"}, desktopPackages, nullptr, {32}},
{vendorRenesas, {"RH850-D1M1A"}, renesasEvalPackages, armGccPackage, {32}},
{vendorStm, {"STM32F469I-DISCOVERY"}, stmEvalPackages, armGccPackage, {24}},
{vendorStm, {"STM32F7508-DISCOVERY"}, stmEvalPackages, armGccPackage, {32, 16}},
{vendorStm, {"STM32F769I-DISCOVERY"}, stmEvalPackages, armGccPackage, {32}},
{vendorStm, {"STM32H750B-DISCOVERY"}, stmEvalPackages, armGccPackage, {32}},
{vendorStm, {"STM32L4R9I-DISCOVERY"}, stmEvalPackages, armGccPackage, {24}},
{vendorStm, {"STM32L4R9I-EVAL"}, stmEvalPackages, armGccPackage, {24}}
};
mcuTarget = new McuTarget(vendorStm, "STM32F7508-DISCOVERY", stmEvalPackages, armGccPackage); const QString QulTargetTemplate =
mcuTarget->setColorDepth(16); dir.toString() + "/lib/cmake/Qul/QulTargets/QulTargets_%1_%2.cmake";
mcuTargets->append(mcuTarget); for (auto target : targets) {
for (int colorDepth : target.colorDepths) {
mcuTarget = new McuTarget(vendorStm, "STM32F769I-DISCOVERY", stmEvalPackages, armGccPackage); const QString QulTarget =
mcuTargets->append(mcuTarget); QulTargetTemplate.arg(target.qulPlatform, QString::number(colorDepth));
if (!Utils::FilePath::fromUserInput(QulTarget).exists())
// NXP continue;
mcuTarget = new McuTarget(vendorNxp, "MIMXRT1050-EVK", nxpEvalPackages, armGccPackage); auto mcuTarget = new McuTarget(target.vendor, target.qulPlatform, target.packages,
mcuTargets->append(mcuTarget); target.toolchainPackage);
if (target.colorDepths.count() > 1)
// Desktop (Qt) mcuTarget->setColorDepth(colorDepth);
mcuTarget = new McuTarget(vendorQt, "Qt", desktopPackages, nullptr); mcuTargets->append(mcuTarget);
mcuTarget->setColorDepth(32); }
mcuTargets->append(mcuTarget); }
} }
} // namespace Sdk } // namespace Sdk

View File

@@ -37,7 +37,7 @@ namespace Sdk {
McuPackage *createQtForMCUsPackage(); McuPackage *createQtForMCUsPackage();
// Legacy: List of targets supported by Qt for MCUs 1.0 // Legacy: List of targets supported by Qt for MCUs 1.0
void hardcodedTargetsAndPackages(const McuPackage* const qtForMCUsSdkPackage, void hardcodedTargetsAndPackages(const Utils::FilePath &qulDir,
QVector<McuPackage*> *packages, QVector<McuTarget*> *mcuTargets); QVector<McuPackage*> *packages, QVector<McuTarget*> *mcuTargets);
} // namespace Sdk } // namespace Sdk

View File

@@ -384,6 +384,8 @@ QVariant QmakeProFileNode::data(Core::Id role) const
if (role == Android::Constants::AndroidTargets) if (role == Android::Constants::AndroidTargets)
return {}; return {};
if (role == Android::Constants::AndroidApk)
return {};
// We can not use AppMan headers even at build time. // We can not use AppMan headers even at build time.
if (role == "AppmanPackageDir") if (role == "AppmanPackageDir")

View File

@@ -106,13 +106,6 @@ QToolBar *CurveEditor::createToolBar(CurveEditorModel *model)
Q_UNUSED(tangentStepAction); Q_UNUSED(tangentStepAction);
Q_UNUSED(tangentDefaultAction); Q_UNUSED(tangentDefaultAction);
auto *valueBox = new QHBoxLayout;
valueBox->addWidget(new QLabel(tr("Value")));
valueBox->addWidget(new QDoubleSpinBox);
auto *valueWidget = new QWidget;
valueWidget->setLayout(valueBox);
bar->addWidget(valueWidget);
auto *durationBox = new QHBoxLayout; auto *durationBox = new QHBoxLayout;
auto *startSpin = new QSpinBox; auto *startSpin = new QSpinBox;
auto *endSpin = new QSpinBox; auto *endSpin = new QSpinBox;

View File

@@ -108,8 +108,7 @@ void CurveEditorModel::reset(const std::vector<TreeItem *> &items)
endResetModel(); endResetModel();
if (!pinned.empty()) graphicsView()->reset(pinned);
graphicsView()->reset(pinned);
if (SelectionModel *sm = selectionModel()) if (SelectionModel *sm = selectionModel())
sm->select(sel); sm->select(sel);

View File

@@ -150,7 +150,18 @@ CurveSegment::CurveSegment(const Keyframe &left, const Keyframe &right)
bool CurveSegment::isValid() const bool CurveSegment::isValid() const
{ {
return m_left.position() != m_right.position(); if (m_left.position() == m_right.position())
return false;
if (interpolation() == Keyframe::Interpolation::Undefined)
return false;
if (interpolation() == Keyframe::Interpolation::Easing
|| interpolation() == Keyframe::Interpolation::Bezier) {
if (qFuzzyCompare(m_left.position().y(), m_right.position().y()))
return false;
}
return true;
} }
bool CurveSegment::containsX(double x) const bool CurveSegment::containsX(double x) const
@@ -224,6 +235,23 @@ QPainterPath CurveSegment::path() const
return path; return path;
} }
void CurveSegment::extendWithEasingCurve(QPainterPath &path, const QEasingCurve &curve) const
{
auto mapEasing = [](const QPointF &start, const QPointF &end, const QPointF &pos) {
QPointF slope(end.x() - start.x(), end.y() - start.y());
return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y());
};
QVector<QPointF> points = curve.toCubicSpline();
int numSegments = points.count() / 3;
for (int i = 0; i < numSegments; i++) {
QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3));
QPointF p2 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 1));
QPointF p3 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 2));
path.cubicTo(p1, p2, p3);
}
}
void CurveSegment::extend(QPainterPath &path) const void CurveSegment::extend(QPainterPath &path) const
{ {
if (interpolation() == Keyframe::Interpolation::Linear) { if (interpolation() == Keyframe::Interpolation::Linear) {
@@ -232,23 +260,11 @@ void CurveSegment::extend(QPainterPath &path) const
path.lineTo(QPointF(m_right.position().x(), m_left.position().y())); path.lineTo(QPointF(m_right.position().x(), m_left.position().y()));
path.lineTo(m_right.position()); path.lineTo(m_right.position());
} else if (interpolation() == Keyframe::Interpolation::Bezier) { } else if (interpolation() == Keyframe::Interpolation::Bezier) {
path.cubicTo(m_left.rightHandle(), m_right.leftHandle(), m_right.position()); extendWithEasingCurve(path, easingCurve());
} else if (interpolation() == Keyframe::Interpolation::Easing) { } else if (interpolation() == Keyframe::Interpolation::Easing) {
auto mapEasing = [](const QPointF &start, const QPointF &end, const QPointF &pos) {
QPointF slope(end.x() - start.x(), end.y() - start.y());
return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y());
};
QVariant data = m_right.data(); QVariant data = m_right.data();
if (data.isValid() && data.type() == static_cast<int>(QMetaType::QEasingCurve)) { if (data.isValid() && data.type() == static_cast<int>(QMetaType::QEasingCurve)) {
QVector<QPointF> points = data.value<QEasingCurve>().toCubicSpline(); extendWithEasingCurve(path, data.value<QEasingCurve>());
int numSegments = points.count() / 3;
for (int i = 0; i < numSegments; i++) {
QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3));
QPointF p2 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 1));
QPointF p3 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 2));
path.cubicTo(p1, p2, p3);
}
} }
} }
} }
@@ -258,6 +274,10 @@ QEasingCurve CurveSegment::easingCurve() const
auto mapPosition = [this](const QPointF &position) { auto mapPosition = [this](const QPointF &position) {
QPointF min = m_left.position(); QPointF min = m_left.position();
QPointF max = m_right.position(); QPointF max = m_right.position();
if (qFuzzyCompare(min.y(), max.y()))
return QPointF((position.x() - min.x()) / (max.x() - min.x()),
(position.y() - min.y()) / (max.y()));
return QPointF((position.x() - min.x()) / (max.x() - min.x()), return QPointF((position.x() - min.x()) / (max.x() - min.x()),
(position.y() - min.y()) / (max.y() - min.y())); (position.y() - min.y()) / (max.y() - min.y()));
}; };
@@ -265,8 +285,7 @@ QEasingCurve CurveSegment::easingCurve() const
QEasingCurve curve; QEasingCurve curve;
curve.addCubicBezierSegment(mapPosition(m_left.rightHandle()), curve.addCubicBezierSegment(mapPosition(m_left.rightHandle()),
mapPosition(m_right.leftHandle()), mapPosition(m_right.leftHandle()),
mapPosition(m_right.position())); QPointF(1., 1.));
return curve; return curve;
} }

View File

@@ -61,6 +61,8 @@ public:
void extend(QPainterPath &path) const; void extend(QPainterPath &path) const;
void extendWithEasingCurve(QPainterPath &path, const QEasingCurve &curve) const;
QEasingCurve easingCurve() const; QEasingCurve easingCurve() const;
std::vector<QPointF> extrema() const; std::vector<QPointF> extrema() const;

View File

@@ -564,7 +564,6 @@ void GraphicsView::drawRangeBar(QPainter *painter, const QRectF &rect)
QRectF activeRect = QRectF(QPointF(mapTimeToX(m_model->minimumTime()), tTick), QRectF activeRect = QRectF(QPointF(mapTimeToX(m_model->minimumTime()), tTick),
QPointF(mapTimeToX(m_model->maximumTime()), bTick)); QPointF(mapTimeToX(m_model->maximumTime()), bTick));
QColor rangeColor = m_style.rangeBarColor;
painter->fillRect(activeRect, m_style.rangeBarColor); painter->fillRect(activeRect, m_style.rangeBarColor);
QColor handleColor(m_style.rangeBarCapsColor); QColor handleColor(m_style.rangeBarCapsColor);

View File

@@ -30,8 +30,8 @@
#include "qmltimeline.h" #include "qmltimeline.h"
#include <bindingproperty.h> #include <bindingproperty.h>
#include <variantproperty.h>
#include <theme.h> #include <theme.h>
#include <variantproperty.h>
namespace QmlDesigner { namespace QmlDesigner {
@@ -204,8 +204,16 @@ std::vector<DesignTools::Keyframe> resolveSmallCurves(
for (auto &&frame : frames) { for (auto &&frame : frames) {
if (frame.hasData() && !out.empty()) { if (frame.hasData() && !out.empty()) {
QEasingCurve curve = frame.data().toEasingCurve(); QEasingCurve curve = frame.data().toEasingCurve();
// One-segment-curve: Since (0,0) is implicit => 3
if (curve.toCubicSpline().count() == 3) { if (curve.toCubicSpline().count() == 3) {
DesignTools::Keyframe &previous = out.back(); DesignTools::Keyframe &previous = out.back();
#if 0
// Do not resolve when two adjacent keyframes have the same value.
if (qFuzzyCompare(previous.position().y(), frame.position().y())) {
out.push_back(frame);
continue;
}
#endif
DesignTools::AnimationCurve acurve(curve, previous.position(), frame.position()); DesignTools::AnimationCurve acurve(curve, previous.position(), frame.position());
previous.setRightHandle(acurve.keyframeAt(0).rightHandle()); previous.setRightHandle(acurve.keyframeAt(0).rightHandle());
out.push_back(acurve.keyframeAt(1)); out.push_back(acurve.keyframeAt(1));

View File

@@ -355,7 +355,8 @@ void TimelineWidget::updateAnimationCurve(DesignTools::PropertyTreeItem *item)
if (previous.isValid()) { if (previous.isValid()) {
if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Bezier) { if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Bezier) {
DesignTools::CurveSegment segment(previous, frame); DesignTools::CurveSegment segment(previous, frame);
attachEasingCurve(pos.x(), segment.easingCurve(), group); if (segment.isValid())
attachEasingCurve(pos.x(), segment.easingCurve(), group);
} else if (frame.interpolation() } else if (frame.interpolation()
== DesignTools::Keyframe::Interpolation::Easing) { == DesignTools::Keyframe::Interpolation::Easing) {
QVariant data = frame.data(); QVariant data = frame.data();

View File

@@ -1089,7 +1089,7 @@ ChangeValuesCommand NodeInstanceView::createChangeValueCommand(const QList<Varia
{ {
QVector<PropertyValueContainer> containerList; QVector<PropertyValueContainer> containerList;
const bool reflectionFlag = m_puppetTransaction.isValid(); const bool reflectionFlag = m_puppetTransaction.isValid() && (!currentTimeline().isValid() || !currentTimeline().isRecording());
foreach (const VariantProperty &property, propertyList) { foreach (const VariantProperty &property, propertyList) {
ModelNode node = property.parentModelNode(); ModelNode node = property.parentModelNode();
@@ -1245,10 +1245,10 @@ void NodeInstanceView::valuesModified(const ValuesModifiedCommand &command)
if (hasInstanceForId(container.instanceId())) { if (hasInstanceForId(container.instanceId())) {
NodeInstance instance = instanceForId(container.instanceId()); NodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid()) { if (instance.isValid()) {
ModelNode node = instance.modelNode(); // QmlVisualNode is needed so timeline and state are updated
VariantProperty property = instance.modelNode().variantProperty(container.name()); QmlVisualNode node = instance.modelNode();
if (property.value() != container.value()) if (node.instanceValue(container.name()) != container.value())
property.setValue(container.value()); node.setVariantProperty(container.name(), container.value());
} }
} }
} }

View File

@@ -38,7 +38,7 @@ VcsOutputFormatter::VcsOutputFormatter() :
m_regexp( m_regexp(
"(https?://\\S*)" // https://codereview.org/c/1234 "(https?://\\S*)" // https://codereview.org/c/1234
"|(v[0-9]+\\.[0-9]+\\.[0-9]+[\\-A-Za-z0-9]*)" // v0.1.2-beta3 "|(v[0-9]+\\.[0-9]+\\.[0-9]+[\\-A-Za-z0-9]*)" // v0.1.2-beta3
"|([0-9a-f]{6,}(?:\\.\\.[0-9a-f]{6,})?)") // 789acf or 123abc..456cde "|([0-9a-f]{6,}(?:\\.\\.[0-9a-f]{6,}|\\^)?)") // 789acf^ or 123abc..456cde
{ {
} }

View File

@@ -88,7 +88,7 @@ def switchSession(toSession):
sessionView = ("{name='sessionView' type='ProjectExplorer::Internal::SessionView' visible='1' " sessionView = ("{name='sessionView' type='ProjectExplorer::Internal::SessionView' visible='1' "
"window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}") "window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}")
mouseClick(waitForObjectItem(sessionView, toSession)) mouseClick(waitForObjectItem(sessionView, toSession))
clickButton(waitForObject("{name='btSwitch' text='Switch to' type='QPushButton' visible='1' " clickButton(waitForObject("{name='btSwitch' type='QPushButton' visible='1' "
"window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}")) "window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}"))
def createAndSwitchToSession(toSession): def createAndSwitchToSession(toSession):