Merge remote-tracking branch 'origin/4.14' into master

Conflicts:
	src/plugins/cppeditor/cppquickfix_test.cpp

Change-Id: I470ee35f54f883244d819531131c172bd25c0e3f
This commit is contained in:
Eike Ziller
2020-10-29 09:18:31 +01:00
170 changed files with 4396 additions and 1170 deletions

View File

@@ -171,9 +171,8 @@ int AndroidQtVersion::minimumNDK() const
void AndroidQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const
{
if (supportsMultipleQtAbis())
m_androidAbis = evaluator->values("ALL_ANDROID_ABIS");
else
m_androidAbis = evaluator->values("ALL_ANDROID_ABIS");
if (m_androidAbis.isEmpty())
m_androidAbis = QStringList{evaluator->value("ANDROID_TARGET_ARCH")};
const QString androidPlatform = evaluator->value("ANDROID_PLATFORM");
if (!androidPlatform.isEmpty()) {

View File

@@ -14,6 +14,7 @@ add_qtc_plugin(BareMetal
debugserverprovidermanager.cpp debugserverprovidermanager.h
debugserverproviderssettingspage.cpp debugserverproviderssettingspage.h
debugservers/gdb/gdbserverprovider.cpp debugservers/gdb/gdbserverprovider.h
debugservers/gdb/genericgdbserverprovider.cpp debugservers/gdb/genericgdbserverprovider.h
debugservers/gdb/openocdgdbserverprovider.cpp debugservers/gdb/openocdgdbserverprovider.h
debugservers/gdb/stlinkutilgdbserverprovider.cpp debugservers/gdb/stlinkutilgdbserverprovider.h
debugservers/gdb/jlinkgdbserverprovider.cpp debugservers/gdb/jlinkgdbserverprovider.h

View File

@@ -42,6 +42,7 @@ QtcPlugin {
prefix: "debugservers/gdb/"
files: [
"gdbserverprovider.cpp", "gdbserverprovider.h",
"genericgdbserverprovider.cpp", "genericgdbserverprovider.h",
"openocdgdbserverprovider.cpp", "openocdgdbserverprovider.h",
"stlinkutilgdbserverprovider.cpp", "stlinkutilgdbserverprovider.h",
"jlinkgdbserverprovider.cpp", "jlinkgdbserverprovider.h",

View File

@@ -39,6 +39,7 @@ const char DEBUG_SERVER_PROVIDERS_SETTINGS_ID[] = "EE.BareMetal.DebugServerProvi
// GDB Debugger Server Provider Ids.
const char GDBSERVER_OPENOCD_PROVIDER_ID[] = "BareMetal.GdbServerProvider.OpenOcd";
const char GDBSERVER_JLINK_PROVIDER_ID[] = "BareMetal.GdbServerProvider.JLink";
const char GDBSERVER_GENERIC_PROVIDER_ID[] = "BareMetal.GdbServerProvider.Generic";
const char GDBSERVER_STLINK_UTIL_PROVIDER_ID[] = "BareMetal.GdbServerProvider.STLinkUtil";
const char GDBSERVER_EBLINK_PROVIDER_ID[] = "BareMetal.GdbServerProvider.EBlink";

View File

@@ -27,6 +27,7 @@
#include "idebugserverprovider.h"
// GDB debug servers.
#include "debugservers/gdb/genericgdbserverprovider.h"
#include "debugservers/gdb/openocdgdbserverprovider.h"
#include "debugservers/gdb/stlinkutilgdbserverprovider.h"
#include "debugservers/gdb/jlinkgdbserverprovider.h"
@@ -61,7 +62,8 @@ static DebugServerProviderManager *m_instance = nullptr;
DebugServerProviderManager::DebugServerProviderManager()
: m_configFile(Utils::FilePath::fromString(Core::ICore::userResourcePath() + fileNameKeyC))
, m_factories({new JLinkGdbServerProviderFactory,
, m_factories({new GenericGdbServerProviderFactory,
new JLinkGdbServerProviderFactory,
new OpenOcdGdbServerProviderFactory,
new StLinkUtilGdbServerProviderFactory,
new EBlinkGdbServerProviderFactory,
@@ -115,7 +117,13 @@ void DebugServerProviderManager::restoreProviders()
if (!data.contains(key))
break;
const QVariantMap map = data.value(key).toMap();
QVariantMap map = data.value(key).toMap();
const QStringList keys = map.keys();
for (const QString &key : keys) {
const int lastDot = key.lastIndexOf('.');
if (lastDot != -1)
map[key.mid(lastDot + 1)] = map[key];
}
bool restored = false;
for (IDebugServerProviderFactory *f : qAsConst(m_factories)) {
if (f->canRestore(map)) {

View File

@@ -46,17 +46,17 @@ using namespace Utils;
namespace BareMetal {
namespace Internal {
const char executableFileKeyC[] = "BareMetal.EBlinkGdbServerProvider.ExecutableFile";
const char verboseLevelKeyC[] = "BareMetal.EBlinkGdbServerProvider.VerboseLevel";
const char deviceScriptC[] = "BareMetal.EBlinkGdbServerProvider.DeviceScript";
const char interfaceTypeC[] = "BareMetal.EBlinkGdbServerProvider.InterfaceType";
const char interfaceResetOnConnectC[] = "BareMetal.EBlinkGdbServerProvider.interfaceResetOnConnect";
const char interfaceSpeedC[] = "BareMetal.EBlinkGdbServerProvider.InterfaceSpeed";
const char interfaceExplicidDeviceC[] = "BareMetal.EBlinkGdbServerProvider.InterfaceExplicidDevice";
const char targetNameC[] = "BareMetal.EBlinkGdbServerProvider.TargetName";
const char targetDisableStackC[] = "BareMetal.EBlinkGdbServerProvider.TargetDisableStack";
const char gdbShutDownAfterDisconnectC[] = "BareMetal.EBlinkGdbServerProvider.GdbShutDownAfterDisconnect";
const char gdbNotUseCacheC[] = "BareMetal.EBlinkGdbServerProvider.GdbNotUseCache";
const char executableFileKeyC[] = "ExecutableFile";
const char verboseLevelKeyC[] = "VerboseLevel";
const char deviceScriptC[] = "DeviceScript";
const char interfaceTypeC[] = "InterfaceType";
const char interfaceResetOnConnectC[] = "interfaceResetOnConnect";
const char interfaceSpeedC[] = "InterfaceSpeed";
const char interfaceExplicidDeviceC[] = "InterfaceExplicidDevice";
const char targetNameC[] = "TargetName";
const char targetDisableStackC[] = "TargetDisableStack";
const char gdbShutDownAfterDisconnectC[] = "GdbShutDownAfterDisconnect";
const char gdbNotUseCacheC[] = "GdbNotUseCache";
// EBlinkGdbServerProvider
@@ -66,7 +66,6 @@ EBlinkGdbServerProvider::EBlinkGdbServerProvider()
setInitCommands(defaultInitCommands());
setResetCommands(defaultResetCommands());
setChannel("127.0.0.1", 2331);
setSettingsKeyBase("BareMetal.EBlinkGdbServerProvider");
setTypeDisplayName(GdbServerProvider::tr("EBlink"));
setConfigurationWidgetCreator([this] { return new EBlinkGdbServerProviderConfigWidget(this); });
}

View File

@@ -49,11 +49,11 @@ using namespace Utils;
namespace BareMetal {
namespace Internal {
const char startupModeKeyC[] = "BareMetal.GdbServerProvider.Mode";
const char peripheralDescriptionFileKeyC[] = "BareMetal.GdbServerProvider.PeripheralDescriptionFile";
const char initCommandsKeyC[] = "BareMetal.GdbServerProvider.InitCommands";
const char resetCommandsKeyC[] = "BareMetal.GdbServerProvider.ResetCommands";
const char useExtendedRemoteKeyC[] = "BareMetal.GdbServerProvider.UseExtendedRemote";
const char startupModeKeyC[] = "Mode";
const char peripheralDescriptionFileKeyC[] = "PeripheralDescriptionFile";
const char initCommandsKeyC[] = "InitCommands";
const char resetCommandsKeyC[] = "ResetCommands";
const char useExtendedRemoteKeyC[] = "UseExtendedRemote";
// GdbServerProvider

View File

@@ -1,13 +1,15 @@
HEADERS += \
$$PWD/eblinkgdbserverprovider.h \
$$PWD/gdbserverprovider.h \
$$PWD/genericgdbserverprovider.h \
$$PWD/jlinkgdbserverprovider.h \
$$PWD/openocdgdbserverprovider.h \
$$PWD/stlinkutilgdbserverprovider.h \
$$PWD/jlinkgdbserverprovider.h \
SOURCES += \
$$PWD/eblinkgdbserverprovider.cpp \
$$PWD/gdbserverprovider.cpp \
$$PWD/genericgdbserverprovider.cpp \
$$PWD/jlinkgdbserverprovider.cpp \
$$PWD/openocdgdbserverprovider.cpp \
$$PWD/stlinkutilgdbserverprovider.cpp \
$$PWD/jlinkgdbserverprovider.cpp \

View File

@@ -0,0 +1,134 @@
/****************************************************************************
**
** Copyright (C) 2020 Denis Shienkov <denis.shienkov@gmail.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "genericgdbserverprovider.h"
#include <baremetal/baremetalconstants.h>
#include <baremetal/debugserverprovidermanager.h>
#include <utils/qtcassert.h>
#include <utils/variablechooser.h>
#include <QCheckBox>
#include <QFormLayout>
#include <QPlainTextEdit>
namespace BareMetal {
namespace Internal {
// GenericGdbServerProvider
GenericGdbServerProvider::GenericGdbServerProvider()
: GdbServerProvider(Constants::GDBSERVER_GENERIC_PROVIDER_ID)
{
setChannel("localhost", 3333);
setTypeDisplayName(GdbServerProvider::tr("Generic"));
setConfigurationWidgetCreator([this] { return new GenericGdbServerProviderConfigWidget(this); });
}
QSet<GdbServerProvider::StartupMode> GenericGdbServerProvider::supportedStartupModes() const
{
return {StartupOnNetwork};
}
// GenericGdbServerProviderFactory
GenericGdbServerProviderFactory::GenericGdbServerProviderFactory()
{
setId(Constants::GDBSERVER_GENERIC_PROVIDER_ID);
setDisplayName(GdbServerProvider::tr("Generic"));
setCreator([] { return new GenericGdbServerProvider; });
}
// GdbServerProviderConfigWidget
GenericGdbServerProviderConfigWidget::GenericGdbServerProviderConfigWidget(
GenericGdbServerProvider *provider)
: GdbServerProviderConfigWidget(provider)
{
Q_ASSERT(provider);
m_hostWidget = new HostWidget(this);
m_mainLayout->addRow(tr("Host:"), m_hostWidget);
m_useExtendedRemoteCheckBox = new QCheckBox(this);
m_useExtendedRemoteCheckBox->setToolTip("Use GDB target extended-remote");
m_mainLayout->addRow(tr("Extended mode:"), m_useExtendedRemoteCheckBox);
m_initCommandsTextEdit = new QPlainTextEdit(this);
m_initCommandsTextEdit->setToolTip(defaultInitCommandsTooltip());
m_mainLayout->addRow(tr("Init commands:"), m_initCommandsTextEdit);
m_resetCommandsTextEdit = new QPlainTextEdit(this);
m_resetCommandsTextEdit->setToolTip(defaultResetCommandsTooltip());
m_mainLayout->addRow(tr("Reset commands:"), m_resetCommandsTextEdit);
addErrorLabel();
setFromProvider();
const auto chooser = new Utils::VariableChooser(this);
chooser->addSupportedWidget(m_initCommandsTextEdit);
chooser->addSupportedWidget(m_resetCommandsTextEdit);
connect(m_hostWidget, &HostWidget::dataChanged,
this, &GdbServerProviderConfigWidget::dirty);
connect(m_useExtendedRemoteCheckBox, &QCheckBox::stateChanged,
this, &GdbServerProviderConfigWidget::dirty);
connect(m_initCommandsTextEdit, &QPlainTextEdit::textChanged,
this, &GdbServerProviderConfigWidget::dirty);
connect(m_resetCommandsTextEdit, &QPlainTextEdit::textChanged,
this, &GdbServerProviderConfigWidget::dirty);
}
void GenericGdbServerProviderConfigWidget::apply()
{
const auto p = static_cast<GenericGdbServerProvider *>(m_provider);
Q_ASSERT(p);
p->setChannel(m_hostWidget->channel());
p->setUseExtendedRemote(m_useExtendedRemoteCheckBox->isChecked());
p->setInitCommands(m_initCommandsTextEdit->toPlainText());
p->setResetCommands(m_resetCommandsTextEdit->toPlainText());
IDebugServerProviderConfigWidget::apply();
}
void GenericGdbServerProviderConfigWidget::discard()
{
setFromProvider();
IDebugServerProviderConfigWidget::discard();
}
void GenericGdbServerProviderConfigWidget::setFromProvider()
{
const auto p = static_cast<GenericGdbServerProvider *>(m_provider);
Q_ASSERT(p);
const QSignalBlocker blocker(this);
m_hostWidget->setChannel(p->channel());
m_useExtendedRemoteCheckBox->setChecked(p->useExtendedRemote());
m_initCommandsTextEdit->setPlainText(p->initCommands());
m_resetCommandsTextEdit->setPlainText(p->resetCommands());
}
} // namespace Internal
} // namespace ProjectExplorer

View File

@@ -0,0 +1,83 @@
/****************************************************************************
**
** Copyright (C) 2020 Denis Shienkov <denis.shienkov@gmail.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "gdbserverprovider.h"
QT_BEGIN_NAMESPACE
class QCheckBox;
class QPlainTextEdit;
QT_END_NAMESPACE
namespace BareMetal {
namespace Internal {
// GenericGdbServerProvider
class GenericGdbServerProvider final : public GdbServerProvider
{
private:
GenericGdbServerProvider();
QSet<StartupMode> supportedStartupModes() const final;
friend class GenericGdbServerProviderConfigWidget;
friend class GenericGdbServerProviderFactory;
friend class BareMetalDevice;
};
// GenericGdbServerProviderFactory
class GenericGdbServerProviderFactory final : public IDebugServerProviderFactory
{
public:
GenericGdbServerProviderFactory();
};
// GenericGdbServerProviderConfigWidget
class GenericGdbServerProviderConfigWidget final
: public GdbServerProviderConfigWidget
{
Q_OBJECT
public:
explicit GenericGdbServerProviderConfigWidget(
GenericGdbServerProvider *provider);
private:
void apply() final;
void discard() final;
void setFromProvider();
HostWidget *m_hostWidget = nullptr;
QCheckBox *m_useExtendedRemoteCheckBox = nullptr;
QPlainTextEdit *m_initCommandsTextEdit = nullptr;
QPlainTextEdit *m_resetCommandsTextEdit = nullptr;
};
} // namespace Internal
} // namespace BareMetal

View File

@@ -46,13 +46,13 @@ using namespace Utils;
namespace BareMetal {
namespace Internal {
const char executableFileKeyC[] = "BareMetal.JLinkGdbServerProvider.ExecutableFile";
const char jlinkDeviceKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkDevice";
const char jlinkHostInterfaceKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkHostInterface";
const char jlinkHostInterfaceIPAddressKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkHostInterfaceIPAddress";
const char jlinkTargetInterfaceKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkTargetInterface";
const char jlinkTargetInterfaceSpeedKeyC[] = "BareMetal.JLinkGdbServerProvider.JLinkTargetInterfaceSpeed";
const char additionalArgumentsKeyC[] = "BareMetal.JLinkGdbServerProvider.AdditionalArguments";
const char executableFileKeyC[] = "ExecutableFile";
const char jlinkDeviceKeyC[] = "JLinkDevice";
const char jlinkHostInterfaceKeyC[] = "JLinkHostInterface";
const char jlinkHostInterfaceIPAddressKeyC[] = "JLinkHostInterfaceIPAddress";
const char jlinkTargetInterfaceKeyC[] = "JLinkTargetInterface";
const char jlinkTargetInterfaceSpeedKeyC[] = "JLinkTargetInterfaceSpeed";
const char additionalArgumentsKeyC[] = "AdditionalArguments";
// JLinkGdbServerProvider
@@ -62,7 +62,6 @@ JLinkGdbServerProvider::JLinkGdbServerProvider()
setInitCommands(defaultInitCommands());
setResetCommands(defaultResetCommands());
setChannel("localhost", 2331);
setSettingsKeyBase("BareMetal.JLinkGdbServerProvider");
setTypeDisplayName(GdbServerProvider::tr("JLink"));
setConfigurationWidgetCreator([this] { return new JLinkGdbServerProviderConfigWidget(this); });
}

View File

@@ -44,10 +44,10 @@ using namespace Utils;
namespace BareMetal {
namespace Internal {
const char executableFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ExecutableFile";
const char rootScriptsDirKeyC[] = "BareMetal.OpenOcdGdbServerProvider.RootScriptsDir";
const char configurationFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ConfigurationPath";
const char additionalArgumentsKeyC[] = "BareMetal.OpenOcdGdbServerProvider.AdditionalArguments";
const char executableFileKeyC[] = "ExecutableFile";
const char rootScriptsDirKeyC[] = "RootScriptsDir";
const char configurationFileKeyC[] = "ConfigurationPath";
const char additionalArgumentsKeyC[] = "AdditionalArguments";
// OpenOcdGdbServerProvider
@@ -57,7 +57,6 @@ OpenOcdGdbServerProvider::OpenOcdGdbServerProvider()
setInitCommands(defaultInitCommands());
setResetCommands(defaultResetCommands());
setChannel("localhost", 3333);
setSettingsKeyBase("BareMetal.OpenOcdGdbServerProvider");
setTypeDisplayName(GdbServerProvider::tr("OpenOCD"));
setConfigurationWidgetCreator([this] { return new OpenOcdGdbServerProviderConfigWidget(this); });
}

View File

@@ -44,11 +44,11 @@ using namespace Utils;
namespace BareMetal {
namespace Internal {
const char executableFileKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExecutableFile";
const char verboseLevelKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.VerboseLevel";
const char extendedModeKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExtendedMode";
const char resetBoardKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ResetBoard";
const char transportLayerKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.TransportLayer";
const char executableFileKeyC[] = "ExecutableFile";
const char verboseLevelKeyC[] = "VerboseLevel";
const char extendedModeKeyC[] = "ExtendedMode";
const char resetBoardKeyC[] = "ResetBoard";
const char transportLayerKeyC[] = "TransportLayer";
// StLinkUtilGdbServerProvider
@@ -58,7 +58,6 @@ StLinkUtilGdbServerProvider::StLinkUtilGdbServerProvider()
setInitCommands(defaultInitCommands());
setResetCommands(defaultResetCommands());
setChannel("localhost", 4242);
setSettingsKeyBase("BareMetal.StLinkUtilGdbServerProvider");
setTypeDisplayName(GdbServerProvider::tr("ST-LINK Utility"));
setConfigurationWidgetCreator([this] { return new StLinkUtilGdbServerProviderConfigWidget(this); });
}

View File

@@ -52,9 +52,9 @@ namespace Internal {
using namespace Uv;
constexpr char adapterOptionsKeyC[] = "BareMetal.JLinkUvscServerProvider.AdapterOptions";
constexpr char adapterPortKeyC[] = "BareMetal.JLinkUvscServerProvider.AdapterPort";
constexpr char adapterSpeedKeyC[] = "BareMetal.JLinkUvscServerProvider.AdapterSpeed";
constexpr char adapterOptionsKeyC[] = "AdapterOptions";
constexpr char adapterPortKeyC[] = "AdapterPort";
constexpr char adapterSpeedKeyC[] = "AdapterSpeed";
static int decodeSpeedCode(JLinkUvscAdapterOptions::Speed speed)
{

View File

@@ -50,7 +50,7 @@ namespace Internal {
using namespace Uv;
const char limitSpeedKeyC[] = "BareMetal.SimulatorUvscServerProvider.LimitSpeed";
const char limitSpeedKeyC[] = "LimitSpeed";
static DriverSelection defaultSimulatorDriverSelection()
{

View File

@@ -52,9 +52,9 @@ namespace Internal {
using namespace Uv;
constexpr char adapterOptionsKeyC[] = "BareMetal.StLinkUvscServerProvider.AdapterOptions";
constexpr char adapterPortKeyC[] = "BareMetal.StLinkUvscServerProvider.AdapterPort";
constexpr char adapterSpeedKeyC[] = "BareMetal.StLinkUvscServerProvider.AdapterSpeed";
constexpr char adapterOptionsKeyC[] = "AdapterOptions";
constexpr char adapterPortKeyC[] = "AdapterPort";
constexpr char adapterSpeedKeyC[] = "AdapterSpeed";
static QString buildAdapterOptions(const StLinkUvscAdapterOptions &opts)
{

View File

@@ -58,9 +58,9 @@ namespace Internal {
using namespace Uv;
// Whole software package selection keys.
constexpr char toolsIniKeyC[] = "BareMetal.UvscServerProvider.ToolsIni";
constexpr char deviceSelectionKeyC[] = "BareMetal.UvscServerProvider.DeviceSelection";
constexpr char driverSelectionKeyC[] = "BareMetal.UvscServerProvider.DriverSelection";
constexpr char toolsIniKeyC[] = "ToolsIni";
constexpr char deviceSelectionKeyC[] = "DeviceSelection";
constexpr char driverSelectionKeyC[] = "DriverSelection";
constexpr int defaultPortNumber = 5101;

View File

@@ -38,39 +38,39 @@ namespace Internal {
namespace Uv {
// Software package data keys.
constexpr char packageDescrKeyC[] = "BareMetal.UvscServerProvider.PackageDescription";
constexpr char packageFileKeyC[] = "BareMetal.UvscServerProvider.PackageFile";
constexpr char packageNameKeyC[] = "BareMetal.UvscServerProvider.PackageName";
constexpr char packageUrlKeyC[] = "BareMetal.UvscServerProvider.PackageUrl";
constexpr char packageVendorNameKeyC[] = "BareMetal.UvscServerProvider.PackageVendorName";
constexpr char packageVendorIdKeyC[] = "BareMetal.UvscServerProvider.PackageVendorId";
constexpr char packageVersionKeyC[] = "BareMetal.UvscServerProvider.PackageVersion";
constexpr char packageDescrKeyC[] = "PackageDescription";
constexpr char packageFileKeyC[] = "PackageFile";
constexpr char packageNameKeyC[] = "PackageName";
constexpr char packageUrlKeyC[] = "PackageUrl";
constexpr char packageVendorNameKeyC[] = "PackageVendorName";
constexpr char packageVendorIdKeyC[] = "PackageVendorId";
constexpr char packageVersionKeyC[] = "PackageVersion";
// Device data keys.
constexpr char deviceNameKeyC[] = "BareMetal.UvscServerProvider.DeviceName";
constexpr char deviceDescrKeyC[] = "BareMetal.UvscServerProvider.DeviceDescription";
constexpr char deviceFamilyKeyC[] = "BareMetal.UvscServerProvider.DeviceFamily";
constexpr char deviceSubFamilyKeyC[] = "BareMetal.UvscServerProvider.DeviceSubFamily";
constexpr char deviceVendorNameKeyC[] = "BareMetal.UvscServerProvider.DeviceVendorName";
constexpr char deviceVendorIdKeyC[] = "BareMetal.UvscServerProvider.DeviceVendorId";
constexpr char deviceSvdKeyC[] = "BareMetal.UvscServerProvider.DeviceSVD";
constexpr char deviceNameKeyC[] = "DeviceName";
constexpr char deviceDescrKeyC[] = "DeviceDescription";
constexpr char deviceFamilyKeyC[] = "DeviceFamily";
constexpr char deviceSubFamilyKeyC[] = "DeviceSubFamily";
constexpr char deviceVendorNameKeyC[] = "DeviceVendorName";
constexpr char deviceVendorIdKeyC[] = "DeviceVendorId";
constexpr char deviceSvdKeyC[] = "DeviceSVD";
// Device CPU data keys.
constexpr char deviceClockKeyC[] = "BareMetal.UvscServerProvider.DeviceClock";
constexpr char deviceCoreKeyC[] = "BareMetal.UvscServerProvider.DeviceCore";
constexpr char deviceFpuKeyC[] = "BareMetal.UvscServerProvider.DeviceFPU";
constexpr char deviceMpuKeyC[] = "BareMetal.UvscServerProvider.DeviceMPU";
constexpr char deviceClockKeyC[] = "DeviceClock";
constexpr char deviceCoreKeyC[] = "DeviceCore";
constexpr char deviceFpuKeyC[] = "DeviceFPU";
constexpr char deviceMpuKeyC[] = "DeviceMPU";
// Device MEMORY data keys.
constexpr char deviceMemoryKeyC[] = "BareMetal.UvscServerProvider.DeviceMemory";
constexpr char deviceMemoryIdKeyC[] = "BareMetal.UvscServerProvider.DeviceMemoryId";
constexpr char deviceMemoryStartKeyC[] = "BareMetal.UvscServerProvider.DeviceMemoryStart";
constexpr char deviceMemorySizeKeyC[] = "BareMetal.UvscServerProvider.DeviceMemorySize";
constexpr char deviceMemoryKeyC[] = "DeviceMemory";
constexpr char deviceMemoryIdKeyC[] = "DeviceMemoryId";
constexpr char deviceMemoryStartKeyC[] = "DeviceMemoryStart";
constexpr char deviceMemorySizeKeyC[] = "DeviceMemorySize";
// Device ALGORITHM data keys.
constexpr char deviceAlgorithmKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithm";
constexpr char deviceAlgorithmPathKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmPath";
constexpr char deviceAlgorithmFlashStartKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmStart";
constexpr char deviceAlgorithmFlashSizeKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmSize";
constexpr char deviceAlgorithmRamStartKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmRamStart";
constexpr char deviceAlgorithmRamSizeKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmRamSize";
constexpr char deviceAlgorithmIndexKeyC[] = "BareMetal.UvscServerProvider.DeviceAlgorithmIndex";
constexpr char deviceAlgorithmKeyC[] = "DeviceAlgorithm";
constexpr char deviceAlgorithmPathKeyC[] = "DeviceAlgorithmPath";
constexpr char deviceAlgorithmFlashStartKeyC[] = "DeviceAlgorithmStart";
constexpr char deviceAlgorithmFlashSizeKeyC[] = "DeviceAlgorithmSize";
constexpr char deviceAlgorithmRamStartKeyC[] = "DeviceAlgorithmRamStart";
constexpr char deviceAlgorithmRamSizeKeyC[] = "DeviceAlgorithmRamSize";
constexpr char deviceAlgorithmIndexKeyC[] = "DeviceAlgorithmIndex";
// DeviceSelection

View File

@@ -36,11 +36,11 @@ namespace Internal {
namespace Uv {
// Driver data keys.
constexpr char driverIndexKeyC[] = "BareMetal.UvscServerProvider.DriverIndex";
constexpr char driverCpuDllIndexKeyC[] = "BareMetal.UvscServerProvider.DriverCpuDllIndex";
constexpr char driverDllKeyC[] = "BareMetal.UvscServerProvider.DriverDll";
constexpr char driverCpuDllsKeyC[] = "BareMetal.UvscServerProvider.DriverCpuDlls";
constexpr char driverNameKeyC[] = "BareMetal.UvscServerProvider.DriverName";
constexpr char driverIndexKeyC[] = "DriverIndex";
constexpr char driverCpuDllIndexKeyC[] = "DriverCpuDllIndex";
constexpr char driverDllKeyC[] = "DriverDll";
constexpr char driverCpuDllsKeyC[] = "DriverCpuDlls";
constexpr char driverNameKeyC[] = "DriverName";
// DriverSelection

View File

@@ -58,9 +58,9 @@ namespace Internal {
// Helpers:
static const char compilerCommandKeyC[] = "BareMetal.IarToolChain.CompilerPath";
static const char compilerPlatformCodeGenFlagsKeyC[] = "BareMetal.IarToolChain.PlatformCodeGenFlags";
static const char targetAbiKeyC[] = "BareMetal.IarToolChain.TargetAbi";
static const char compilerCommandKeyC[] = "CompilerPath";
static const char compilerPlatformCodeGenFlagsKeyC[] = "PlatformCodeGenFlags";
static const char targetAbiKeyC[] = "TargetAbi";
static bool compilerExists(const FilePath &compilerPath)
{

View File

@@ -43,12 +43,12 @@ using namespace ProjectExplorer;
namespace BareMetal {
namespace Internal {
const char idKeyC[] = "BareMetal.IDebugServerProvider.Id";
const char displayNameKeyC[] = "BareMetal.IDebugServerProvider.DisplayName";
const char engineTypeKeyC[] = "BareMetal.IDebugServerProvider.EngineType";
const char idKeyC[] = "Id";
const char displayNameKeyC[] = "DisplayName";
const char engineTypeKeyC[] = "EngineType";
const char hostKeySuffixC[] = ".Host";
const char portKeySuffixC[] = ".Port";
const char hostKeyC[] = "Host";
const char portKeyC[] = "Port";
static QString createId(const QString &id)
{
@@ -139,11 +139,6 @@ void IDebugServerProvider::setEngineType(DebuggerEngineType engineType)
providerUpdated();
}
void IDebugServerProvider::setSettingsKeyBase(const QString &settingsBase)
{
m_settingsBase = settingsBase;
}
bool IDebugServerProvider::operator==(const IDebugServerProvider &other) const
{
if (this == &other)
@@ -170,8 +165,8 @@ QVariantMap IDebugServerProvider::toMap() const
{idKeyC, m_id},
{displayNameKeyC, m_displayName},
{engineTypeKeyC, m_engineType},
{m_settingsBase + hostKeySuffixC, m_channel.host()},
{m_settingsBase + portKeySuffixC, m_channel.port()},
{hostKeyC, m_channel.host()},
{portKeyC, m_channel.port()},
};
}
@@ -201,8 +196,8 @@ bool IDebugServerProvider::fromMap(const QVariantMap &data)
m_displayName = data.value(displayNameKeyC).toString();
m_engineType = static_cast<DebuggerEngineType>(
data.value(engineTypeKeyC, NoEngineType).toInt());
m_channel.setHost(data.value(m_settingsBase + hostKeySuffixC).toString());
m_channel.setPort(data.value(m_settingsBase + portKeySuffixC).toInt());
m_channel.setHost(data.value(hostKeyC).toString());
m_channel.setPort(data.value(portKeyC).toInt());
return true;
}
@@ -238,9 +233,7 @@ IDebugServerProvider *IDebugServerProviderFactory::create() const
IDebugServerProvider *IDebugServerProviderFactory::restore(const QVariantMap &data) const
{
IDebugServerProvider *p = m_creator();
const auto updated = data;
if (p->fromMap(updated))
if (p->fromMap(data))
return p;
delete p;
return nullptr;

View File

@@ -104,7 +104,6 @@ public:
protected:
void setTypeDisplayName(const QString &typeDisplayName);
void setEngineType(Debugger::DebuggerEngineType engineType);
void setSettingsKeyBase(const QString &settingsBase);
void providerUpdated();
void resetId();
@@ -112,7 +111,6 @@ protected:
QString m_id;
mutable QString m_displayName;
QString m_typeDisplayName;
QString m_settingsBase;
QUrl m_channel;
Debugger::DebuggerEngineType m_engineType = Debugger::NoEngineType;
QSet<BareMetalDevice *> m_devices;

View File

@@ -60,9 +60,9 @@ namespace Internal {
// Helpers:
static const char compilerCommandKeyC[] = "BareMetal.KeilToolchain.CompilerPath";
static const char compilerPlatformCodeGenFlagsKeyC[] = "BareMetal.KeilToolchain.PlatformCodeGenFlags";
static const char targetAbiKeyC[] = "BareMetal.KeilToolchain.TargetAbi";
static const char compilerCommandKeyC[] = "CompilerPath";
static const char compilerPlatformCodeGenFlagsKeyC[] = "PlatformCodeGenFlags";
static const char targetAbiKeyC[] = "TargetAbi";
static bool compilerExists(const FilePath &compilerPath)
{

View File

@@ -58,8 +58,8 @@ namespace Internal {
// Helpers:
static const char compilerCommandKeyC[] = "BareMetal.SdccToolChain.CompilerPath";
static const char targetAbiKeyC[] = "BareMetal.SdccToolChain.TargetAbi";
static const char compilerCommandKeyC[] = "CompilerPath";
static const char targetAbiKeyC[] = "TargetAbi";
static bool compilerExists(const FilePath &compilerPath)
{

View File

@@ -121,7 +121,7 @@ AnalyzeUnit::AnalyzeUnit(const FileInfo &fileInfo,
{
CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart,
UseSystemHeader::No,
UseTweakedHeaderPaths::Yes,
UseTweakedHeaderPaths::Tools,
UseLanguageDefines::No,
UseBuildSystemWarnings::No,
clangVersion,

View File

@@ -629,8 +629,10 @@ bool DiagnosticFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s
const Diagnostic &diag = diagnosticItem->diagnostic();
// Filtered out?
if (m_filterOptions && !m_filterOptions->checks.contains(diag.name))
if (m_filterOptions && !m_filterOptions->checks.contains(diag.name)) {
diagnosticItem->textMark()->setVisible(false);
return false;
}
// Explicitly suppressed?
foreach (const SuppressedDiagnostic &d, m_suppressedDiagnostics) {
@@ -640,10 +642,12 @@ bool DiagnosticFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s
QFileInfo fi(filePath);
if (fi.isRelative())
filePath = m_lastProjectDirectory.toString() + QLatin1Char('/') + filePath;
if (filePath == diag.location.filePath)
if (filePath == diag.location.filePath) {
diagnosticItem->textMark()->setVisible(false);
return false;
}
}
diagnosticItem->textMark()->setVisible(true);
return true;
}

View File

@@ -74,6 +74,7 @@ public:
~DiagnosticItem() override;
const Diagnostic &diagnostic() const { return m_diagnostic; }
TextEditor::TextMark *textMark() { return m_mark; }
FixitStatus fixItStatus() const { return m_fixitStatus; }
void setFixItStatus(const FixitStatus &status);

View File

@@ -232,12 +232,14 @@ void DiagnosticView::goNext()
{
const QModelIndex currentIndex = selectionModel()->currentIndex();
selectIndex(getIndex(currentIndex, Next));
openEditorForCurrentIndex();
}
void DiagnosticView::goBack()
{
const QModelIndex currentIndex = selectionModel()->currentIndex();
selectIndex(getIndex(currentIndex, Previous));
openEditorForCurrentIndex();
}
QModelIndex DiagnosticView::getIndex(const QModelIndex &index, Direction direction) const

View File

@@ -69,7 +69,7 @@
<item>
<widget class="QPushButton" name="topicsResetButton">
<property name="text">
<string>Reset to All</string>
<string>Reset Filter</string>
</property>
</widget>
</item>

View File

@@ -199,13 +199,6 @@ static bool needsLink(ProjectExplorer::Tree *node) {
return !node->isDir && !node->fullPath.toString().startsWith("clang-analyzer-");
}
static void selectAll(QAbstractItemView *view)
{
view->setSelectionMode(QAbstractItemView::MultiSelection);
view->selectAll();
view->setSelectionMode(QAbstractItemView::SingleSelection);
}
class BaseChecksTreeModel : public ProjectExplorer::SelectableFilesModel
{
Q_OBJECT
@@ -628,7 +621,7 @@ public:
const auto *node = ClazyChecksTree::fromIndex(index);
if (node->kind == ClazyChecksTree::CheckNode) {
const QStringList topics = node->check.topics;
return Utils::anyOf(m_topics, [topics](const QString &topic) {
return m_topics.isEmpty() || Utils::anyOf(m_topics, [topics](const QString &topic) {
return topics.contains(topic);
});
}
@@ -717,8 +710,9 @@ DiagnosticConfigsWidget::DiagnosticConfigsWidget(const ClangDiagnosticConfigs &c
topicsModel->sort(0);
m_clazyChecks->topicsView->setModel(topicsModel);
connect(m_clazyChecks->topicsResetButton, &QPushButton::clicked, [this](){
selectAll(m_clazyChecks->topicsView);
m_clazyChecks->topicsView->clearSelection();
});
m_clazyChecks->topicsView->setSelectionMode(QAbstractItemView::MultiSelection);
connect(m_clazyChecks->topicsView->selectionModel(),
&QItemSelectionModel::selectionChanged,
[this, topicsModel](const QItemSelection &, const QItemSelection &) {
@@ -731,7 +725,6 @@ DiagnosticConfigsWidget::DiagnosticConfigsWidget(const ClangDiagnosticConfigs &c
this->syncClazyChecksGroupBox();
});
selectAll(m_clazyChecks->topicsView);
connect(m_clazyChecks->checksView,
&QTreeView::clicked,
[model = m_clazySortFilterProxyModel](const QModelIndex &index) {
@@ -866,7 +859,7 @@ void DiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &conf
const bool enabled = !config.isReadOnly();
m_clazyChecks->topicsResetButton->setEnabled(enabled);
m_clazyChecks->enableLowerLevelsCheckBox->setEnabled(enabled);
selectAll(m_clazyChecks->topicsView);
m_clazyChecks->topicsView->clearSelection();
m_clazyChecks->topicsView->setEnabled(enabled);
m_clazyTreeModel->setEnabled(enabled);

View File

@@ -194,6 +194,9 @@ void DocumentClangToolRunner::run()
const RunSettings &runSettings = projectSettings->useGlobalSettings()
? ClangToolsSettings::instance()->runSettings()
: projectSettings->runSettings();
m_suppressed = projectSettings->suppressedDiagnostics();
m_lastProjectDirectory = project->projectDirectory();
m_projectSettingsUpdate = connect(projectSettings.data(),
&ClangToolsProjectSettings::changed,
this,
@@ -293,6 +296,9 @@ void DocumentClangToolRunner::onSuccess()
TextEditor::RefactorMarkers markers;
for (const Diagnostic &diagnostic : diagnostics) {
if (isSuppressed(diagnostic))
continue;
auto mark = new DiagnosticMark(diagnostic);
mark->source = m_currentRunner->name();
@@ -351,6 +357,20 @@ void DocumentClangToolRunner::cancel()
}
}
bool DocumentClangToolRunner::isSuppressed(const Diagnostic &diagnostic) const
{
auto equalsSuppressed = [this, &diagnostic](const SuppressedDiagnostic &suppressed) {
if (suppressed.description != diagnostic.description)
return false;
QString filePath = suppressed.filePath.toString();
QFileInfo fi(filePath);
if (fi.isRelative())
filePath = m_lastProjectDirectory.toString() + QLatin1Char('/') + filePath;
return filePath == diagnostic.location.filePath;
};
return Utils::anyOf(m_suppressed, equalsSuppressed);
}
const CppTools::ClangDiagnosticConfig DocumentClangToolRunner::getDiagnosticConfig(ProjectExplorer::Project *project)
{
const auto projectSettings = ClangToolsProjectSettings::getSettings(project);

View File

@@ -27,6 +27,7 @@
#include "clangfileinfo.h"
#include "clangtoolsdiagnostic.h"
#include "clangtoolsprojectsettings.h"
#include <utils/fileutils.h>
#include <utils/temporarydirectory.h>
@@ -67,6 +68,7 @@ private:
void cancel();
bool isSuppressed(const Diagnostic &diagnostic) const;
const CppTools::ClangDiagnosticConfig getDiagnosticConfig(ProjectExplorer::Project *project);
template<class T>
@@ -82,6 +84,8 @@ private:
FileInfo m_fileInfo;
QMetaObject::Connection m_projectSettingsUpdate;
QSet<TextEditor::TextEditorWidget *> m_editorsWithMarkers;
SuppressedDiagnosticsList m_suppressed;
Utils::FilePath m_lastProjectDirectory;
};
} // namespace Internal

View File

@@ -1650,62 +1650,91 @@ bool EditorManagerPrivate::closeEditors(const QList<IEditor*> &editors, CloseFla
if (acceptedEditors.isEmpty())
return false;
QList<EditorView*> closedViews;
EditorView *focusView = nullptr;
// remove the editors
foreach (IEditor *editor, acceptedEditors) {
emit m_instance->editorAboutToClose(editor);
if (!editor->document()->filePath().isEmpty()
&& !editor->document()->isTemporary()) {
// save editor states
for (IEditor *editor : qAsConst(acceptedEditors)) {
if (!editor->document()->filePath().isEmpty() && !editor->document()->isTemporary()) {
QByteArray state = editor->saveState();
if (!state.isEmpty())
d->m_editorStates.insert(editor->document()->filePath().toString(), QVariant(state));
}
}
EditorView *focusView = nullptr;
// Remove accepted editors from document model/manager and context list,
// and sort them per view, so we can remove them from views in an orderly
// manner.
QMultiHash<EditorView *, IEditor *> editorsPerView;
for (IEditor *editor : qAsConst(acceptedEditors)) {
emit m_instance->editorAboutToClose(editor);
removeEditor(editor, flag != CloseFlag::Suspend);
if (EditorView *view = viewForEditor(editor)) {
if (QApplication::focusWidget() && QApplication::focusWidget() == editor->widget()->focusWidget())
editorsPerView.insert(view, editor);
if (QApplication::focusWidget()
&& QApplication::focusWidget() == editor->widget()->focusWidget()) {
focusView = view;
if (editor == view->currentEditor())
closedViews += view;
if (d->m_currentEditor == editor) {
// avoid having a current editor without view
setCurrentView(view);
setCurrentEditor(nullptr);
}
view->removeEditor(editor);
}
}
QTC_CHECK(!focusView || focusView == currentView);
// TODO doesn't work as expected with multiple areas in main window and some other cases
// instead each view should have its own file history and handle solely themselves
// which editor is shown if their current editor closes
EditorView *forceViewToShowEditor = nullptr;
if (!closedViews.isEmpty() && EditorManager::visibleEditors().isEmpty()) {
if (closedViews.contains(currentView))
forceViewToShowEditor = currentView;
else
forceViewToShowEditor = closedViews.first();
}
foreach (EditorView *view, closedViews) {
IEditor *newCurrent = view->currentEditor();
if (!newCurrent && forceViewToShowEditor == view)
newCurrent = pickUnusedEditor();
if (newCurrent) {
activateEditor(view, newCurrent, EditorManager::DoNotChangeCurrentEditor);
} else if (forceViewToShowEditor == view) {
DocumentModel::Entry *entry = DocumentModelPrivate::firstSuspendedEntry();
if (entry) {
activateEditorForEntry(view, entry, EditorManager::DoNotChangeCurrentEditor);
} else { // no "suspended" ones, so any entry left should have a document
const QList<DocumentModel::Entry *> documents = DocumentModel::entries();
if (!documents.isEmpty()) {
if (IDocument *document = documents.last()->document) {
activateEditorForDocument(view, document, EditorManager::DoNotChangeCurrentEditor);
// Go through views, remove the editors from them.
// Sort such that views for which the current editor is closed come last,
// and if the global current view is one of them, that comes very last.
// When handling the last view in the list we handle the case where all
// visible editors are closed, and we need to e.g. revive an invisible or
// a suspended editor
QList<EditorView *> views = editorsPerView.keys();
Utils::sort(views, [editorsPerView, currentView](EditorView *a, EditorView *b) {
if (a == b)
return false;
const bool aHasCurrent = editorsPerView.values(a).contains(a->currentEditor());
const bool bHasCurrent = editorsPerView.values(b).contains(b->currentEditor());
const bool aHasGlobalCurrent = (a == currentView && aHasCurrent);
const bool bHasGlobalCurrent = (b == currentView && bHasCurrent);
if (bHasGlobalCurrent && !aHasGlobalCurrent)
return true;
if (bHasCurrent && !aHasCurrent)
return true;
return false;
});
for (EditorView *view : qAsConst(views)) {
QList<IEditor *> editors = editorsPerView.values(view);
// handle current editor in view last
IEditor *viewCurrentEditor = view->currentEditor();
if (editors.contains(viewCurrentEditor) && editors.last() != viewCurrentEditor) {
editors.removeAll(viewCurrentEditor);
editors.append(viewCurrentEditor);
}
for (IEditor *editor : qAsConst(editors)) {
if (editor == viewCurrentEditor && view == views.last()) {
// Avoid removing the globally current editor from its view,
// set a new current editor before.
const EditorManager::OpenEditorFlags flags = view != currentView
? EditorManager::DoNotChangeCurrentEditor
: EditorManager::NoFlags;
const QList<IEditor *> viewEditors = view->editors();
IEditor *newCurrent = viewEditors.size() > 1 ? viewEditors.at(viewEditors.size() - 2)
: nullptr;
if (!newCurrent)
newCurrent = pickUnusedEditor();
if (newCurrent) {
activateEditor(view, newCurrent, flags);
} else {
DocumentModel::Entry *entry = DocumentModelPrivate::firstSuspendedEntry();
if (entry) {
activateEditorForEntry(view, entry, flags);
} else { // no "suspended" ones, so any entry left should have a document
const QList<DocumentModel::Entry *> documents = DocumentModel::entries();
if (!documents.isEmpty()) {
if (IDocument *document = documents.last()->document) {
activateEditorForDocument(view, document, flags);
}
}
}
}
}
view->removeEditor(editor);
}
}

View File

@@ -190,6 +190,7 @@ private slots:
void test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames2();
void test_quickfix_MoveFuncDefOutside_macroUses();
void test_quickfix_MoveFuncDefOutside_template();
void test_quickfix_MoveFuncDefOutside_unnamedTemplate();
void test_quickfix_MoveAllFuncDefOutside_MemberFuncToCpp();
void test_quickfix_MoveAllFuncDefOutside_MemberFuncOutside();

View File

@@ -383,6 +383,32 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_basic1_enum class")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"enum class EnumType { V1, V2 };\n"
"\n"
"void f()\n"
"{\n"
" EnumType t;\n"
" @switch (t) {\n"
" }\n"
"}\n"
) << _(
"enum class EnumType { V1, V2 };\n"
"\n"
"void f()\n"
"{\n"
" EnumType t;\n"
" switch (t) {\n"
" case EnumType::V1:\n"
" break;\n"
" case EnumType::V2:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: All enum values are added as case statements for a blank switch when
// the variable is declared alongside the enum definition.
QTest::newRow("CompleteSwitchCaseStatement_basic1_enum_with_declaration")
@@ -408,6 +434,30 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_basic1_enum_with_declaration_enumClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"enum class EnumType { V1, V2 } t;\n"
"\n"
"void f()\n"
"{\n"
" @switch (t) {\n"
" }\n"
"}\n"
) << _(
"enum class EnumType { V1, V2 } t;\n"
"\n"
"void f()\n"
"{\n"
" switch (t) {\n"
" case EnumType::V1:\n"
" break;\n"
" case EnumType::V2:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: All enum values are added as case statements for a blank switch
// for anonymous enums.
QTest::newRow("CompleteSwitchCaseStatement_basic1_anonymous_enum")
@@ -463,6 +513,36 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_basic2_enumClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"enum class EnumType { V1, V2 };\n"
"\n"
"void f()\n"
"{\n"
" EnumType t;\n"
" @switch (t) {\n"
" default:\n"
" break;\n"
" }\n"
"}\n"
) << _(
"enum class EnumType { V1, V2 };\n"
"\n"
"void f()\n"
"{\n"
" EnumType t;\n"
" switch (t) {\n"
" case EnumType::V1:\n"
" break;\n"
" case EnumType::V2:\n"
" break;\n"
" default:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: Enum type in class is found.
QTest::newRow("CompleteSwitchCaseStatement_enumTypeInClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
@@ -485,6 +565,28 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_enumClassInClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"struct C { enum class EnumType { V1, V2 }; };\n"
"\n"
"void f(C::EnumType t) {\n"
" @switch (t) {\n"
" }\n"
"}\n"
) << _(
"struct C { enum class EnumType { V1, V2 }; };\n"
"\n"
"void f(C::EnumType t) {\n"
" switch (t) {\n"
" case C::EnumType::V1:\n"
" break;\n"
" case C::EnumType::V2:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: Enum type in namespace is found.
QTest::newRow("CompleteSwitchCaseStatement_enumTypeInNamespace")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
@@ -507,6 +609,28 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_enumClassInNamespace")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"namespace N { enum class EnumType { V1, V2 }; };\n"
"\n"
"void f(N::EnumType t) {\n"
" @switch (t) {\n"
" }\n"
"}\n"
) << _(
"namespace N { enum class EnumType { V1, V2 }; };\n"
"\n"
"void f(N::EnumType t) {\n"
" switch (t) {\n"
" case N::EnumType::V1:\n"
" break;\n"
" case N::EnumType::V2:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: The missing enum value is added.
QTest::newRow("CompleteSwitchCaseStatement_oneValueMissing")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
@@ -539,6 +663,38 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Checks: Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_oneValueMissing_enumClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"enum class EnumType { V1, V2 };\n"
"\n"
"void f()\n"
"{\n"
" EnumType t;\n"
" @switch (t) {\n"
" case EnumType::V2:\n"
" break;\n"
" default:\n"
" break;\n"
" }\n"
"}\n"
) << _(
"enum class EnumType { V1, V2 };\n"
"\n"
"void f()\n"
"{\n"
" EnumType t;\n"
" switch (t) {\n"
" case EnumType::V1:\n"
" break;\n"
" case EnumType::V2:\n"
" break;\n"
" default:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: Find the correct enum type despite there being a declaration with the same name.
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_1")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
@@ -563,6 +719,30 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_1_enumClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"enum class test { TEST_1, TEST_2 };\n"
"\n"
"void f() {\n"
" enum test test;\n"
" @switch (test) {\n"
" }\n"
"}\n"
) << _(
"enum class test { TEST_1, TEST_2 };\n"
"\n"
"void f() {\n"
" enum test test;\n"
" switch (test) {\n"
" case test::TEST_1:\n"
" break;\n"
" case test::TEST_2:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: Find the correct enum type despite there being a declaration with the same name.
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_2")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
@@ -591,6 +771,34 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_2_enumClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"enum class test1 { Wrong11, Wrong12 };\n"
"enum class test { Right1, Right2 };\n"
"enum class test2 { Wrong21, Wrong22 };\n"
"\n"
"int main() {\n"
" enum test test;\n"
" @switch (test) {\n"
" }\n"
"}\n"
) << _(
"enum class test1 { Wrong11, Wrong12 };\n"
"enum class test { Right1, Right2 };\n"
"enum class test2 { Wrong21, Wrong22 };\n"
"\n"
"int main() {\n"
" enum test test;\n"
" switch (test) {\n"
" case test::Right1:\n"
" break;\n"
" case test::Right2:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: Do not crash on incomplete case statetement.
QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
@@ -606,6 +814,21 @@ void CppEditorPlugin::test_quickfix_data()
""
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase_enumClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"enum class E {};\n"
"void f(E o)\n"
"{\n"
" @switch (o)\n"
" {\n"
" case\n"
" }\n"
"}\n"
) << _(
""
);
// Checks: complete switch statement where enum is goes via a template type parameter
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG-24752")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
@@ -632,6 +855,32 @@ void CppEditorPlugin::test_quickfix_data()
"}\n"
);
// Same as above for enum class.
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG-24752_enumClass")
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
"enum class E {A, B};\n"
"template<typename T> struct S {\n"
" static T theType() { return T(); }\n"
"};\n"
"int main() {\n"
" @switch (S<E>::theType()) {\n"
" }\n"
"}\n"
) << _(
"enum class E {A, B};\n"
"template<typename T> struct S {\n"
" static T theType() { return T(); }\n"
"};\n"
"int main() {\n"
" switch (S<E>::theType()) {\n"
" case E::A:\n"
" break;\n"
" case E::B:\n"
" break;\n"
" }\n"
"}\n"
);
// Checks: No special treatment for reference to non const.
// Check: Quick fix is not triggered on a member function.
@@ -5954,7 +6203,24 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_template()
"class Foo { void fu@nc(); };\n"
"\n"
"template<class T>\n"
"void Foo::func() {}\n"; // Should be Foo<T>::func
"void Foo<T>::func() {}\n";
;
MoveFuncDefOutside factory;
QuickFixOperationTest(singleDocument(original, expected), &factory);
}
void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_unnamedTemplate()
{
QByteArray original =
"template<typename T, typename>\n"
"class Foo { void fu@nc() {} };\n";
QByteArray expected =
"template<typename T, typename>\n"
"class Foo { void fu@nc(); };\n"
"\n"
"template<typename T, typename T2>\n"
"void Foo<T, T2>::func() {}\n";
;
MoveFuncDefOutside factory;

View File

@@ -2770,7 +2770,12 @@ static Enum *findEnum(const QList<LookupItem> &results, const LookupContext &ctx
return e;
if (const NamedType *namedType = type->asNamedType()) {
if (ClassOrNamespace *con = ctxt.lookupType(namedType->name(), result.scope())) {
const QList<Enum *> enums = con->unscopedEnums();
QList<Enum *> enums = con->unscopedEnums();
const QList<Symbol *> symbols = con->symbols();
for (Symbol * const s : symbols) {
if (const auto e = s->asEnum())
enums << e;
}
const Name *referenceName = namedType->name();
if (const QualifiedNameId *qualifiedName = referenceName->asQualifiedNameId())
referenceName = qualifiedName->name();
@@ -6457,6 +6462,7 @@ QString definitionSignature(const CppQuickFixInterface *assist,
oo.showReturnTypes = true;
oo.showArgumentNames = true;
oo.showEnclosingTemplate = true;
oo.showTemplateParameters = true;
const Name *name = func->name();
if (name && nameIncludesOperatorName(name)) {
CoreDeclaratorAST *coreDeclarator = functionDefinitionAST->declarator->core_declarator;

View File

@@ -298,7 +298,8 @@ void CompilerOptionsBuilder::enableExceptions()
void CompilerOptionsBuilder::insertWrappedQtHeaders()
{
insertWrappedHeaders(wrappedQtHeadersIncludePath());
if (m_useTweakedHeaderPaths == UseTweakedHeaderPaths::Yes)
insertWrappedHeaders(wrappedQtHeadersIncludePath());
}
void CompilerOptionsBuilder::insertWrappedMingwHeaders()

View File

@@ -33,7 +33,7 @@ namespace CppTools {
enum class UsePrecompiledHeaders : char { Yes, No };
enum class UseSystemHeader : char { Yes, No };
enum class UseTweakedHeaderPaths : char { Yes, No };
enum class UseTweakedHeaderPaths : char { Yes, Tools, No };
enum class UseToolchainMacros : char { Yes, No };
enum class UseLanguageDefines : char { Yes, No };
enum class UseBuildSystemWarnings : char { Yes, No };

View File

@@ -8,6 +8,7 @@ Project {
QtcPlugin {
Depends { name: "Qt.widgets" }
Depends { name: "Qt.testlib"; condition: project.withAutotests }
Depends { name: "CPlusPlus" }
Depends { name: "Utils" }
@@ -216,6 +217,15 @@ Project {
"usages.h",
]
Group {
name: "TestCase"
condition: qtc.testsEnabled || project.withAutotests
files: [
"cpptoolstestcase.cpp",
"cpptoolstestcase.h",
]
}
Group {
name: "Tests"
condition: qtc.testsEnabled
@@ -230,8 +240,6 @@ Project {
"cppsourceprocessertesthelper.cpp",
"cppsourceprocessertesthelper.h",
"cppsourceprocessor_test.cpp",
"cpptoolstestcase.cpp",
"cpptoolstestcase.h",
"modelmanagertesthelper.cpp",
"modelmanagertesthelper.h",
"symbolsearcher_test.cpp",

View File

@@ -164,6 +164,11 @@ void BranchView::refresh(const QString &repository, bool force)
m_addButton->setToolTip(tr("Add Branch..."));
m_branchView->setEnabled(true);
}
// Do not refresh the model when the view is hidden
if (!isVisible())
return;
QString errorMessage;
if (!m_model->refresh(m_repository, &errorMessage))
VcsBase::VcsOutputWindow::appendError(errorMessage);
@@ -174,6 +179,11 @@ void BranchView::refreshCurrentBranch()
m_model->refreshCurrentBranch();
}
void BranchView::showEvent(QShowEvent *)
{
refreshCurrentRepository();
}
QToolButton *BranchView::addButton() const
{
return m_addButton;

View File

@@ -65,6 +65,9 @@ public:
QAction *m_includeOldEntriesAction = nullptr;
QAction *m_includeTagsAction = nullptr;
protected:
void showEvent(QShowEvent *) override;
private:
void refreshCurrentRepository();
void resizeColumns();

View File

@@ -1169,7 +1169,7 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams &params)
const DocumentUri &uri = params.uri();
const QList<Diagnostic> &diagnostics = params.diagnostics();
m_diagnosticManager.setDiagnostics(uri, params.diagnostics());
m_diagnosticManager.setDiagnostics(uri, diagnostics);
if (LanguageClientManager::clientForUri(uri) == this) {
m_diagnosticManager.showDiagnostics(uri);
requestCodeActions(uri, diagnostics);

View File

@@ -33,6 +33,7 @@
#include <utils/qtcassert.h>
#include <QDesktopServices>
#include <QFileInfo>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
@@ -380,8 +381,10 @@ void SectionedProducts::onImageDownloadFinished(QNetworkReply *reply)
if (reply->error() == QNetworkReply::NoError) {
const QByteArray data = reply->readAll();
QPixmap pixmap;
if (pixmap.loadFromData(data)) {
const QString url = reply->request().url().toString();
const QUrl imageUrl = reply->request().url();
const QString imageFormat = QFileInfo(imageUrl.fileName()).suffix();
if (pixmap.loadFromData(data, imageFormat.toLatin1())) {
const QString url = imageUrl.toString();
QPixmapCache::insert(url, pixmap.scaled(ProductListModel::defaultImageSize,
Qt::KeepAspectRatio, Qt::SmoothTransformation));
for (ProductListModel *model : m_productModels.values())

View File

@@ -183,6 +183,11 @@ add_qtc_plugin(ProjectExplorer
xcodebuildparser.cpp xcodebuildparser.h
)
extend_qtc_plugin(ProjectExplorer
CONDITION PROJECT_USER_FILE_EXTENSION
DEFINES "PROJECT_USER_FILE_EXTENSION=${PROJECT_USER_FILE_EXTENSION}"
)
if (TARGET libclang)
set(CLANG_BINDIR "$<TARGET_FILE_DIR:libclang>")
endif()

View File

@@ -661,8 +661,38 @@ void ProjectWindow::activateProjectPanel(Utils::Id panelId)
d->activateProjectPanel(panelId);
}
void ProjectWindow::hideEvent(QHideEvent *event)
{
savePersistentSettings();
FancyMainWindow::hideEvent(event);
}
void ProjectWindow::showEvent(QShowEvent *event)
{
loadPersistentSettings();
FancyMainWindow::showEvent(event);
}
ProjectWindow::~ProjectWindow() = default;
const char PROJECT_WINDOW_KEY[] = "ProjectExplorer.ProjectWindow";
void ProjectWindow::savePersistentSettings() const
{
QSettings * const settings = ICore::settings();
settings->beginGroup(PROJECT_WINDOW_KEY);
saveSettings(settings);
settings->endGroup();
}
void ProjectWindow::loadPersistentSettings()
{
QSettings * const settings = ICore::settings();
settings->beginGroup(PROJECT_WINDOW_KEY);
restoreSettings(settings);
settings->endGroup();
}
QSize SelectorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QSize s = QStyledItemDelegate::sizeHint(option, index);

View File

@@ -64,6 +64,12 @@ public:
void activateProjectPanel(Utils::Id panelId);
private:
void hideEvent(QHideEvent *event) override;
void showEvent(QShowEvent *event) override;
void savePersistentSettings() const;
void loadPersistentSettings();
const std::unique_ptr<ProjectWindowPrivate> d;
};

View File

@@ -614,7 +614,8 @@ void QMakeStep::userArgumentsChanged()
{
if (m_ignoreChange)
return;
qmakeAdditonalArgumentsLineEdit->setText(m_userArgs);
if (qmakeAdditonalArgumentsLineEdit)
qmakeAdditonalArgumentsLineEdit->setText(m_userArgs);
updateAbiWidgets();
updateEffectiveQMakeCall();
}
@@ -723,6 +724,9 @@ bool QMakeStep::isAndroidKit() const
void QMakeStep::updateAbiWidgets()
{
if (!abisLabel)
return;
BaseQtVersion *qtVersion = QtKitAspect::qtVersion(target()->kit());
if (!qtVersion)
return;
@@ -762,7 +766,8 @@ void QMakeStep::updateAbiWidgets()
void QMakeStep::updateEffectiveQMakeCall()
{
qmakeArgumentsEdit->setPlainText(effectiveQMakeCall());
if (qmakeArgumentsEdit)
qmakeArgumentsEdit->setPlainText(effectiveQMakeCall());
}
void QMakeStep::recompileMessageBoxFinished(int button)

View File

@@ -42,7 +42,7 @@ add_qtc_plugin(QmlDesigner
add_qtc_plugin(assetexporterplugin
CONDITION TARGET QmlDesigner
DEPENDS Core ProjectExplorer QmlDesigner Utils Qt5::Qml
DEPENDS Core ProjectExplorer QmlDesigner Utils Qt5::Qml Qt5::QuickPrivate
PUBLIC_INCLUDES assetexporterplugin
SOURCES
assetexporterplugin/assetexportdialog.h assetexporterplugin/assetexportdialog.cpp assetexporterplugin/assetexportdialog.ui

View File

@@ -1,4 +1,5 @@
QT *= qml quick core widgets
QT += quick-private
VPATH += $$PWD

View File

@@ -10,6 +10,12 @@ QtcProduct {
Depends { name: "ProjectExplorer" }
Depends { name: "QmlDesigner" }
Depends { name: "Utils" }
Depends {
name: "Qt"
submodules: [
"quick-private"
]
}
cpp.includePaths: base.concat([
"./",

View File

@@ -28,7 +28,11 @@
#include <QColor>
#include <QFontInfo>
#include <QFontMetricsF>
#include <QHash>
#include <QtMath>
#include <private/qquicktext_p.h>
namespace {
const QHash<QString, QString> AlignMapping{
@@ -86,6 +90,14 @@ QJsonObject TextNodeParser::json(Component &component) const
textDetails.insert(IsMultilineTag, propertyValue("wrapMode").toString().compare("NoWrap") != 0);
// Calculate line height in pixels
QFontMetricsF fm(font);
auto lineHeightMode = propertyValue("lineHeightMode").value<QQuickText::LineHeightMode>();
double lineHeight = propertyValue("lineHeight").toDouble();
qreal lineHeightPx = (lineHeightMode == QQuickText::FixedHeight) ?
lineHeight : qCeil(fm.height()) * lineHeight;
textDetails.insert(LineHeightTag, lineHeightPx);
QJsonObject metadata = jsonObject.value(MetadataTag).toObject();
metadata.insert(TextDetailsTag, textDetails);
jsonObject.insert(MetadataTag, metadata);

View File

@@ -34,7 +34,7 @@ namespace ComponentCoreConstants {
const char rootCategory[] = "";
const char selectionCategory[] = "Selection";
const char stackCategory[] = "Stack (z)";
const char arrangeCategory[] = "Arrange";
const char qmlPreviewCategory[] = "QmlPreview";
const char editCategory[] = "Edit";
const char anchorsCategory[] = "Anchors";
@@ -52,6 +52,7 @@ const char toBackCommandId[] = "ToBack";
const char raiseCommandId[] = "Raise";
const char lowerCommandId[] = "Lower";
const char resetZCommandId[] = "ResetZ";
const char reverseCommandId[] = "Reverse";
const char resetSizeCommandId[] = "ResetSize";
const char resetPositionCommandId[] = "ResetPosition";
const char visiblityCommandId[] = "ToggleVisiblity";
@@ -90,7 +91,7 @@ const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen";
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect");
const char stackCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Stack (z)");
const char arrangeCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Arrange");
const char editCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit");
const char anchorsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Anchors");
const char positionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Position");
@@ -105,11 +106,11 @@ const char copySelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMen
const char pasteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Paste");
const char deleteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Delete Selection");
const char toFrontDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "To Front");
const char toBackDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "To Back");
const char toFrontDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bring to Front");
const char toBackDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Send to Back");
const char raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Raise");
const char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Lower");
const char raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bring Forward");
const char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Send Backward");
const char undoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Undo");
const char redoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Redo");
@@ -129,6 +130,8 @@ const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set
const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z Property");
const char reverseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reverse");
const char anchorsFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fill");
const char anchorsResetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset");

View File

@@ -594,6 +594,11 @@ bool selectionHasSameParentAndInBaseState(const SelectionContext &context)
return selectionHasSameParent(context) && inBaseState(context);
}
bool multiSelectionAndHasSameParent(const SelectionContext &context)
{
return multiSelection(context) && selectionHasSameParent(context);
}
bool isNotInLayout(const SelectionContext &context)
{
if (selectionNotEmpty(context)) {
@@ -914,8 +919,8 @@ void DesignerActionManager::createDefaultDesignerActions()
prioritySelectionCategory));
addDesignerAction(new ActionGroup(
stackCategoryDisplayName,
stackCategory,
arrangeCategoryDisplayName,
arrangeCategory,
priorityStackCategory,
&selectionNotEmpty));
@@ -923,28 +928,19 @@ void DesignerActionManager::createDefaultDesignerActions()
toFrontCommandId,
toFrontDisplayName,
{},
stackCategory,
arrangeCategory,
QKeySequence(),
200,
&toFront,
&singleSelection));
addDesignerAction(new ModelNodeContextMenuAction(
toBackCommandId,
toBackDisplayName,
{},
stackCategory,
raiseCommandId,
raiseDisplayName,
Utils::Icon({{":/qmldesigner/icon/designeractions/images/raise.png", Utils::Theme::IconsBaseColor}}).icon(),
arrangeCategory,
QKeySequence(),
180,
&toBack,
&singleSelection));
addDesignerAction(new ModelNodeContextMenuAction(
raiseCommandId, raiseDisplayName,
Utils::Icon({{":/qmldesigner/icon/designeractions/images/raise.png", Utils::Theme::IconsBaseColor}}).icon(),
stackCategory,
QKeySequence(),
160,
&raise,
&raiseAvailable));
@@ -952,23 +948,31 @@ void DesignerActionManager::createDefaultDesignerActions()
lowerCommandId,
lowerDisplayName,
Utils::Icon({{":/qmldesigner/icon/designeractions/images/lower.png", Utils::Theme::IconsBaseColor}}).icon(),
stackCategory,
arrangeCategory,
QKeySequence(),
140,
160,
&lower,
&lowerAvailable));
addDesignerAction(new SeperatorDesignerAction(stackCategory, 120));
addDesignerAction(new ModelNodeContextMenuAction(
toBackCommandId,
toBackDisplayName,
{},
arrangeCategory,
QKeySequence(),
140,
&toBack,
&singleSelection));
addDesignerAction(new ModelNodeContextMenuAction(
resetZCommandId,
resetZDisplayName,
reverseCommandId,
reverseDisplayName,
{},
stackCategory,
arrangeCategory,
QKeySequence(),
100,
&resetZ,
&selectionNotEmptyAndHasZProperty));
&reverse,
&multiSelectionAndHasSameParent));
addDesignerAction(new ActionGroup(editCategoryDisplayName, editCategory, priorityEditCategory, &selectionNotEmpty));
@@ -979,7 +983,9 @@ void DesignerActionManager::createDefaultDesignerActions()
resetPositionDisplayName,
Utils::Icon({{":/utils/images/pan.png", Utils::Theme::IconsBaseColor},
{":/utils/images/iconoverlay_reset.png", Utils::Theme::IconsStopToolBarColor}}).icon(),
resetPositionTooltip, editCategory, QKeySequence("Ctrl+d"),
resetPositionTooltip,
editCategory,
QKeySequence("Ctrl+d"),
200,
&resetPosition,
&selectionNotEmptyAndHasXorYProperty));

View File

@@ -206,9 +206,9 @@ void toBack(const SelectionContext &selectionState)
}
}
enum OderAction {RaiseItem, LowerItem};
enum OrderAction {RaiseItem, LowerItem};
void changeOrder(const SelectionContext &selectionState, OderAction orderAction)
void changeOrder(const SelectionContext &selectionState, OrderAction orderAction)
{
if (!selectionState.view())
return;
@@ -221,13 +221,12 @@ void changeOrder(const SelectionContext &selectionState, OderAction orderAction)
if (!modelNode.parentProperty().isNodeListProperty())
return;
selectionState.view()->executeInTransaction("DesignerActionManager|raise",[orderAction, selectionState, modelNode](){
selectionState.view()->executeInTransaction("DesignerActionManager|changeOrder", [orderAction, selectionState, modelNode]() {
ModelNode modelNode = selectionState.currentSingleSelectedNode();
NodeListProperty parentProperty = modelNode.parentProperty().toNodeListProperty();
const int index = parentProperty.indexOf(modelNode);
if (orderAction == RaiseItem) {
if (index < parentProperty.count() - 1)
parentProperty.slide(index, index + 1);
} else if (orderAction == LowerItem) {
@@ -244,7 +243,6 @@ void raise(const SelectionContext &selectionState)
void lower(const SelectionContext &selectionState)
{
changeOrder(selectionState, LowerItem);
}
@@ -344,8 +342,8 @@ void resetZ(const SelectionContext &selectionState)
if (!selectionState.view())
return;
selectionState.view()->executeInTransaction("DesignerActionManager|resetZ",[selectionState](){
foreach (ModelNode node, selectionState.selectedModelNodes()) {
selectionState.view()->executeInTransaction("DesignerActionManager|resetZ", [selectionState](){
for (ModelNode node : selectionState.selectedModelNodes()) {
QmlItemNode itemNode(node);
if (itemNode.isValid())
itemNode.removeProperty("z");
@@ -353,6 +351,16 @@ void resetZ(const SelectionContext &selectionState)
});
}
void reverse(const SelectionContext &selectionState)
{
if (!selectionState.view())
return;
selectionState.view()->executeInTransaction("DesignerActionManager|reverse", [selectionState](){
NodeListProperty::reverseModelNodes(selectionState.selectedModelNodes());
});
}
static inline void backupPropertyAndRemove(const ModelNode &node, const PropertyName &propertyName)
{
if (node.hasVariantProperty(propertyName)) {
@@ -366,7 +374,6 @@ static inline void backupPropertyAndRemove(const ModelNode &node, const Property
}
}
static inline void restoreProperty(const ModelNode &node, const PropertyName &propertyName)
{
if (node.hasAuxiliaryData(auxDataString + propertyName))

View File

@@ -52,6 +52,7 @@ void resetPosition(const SelectionContext &selectionState);
void goIntoComponentOperation(const SelectionContext &selectionState);
void setId(const SelectionContext &selectionState);
void resetZ(const SelectionContext &selectionState);
void reverse(const SelectionContext &selectionState);
void anchorsFill(const SelectionContext &selectionState);
void anchorsReset(const SelectionContext &selectionState);
void layoutRowPositioner(const SelectionContext &selectionState);

View File

@@ -33,7 +33,7 @@
#include <sstream>
namespace DesignTools {
namespace QmlDesigner {
AnimationCurve::AnimationCurve()
: m_fromData(false)
@@ -395,4 +395,4 @@ void AnimationCurve::analyze()
}
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -33,7 +33,7 @@
QT_FORWARD_DECLARE_CLASS(QEasingCurve);
QT_FORWARD_DECLARE_CLASS(QPainterPath);
namespace DesignTools {
namespace QmlDesigner {
class CurveSegment;
@@ -100,4 +100,4 @@ private:
std::vector<Keyframe> m_frames;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -35,7 +35,7 @@
#include <QSplitter>
#include <QVBoxLayout>
namespace DesignTools {
namespace QmlDesigner {
CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
: QWidget(parent)
@@ -52,10 +52,9 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
box->addWidget(splitter);
setLayout(box);
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::curveChanged);
connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::curveChanged);
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::setLocked);
connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::setPinned);
connect(m_tree, &TreeView::treeItemLocked, m_view, &GraphicsView::setLocked);
connect(m_tree->selectionModel(),
&SelectionModel::curvesSelected,
m_view,
@@ -180,4 +179,4 @@ QToolBar *CurveEditor::createToolBar(CurveEditorModel *model)
return bar;
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -28,7 +28,7 @@
#include <QToolBar>
#include <QWidget>
namespace DesignTools {
namespace QmlDesigner {
class CurveEditorModel;
class GraphicsView;
@@ -57,4 +57,4 @@ private:
GraphicsView *m_view;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -25,6 +25,7 @@
#include "curveeditormodel.h"
#include "curveeditorstyle.h"
#include "detail/treeview.h"
#include "treeitem.h"
#include "detail/graphicsview.h"
@@ -34,10 +35,11 @@
#include "qmltimeline.h"
#include <bindingproperty.h>
#include <nodeabstractproperty.h>
#include <theme.h>
#include <variantproperty.h>
namespace DesignTools {
namespace QmlDesigner {
CurveEditorModel::CurveEditorModel(QObject *parent)
: TreeModel(parent)
@@ -57,10 +59,10 @@ double CurveEditorModel::maximumTime() const
return m_maxTime;
}
DesignTools::CurveEditorStyle CurveEditorModel::style() const
CurveEditorStyle CurveEditorModel::style() const
{
// Pseudo auto generated. See: CurveEditorStyleDialog
DesignTools::CurveEditorStyle out;
CurveEditorStyle out;
out.backgroundBrush = QBrush(QColor(21, 21, 21));
out.backgroundAlternateBrush = QBrush(QColor(32, 32, 32));
out.fontColor = QColor(255, 255, 255);
@@ -98,9 +100,9 @@ void CurveEditorModel::setTimeline(const QmlDesigner::QmlTimeline &timeline)
{
m_minTime = timeline.startKeyframe();
m_maxTime = timeline.endKeyframe();
std::vector<DesignTools::TreeItem *> items;
std::vector<TreeItem *> items;
for (auto &&target : timeline.allTargets()) {
if (DesignTools::TreeItem *item = createTopLevelItem(timeline, target))
if (TreeItem *item = createTopLevelItem(timeline, target))
items.push_back(item);
}
@@ -135,6 +137,32 @@ void CurveEditorModel::setCurve(unsigned int id, const AnimationCurve &curve)
}
}
void CurveEditorModel::setLocked(TreeItem *item, bool val)
{
item->setLocked(val);
if (auto *gview = graphicsView())
gview->setLocked(item);
if (auto *tview = treeView())
tview->viewport()->update();
emit curveChanged(item);
}
void CurveEditorModel::setPinned(TreeItem *item, bool val)
{
item->setPinned(val);
if (auto *gview = graphicsView())
gview->setPinned(item);
if (auto *tview = treeView())
tview->viewport()->update();
emit curveChanged(item);
}
bool contains(const std::vector<TreeItem::Path> &selection, const TreeItem::Path &path)
{
for (auto &&sel : selection)
@@ -176,38 +204,57 @@ void CurveEditorModel::reset(const std::vector<TreeItem *> &items)
sm->selectPaths(sel);
}
DesignTools::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group)
PropertyTreeItem::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group)
{
if (group.valueType() == QmlDesigner::TypeName("double")
|| group.valueType() == QmlDesigner::TypeName("real")
|| group.valueType() == QmlDesigner::TypeName("float"))
return DesignTools::ValueType::Double;
return PropertyTreeItem::ValueType::Double;
if (group.valueType() == QmlDesigner::TypeName("boolean")
|| group.valueType() == QmlDesigner::TypeName("bool"))
return DesignTools::ValueType::Bool;
return PropertyTreeItem::ValueType::Bool;
if (group.valueType() == QmlDesigner::TypeName("integer")
|| group.valueType() == QmlDesigner::TypeName("int"))
return DesignTools::ValueType::Integer;
return PropertyTreeItem::ValueType::Integer;
// Ignoring: QColor / HAlignment / VAlignment
return DesignTools::ValueType::Undefined;
return PropertyTreeItem::ValueType::Undefined;
}
DesignTools::TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::QmlTimeline &timeline,
const QmlDesigner::ModelNode &node)
std::vector<QString> parentIds(const QmlDesigner::ModelNode &node)
{
std::vector<QString> out;
QmlDesigner::ModelNode parent = node.parentProperty().parentModelNode();
while (parent.isValid()) {
out.push_back(parent.id());
if (parent.hasParentProperty())
parent = parent.parentProperty().parentModelNode();
else
break;
}
return out;
}
TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::QmlTimeline &timeline,
const QmlDesigner::ModelNode &node)
{
if (!node.isValid())
return nullptr;
auto *nodeItem = new DesignTools::NodeTreeItem(node.id(), QIcon(":/ICON_INSTANCE"));
auto *nodeItem = new NodeTreeItem(node.id(), node.typeIcon(), parentIds(node));
if (node.hasAuxiliaryData("locked"))
nodeItem->setLocked(true);
for (auto &&grp : timeline.keyframeGroupsForTarget(node)) {
if (grp.isValid()) {
DesignTools::AnimationCurve curve = createAnimationCurve(grp);
AnimationCurve curve = createAnimationCurve(grp);
if (curve.isValid()) {
QString name = QString::fromUtf8(grp.propertyName());
auto propertyItem = new DesignTools::PropertyTreeItem(name, curve, typeFrom(grp));
auto propertyItem = new PropertyTreeItem(name, curve, typeFrom(grp));
QmlDesigner::ModelNode target = grp.modelNode();
if (target.hasAuxiliaryData("locked"))
@@ -229,25 +276,24 @@ DesignTools::TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::Q
return nodeItem;
}
DesignTools::AnimationCurve CurveEditorModel::createAnimationCurve(
const QmlDesigner::QmlTimelineKeyframeGroup &group)
AnimationCurve CurveEditorModel::createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group)
{
switch (typeFrom(group)) {
case DesignTools::ValueType::Bool:
case PropertyTreeItem::ValueType::Bool:
return createDoubleCurve(group);
case DesignTools::ValueType::Integer:
case PropertyTreeItem::ValueType::Integer:
return createDoubleCurve(group);
case DesignTools::ValueType::Double:
case PropertyTreeItem::ValueType::Double:
return createDoubleCurve(group);
default:
return DesignTools::AnimationCurve();
return AnimationCurve();
}
}
std::vector<DesignTools::Keyframe> createKeyframes(QList<QmlDesigner::ModelNode> nodes)
std::vector<Keyframe> createKeyframes(QList<QmlDesigner::ModelNode> nodes)
{
auto byTime = [](const auto &a, const auto &b) {
return a.variantProperty("frame").value().toDouble()
@@ -255,7 +301,7 @@ std::vector<DesignTools::Keyframe> createKeyframes(QList<QmlDesigner::ModelNode>
};
std::sort(nodes.begin(), nodes.end(), byTime);
std::vector<DesignTools::Keyframe> frames;
std::vector<Keyframe> frames;
for (auto &&node : nodes) {
QVariant timeVariant = node.variantProperty("frame").value();
QVariant valueVariant = node.variantProperty("value").value();
@@ -264,7 +310,7 @@ std::vector<DesignTools::Keyframe> createKeyframes(QList<QmlDesigner::ModelNode>
QPointF position(timeVariant.toDouble(), valueVariant.toDouble());
auto keyframe = DesignTools::Keyframe(position);
auto keyframe = Keyframe(position);
if (node.hasBindingProperty("easing.bezierCurve")) {
QmlDesigner::EasingCurve ecurve;
@@ -276,15 +322,15 @@ std::vector<DesignTools::Keyframe> createKeyframes(QList<QmlDesigner::ModelNode>
return frames;
}
std::vector<DesignTools::Keyframe> resolveSmallCurves(const std::vector<DesignTools::Keyframe> &frames)
std::vector<Keyframe> resolveSmallCurves(const std::vector<Keyframe> &frames)
{
std::vector<DesignTools::Keyframe> out;
std::vector<Keyframe> out;
for (auto &&frame : frames) {
if (frame.hasData() && !out.empty()) {
QEasingCurve curve = frame.data().toEasingCurve();
// One-segment-curve: Since (0,0) is implicit => 3
if (curve.toCubicSpline().count() == 3) {
DesignTools::Keyframe &previous = out.back();
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())) {
@@ -292,7 +338,7 @@ std::vector<DesignTools::Keyframe> resolveSmallCurves(const std::vector<DesignTo
continue;
}
#endif
DesignTools::AnimationCurve acurve(curve, previous.position(), frame.position());
AnimationCurve acurve(curve, previous.position(), frame.position());
previous.setRightHandle(acurve.keyframeAt(0).rightHandle());
out.push_back(acurve.keyframeAt(1));
continue;
@@ -303,10 +349,9 @@ std::vector<DesignTools::Keyframe> resolveSmallCurves(const std::vector<DesignTo
return out;
}
DesignTools::AnimationCurve CurveEditorModel::createDoubleCurve(
const QmlDesigner::QmlTimelineKeyframeGroup &group)
AnimationCurve CurveEditorModel::createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group)
{
std::vector<DesignTools::Keyframe> keyframes = createKeyframes(group.keyframePositions());
std::vector<Keyframe> keyframes = createKeyframes(group.keyframePositions());
keyframes = resolveSmallCurves(keyframes);
QString str;
@@ -321,7 +366,7 @@ DesignTools::AnimationCurve CurveEditorModel::createDoubleCurve(
}
}
return DesignTools::AnimationCurve(keyframes);
return AnimationCurve(keyframes);
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -35,7 +35,7 @@ QT_BEGIN_NAMESPACE
class QPointF;
QT_END_NAMESPACE
namespace DesignTools {
namespace QmlDesigner {
struct CurveEditorStyle;
@@ -54,7 +54,7 @@ signals:
void commitEndFrame(int frame);
void curveChanged(PropertyTreeItem *item);
void curveChanged(TreeItem *item);
public:
CurveEditorModel(QObject *parent = nullptr);
@@ -65,7 +65,7 @@ public:
double maximumTime() const;
DesignTools::CurveEditorStyle style() const;
CurveEditorStyle style() const;
public:
void setTimeline(const QmlDesigner::QmlTimeline &timeline);
@@ -78,19 +78,23 @@ public:
void setCurve(unsigned int id, const AnimationCurve &curve);
void setLocked(TreeItem *item, bool val);
void setPinned(TreeItem *item, bool val);
void reset(const std::vector<TreeItem *> &items);
private:
DesignTools::TreeItem *createTopLevelItem(const QmlDesigner::QmlTimeline &timeline,
const QmlDesigner::ModelNode &node);
TreeItem *createTopLevelItem(const QmlDesigner::QmlTimeline &timeline,
const QmlDesigner::ModelNode &node);
DesignTools::AnimationCurve createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
AnimationCurve createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
DesignTools::AnimationCurve createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
AnimationCurve createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
double m_minTime = 0.;
double m_maxTime = 0.;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -27,7 +27,9 @@
#include "detail/shortcut.h"
#include <theme.h>
#include <utils/hostosinfo.h>
#include <utils/stylehelper.h>
#include <QBitmap>
#include <QBrush>
@@ -38,15 +40,30 @@
#include <cmath>
namespace DesignTools {
namespace QmlDesigner {
struct TreeItemStyleOption
{
double margins;
QIcon pinnedIcon = QIcon(":/curveeditor/images/treeview_pin.png");
QIcon unpinnedIcon = QIcon(":/curveeditor/images/treeview_unpin.png");
QIcon lockedIcon = QIcon(":/curveeditor/images/treeview_lock.png");
QIcon unlockedIcon = QIcon(":/curveeditor/images/treeview_unlock.png");
QIcon pinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::pin);
QIcon unpinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::unpin);
QIcon implicitlyPinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::pin, Qt::gray);
QIcon lockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOn);
QIcon unlockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOff);
QIcon implicitlyLockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOn, Qt::gray);
static QIcon iconFromFont(QmlDesigner::Theme::Icon type, const QColor &color = Qt::white)
{
const QString fontName = "qtds_propertyIconFont.ttf";
static const int fontSize = 28;
static const int iconSize = 28;
return Utils::StyleHelper::getIconFromIconFont(fontName,
QmlDesigner::Theme::getIconUnicode(type),
fontSize,
iconSize,
color);
}
};
struct HandleItemStyleOption
@@ -122,15 +139,15 @@ struct CurveEditorStyle
QColor iconColor = QColor(128, 128, 128);
QColor iconHoverColor = QColor(170, 170, 170);
QColor gridColor = QColor(128, 128, 128);
double canvasMargin = 5.0;
int canvasMargin = 5;
int zoomInWidth = 100;
int zoomInHeight = 100;
double timeAxisHeight = 40.0;
int timeAxisHeight = 40;
double timeOffsetLeft = 10.0;
double timeOffsetRight = 10.0;
QColor rangeBarColor = QColor(128, 128, 128);
QColor rangeBarCapsColor = QColor(50, 50, 255);
double valueAxisWidth = 60.0;
int valueAxisWidth = 60;
double valueOffsetTop = 10.0;
double valueOffsetBottom = 10.0;
double labelDensityY = 2.0;
@@ -151,4 +168,4 @@ inline QPixmap pixmapFromIcon(const QIcon &icon, const QSize &size, const QColor
return mask;
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -27,6 +27,7 @@
#include "curveeditor.h"
#include "curveeditormodel.h"
#include "curvesegment.h"
#include "treeitem.h"
#include <bindingproperty.h>
#include <easingcurve.h>
@@ -42,29 +43,14 @@ namespace QmlDesigner {
CurveEditorView::CurveEditorView(QObject *parent)
: AbstractView(parent)
, m_block(false)
, m_model(new DesignTools::CurveEditorModel())
, m_editor(new DesignTools::CurveEditor(m_model))
, m_model(new CurveEditorModel())
, m_editor(new CurveEditor(m_model))
{
Q_UNUSED(parent);
connect(m_model,
&DesignTools::CurveEditorModel::commitCurrentFrame,
this,
&CurveEditorView::commitCurrentFrame);
connect(m_model,
&DesignTools::CurveEditorModel::commitStartFrame,
this,
&CurveEditorView::commitStartFrame);
connect(m_model,
&DesignTools::CurveEditorModel::commitEndFrame,
this,
&CurveEditorView::commitEndFrame);
connect(m_model,
&DesignTools::CurveEditorModel::curveChanged,
this,
&CurveEditorView::commitKeyframes);
connect(m_model, &CurveEditorModel::commitCurrentFrame, this, &CurveEditorView::commitCurrentFrame);
connect(m_model, &CurveEditorModel::commitStartFrame, this, &CurveEditorView::commitStartFrame);
connect(m_model, &CurveEditorModel::commitEndFrame, this, &CurveEditorView::commitEndFrame);
connect(m_model, &CurveEditorModel::curveChanged, this, &CurveEditorView::commitKeyframes);
}
CurveEditorView::~CurveEditorView() {}
@@ -134,6 +120,18 @@ void CurveEditorView::nodeReparented(const ModelNode &node,
updateKeyframes();
}
void CurveEditorView::auxiliaryDataChanged(const ModelNode &node,
const PropertyName &name,
const QVariant &data)
{
if (name == "locked") {
if (auto *item = m_model->find(node.id())) {
QSignalBlocker blocker(m_model);
m_model->setLocked(item, data.toBool());
}
}
}
void CurveEditorView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName>> &propertyList)
{
Q_UNUSED(propertyList);
@@ -261,9 +259,9 @@ void CurveEditorView::updateEndFrame(const ModelNode &node)
m_model->setMaximumTime(static_cast<int>(std::round(timeline.endKeyframe())));
}
ModelNode getTargetNode1(DesignTools::PropertyTreeItem *item, const QmlTimeline &timeline)
ModelNode getTargetNode(PropertyTreeItem *item, const QmlTimeline &timeline)
{
if (const DesignTools::NodeTreeItem *nodeItem = item->parentNodeTreeItem()) {
if (const NodeTreeItem *nodeItem = item->parentNodeTreeItem()) {
QString targetId = nodeItem->name();
if (timeline.isValid()) {
for (auto &&target : timeline.allTargets()) {
@@ -275,17 +273,16 @@ ModelNode getTargetNode1(DesignTools::PropertyTreeItem *item, const QmlTimeline
return ModelNode();
}
QmlTimelineKeyframeGroup timelineKeyframeGroup1(QmlTimeline &timeline,
DesignTools::PropertyTreeItem *item)
QmlTimelineKeyframeGroup timelineKeyframeGroup(QmlTimeline &timeline, PropertyTreeItem *item)
{
ModelNode node = getTargetNode1(item, timeline);
ModelNode node = getTargetNode(item, timeline);
if (node.isValid())
return timeline.keyframeGroup(node, item->name().toLatin1());
return QmlTimelineKeyframeGroup();
}
void attachEasingCurve1(double frame, const QEasingCurve &curve, const QmlTimelineKeyframeGroup &group)
void attachEasingCurve(const QmlTimelineKeyframeGroup &group, double frame, const QEasingCurve &curve)
{
ModelNode frameNode = group.keyframe(frame);
if (frameNode.isValid()) {
@@ -294,61 +291,73 @@ void attachEasingCurve1(double frame, const QEasingCurve &curve, const QmlTimeli
}
}
void CurveEditorView::commitKeyframes(DesignTools::PropertyTreeItem *item)
void commitAuxiliaryData(ModelNode &node, TreeItem *item)
{
QmlTimeline currentTimeline = activeTimeline();
QmlTimelineKeyframeGroup group = timelineKeyframeGroup1(currentTimeline, item);
if (node.isValid()) {
if (item->locked())
node.setAuxiliaryData("locked", true);
else
node.removeAuxiliaryData("locked");
if (group.isValid()) {
ModelNode groupNode = group.modelNode();
if (item->pinned())
node.setAuxiliaryData("pinned", true);
else
node.removeAuxiliaryData("pinned");
if (groupNode.isValid()) {
if (item->locked())
groupNode.setAuxiliaryData("locked", true);
if (auto *pitem = item->asPropertyItem()) {
if (pitem->hasUnified())
node.setAuxiliaryData("unified", pitem->unifyString());
else
groupNode.removeAuxiliaryData("locked");
if (item->pinned())
groupNode.setAuxiliaryData("pinned", true);
else
groupNode.removeAuxiliaryData("pinned");
if (item->hasUnified())
groupNode.setAuxiliaryData("unified", item->unifyString());
else
groupNode.removeAuxiliaryData("unified");
node.removeAuxiliaryData("unified");
}
}
}
auto replaceKeyframes = [&group, item, this]() {
m_block = true;
for (auto frame : group.keyframes())
frame.destroy();
void CurveEditorView::commitKeyframes(TreeItem *item)
{
if (auto *nitem = item->asNodeItem()) {
ModelNode node = modelNodeForId(nitem->name());
commitAuxiliaryData(node, item);
DesignTools::Keyframe previous;
for (auto &&frame : item->curve().keyframes()) {
QPointF pos = frame.position();
group.setValue(QVariant(pos.y()), pos.x());
} else if (auto *pitem = item->asPropertyItem()) {
QmlTimeline currentTimeline = activeTimeline();
QmlTimelineKeyframeGroup group = timelineKeyframeGroup(currentTimeline, pitem);
if (previous.isValid()) {
if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Bezier) {
DesignTools::CurveSegment segment(previous, frame);
if (segment.isValid())
attachEasingCurve1(pos.x(), segment.easingCurve(), group);
} else if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Easing) {
QVariant data = frame.data();
if (data.type() == static_cast<int>(QMetaType::QEasingCurve))
attachEasingCurve1(pos.x(), data.value<QEasingCurve>(), group);
} else if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Step) {
// Warning: Keyframe::Interpolation::Step not yet implemented
if (group.isValid()) {
ModelNode groupNode = group.modelNode();
commitAuxiliaryData(groupNode, item);
auto replaceKeyframes = [&group, pitem, this]() {
m_block = true;
for (auto frame : group.keyframes())
frame.destroy();
Keyframe previous;
for (auto &&frame : pitem->curve().keyframes()) {
QPointF pos = frame.position();
group.setValue(QVariant(pos.y()), pos.x());
if (previous.isValid()) {
if (frame.interpolation() == Keyframe::Interpolation::Bezier) {
CurveSegment segment(previous, frame);
if (segment.isValid())
attachEasingCurve(group, pos.x(), segment.easingCurve());
} else if (frame.interpolation() == Keyframe::Interpolation::Easing) {
QVariant data = frame.data();
if (data.type() == static_cast<int>(QMetaType::QEasingCurve))
attachEasingCurve(group, pos.x(), data.value<QEasingCurve>());
} else if (frame.interpolation() == Keyframe::Interpolation::Step) {
// Warning: Keyframe::Interpolation::Step not yet implemented
}
}
previous = frame;
}
m_block = false;
};
previous = frame;
}
m_block = false;
};
executeInTransaction("CurveEditor::commitKeyframes", replaceKeyframes);
executeInTransaction("CurveEditor::commitKeyframes", replaceKeyframes);
}
}
}

View File

@@ -59,6 +59,10 @@ public:
const NodeAbstractProperty &oldPropertyParent,
PropertyChangeFlags propertyChange) override;
void auxiliaryDataChanged(const ModelNode &node,
const PropertyName &name,
const QVariant &data) override;
void instancePropertyChanged(const QList<QPair<ModelNode, PropertyName>> &propertyList) override;
void variantPropertiesChanged(const QList<VariantProperty> &propertyList,
@@ -77,15 +81,15 @@ private:
void updateStartFrame(const ModelNode &node);
void updateEndFrame(const ModelNode &node);
void commitKeyframes(DesignTools::PropertyTreeItem *item);
void commitKeyframes(TreeItem *item);
void commitCurrentFrame(int frame);
void commitStartFrame(int frame);
void commitEndFrame(int frame);
private:
bool m_block;
DesignTools::CurveEditorModel *m_model;
DesignTools::CurveEditor *m_editor;
CurveEditorModel *m_model;
CurveEditor *m_editor;
};
} // namespace QmlDesigner

View File

@@ -33,7 +33,7 @@
#include <assert.h>
namespace DesignTools {
namespace QmlDesigner {
class CubicPolynomial
{
@@ -566,4 +566,4 @@ void CurveSegment::setInterpolation(const Keyframe::Interpolation &interpol)
}
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -36,7 +36,7 @@ class QEasingCurve;
class QPainterPath;
QT_END_NAMESPACE
namespace DesignTools {
namespace QmlDesigner {
class CurveSegment
{
@@ -97,4 +97,4 @@ private:
Keyframe m_right;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -29,7 +29,7 @@
#include <cmath>
#include <limits>
namespace DesignTools {
namespace QmlDesigner {
// The following is based on: "An Extension of Wilkinson's Algorithm for Positioning Tick Labels on Axes"
// by Justin Talbot, Sharon Lin and Pat Hanrahan.
@@ -210,4 +210,4 @@ Axis Axis::compute(double dmin, double dmax, double height, double pt)
return result;
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -28,7 +28,7 @@
#include <QToolBar>
#include <QWidget>
namespace DesignTools {
namespace QmlDesigner {
struct Axis
{
@@ -39,4 +39,4 @@ struct Axis
double lstep;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -30,7 +30,9 @@
#include <QPainter>
#include <QToolTip>
namespace DesignTools {
namespace QmlDesigner {
namespace StyleEditor {
ColorControl::ColorControl()
: QWidget(nullptr)
@@ -98,4 +100,6 @@ void ColorControl::mousePressEvent(QMouseEvent *event)
event->accept();
}
} // End namespace DesignTools.
} // End namespace StyleEditor.
} // End namespace QmlDesigner.

View File

@@ -27,7 +27,9 @@
#include <QWidget>
namespace DesignTools {
namespace QmlDesigner {
namespace StyleEditor {
class ColorControl : public QWidget
{
@@ -60,4 +62,6 @@ private:
QColor m_color;
};
} // End namespace DesignTools.
} // End namespace StyleEditor.
} // End namespace QmlDesigner.

View File

@@ -33,7 +33,7 @@
#include <QSpinBox>
#include <QVBoxLayout>
namespace DesignTools {
namespace QmlDesigner {
QHBoxLayout *createRow(const QString &title, QWidget *widget)
{
@@ -50,35 +50,35 @@ QHBoxLayout *createRow(const QString &title, QWidget *widget)
CurveEditorStyleDialog::CurveEditorStyleDialog(CurveEditorStyle &style, QWidget *parent)
: QDialog(parent)
, m_printButton(new QPushButton("Print"))
, m_background(new ColorControl(style.backgroundBrush.color()))
, m_backgroundAlternate(new ColorControl(style.backgroundAlternateBrush.color()))
, m_fontColor(new ColorControl(style.fontColor))
, m_gridColor(new ColorControl(style.gridColor))
, m_background(new StyleEditor::ColorControl(style.backgroundBrush.color()))
, m_backgroundAlternate(new StyleEditor::ColorControl(style.backgroundAlternateBrush.color()))
, m_fontColor(new StyleEditor::ColorControl(style.fontColor))
, m_gridColor(new StyleEditor::ColorControl(style.gridColor))
, m_canvasMargin(new QDoubleSpinBox())
, m_zoomInWidth(new QSpinBox())
, m_zoomInHeight(new QSpinBox())
, m_timeAxisHeight(new QDoubleSpinBox())
, m_timeOffsetLeft(new QDoubleSpinBox())
, m_timeOffsetRight(new QDoubleSpinBox())
, m_rangeBarColor(new ColorControl(style.rangeBarCapsColor))
, m_rangeBarCapsColor(new ColorControl(style.rangeBarCapsColor))
, m_rangeBarColor(new StyleEditor::ColorControl(style.rangeBarCapsColor))
, m_rangeBarCapsColor(new StyleEditor::ColorControl(style.rangeBarCapsColor))
, m_valueAxisWidth(new QDoubleSpinBox())
, m_valueOffsetTop(new QDoubleSpinBox())
, m_valueOffsetBottom(new QDoubleSpinBox())
, m_handleSize(new QDoubleSpinBox())
, m_handleLineWidth(new QDoubleSpinBox())
, m_handleColor(new ColorControl(style.handleStyle.color))
, m_handleSelectionColor(new ColorControl(style.handleStyle.selectionColor))
, m_handleColor(new StyleEditor::ColorControl(style.handleStyle.color))
, m_handleSelectionColor(new StyleEditor::ColorControl(style.handleStyle.selectionColor))
, m_keyframeSize(new QDoubleSpinBox())
, m_keyframeColor(new ColorControl(style.keyframeStyle.color))
, m_keyframeSelectionColor(new ColorControl(style.keyframeStyle.selectionColor))
, m_keyframeColor(new StyleEditor::ColorControl(style.keyframeStyle.color))
, m_keyframeSelectionColor(new StyleEditor::ColorControl(style.keyframeStyle.selectionColor))
, m_curveWidth(new QDoubleSpinBox())
, m_curveColor(new ColorControl(style.curveStyle.color))
, m_curveSelectionColor(new ColorControl(style.curveStyle.selectionColor))
, m_curveColor(new StyleEditor::ColorControl(style.curveStyle.color))
, m_curveSelectionColor(new StyleEditor::ColorControl(style.curveStyle.selectionColor))
, m_treeMargins(new QDoubleSpinBox())
, m_playheadWidth(new QDoubleSpinBox())
, m_playheadRadius(new QDoubleSpinBox())
, m_playheadColor(new ColorControl(style.playhead.color))
, m_playheadColor(new StyleEditor::ColorControl(style.playhead.color))
{
setWindowFlag(Qt::Tool, true);
@@ -111,35 +111,35 @@ CurveEditorStyleDialog::CurveEditorStyleDialog(CurveEditorStyle &style, QWidget
auto intSignal = static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged);
auto doubleSignal = static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged);
connect(m_background, &ColorControl::valueChanged, colorChanged);
connect(m_backgroundAlternate, &ColorControl::valueChanged, colorChanged);
connect(m_fontColor, &ColorControl::valueChanged, colorChanged);
connect(m_gridColor, &ColorControl::valueChanged, colorChanged);
connect(m_background, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_backgroundAlternate, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_fontColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_gridColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_canvasMargin, doubleSignal, doubleChanged);
connect(m_zoomInWidth, intSignal, intChanged);
connect(m_zoomInHeight, intSignal, intChanged);
connect(m_timeAxisHeight, doubleSignal, doubleChanged);
connect(m_timeOffsetLeft, doubleSignal, doubleChanged);
connect(m_timeOffsetRight, doubleSignal, doubleChanged);
connect(m_rangeBarColor, &ColorControl::valueChanged, colorChanged);
connect(m_rangeBarCapsColor, &ColorControl::valueChanged, colorChanged);
connect(m_rangeBarColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_rangeBarCapsColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_valueAxisWidth, doubleSignal, doubleChanged);
connect(m_valueOffsetTop, doubleSignal, doubleChanged);
connect(m_valueOffsetBottom, doubleSignal, doubleChanged);
connect(m_handleSize, doubleSignal, doubleChanged);
connect(m_handleLineWidth, doubleSignal, doubleChanged);
connect(m_handleColor, &ColorControl::valueChanged, colorChanged);
connect(m_handleSelectionColor, &ColorControl::valueChanged, colorChanged);
connect(m_handleColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_handleSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_keyframeSize, doubleSignal, doubleChanged);
connect(m_keyframeColor, &ColorControl::valueChanged, colorChanged);
connect(m_keyframeSelectionColor, &ColorControl::valueChanged, colorChanged);
connect(m_keyframeColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_keyframeSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_curveWidth, doubleSignal, doubleChanged);
connect(m_curveColor, &ColorControl::valueChanged, colorChanged);
connect(m_curveSelectionColor, &ColorControl::valueChanged, colorChanged);
connect(m_curveColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_curveSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
connect(m_treeMargins, doubleSignal, doubleChanged);
connect(m_playheadWidth, doubleSignal, doubleChanged);
connect(m_playheadRadius, doubleSignal, doubleChanged);
connect(m_playheadColor, &ColorControl::valueChanged, colorChanged);
connect(m_playheadColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
auto *box = new QVBoxLayout;
box->addLayout(createRow("Background Color", m_background));
@@ -266,4 +266,4 @@ void CurveEditorStyleDialog::printStyle()
qDebug() << "";
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -34,9 +34,11 @@ class QSpinBox;
class QDoubleSpinBox;
QT_END_NAMESPACE
namespace DesignTools {
namespace QmlDesigner {
namespace StyleEditor {
class ColorControl;
}
struct CurveEditorStyle;
@@ -60,13 +62,13 @@ private:
private:
QPushButton *m_printButton;
ColorControl *m_background;
StyleEditor::ColorControl *m_background;
ColorControl *m_backgroundAlternate;
StyleEditor::ColorControl *m_backgroundAlternate;
ColorControl *m_fontColor;
StyleEditor::ColorControl *m_fontColor;
ColorControl *m_gridColor;
StyleEditor::ColorControl *m_gridColor;
QDoubleSpinBox *m_canvasMargin;
@@ -80,9 +82,9 @@ private:
QDoubleSpinBox *m_timeOffsetRight;
ColorControl *m_rangeBarColor;
StyleEditor::ColorControl *m_rangeBarColor;
ColorControl *m_rangeBarCapsColor;
StyleEditor::ColorControl *m_rangeBarCapsColor;
QDoubleSpinBox *m_valueAxisWidth;
@@ -95,23 +97,23 @@ private:
QDoubleSpinBox *m_handleLineWidth;
ColorControl *m_handleColor;
StyleEditor::ColorControl *m_handleColor;
ColorControl *m_handleSelectionColor;
StyleEditor::ColorControl *m_handleSelectionColor;
// KeyframeItem
QDoubleSpinBox *m_keyframeSize;
ColorControl *m_keyframeColor;
StyleEditor::ColorControl *m_keyframeColor;
ColorControl *m_keyframeSelectionColor;
StyleEditor::ColorControl *m_keyframeSelectionColor;
// CurveItem
QDoubleSpinBox *m_curveWidth;
ColorControl *m_curveColor;
StyleEditor::ColorControl *m_curveColor;
ColorControl *m_curveSelectionColor;
StyleEditor::ColorControl *m_curveSelectionColor;
// TreeItem
QDoubleSpinBox *m_treeMargins;
@@ -121,7 +123,7 @@ private:
QDoubleSpinBox *m_playheadRadius;
ColorControl *m_playheadColor;
StyleEditor::ColorControl *m_playheadColor;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -35,13 +35,13 @@
#include <cmath>
#include <sstream>
namespace DesignTools {
namespace QmlDesigner {
CurveItem::CurveItem(QGraphicsItem *parent)
: CurveEditorItem(parent)
, m_id(0)
, m_style()
, m_type(ValueType::Undefined)
, m_type(PropertyTreeItem::ValueType::Undefined)
, m_component(PropertyTreeItem::Component::Generic)
, m_transform()
, m_keyframes()
@@ -52,7 +52,7 @@ CurveItem::CurveItem(unsigned int id, const AnimationCurve &curve, QGraphicsItem
: CurveEditorItem(parent)
, m_id(id)
, m_style()
, m_type(ValueType::Undefined)
, m_type(PropertyTreeItem::ValueType::Undefined)
, m_component(PropertyTreeItem::Component::Generic)
, m_transform()
, m_keyframes()
@@ -225,7 +225,7 @@ unsigned int CurveItem::id() const
return m_id;
}
ValueType CurveItem::valueType() const
PropertyTreeItem::ValueType CurveItem::valueType() const
{
return m_type;
}
@@ -385,7 +385,7 @@ void CurveItem::setHandleVisibility(bool visible)
frame->setHandleVisibility(visible);
}
void CurveItem::setValueType(ValueType type)
void CurveItem::setValueType(PropertyTreeItem::ValueType type)
{
m_type = type;
}
@@ -508,4 +508,4 @@ void CurveItem::emitCurveChanged()
update();
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -35,7 +35,7 @@
#include <string>
#include <QGraphicsObject>
namespace DesignTools {
namespace QmlDesigner {
class AnimationCurve;
class KeyframeItem;
@@ -89,7 +89,7 @@ public:
unsigned int id() const;
ValueType valueType() const;
PropertyTreeItem::ValueType valueType() const;
PropertyTreeItem::Component component() const;
@@ -113,7 +113,7 @@ public:
void setHandleVisibility(bool visible);
void setValueType(ValueType type);
void setValueType(PropertyTreeItem::ValueType type);
void setComponent(PropertyTreeItem::Component comp);
@@ -140,7 +140,7 @@ private:
CurveItemStyleOption m_style;
ValueType m_type;
PropertyTreeItem::ValueType m_type;
PropertyTreeItem::Component m_component;
@@ -151,4 +151,4 @@ private:
bool m_itemDirty;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -33,7 +33,7 @@
#include <cmath>
namespace DesignTools {
namespace QmlDesigner {
GraphicsScene::GraphicsScene(QObject *parent)
: QGraphicsScene(parent)
@@ -236,9 +236,34 @@ void GraphicsScene::doNotMoveItems(bool val)
m_doNotMoveItems = val;
}
void GraphicsScene::removeCurveItem(unsigned int id)
{
CurveItem *tmp = nullptr;
for (auto *curve : m_curves) {
if (curve->id() == id) {
removeItem(curve);
tmp = curve;
break;
}
}
if (tmp) {
Q_UNUSED(m_curves.removeOne(tmp));
delete tmp;
}
m_dirty = true;
}
void GraphicsScene::addCurveItem(CurveItem *item)
{
m_dirty = true;
for (auto *curve : m_curves) {
if (curve->id() == item->id()) {
delete item;
return;
}
}
item->setDirty(false);
item->connect(this);
addItem(item);
@@ -249,6 +274,8 @@ void GraphicsScene::addCurveItem(CurveItem *item)
m_curves.push_back(item);
resetZValues();
m_dirty = true;
}
void GraphicsScene::moveToBottom(CurveItem *item)
@@ -449,4 +476,4 @@ void GraphicsScene::resetZValues()
}
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -29,7 +29,7 @@
#include <QGraphicsScene>
namespace DesignTools {
namespace QmlDesigner {
class AnimationCurve;
class CurveItem;
@@ -95,6 +95,8 @@ public:
void doNotMoveItems(bool tmp);
void removeCurveItem(unsigned int id);
void addCurveItem(CurveItem *item);
void moveToBottom(CurveItem *item);
@@ -140,4 +142,4 @@ private:
bool m_doNotMoveItems;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -40,7 +40,7 @@
#include <iomanip>
#include <sstream>
namespace DesignTools {
namespace QmlDesigner {
GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
: QGraphicsView(parent)
@@ -75,18 +75,15 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
connect(m_scene, &GraphicsScene::curveChanged, itemSlot);
auto pinSlot = [this](PropertyTreeItem *pti) { m_scene->setPinned(pti->id(), pti->pinned()); };
connect(m_model, &CurveEditorModel::curveChanged, pinSlot);
applyZoom(m_zoomX, m_zoomY);
update();
QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(this);
auto zoomChanged = &QmlDesigner::Navigation2dFilter::zoomChanged;
connect(filter, zoomChanged, [this](double scale, const QPointF &pos) {
applyZoom(m_zoomX + scale, m_zoomY, mapToGlobal(pos.toPoint()));
});
installEventFilter(filter);
applyZoom(m_zoomX, m_zoomY);
update();
}
GraphicsView::~GraphicsView()
@@ -189,19 +186,62 @@ void GraphicsView::setStyle(const CurveEditorStyle &style)
viewport()->update();
}
void GraphicsView::setLocked(PropertyTreeItem *item)
void GraphicsView::setLocked(TreeItem *item)
{
if (CurveItem *curve = m_scene->findCurve(item->id())) {
if (item->locked()) {
curve->setLocked(true);
m_scene->moveToBottom(curve);
} else {
curve->setLocked(false);
m_scene->moveToTop(curve);
if (item->asNodeItem()) {
for (auto *ci : item->children())
setLocked(ci);
} else if (item->asPropertyItem()) {
if (CurveItem *curve = m_scene->findCurve(item->id())) {
if (item->locked() || item->implicitlyLocked()) {
curve->setLocked(true);
m_scene->moveToBottom(curve);
} else {
curve->setLocked(false);
m_scene->moveToTop(curve);
}
}
}
}
void GraphicsView::setPinned(TreeItem *item)
{
auto pin = [this](PropertyTreeItem *pitem, bool pinned) {
if (pinned) {
if (CurveItem *curve = m_scene->findCurve(pitem->id()))
curve->setPinned(pinned);
else if (CurveItem *citem = TreeModel::curveItem(pitem))
m_scene->addCurveItem(citem);
} else if (!pinned) {
if (!m_model->isSelected(pitem) && !pitem->pinned())
m_scene->removeCurveItem(pitem->id());
else if (CurveItem *curve = m_scene->findCurve(pitem->id()))
curve->setPinned(pinned);
}
};
if (auto *pitem = item->asPropertyItem()) {
pin(pitem, pitem->pinned() || pitem->implicitlyPinned());
} else if (auto *nitem = item->asNodeItem()) {
bool pinned = nitem->pinned();
if (!pinned && m_model->isSelected(nitem)) {
for (auto *i : nitem->children()) {
if (CurveItem *curve = m_scene->findCurve(i->id()))
curve->setPinned(pinned);
}
return;
}
for (auto *i : nitem->children()) {
if (auto *pitem = i->asPropertyItem())
pin(pitem, pinned);
}
}
applyZoom(m_zoomX, m_zoomY);
viewport()->update();
}
void GraphicsView::setZoomX(double zoom, const QPoint &pivot)
{
applyZoom(zoom, m_zoomY, pivot);
@@ -228,8 +268,8 @@ void GraphicsView::scrollContent(double x, double y)
{
QScrollBar *hs = horizontalScrollBar();
QScrollBar *vs = verticalScrollBar();
hs->setValue(hs->value() + x);
vs->setValue(vs->value() + y);
hs->setValue(hs->value() + static_cast<int>(x));
vs->setValue(vs->value() + static_cast<int>(y));
}
void GraphicsView::reset(const std::vector<CurveItem *> &items)
@@ -242,15 +282,19 @@ void GraphicsView::reset(const std::vector<CurveItem *> &items)
viewport()->update();
}
void GraphicsView::updateSelection(const std::vector<CurveItem *> &items)
void GraphicsView::updateSelection()
{
std::vector<CurveItem *> preservedItems = m_scene->takePinnedItems();
for (auto *curve : items) {
std::vector<CurveItem *> deleteItems;
for (auto *curve : m_model->selectedCurves()) {
auto finder = [curve](CurveItem *item) { return curve->id() == item->id(); };
auto iter = std::find_if(preservedItems.begin(), preservedItems.end(), finder);
if (iter == preservedItems.end())
preservedItems.push_back(curve);
else
deleteItems.push_back(curve);
}
freeClear(deleteItems);
reset(preservedItems);
}
@@ -304,7 +348,8 @@ void GraphicsView::mousePressEvent(QMouseEvent *event)
QPointF pos = mapToScene(event->pos());
if (timeScaleRect().contains(pos)) {
m_dragging = true;
setCurrentFrame(std::round(mapXtoTime(pos.x())));
double t = mapXtoTime(static_cast<int>(pos.x()));
setCurrentFrame(roundToInt(t));
m_playhead.setMoving(true);
event->accept();
return;
@@ -398,19 +443,18 @@ void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
void GraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
painter->fillRect(rect, m_style.backgroundBrush);
painter->fillRect(scene()->sceneRect(), m_style.backgroundAlternateBrush);
drawGrid(painter, rect);
drawGrid(painter);
}
int GraphicsView::mapTimeToX(double time) const
{
return std::round(time * scaleX(m_transform));
return roundToInt(time * scaleX(m_transform));
}
int GraphicsView::mapValueToY(double y) const
{
return std::round(y * scaleY(m_transform));
return roundToInt(y * scaleY(m_transform));
}
double GraphicsView::mapXtoTime(int x) const
@@ -430,7 +474,7 @@ QPointF GraphicsView::globalToScene(const QPoint &point) const
QPointF GraphicsView::globalToRaster(const QPoint &point) const
{
QPointF scene = globalToScene(point);
QPoint scene = globalToScene(point).toPoint();
return QPointF(mapXtoTime(scene.x()), mapYtoValue(scene.y()));
}
@@ -480,7 +524,7 @@ void GraphicsView::applyZoom(double x, double y, const QPoint &pivot)
m_scene->doNotMoveItems(false);
}
void GraphicsView::drawGrid(QPainter *painter, const QRectF &rect)
void GraphicsView::drawGrid(QPainter *painter)
{
QRectF gridRect = scene()->sceneRect();
@@ -488,12 +532,16 @@ void GraphicsView::drawGrid(QPainter *painter, const QRectF &rect)
return;
auto drawVerticalLine = [painter, gridRect](double position) {
painter->drawLine(position, gridRect.top(), position, gridRect.bottom());
QPointF p1(position, gridRect.top());
QPointF p2(position, gridRect.bottom());
painter->drawLine(p1, p2);
};
painter->save();
painter->setPen(m_style.gridColor);
painter->fillRect(gridRect, m_style.backgroundAlternateBrush);
double timeIncrement = timeLabelInterval(painter, m_model->maximumTime());
for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement)
drawVerticalLine(mapTimeToX(i));
@@ -635,7 +683,7 @@ double GraphicsView::timeLabelInterval(QPainter *painter, double maxTime)
double tickDistance = mapTimeToX(deltaTime);
while (true) {
if (tickDistance == 0 && deltaTime >= maxTime)
if (qFuzzyCompare(tickDistance, 0.) && deltaTime >= maxTime)
return maxTime;
if (tickDistance > minTextSpacing)
@@ -658,12 +706,12 @@ QRectF GraphicsView::rangeMinHandle(const QRectF &rect)
QRectF labelRect = fontMetrics().boundingRect(QString("0"));
labelRect.moveCenter(rect.center());
qreal top = rect.bottom() - 2;
qreal bottom = labelRect.bottom() + 2;
QSize size(10, top - bottom);
qreal top = rect.bottom() - 2.;
qreal bottom = labelRect.bottom() + 2.;
QSize size(10, roundToInt(top - bottom));
int leftHandleLeft = mapTimeToX(m_model->minimumTime()) - size.width();
return QRectF(QPointF(leftHandleLeft, bottom), size);
int handle = mapTimeToX(m_model->minimumTime()) - size.width();
return QRectF(QPointF(handle, bottom), size);
}
QRectF GraphicsView::rangeMaxHandle(const QRectF &rect)
@@ -671,10 +719,13 @@ QRectF GraphicsView::rangeMaxHandle(const QRectF &rect)
QRectF labelRect = fontMetrics().boundingRect(QString("0"));
labelRect.moveCenter(rect.center());
qreal bottom = rect.bottom() - 2;
qreal top = labelRect.bottom() + 2;
qreal bottom = rect.bottom() - 2.;
qreal top = labelRect.bottom() + 2.;
return QRectF(QPointF(mapTimeToX(m_model->maximumTime()), bottom), QSize(10, top - bottom));
QSize size(10, roundToInt(top - bottom));
int handle = mapTimeToX(m_model->maximumTime());
return QRectF(QPointF(handle, bottom), size);
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -33,12 +33,12 @@
#include <QGraphicsView>
namespace DesignTools {
namespace QmlDesigner {
class CurveItem;
class CurveEditorModel;
class Playhead;
class PropertyTreeItem;
class TreeItem;
class GraphicsView : public QGraphicsView
{
@@ -92,7 +92,9 @@ public:
QRectF defaultRasterRect() const;
void setLocked(PropertyTreeItem *item);
void setLocked(TreeItem *item);
void setPinned(TreeItem *item);
void setStyle(const CurveEditorStyle &style);
@@ -106,7 +108,7 @@ public:
void reset(const std::vector<CurveItem *> &items);
void updateSelection(const std::vector<CurveItem *> &items);
void updateSelection();
void setInterpolation(Keyframe::Interpolation interpol);
@@ -134,7 +136,7 @@ protected:
private:
void applyZoom(double x, double y, const QPoint &pivot = QPoint());
void drawGrid(QPainter *painter, const QRectF &rect);
void drawGrid(QPainter *painter);
#if 0
void drawExtremaX(QPainter *painter, const QRectF &rect);
@@ -176,4 +178,4 @@ private:
CurveEditorStyleDialog m_dialog;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -31,7 +31,7 @@
#include <QPainter>
namespace DesignTools {
namespace QmlDesigner {
struct HandleGeometry
{
@@ -196,4 +196,4 @@ QVariant HandleItem::itemChange(QGraphicsItem::GraphicsItemChange change, const
return QGraphicsItem::itemChange(change, value);
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -28,7 +28,7 @@
#include "curveeditorstyle.h"
#include "selectableitem.h"
namespace DesignTools {
namespace QmlDesigner {
class KeyframeItem;
class CurveSegment;
@@ -77,4 +77,4 @@ private:
QPointF m_validPos;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -31,7 +31,7 @@
#include <cmath>
namespace DesignTools {
namespace QmlDesigner {
KeyframeItem::KeyframeItem(QGraphicsItem *parent)
: SelectableItem(parent)
@@ -408,9 +408,9 @@ QVariant KeyframeItem::itemChange(QGraphicsItem::GraphicsItemChange change, cons
if (ok) {
position.setX(std::round(position.x()));
if (curveItem->valueType() == ValueType::Integer)
if (curveItem->valueType() == PropertyTreeItem::ValueType::Integer)
position.setY(std::round(position.y()));
else if (curveItem->valueType() == ValueType::Bool)
else if (curveItem->valueType() == PropertyTreeItem::ValueType::Bool)
position.setY(position.y() > 0.5 ? 1.0 : 0.0);
if (!legalLeft() || !legalRight()) {
@@ -463,4 +463,4 @@ void KeyframeItem::selectionCallback()
m_right->setSelected(selected());
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -32,7 +32,7 @@
#include <QGraphicsObject>
namespace DesignTools {
namespace QmlDesigner {
class HandleItem;
@@ -134,4 +134,4 @@ private:
bool m_visibleOverride = true;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -34,7 +34,7 @@
#include <cmath>
namespace DesignTools {
namespace QmlDesigner {
constexpr double g_playheadMargin = 5.0;
@@ -149,6 +149,7 @@ void Playhead::mouseMoveOutOfBounds(GraphicsView *view)
void Playhead::mouseRelease(GraphicsView *view)
{
Q_UNUSED(view);
m_moving = false;
}
@@ -188,4 +189,4 @@ void Playhead::paint(QPainter *painter, GraphicsView *view) const
painter->restore();
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -32,7 +32,7 @@ QT_BEGIN_NAMESPACE
class QPainter;
QT_END_NAMESPACE
namespace DesignTools {
namespace QmlDesigner {
class GraphicsView;
@@ -69,4 +69,4 @@ private:
QTimer m_timer;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -26,7 +26,7 @@
#include "selectableitem.h"
#include "keyframeitem.h"
namespace DesignTools {
namespace QmlDesigner {
CurveEditorItem::CurveEditorItem(QGraphicsItem *parent)
: QGraphicsObject(parent)
@@ -193,4 +193,4 @@ void SelectableItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
activationCallback();
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -27,7 +27,7 @@
#include <QGraphicsObject>
namespace DesignTools {
namespace QmlDesigner {
class CurveEditorItem : public QGraphicsObject
{
@@ -58,13 +58,14 @@ enum ItemType {
ItemTypeCurve = QGraphicsItem::UserType + 3
};
enum class SelectionMode : unsigned int { Undefined, Clear, New, Add, Remove, Toggle };
class SelectableItem : public CurveEditorItem
{
Q_OBJECT
public:
enum class SelectionMode : unsigned int { Undefined, Clear, New, Add, Remove, Toggle };
SelectableItem(QGraphicsItem *parent = nullptr);
~SelectableItem() override;
@@ -102,4 +103,4 @@ private:
SelectionMode m_preSelected;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -27,7 +27,7 @@
#include "curveitem.h"
#include "treemodel.h"
namespace DesignTools {
namespace QmlDesigner {
SelectionModel::SelectionModel(QAbstractItemModel *model)
: QItemSelectionModel(model)
@@ -46,10 +46,19 @@ void SelectionModel::select(const QItemSelection &selection,
}
}
bool SelectionModel::isSelected(TreeItem *item) const
{
for (auto *i : selectedTreeItems())
if (i->id() == item->id())
return true;
return false;
}
std::vector<TreeItem::Path> SelectionModel::selectedPaths() const
{
std::vector<TreeItem::Path> out;
for (auto &&item : selectedTreeItems())
for (auto *item : selectedTreeItems())
out.push_back(item->path());
return out;
}
@@ -112,20 +121,11 @@ void SelectionModel::selectPaths(const std::vector<TreeItem::Path> &selection)
}
}
void SelectionModel::changeSelection(const QItemSelection &selected,
const QItemSelection &deselected)
void SelectionModel::changeSelection(const QItemSelection &selected, const QItemSelection &deselected)
{
Q_UNUSED(selected)
Q_UNUSED(deselected)
std::vector<CurveItem *> curves;
const auto ids = selectedIndexes();
for (auto &&index : ids) {
if (auto *curveItem = TreeModel::curveItem(index))
curves.push_back(curveItem);
}
emit curvesSelected(curves);
emit curvesSelected();
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -30,7 +30,7 @@
#include <QItemSelectionModel>
namespace DesignTools {
namespace QmlDesigner {
class TreeItem;
class NodeTreeItem;
@@ -41,13 +41,14 @@ class SelectionModel : public QItemSelectionModel
Q_OBJECT
signals:
void curvesSelected(const std::vector<CurveItem *> &curves);
void curvesSelected();
public:
SelectionModel(QAbstractItemModel *model = nullptr);
void select(const QItemSelection &selection,
QItemSelectionModel::SelectionFlags command) override;
void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override;
bool isSelected(TreeItem *item) const;
std::vector<TreeItem::Path> selectedPaths() const;
@@ -65,4 +66,4 @@ private:
void changeSelection(const QItemSelection &selected, const QItemSelection &deselected);
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -36,7 +36,7 @@
#include <cmath>
namespace DesignTools {
namespace QmlDesigner {
Selector::Selector() {}
@@ -139,7 +139,7 @@ void Selector::mouseRelease(QMouseEvent *event, GraphicsScene *scene)
bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsScene *scene)
{
auto selectWidthTool = [this,
tool](SelectionMode mode, const QPointF &pos, GraphicsScene *scene) {
tool](SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene) {
switch (tool) {
case SelectionTool::Lasso:
return lassoSelection(mode, pos, scene);
@@ -152,19 +152,19 @@ bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsSce
if (m_shortcut == m_shortcuts.newSelection) {
clearSelection(scene);
return selectWidthTool(SelectionMode::New, pos, scene);
return selectWidthTool(SelectableItem::SelectionMode::New, pos, scene);
} else if (m_shortcut == m_shortcuts.addToSelection) {
return selectWidthTool(SelectionMode::Add, pos, scene);
return selectWidthTool(SelectableItem::SelectionMode::Add, pos, scene);
} else if (m_shortcut == m_shortcuts.removeFromSelection) {
return selectWidthTool(SelectionMode::Remove, pos, scene);
return selectWidthTool(SelectableItem::SelectionMode::Remove, pos, scene);
} else if (m_shortcut == m_shortcuts.toggleSelection) {
return selectWidthTool(SelectionMode::Toggle, pos, scene);
return selectWidthTool(SelectableItem::SelectionMode::Toggle, pos, scene);
}
return false;
}
bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
bool Selector::pressSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
{
bool out = false;
const auto itemList = scene->items();
@@ -190,7 +190,7 @@ bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsSc
return out;
}
bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
bool Selector::rectangleSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
{
bool out = false;
m_rect.setBottomRight(pos);
@@ -201,14 +201,14 @@ bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, Graphi
keyframeItem->setPreselected(mode);
out = true;
} else {
keyframeItem->setPreselected(SelectionMode::Undefined);
keyframeItem->setPreselected(SelectableItem::SelectionMode::Undefined);
}
}
}
return out;
}
bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
bool Selector::lassoSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
{
bool out = false;
m_lasso.lineTo(pos);
@@ -219,7 +219,7 @@ bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsSc
keyframeItem->setPreselected(mode);
out = true;
} else {
keyframeItem->setPreselected(SelectionMode::Undefined);
keyframeItem->setPreselected(SelectableItem::SelectionMode::Undefined);
}
}
}
@@ -231,7 +231,7 @@ void Selector::clearSelection(GraphicsScene *scene)
const auto itemList = scene->items();
for (auto *item : itemList) {
if (auto *frameItem = qgraphicsitem_cast<KeyframeItem *>(item)) {
frameItem->setPreselected(SelectionMode::Clear);
frameItem->setPreselected(SelectableItem::SelectionMode::Clear);
frameItem->applyPreselection();
frameItem->setActivated(false, HandleItem::Slot::Left);
frameItem->setActivated(false, HandleItem::Slot::Right);
@@ -248,4 +248,4 @@ void Selector::applyPreSelection(GraphicsScene *scene)
}
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -28,14 +28,12 @@
#include "curveeditorstyle.h"
#include "selectableitem.h"
namespace DesignTools {
namespace QmlDesigner {
class GraphicsView;
class GraphicsScene;
class Playhead;
enum class SelectionTool { Undefined, Lasso, Rectangle };
class Selector
{
public:
@@ -50,13 +48,15 @@ public:
void mouseRelease(QMouseEvent *event, GraphicsScene *scene);
private:
enum class SelectionTool { Undefined, Lasso, Rectangle };
bool select(const SelectionTool &tool, const QPointF &pos, GraphicsScene *scene);
bool pressSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
bool pressSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
bool rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
bool rectangleSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
bool lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
bool lassoSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
void clearSelection(GraphicsScene *scene);
@@ -77,4 +77,4 @@ private:
QRectF m_rect;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -24,7 +24,7 @@
****************************************************************************/
#include "shortcut.h"
namespace DesignTools {
namespace QmlDesigner {
Shortcut::Shortcut()
: m_key()
@@ -78,4 +78,4 @@ bool Shortcut::operator==(const Shortcut &other) const
return m_key == other.m_key && m_buttons == other.m_buttons && m_modifiers == other.m_modifiers;
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -27,7 +27,7 @@
#include <QMouseEvent>
namespace DesignTools {
namespace QmlDesigner {
class Shortcut
{
@@ -58,4 +58,4 @@ private:
Qt::KeyboardModifiers m_modifiers;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -24,13 +24,14 @@
****************************************************************************/
#include "treeitemdelegate.h"
#include "treeitem.h"
#include "treemodel.h"
#include <QApplication>
#include <QEvent>
#include <QMouseEvent>
#include <QPainter>
namespace DesignTools {
namespace QmlDesigner {
TreeItemDelegate::TreeItemDelegate(const CurveEditorStyle &style, QObject *parent)
: QStyledItemDelegate(parent)
@@ -50,56 +51,66 @@ QRect makeSquare(const QRect &rect)
return r;
}
QPixmap pixmapFromStyle(int column, const CurveEditorStyle &style, const QRect &rect, TreeItem *item, bool underMouse)
{
QColor color = underMouse ? style.iconHoverColor : style.iconColor;
if (column == 1) {
bool locked = item->locked();
if (underMouse)
locked = !locked;
if (locked)
return pixmapFromIcon(style.treeItemStyle.lockedIcon, rect.size(), color);
else
return pixmapFromIcon(style.treeItemStyle.unlockedIcon, rect.size(), color);
}
bool pinned = item->pinned();
if (underMouse)
pinned = !pinned;
if (pinned)
return pixmapFromIcon(style.treeItemStyle.pinnedIcon, rect.size(), color);
else
return pixmapFromIcon(style.treeItemStyle.unpinnedIcon, rect.size(), color);
}
void TreeItemDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (index.column() == 1 || index.column() == 2) {
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
auto *treeItem = static_cast<TreeItem *>(index.internalPointer());
QColor high = Theme::getColor(Theme::Color::QmlDesigner_HighlightColor);
opt.palette.setColor(QPalette::Active, QPalette::Highlight, high);
opt.palette.setColor(QPalette::Inactive, QPalette::Highlight, high);
QPoint mousePos = QCursor::pos();
mousePos = option.widget->mapFromGlobal(mousePos);
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
QRect iconRect = makeSquare(option.rect);
bool underMouse = option.rect.contains(m_mousePos)
&& option.state & QStyle::State_MouseOver;
auto *treeItem = static_cast<TreeItem *>(index.internalPointer());
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
bool textColumn = TreeModel::isTextColumn(index);
bool lockedColumn = TreeModel::isLockedColumn(index);
bool pinnedColumn = TreeModel::isPinnedColumn(index);
QPixmap pixmap = pixmapFromStyle(index.column(), m_style, iconRect, treeItem, underMouse);
painter->drawPixmap(iconRect, pixmap);
QPixmap pixmap;
QRect iconRect = makeSquare(option.rect);
if (lockedColumn) {
if (treeItem->locked()) {
pixmap = m_style.treeItemStyle.lockedIcon.pixmap(iconRect.size());
} else if (treeItem->asNodeItem() != nullptr && treeItem->implicitlyLocked()) {
pixmap = m_style.treeItemStyle.implicitlyLockedIcon.pixmap(iconRect.size());
} else if (option.state.testFlag(QStyle::State_MouseOver)) {
if (treeItem->implicitlyLocked()) {
pixmap = m_style.treeItemStyle.implicitlyLockedIcon.pixmap(iconRect.size());
} else {
pixmap = m_style.treeItemStyle.unlockedIcon.pixmap(iconRect.size());
}
}
} else if (pinnedColumn) {
if (treeItem->pinned()) {
pixmap = m_style.treeItemStyle.pinnedIcon.pixmap(iconRect.size());
} else if (treeItem->asNodeItem() != nullptr && treeItem->implicitlyPinned()) {
pixmap = m_style.treeItemStyle.implicitlyPinnedIcon.pixmap(iconRect.size());
} else if (option.state.testFlag(QStyle::State_MouseOver)) {
if (treeItem->implicitlyPinned()) {
pixmap = m_style.treeItemStyle.implicitlyPinnedIcon.pixmap(iconRect.size());
} else {
pixmap = m_style.treeItemStyle.unpinnedIcon.pixmap(iconRect.size());
}
}
} else {
QStyledItemDelegate::paint(painter, option, index);
if (textColumn && (treeItem->locked() || treeItem->implicitlyLocked())) {
QColor col = opt.palette.color(QPalette::Disabled, QPalette::Text).darker();
opt.palette.setColor(QPalette::Active, QPalette::Text, col);
opt.palette.setColor(QPalette::Inactive, QPalette::Text, col);
}
QStyledItemDelegate::paint(painter, opt, index);
}
if (!pixmap.isNull())
painter->drawPixmap(iconRect, pixmap);
}
void TreeItemDelegate::setStyle(const CurveEditorStyle &style)
@@ -118,4 +129,4 @@ bool TreeItemDelegate::editorEvent(QEvent *event,
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -29,7 +29,7 @@
#include <QStyledItemDelegate>
namespace DesignTools {
namespace QmlDesigner {
class TreeItemDelegate : public QStyledItemDelegate
{
@@ -60,4 +60,4 @@ private:
QPoint m_mousePos;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -31,7 +31,22 @@
#include <QIcon>
namespace DesignTools {
namespace QmlDesigner {
bool TreeModel::isTextColumn(const QModelIndex &index)
{
return index.column() == 0;
}
bool TreeModel::isLockedColumn(const QModelIndex &index)
{
return index.column() == 1;
}
bool TreeModel::isPinnedColumn(const QModelIndex &index)
{
return index.column() == 2;
}
TreeItem *TreeModel::treeItem(const QModelIndex &index)
{
@@ -71,8 +86,8 @@ CurveItem *TreeModel::curveItem(TreeItem *item)
auto *citem = new CurveItem(pti->id(), pti->curve());
citem->setValueType(pti->valueType());
citem->setComponent(pti->component());
citem->setLocked(pti->locked());
citem->setPinned(pti->pinned());
citem->setLocked(pti->locked() || item->implicitlyLocked());
citem->setPinned(pti->pinned() || item->implicitlyPinned());
return citem;
}
@@ -183,6 +198,11 @@ void TreeModel::setGraphicsView(GraphicsView *view)
m_view = view;
}
TreeView *TreeModel::treeView() const
{
return m_tree;
}
GraphicsView *TreeModel::graphicsView() const
{
return m_view;
@@ -208,6 +228,36 @@ QModelIndex TreeModel::findIdx(const QString &name, const QModelIndex &parent) c
return QModelIndex();
}
bool TreeModel::isSelected(TreeItem *item) const
{
if (auto *sm = selectionModel())
return sm->isSelected(item);
return false;
}
void addCurvesFromItem(TreeItem *item, std::vector<CurveItem *> &curves)
{
if (auto *pitem = item->asPropertyItem()) {
if (auto *curveItem = TreeModel::curveItem(pitem))
curves.push_back(curveItem);
} else if (auto *nitem = item->asNodeItem()) {
for (auto *child : nitem->children())
addCurvesFromItem(child, curves);
}
}
std::vector<CurveItem *> TreeModel::selectedCurves() const
{
std::vector<CurveItem *> curves;
const auto ids = selectionModel()->selectedIndexes();
for (auto &&index : ids) {
if (auto *treeItem = TreeModel::treeItem(index))
addCurvesFromItem(treeItem, curves);
}
return curves;
}
QModelIndex TreeModel::indexOf(const TreeItem::Path &path) const
{
QModelIndex parent;
@@ -238,4 +288,9 @@ TreeItem *TreeModel::find(unsigned int id)
return m_root->find(id);
}
} // End namespace DesignTools.
TreeItem *TreeModel::find(const QString &id)
{
return m_root->find(id);
}
} // End namespace QmlDesigner.

View File

@@ -31,13 +31,11 @@
#include <vector>
namespace DesignTools {
namespace QmlDesigner {
class GraphicsView;
class TreeView;
class TreeItem;
class CurveItem;
class PropertyTreeItem;
class SelectionModel;
class TreeModel : public QAbstractItemModel
@@ -45,6 +43,12 @@ class TreeModel : public QAbstractItemModel
Q_OBJECT
public:
static bool isTextColumn(const QModelIndex &index);
static bool isLockedColumn(const QModelIndex &index);
static bool isPinnedColumn(const QModelIndex &index);
static TreeItem *treeItem(const QModelIndex &index);
static NodeTreeItem *nodeItem(const QModelIndex &index);
@@ -73,13 +77,23 @@ public:
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
bool isSelected(TreeItem *item) const;
std::vector<CurveItem *> selectedCurves() const;
QModelIndex indexOf(const TreeItem::Path &path) const;
TreeItem *find(unsigned int id);
TreeItem *find(const QString &id);
void setTreeView(TreeView *view);
void setGraphicsView(GraphicsView *view);
protected:
TreeView *treeView() const;
GraphicsView *graphicsView() const;
SelectionModel *selectionModel() const;
@@ -88,8 +102,6 @@ protected:
TreeItem *root();
TreeItem *find(unsigned int id);
QModelIndex findIdx(const QString &name, const QModelIndex &parent) const;
private:
@@ -100,4 +112,4 @@ private:
TreeItem *m_root;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -28,11 +28,12 @@
#include "selectionmodel.h"
#include "treeitem.h"
#include "treeitemdelegate.h"
#include "treemodel.h"
#include <QHeaderView>
#include <QMouseEvent>
namespace DesignTools {
namespace QmlDesigner {
TreeView::TreeView(CurveEditorModel *model, QWidget *parent)
: QTreeView(parent)
@@ -105,17 +106,12 @@ void TreeView::mousePressEvent(QMouseEvent *event)
QModelIndex index = indexAt(event->pos());
if (index.isValid()) {
auto *treeItem = static_cast<TreeItem *>(index.internalPointer());
if (index.column() == 1) {
treeItem->setLocked(!treeItem->locked());
if (auto *propertyItem = treeItem->asPropertyItem())
emit treeItemLocked(propertyItem);
} else if (index.column() == 2) {
treeItem->setPinned(!treeItem->pinned());
if (auto *propertyItem = treeItem->asPropertyItem())
emit treeItemPinned(propertyItem);
}
if (TreeModel::isLockedColumn(index))
emit treeItemLocked(treeItem, !treeItem->locked());
else if (TreeModel::isPinnedColumn(index))
emit treeItemPinned(treeItem, !treeItem->pinned());
}
QTreeView::mousePressEvent(event);
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -30,7 +30,7 @@
#include <QTreeView>
namespace DesignTools {
namespace QmlDesigner {
class AnimationCurve;
class CurveEditorModel;
@@ -44,9 +44,9 @@ class TreeView : public QTreeView
signals:
void curvesSelected(const std::vector<CurveItem *> &curves);
void treeItemLocked(PropertyTreeItem *item);
void treeItemLocked(TreeItem *item, bool val);
void treeItemPinned(PropertyTreeItem *item);
void treeItemPinned(TreeItem *item, bool val);
public:
TreeView(CurveEditorModel *model, QWidget *parent = nullptr);
@@ -63,4 +63,4 @@ protected:
void mousePressEvent(QMouseEvent *event) override;
};
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -29,7 +29,7 @@
#include <QRectF>
#include <QTransform>
namespace DesignTools {
namespace QmlDesigner {
double scaleX(const QTransform &transform)
{
@@ -92,4 +92,4 @@ QPalette singleColorPalette(const QColor &color)
return palette;
}
} // End namespace DesignTools.
} // End namespace QmlDesigner.

View File

@@ -26,6 +26,7 @@
#pragma once
#include <QtGlobal>
#include <cmath>
QT_BEGIN_NAMESPACE
class QColor;
@@ -37,7 +38,7 @@ QT_END_NAMESPACE
#include <vector>
namespace DesignTools {
namespace QmlDesigner {
double scaleX(const QTransform &transform);
@@ -58,7 +59,7 @@ inline void freeClear(T &vec)
}
template<typename TV, typename TC>
inline double clamp(const TV &val, const TC &lo, const TC &hi)
inline TV clamp(const TV &val, const TC &lo, const TC &hi)
{
return val < lo ? lo : (val > hi ? hi : val);
}
@@ -75,4 +76,10 @@ inline T reverseLerp(double blend, const T &a, const T &b)
return (blend - b) / (a - b);
}
} // End namespace DesignTools.
template<typename T>
inline int roundToInt(const T &val)
{
return static_cast<int>(std::round(val));
}
} // End namespace QmlDesigner.

Some files were not shown because too many files have changed in this diff Show More