Merge remote-tracking branch 'origin/4.11'

Conflicts:
	src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp
	src/plugins/qtsupport/qtversionmanager.cpp

Change-Id: I2f29dd2e86b028be46184b12ac2c17ace2513d5a
This commit is contained in:
Eike Ziller
2019-10-23 07:41:01 +02:00
107 changed files with 1994 additions and 983 deletions

View File

@@ -838,6 +838,8 @@ function(add_qtc_executable name)
INSTALL_RPATH "${_RPATH_BASE}/${_RELATIVE_LIB_PATH}" INSTALL_RPATH "${_RPATH_BASE}/${_RELATIVE_LIB_PATH}"
RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}" RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}"
QT_SKIP_TRANSLATION "${skip_translation}" QT_SKIP_TRANSLATION "${skip_translation}"
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
${_arg_PROPERTIES} ${_arg_PROPERTIES}
) )
append_extra_translations("${name}" "${_arg_EXTRA_TRANSLATIONS}") append_extra_translations("${name}" "${_arg_EXTRA_TRANSLATIONS}")

View File

@@ -1,9 +1,9 @@
#BINARY_ARTIFACTS_BRANCH = master #BINARY_ARTIFACTS_BRANCH = master
#PROJECT_USER_FILE_EXTENSION = .user #PROJECT_USER_FILE_EXTENSION = .user
set(IDE_VERSION "4.10.82") # The IDE version. set(IDE_VERSION "4.10.83") # The IDE version.
set(IDE_VERSION_COMPAT "4.10.82") # The IDE Compatibility version. set(IDE_VERSION_COMPAT "4.10.83") # The IDE Compatibility version.
set(IDE_VERSION_DISPLAY "4.11.0-beta1") # The IDE display version. set(IDE_VERSION_DISPLAY "4.11.0-beta2") # The IDE display version.
set(IDE_COPYRIGHT_YEAR "2019") # The IDE current copyright year. set(IDE_COPYRIGHT_YEAR "2019") # The IDE current copyright year.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2018 The Qt Company Ltd. ** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -28,7 +28,7 @@
\contentspage index.html \contentspage index.html
\previouspage creator-developing-generic-linux.html \previouspage creator-developing-generic-linux.html
\page creator-developing-ios.html \page creator-developing-ios.html
\nextpage creator-developing-qnx.html \nextpage creator-developing-mcu.html
\title Connecting iOS Devices \title Connecting iOS Devices

View File

@@ -0,0 +1,203 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
**
** 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 Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
**
****************************************************************************/
/*!
\contentspage index.html
\previouspage creator-developing-ios.html
\page creator-developing-mcu.html
\nextpage creator-developing-qnx.html
\title Connecting MCUs
\l{Qt for MCUs} enables you to use subsets of QML and Qt Quick Controls
to create user interfaces for devices that are powered by microcontroller
units (MCU). It includes a new graphics rendering engine that has a low
memory footprint and is optimized for MCUs and other resource-constrained
devices.
You can connect MCU boards to a development host to build applications for
them using the GNU Arm Embedded GCC compiler, libraries, and other GNU tools
necessary for bare metal software development on devices based on the Arm
Cortex-M processors. You can deploy the applications on MCUs to run and
debug them using \QC.
The toolchains are available for cross-compilation on Microsoft Windows,
Linux, and macOS.
The following MCU boards are currently supported:
\list
\li \l{https://www.st.com/en/evaluation-tools/stm32f7508-dk.html}
{STM32F7508-DK}
\li \l{https://www.st.com/en/evaluation-tools/32f769idiscovery.html}
{32F769IDISCOVERY}
\li \l{https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/i.mx-rt1050-evaluation-kit:MIMXRT1050-EVK}
{NXP i.MX RT1050 EVK}
\endlist
For a list of Qt for MCU reference implementations, see the Qt for MCU
documentation.
You use the \l{Connecting Bare Metal Devices}{Bare metal plugin} to connect
to OpenOCD or ST-LINK Utility for debugging on MCUs.
\section1 Requirements
To use \QC to develop QML applications for MCUs, you need the following:
\list
\li Qt for MCU SDK
\li The Bare Metal plugin
\li GNU ARM Embedded Toolchain
\li For STM32 boards:
\list
\li \l{https://www.st.com/en/embedded-software/stm32cubef7.html}
{STM32Cube SDK}
\li \l{https://www.st.com/en/development-tools/stm32cubeprog.html}
{STM32Cube Programmer}
\endlist
\li For NXP boards:
\list
\li \l{https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/i.mx-rt1050-evaluation-kit:MIMXRT1050-EVK}
NXP EVKB-IMXRT 1050 SDK
\li \l{https://www.segger.com/downloads/jlink}{SEGGER JLink}
\endlist
\endlist
\section1 Setting Up the Development Environment
You must download and install the required software and create connections
between \QC and MCUs.
\section2 Enabling Bare Metal and MCU Plugins
To be able to develop for MCUs, you must enable the Bare Metal and MCU
plugins:
\list 1
\li Select \uicontrol Help > \uicontrol {About Plugins} >
\uicontrol {Device Support} > \uicontrol {Bare Metal} and
\uicontrol {MCU Support} to enable the Bare Metal and MCU
plugins.
\li Restart \QC to be able to use the plugins.
\li Create connections for debugging on the MCU board, as described in
\l{Connecting Bare Metal Devices}.
\endlist
\section2 Specifying MCU Settings
To configure a connection between \QC and your MCU board, select
\uicontrol Tools > \uicontrol Options > \uicontrol Devices >
\uicontrol MCU:
\image qtcreator-mcu-options.png "MCU options"
\list 1
\li In the \uicontrol {MCU board} field, select your MCU board.
\li In the \uicontrol {GNU ARM Embedded Toolchain} field,
specify the path to the directory where you installed the
tool chain.
\li For STM32 boards:
\list
\li In the \uicontrol {STM32Cube SDK} field, specify the
path to the directory where you installed the SDK.
\li In the \uicontrol {STM32Cube Programmer} field,
specify the path to the directory where you
installed the tool.
\endlist
\li For NXP boards:
\list
\li In the \uicontrol {NXP EVKB-IMXRT 1050 SDK} field,
specify the path to the directory where you
installed the SDK.
\li In the \uicontrol {SEGGER JLink} field, specify the
path to the directory where you installed the tool.
\endlist
\li In the \uicontrol {Qt MCU SDK} field, specify the path to the
directory where you installed Qt MCU.
\li Select \uicontrol Apply to save the settings and to generate
a MCU device and kit.
\endlist
\section2 Adding MCU Devices
\QC automatically adds a default MCU device when you select
\uicontrol Apply in the \uicontrol MCU tab after configuring the
MCU tool chain.
\image qtcreator-mcu-device.png "MCU devices"
To add MCU devices, select \uicontrol Tools > \uicontrol Options >
\uicontrol Devices > \uicontrol Add > \uicontrol {MCU Device} >
\uicontrol {Start Wizard}:
\list 1
\li In the \uicontrol Name field, give the device a name.
\li In the \uicontrol Type field, select the board type.
\li Select \uicontrol Apply to add the device.
\endlist
\section2 Adding MCU Kits
\QC automatically adds kits for building applications and running them
on the specified MCU boards when you select \uicontrol Apply in the
\uicontrol MCU tab after configuring the MCU tool chain.
\image qtcreator-mcu-kit.png "MCU kits"
To add kits, select \uicontrol Tools > \uicontrol Options > \uicontrol Kits
> \uicontrol Add:
\list 1
\li In the \uicontrol Name field, specify a name for the kit.
\li In the \uicontrol {Device type} field, select
\uicontrol {MCU}.
\li In the \uicontrol Device field, select the MCU board for the kit.
\li In the \uicontrol Compiler field, select the Arm GCC compiler for
the kit.
\li Select \uicontrol Apply to add the kit.
\endlist
\section1 Running Applications on MCUs
You can use a wizard to set up a project for developing an application that
you can run on MCUs. The project uses a subset of QML and Qt Quick Controls
that are supported by Qt for MCUs. For more information about developing
applications for MCUs, see the Qt for MCU documentation.
To create an application and run it on a MCU board:
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol Application > \uicontrol {MCU Support Application} >
\uicontrol Choose.
\li Follow the instructions of the wizard to create the project.
\li Select \uicontrol Projects > \uicontrol {Build & Run}, and then
select the kit for building the application and running it on the
MCU board specified in the kit.
\li Select \uicontrol Run to specify run settings.
Usually, you can use the default settings.
\endlist
*/

View File

@@ -83,6 +83,11 @@
\QC detects the tools and configured devices automatically and uses \QC detects the tools and configured devices automatically and uses
the tools to build, deploy, and run applications. the tools to build, deploy, and run applications.
\li \l{Connecting MCUs}
You can connect MCU boards to a development host to deploy, run, and
debug applications on them from \QC.
\li \l{Connecting QNX Devices} \li \l{Connecting QNX Devices}
You can connect QNX devices to the development PC to deploy, run and You can connect QNX devices to the development PC to deploy, run and

View File

@@ -42,6 +42,8 @@
\li iOS \li iOS
\li Microcontroller Units (MCU)
\li QNX \li QNX
\li Universal Windows Platform (UWP) \li Universal Windows Platform (UWP)
@@ -95,6 +97,11 @@
\li \li
\li \image ok \li \image ok
\li \li
\row
\li MCUs
\li \image ok
\li \image ok
\li \image ok
\row \row
\li QNX \li QNX
\li \image ok \li \image ok

View File

@@ -133,6 +133,13 @@
code for a QApplication or create one that contains an code for a QApplication or create one that contains an
empty window. empty window.
\li MCU Support Application
Creates an application that uses a subset of QML and
Qt Quick Controls (as supported by Qt for MCUs) that
you can deploy, run, and debug on MCU boards. For more
information, see \l {Connecting MCUs}.
\endlist \endlist
\li Libraries \li Libraries

View File

@@ -30,7 +30,7 @@
/*! /*!
\contentspage index.html \contentspage index.html
\previouspage creator-developing-ios.html \previouspage creator-developing-mcu.html
\page creator-developing-qnx.html \page creator-developing-qnx.html
\nextpage creator-setup-webassembly.html \nextpage creator-setup-webassembly.html

View File

@@ -175,6 +175,7 @@
\li \l{Connecting Bare Metal Devices} \li \l{Connecting Bare Metal Devices}
\li \l{Connecting Embedded Linux Devices} \li \l{Connecting Embedded Linux Devices}
\li \l{Connecting iOS Devices} \li \l{Connecting iOS Devices}
\li \l{Connecting MCUs}
\li \l{Connecting QNX Devices} \li \l{Connecting QNX Devices}
\li \l{Building Applications for the Web} \li \l{Building Applications for the Web}
\endlist \endlist

View File

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

View File

@@ -1,8 +1,8 @@
QTCREATOR_VERSION = 4.10.82 QTCREATOR_VERSION = 4.10.83
QTCREATOR_COMPAT_VERSION = 4.10.82 QTCREATOR_COMPAT_VERSION = 4.10.83
QTCREATOR_DISPLAY_VERSION = 4.11.0-beta1 QTCREATOR_DISPLAY_VERSION = 4.11.0-beta2
QTCREATOR_COPYRIGHT_YEAR = 2019 QTCREATOR_COPYRIGHT_YEAR = 2019
BINARY_ARTIFACTS_BRANCH = master BINARY_ARTIFACTS_BRANCH = 4.11
IDE_DISPLAY_NAME = Qt Creator IDE_DISPLAY_NAME = Qt Creator
IDE_ID = qtcreator IDE_ID = qtcreator

View File

@@ -0,0 +1,69 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** 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 "changeselectioncommand.h"
#include <QDataStream>
#include <QDebug>
namespace QmlDesigner {
ChangeSelectionCommand::ChangeSelectionCommand() = default;
ChangeSelectionCommand::ChangeSelectionCommand(const QVector<qint32> &idVector)
: m_instanceIdVector(idVector)
{
}
QVector<qint32> ChangeSelectionCommand::instanceIds() const
{
return m_instanceIdVector;
}
QDataStream &operator<<(QDataStream &out, const ChangeSelectionCommand &command)
{
out << command.instanceIds();
return out;
}
QDataStream &operator>>(QDataStream &in, ChangeSelectionCommand &command)
{
in >> command.m_instanceIdVector;
return in;
}
QDebug operator <<(QDebug debug, const ChangeSelectionCommand &command)
{
return debug.nospace() << "ChangeSelectionCommand(instanceIdVector: " << command.m_instanceIdVector << ")";
}
bool operator ==(const ChangeSelectionCommand &first, const ChangeSelectionCommand &second)
{
return first.m_instanceIdVector == second.m_instanceIdVector;
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,61 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** 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 <QMetaType>
#include <QVector>
#include <QDataStream>
#include "instancecontainer.h"
namespace QmlDesigner {
class ChangeSelectionCommand
{
friend QDataStream &operator>>(QDataStream &in, ChangeSelectionCommand &command);
friend QDebug operator <<(QDebug debug, const ChangeSelectionCommand &command);
friend bool operator ==(const ChangeSelectionCommand &first,
const ChangeSelectionCommand &second);
public:
ChangeSelectionCommand();
explicit ChangeSelectionCommand(const QVector<qint32> &idVector);
QVector<qint32> instanceIds() const;
private:
QVector<qint32> m_instanceIdVector;
};
QDataStream &operator<<(QDataStream &out, const ChangeSelectionCommand &command);
QDataStream &operator>>(QDataStream &in, ChangeSelectionCommand &command);
bool operator ==(const ChangeSelectionCommand &first, const ChangeSelectionCommand &second);
QDebug operator <<(QDebug debug, const ChangeSelectionCommand &command);
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::ChangeSelectionCommand)

View File

@@ -26,6 +26,7 @@ HEADERS += $$PWD/valueschangedcommand.h
HEADERS += $$PWD/changeauxiliarycommand.h HEADERS += $$PWD/changeauxiliarycommand.h
HEADERS += $$PWD/removesharedmemorycommand.h HEADERS += $$PWD/removesharedmemorycommand.h
HEADERS += $$PWD/puppetalivecommand.h HEADERS += $$PWD/puppetalivecommand.h
HEADERS += $$PWD/changeselectioncommand.h
SOURCES += $$PWD/synchronizecommand.cpp SOURCES += $$PWD/synchronizecommand.cpp
SOURCES += $$PWD/debugoutputcommand.cpp SOURCES += $$PWD/debugoutputcommand.cpp
@@ -53,3 +54,4 @@ SOURCES += $$PWD/pixmapchangedcommand.cpp
SOURCES += $$PWD/changeauxiliarycommand.cpp SOURCES += $$PWD/changeauxiliarycommand.cpp
SOURCES += $$PWD/removesharedmemorycommand.cpp SOURCES += $$PWD/removesharedmemorycommand.cpp
SOURCES += $$PWD/puppetalivecommand.cpp SOURCES += $$PWD/puppetalivecommand.cpp
SOURCES += $$PWD/changeselectioncommand.cpp

View File

@@ -50,7 +50,7 @@ ValuesChangedCommand::ValuesChangedCommand(const QVector<PropertyValueContainer>
{ {
} }
QVector<PropertyValueContainer> ValuesChangedCommand::valueChanges() const const QVector<PropertyValueContainer> ValuesChangedCommand::valueChanges() const
{ {
return m_valueChangeVector; return m_valueChangeVector;
} }

View File

@@ -42,7 +42,7 @@ public:
ValuesChangedCommand(); ValuesChangedCommand();
explicit ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector); explicit ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector);
QVector<PropertyValueContainer> valueChanges() const; const QVector<PropertyValueContainer> valueChanges() const;
quint32 keyNumber() const; quint32 keyNumber() const;
static void removeSharedMemorys(const QVector<qint32> &keyNumberVector); static void removeSharedMemorys(const QVector<qint32> &keyNumberVector);
@@ -59,6 +59,26 @@ QDataStream &operator>>(QDataStream &in, ValuesChangedCommand &command);
bool operator ==(const ValuesChangedCommand &first, const ValuesChangedCommand &second); bool operator ==(const ValuesChangedCommand &first, const ValuesChangedCommand &second);
QDebug operator <<(QDebug debug, const ValuesChangedCommand &instance); QDebug operator <<(QDebug debug, const ValuesChangedCommand &instance);
/* ValuesChangedCommand is used to notify that the values of a specific instatiated
* QObject changed.
* The ValuesModifiedCommand is used to notify that a user changed a QML property and
* that this property should be changed in the data model.
*/
class ValuesModifiedCommand : public ValuesChangedCommand
{
public:
ValuesModifiedCommand()
{}
explicit ValuesModifiedCommand(const QVector<PropertyValueContainer> &valueChangeVector)
: ValuesChangedCommand(valueChangeVector)
{}
};
} // namespace QmlDesigner } // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::ValuesModifiedCommand)
Q_DECLARE_METATYPE(QmlDesigner::ValuesChangedCommand) Q_DECLARE_METATYPE(QmlDesigner::ValuesChangedCommand)

View File

@@ -67,6 +67,7 @@
#include "endpuppetcommand.h" #include "endpuppetcommand.h"
#include "debugoutputcommand.h" #include "debugoutputcommand.h"
#include "puppetalivecommand.h" #include "puppetalivecommand.h"
#include "changeselectioncommand.h"
namespace QmlDesigner { namespace QmlDesigner {
@@ -129,6 +130,7 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
{ {
static const int informationChangedCommandType = QMetaType::type("InformationChangedCommand"); static const int informationChangedCommandType = QMetaType::type("InformationChangedCommand");
static const int valuesChangedCommandType = QMetaType::type("ValuesChangedCommand"); static const int valuesChangedCommandType = QMetaType::type("ValuesChangedCommand");
static const int valuesModifiedCommandType = QMetaType::type("ValuesModifiedCommand");
static const int pixmapChangedCommandType = QMetaType::type("PixmapChangedCommand"); static const int pixmapChangedCommandType = QMetaType::type("PixmapChangedCommand");
static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand"); static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand");
static const int statePreviewImageChangedCommandType = QMetaType::type("StatePreviewImageChangedCommand"); static const int statePreviewImageChangedCommandType = QMetaType::type("StatePreviewImageChangedCommand");
@@ -136,12 +138,15 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
static const int synchronizeCommandType = QMetaType::type("SynchronizeCommand"); static const int synchronizeCommandType = QMetaType::type("SynchronizeCommand");
static const int tokenCommandType = QMetaType::type("TokenCommand"); static const int tokenCommandType = QMetaType::type("TokenCommand");
static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand"); static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand");
if (command.userType() == controlCommand.userType()) { if (command.userType() == controlCommand.userType()) {
if (command.userType() == informationChangedCommandType) if (command.userType() == informationChangedCommandType)
return command.value<InformationChangedCommand>() == controlCommand.value<InformationChangedCommand>(); return command.value<InformationChangedCommand>() == controlCommand.value<InformationChangedCommand>();
else if (command.userType() == valuesChangedCommandType) else if (command.userType() == valuesChangedCommandType)
return command.value<ValuesChangedCommand>() == controlCommand.value<ValuesChangedCommand>(); return command.value<ValuesChangedCommand>() == controlCommand.value<ValuesChangedCommand>();
else if (command.userType() == valuesModifiedCommandType)
return command.value<ValuesModifiedCommand>() == controlCommand.value<ValuesModifiedCommand>();
else if (command.userType() == pixmapChangedCommandType) else if (command.userType() == pixmapChangedCommandType)
return command.value<PixmapChangedCommand>() == controlCommand.value<PixmapChangedCommand>(); return command.value<PixmapChangedCommand>() == controlCommand.value<PixmapChangedCommand>();
else if (command.userType() == childrenChangedCommandType) else if (command.userType() == childrenChangedCommandType)
@@ -156,6 +161,8 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
return command.value<TokenCommand>() == controlCommand.value<TokenCommand>(); return command.value<TokenCommand>() == controlCommand.value<TokenCommand>();
else if (command.userType() == debugOutputCommandType) else if (command.userType() == debugOutputCommandType)
return command.value<DebugOutputCommand>() == controlCommand.value<DebugOutputCommand>(); return command.value<DebugOutputCommand>() == controlCommand.value<DebugOutputCommand>();
else if (command.userType() == changeSelectionCommandType)
return command.value<ChangeSelectionCommand>() == controlCommand.value<ChangeSelectionCommand>();
} }
return false; return false;
@@ -198,6 +205,11 @@ void NodeInstanceClientProxy::valuesChanged(const ValuesChangedCommand &command)
writeCommand(QVariant::fromValue(command)); writeCommand(QVariant::fromValue(command));
} }
void NodeInstanceClientProxy::valuesModified(const ValuesModifiedCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceClientProxy::pixmapChanged(const PixmapChangedCommand &command) void NodeInstanceClientProxy::pixmapChanged(const PixmapChangedCommand &command)
{ {
writeCommand(QVariant::fromValue(command)); writeCommand(QVariant::fromValue(command));
@@ -233,6 +245,11 @@ void NodeInstanceClientProxy::puppetAlive(const PuppetAliveCommand &command)
writeCommand(QVariant::fromValue(command)); writeCommand(QVariant::fromValue(command));
} }
void NodeInstanceClientProxy::selectionChanged(const ChangeSelectionCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceClientProxy::flush() void NodeInstanceClientProxy::flush()
{ {
} }
@@ -252,9 +269,6 @@ qint64 NodeInstanceClientProxy::bytesToWrite() const
QVariant NodeInstanceClientProxy::readCommandFromIOStream(QIODevice *ioDevice, quint32 *readCommandCounter, quint32 *blockSize) QVariant NodeInstanceClientProxy::readCommandFromIOStream(QIODevice *ioDevice, quint32 *readCommandCounter, quint32 *blockSize)
{ {
QDataStream in(ioDevice); QDataStream in(ioDevice);
in.setVersion(QDataStream::Qt_4_8); in.setVersion(QDataStream::Qt_4_8);
@@ -416,6 +430,11 @@ void NodeInstanceClientProxy::redirectToken(const EndPuppetCommand & /*command*/
QCoreApplication::exit(); QCoreApplication::exit();
} }
void NodeInstanceClientProxy::changeSelection(const ChangeSelectionCommand &command)
{
nodeInstanceServer()->changeSelection(command);
}
void NodeInstanceClientProxy::dispatchCommand(const QVariant &command) void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
{ {
static const int createInstancesCommandType = QMetaType::type("CreateInstancesCommand"); static const int createInstancesCommandType = QMetaType::type("CreateInstancesCommand");
@@ -436,6 +455,7 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
static const int removeSharedMemoryCommandType = QMetaType::type("RemoveSharedMemoryCommand"); static const int removeSharedMemoryCommandType = QMetaType::type("RemoveSharedMemoryCommand");
static const int tokenCommandType = QMetaType::type("TokenCommand"); static const int tokenCommandType = QMetaType::type("TokenCommand");
static const int endPuppetCommandType = QMetaType::type("EndPuppetCommand"); static const int endPuppetCommandType = QMetaType::type("EndPuppetCommand");
static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand");
const int commandType = command.userType(); const int commandType = command.userType();
@@ -476,6 +496,9 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
else if (commandType == synchronizeCommandType) { else if (commandType == synchronizeCommandType) {
SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>(); SynchronizeCommand synchronizeCommand = command.value<SynchronizeCommand>();
m_synchronizeId = synchronizeCommand.synchronizeId(); m_synchronizeId = synchronizeCommand.synchronizeId();
} else if (commandType == changeSelectionCommandType) {
ChangeSelectionCommand changeSelectionCommand = command.value<ChangeSelectionCommand>();
changeSelection(changeSelectionCommand);
} else { } else {
Q_ASSERT(false); Q_ASSERT(false);
} }

View File

@@ -56,7 +56,7 @@ class CompleteComponentCommand;
class ChangeStateCommand; class ChangeStateCommand;
class ChangeNodeSourceCommand; class ChangeNodeSourceCommand;
class EndPuppetCommand; class EndPuppetCommand;
class ChangeSelectionCommand;
class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterface class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterface
{ {
@@ -67,6 +67,7 @@ public:
void informationChanged(const InformationChangedCommand &command) override; void informationChanged(const InformationChangedCommand &command) override;
void valuesChanged(const ValuesChangedCommand &command) override; void valuesChanged(const ValuesChangedCommand &command) override;
void valuesModified(const ValuesModifiedCommand &command) override;
void pixmapChanged(const PixmapChangedCommand &command) override; void pixmapChanged(const PixmapChangedCommand &command) override;
void childrenChanged(const ChildrenChangedCommand &command) override; void childrenChanged(const ChildrenChangedCommand &command) override;
void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command) override; void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command) override;
@@ -74,6 +75,7 @@ public:
void token(const TokenCommand &command) override; void token(const TokenCommand &command) override;
void debugOutput(const DebugOutputCommand &command) override; void debugOutput(const DebugOutputCommand &command) override;
void puppetAlive(const PuppetAliveCommand &command); void puppetAlive(const PuppetAliveCommand &command);
void selectionChanged(const ChangeSelectionCommand &command) override;
void flush() override; void flush() override;
void synchronizeWithClientProcess() override; void synchronizeWithClientProcess() override;
@@ -104,6 +106,7 @@ protected:
void removeSharedMemory(const RemoveSharedMemoryCommand &command); void removeSharedMemory(const RemoveSharedMemoryCommand &command);
void redirectToken(const TokenCommand &command); void redirectToken(const TokenCommand &command);
void redirectToken(const EndPuppetCommand &command); void redirectToken(const EndPuppetCommand &command);
void changeSelection(const ChangeSelectionCommand &command);
static QVariant readCommandFromIOStream(QIODevice *ioDevice, quint32 *readCommandCounter, quint32 *blockSize); static QVariant readCommandFromIOStream(QIODevice *ioDevice, quint32 *readCommandCounter, quint32 *blockSize);
protected slots: protected slots:

View File

@@ -30,6 +30,7 @@
namespace QmlDesigner { namespace QmlDesigner {
class ValuesChangedCommand; class ValuesChangedCommand;
class ValuesModifiedCommand;
class PixmapChangedCommand; class PixmapChangedCommand;
class InformationChangedCommand; class InformationChangedCommand;
class ChildrenChangedCommand; class ChildrenChangedCommand;
@@ -39,18 +40,21 @@ class TokenCommand;
class RemoveSharedMemoryCommand; class RemoveSharedMemoryCommand;
class DebugOutputCommand; class DebugOutputCommand;
class PuppetAliveCommand; class PuppetAliveCommand;
class ChangeSelectionCommand;
class NodeInstanceClientInterface class NodeInstanceClientInterface
{ {
public: public:
virtual void informationChanged(const InformationChangedCommand &command) = 0; virtual void informationChanged(const InformationChangedCommand &command) = 0;
virtual void valuesChanged(const ValuesChangedCommand &command) = 0; virtual void valuesChanged(const ValuesChangedCommand &command) = 0;
virtual void valuesModified(const ValuesModifiedCommand &command) = 0;
virtual void pixmapChanged(const PixmapChangedCommand &command) = 0; virtual void pixmapChanged(const PixmapChangedCommand &command) = 0;
virtual void childrenChanged(const ChildrenChangedCommand &command) = 0; virtual void childrenChanged(const ChildrenChangedCommand &command) = 0;
virtual void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command) = 0; virtual void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command) = 0;
virtual void componentCompleted(const ComponentCompletedCommand &command) = 0; virtual void componentCompleted(const ComponentCompletedCommand &command) = 0;
virtual void token(const TokenCommand &command) = 0; virtual void token(const TokenCommand &command) = 0;
virtual void debugOutput(const DebugOutputCommand &command) = 0; virtual void debugOutput(const DebugOutputCommand &command) = 0;
virtual void selectionChanged(const ChangeSelectionCommand &command) = 0;
virtual void flush() {} virtual void flush() {}
virtual void synchronizeWithClientProcess() {} virtual void synchronizeWithClientProcess() {}

View File

@@ -45,6 +45,7 @@
#include "completecomponentcommand.h" #include "completecomponentcommand.h"
#include "addimportcontainer.h" #include "addimportcontainer.h"
#include "changenodesourcecommand.h" #include "changenodesourcecommand.h"
#include "changeselectioncommand.h"
#include "informationchangedcommand.h" #include "informationchangedcommand.h"
#include "pixmapchangedcommand.h" #include "pixmapchangedcommand.h"
@@ -103,6 +104,9 @@ void NodeInstanceServerInterface::registerCommands()
qRegisterMetaType<RemoveInstancesCommand>("RemoveInstancesCommand"); qRegisterMetaType<RemoveInstancesCommand>("RemoveInstancesCommand");
qRegisterMetaTypeStreamOperators<RemoveInstancesCommand>("RemoveInstancesCommand"); qRegisterMetaTypeStreamOperators<RemoveInstancesCommand>("RemoveInstancesCommand");
qRegisterMetaType<ChangeSelectionCommand>("ChangeSelectionCommand");
qRegisterMetaTypeStreamOperators<ChangeSelectionCommand>("ChangeSelectionCommand");
qRegisterMetaType<RemovePropertiesCommand>("RemovePropertiesCommand"); qRegisterMetaType<RemovePropertiesCommand>("RemovePropertiesCommand");
qRegisterMetaTypeStreamOperators<RemovePropertiesCommand>("RemovePropertiesCommand"); qRegisterMetaTypeStreamOperators<RemovePropertiesCommand>("RemovePropertiesCommand");
@@ -121,6 +125,9 @@ void NodeInstanceServerInterface::registerCommands()
qRegisterMetaType<ValuesChangedCommand>("ValuesChangedCommand"); qRegisterMetaType<ValuesChangedCommand>("ValuesChangedCommand");
qRegisterMetaTypeStreamOperators<ValuesChangedCommand>("ValuesChangedCommand"); qRegisterMetaTypeStreamOperators<ValuesChangedCommand>("ValuesChangedCommand");
qRegisterMetaType<ValuesModifiedCommand>("ValuesModifiedCommand");
qRegisterMetaTypeStreamOperators<ValuesModifiedCommand>("ValuesModifiedCommand");
qRegisterMetaType<PixmapChangedCommand>("PixmapChangedCommand"); qRegisterMetaType<PixmapChangedCommand>("PixmapChangedCommand");
qRegisterMetaTypeStreamOperators<PixmapChangedCommand>("PixmapChangedCommand"); qRegisterMetaTypeStreamOperators<PixmapChangedCommand>("PixmapChangedCommand");

View File

@@ -49,6 +49,7 @@ class CompleteComponentCommand;
class ChangeNodeSourceCommand; class ChangeNodeSourceCommand;
class TokenCommand; class TokenCommand;
class RemoveSharedMemoryCommand; class RemoveSharedMemoryCommand;
class ChangeSelectionCommand;
class NodeInstanceServerInterface : public QObject class NodeInstanceServerInterface : public QObject
{ {
@@ -77,6 +78,7 @@ public:
virtual void changeNodeSource(const ChangeNodeSourceCommand &command) = 0; virtual void changeNodeSource(const ChangeNodeSourceCommand &command) = 0;
virtual void token(const TokenCommand &command) = 0; virtual void token(const TokenCommand &command) = 0;
virtual void removeSharedMemory(const RemoveSharedMemoryCommand &command) = 0; virtual void removeSharedMemory(const RemoveSharedMemoryCommand &command) = 0;
virtual void changeSelection(const ChangeSelectionCommand &command) = 0;
virtual void benchmark(const QString &) virtual void benchmark(const QString &)
{} {}

View File

@@ -23,79 +23,100 @@
** **
****************************************************************************/ ****************************************************************************/
import QtQuick 2.0 import QtQuick 2.12
import QtQuick.Window 2.0 import QtQuick.Window 2.0
import QtQuick3D 1.0 import QtQuick3D 1.0
import QtQuick3D.Helpers 1.0
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
Window { Window {
id: viewWindow
width: 1024 width: 1024
height: 768 height: 768
visible: true visible: true
title: "3D" title: "3D"
flags: Qt.WindowStaysOnTopHint | Qt.Window | Qt.WindowTitleHint | Qt.WindowCloseButtonHint flags: Qt.WindowStaysOnTopHint | Qt.Window | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
property alias scene: editView.scene
property alias showEditLight: editLightCheckbox.checked
property alias usePerspective: usePerspectiveCheckbox.checked
Rectangle { Rectangle {
color: "black" id: sceneBg
color: "#FFFFFF"
anchors.fill: parent anchors.fill: parent
} focus: true
Column {
y: 32
Slider {
id: slider
value: -600
from: -1200
to: 600
}
Slider {
id: slider2
value: 0
from: -360
to: 360
}
CheckBox {
id: checkBox
text: "Light"
Rectangle {
anchors.fill: parent
z: -1
}
}
}
Binding {
target: view.scene
property: "rotation.y"
value: slider2.value
}
property alias scene: view.scene
property alias showLight: checkBox.checked
id: viewWindow
View3D { View3D {
id: view id: editView
anchors.fill: parent anchors.fill: parent
enableWireframeMode: true enableWireframeMode: true
camera: camera01 camera: editCamera
AxisHelper {
id: axisGrid
enableXZGrid: true
enableAxisLines: false
}
Light { Light {
id: directionalLight id: pointLight
visible: checkBox.checked visible: showEditLight
position: editCamera.position
lightType: Light.Point
} }
Camera { Camera {
id: camera01 id: editCamera
z: slider.value y: 200
z: -300
clipFar: 100000
projectionMode: usePerspective ? Camera.Perspective : Camera.Orthographic
} }
Component.onCompleted: { Component.onCompleted: {
directionalLight.setParentItem(view.scene) pointLight.setParentItem(editView.scene);
camera01.setParentItem(view.scene) editCamera.setParentItem(editView.scene);
} }
} }
WasdController {
id: cameraControl
controlledObject: editView.camera
acceptedButtons: Qt.RightButton
onInputsNeedProcessingChanged: designStudioNativeCameraControlHelper.enabled
= cameraControl.inputsNeedProcessing
// Use separate native timer as QML timers don't work inside Qt Design Studio
Connections {
target: designStudioNativeCameraControlHelper
onUpdateInputs: cameraControl.processInputs()
}
}
}
Column {
y: 8
CheckBox {
id: editLightCheckbox
checked: false
text: qsTr("Use Edit View Light")
onCheckedChanged: cameraControl.forceActiveFocus()
}
CheckBox {
id: usePerspectiveCheckbox
checked: true
text: qsTr("Use Perspective Projection")
onCheckedChanged: cameraControl.forceActiveFocus()
}
}
Text {
id: helpText
text: qsTr("Camera: W,A,S,D,R,F,right mouse drag")
anchors.bottom: parent.bottom
}
} }

View File

@@ -0,0 +1,59 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** 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 "cameracontrolhelper.h"
namespace QmlDesigner {
namespace Internal {
CameraControlHelper::CameraControlHelper()
: QObject()
{
m_timer.setInterval(16);
m_timer.setSingleShot(false);
QObject::connect(&m_timer, &QTimer::timeout,
this, &CameraControlHelper::handleUpdateTimer);
}
bool CameraControlHelper::enabled()
{
return m_enabled;
}
void CameraControlHelper::handleUpdateTimer()
{
emit updateInputs();
}
void CameraControlHelper::setEnabled(bool enabled)
{
if (enabled)
m_timer.start();
else
m_timer.stop();
m_enabled = enabled;
}
}
}

View File

@@ -0,0 +1,57 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** 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 <QtCore/QObject>
#include <QtCore/QTimer>
namespace QmlDesigner {
namespace Internal {
class CameraControlHelper : public QObject
{
Q_OBJECT
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
public:
CameraControlHelper();
bool enabled();
void setEnabled(bool enabled);
public slots:
void handleUpdateTimer();
signals:
void updateInputs();
void enabledChanged(bool enabled);
private:
bool m_enabled = false;
QTimer m_timer;
};
}
}

View File

@@ -0,0 +1,2 @@
HEADERS += $$PWD/cameracontrolhelper.h
SOURCES += $$PWD/cameracontrolhelper.cpp

View File

@@ -1,5 +1,10 @@
INCLUDEPATH += $$PWD/ INCLUDEPATH += $$PWD/
qtHaveModule(quick3d) {
QT *= quick3d-private
DEFINES *= QUICK3D_MODULE
}
HEADERS += $$PWD/qt5nodeinstanceserver.h HEADERS += $$PWD/qt5nodeinstanceserver.h
HEADERS += $$PWD/qt5testnodeinstanceserver.h HEADERS += $$PWD/qt5testnodeinstanceserver.h
HEADERS += $$PWD/qt5informationnodeinstanceserver.h HEADERS += $$PWD/qt5informationnodeinstanceserver.h
@@ -23,6 +28,7 @@ HEADERS += $$PWD/anchorchangesnodeinstance.h
HEADERS += $$PWD/positionernodeinstance.h HEADERS += $$PWD/positionernodeinstance.h
HEADERS += $$PWD/layoutnodeinstance.h HEADERS += $$PWD/layoutnodeinstance.h
HEADERS += $$PWD/qt3dpresentationnodeinstance.h HEADERS += $$PWD/qt3dpresentationnodeinstance.h
HEADERS += $$PWD/quick3dnodeinstance.h
SOURCES += $$PWD/qt5nodeinstanceserver.cpp SOURCES += $$PWD/qt5nodeinstanceserver.cpp
SOURCES += $$PWD/qt5testnodeinstanceserver.cpp SOURCES += $$PWD/qt5testnodeinstanceserver.cpp
@@ -47,3 +53,4 @@ SOURCES += $$PWD/anchorchangesnodeinstance.cpp
SOURCES += $$PWD/positionernodeinstance.cpp SOURCES += $$PWD/positionernodeinstance.cpp
SOURCES += $$PWD/layoutnodeinstance.cpp SOURCES += $$PWD/layoutnodeinstance.cpp
SOURCES += $$PWD/qt3dpresentationnodeinstance.cpp SOURCES += $$PWD/qt3dpresentationnodeinstance.cpp
SOURCES += $$PWD/quick3dnodeinstance.cpp

View File

@@ -66,6 +66,7 @@
#include <changenodesourcecommand.h> #include <changenodesourcecommand.h>
#include <tokencommand.h> #include <tokencommand.h>
#include <removesharedmemorycommand.h> #include <removesharedmemorycommand.h>
#include <changeselectioncommand.h>
#include <QDebug> #include <QDebug>
#include <QQmlEngine> #include <QQmlEngine>
@@ -330,6 +331,10 @@ void NodeInstanceServer::clearScene(const ClearSceneCommand &/*command*/)
m_fileUrl.clear(); m_fileUrl.clear();
} }
void NodeInstanceServer::changeSelection(const ChangeSelectionCommand & /*command*/)
{
}
void NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) void NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command)
{ {
ServerNodeInstance oldState = activeStateInstance(); ServerNodeInstance oldState = activeStateInstance();
@@ -980,12 +985,10 @@ void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &
} else if (auxiliaryContainer.name() == "invisible") { } else if (auxiliaryContainer.name() == "invisible") {
if (hasInstanceForId(auxiliaryContainer.instanceId())) { if (hasInstanceForId(auxiliaryContainer.instanceId())) {
ServerNodeInstance instance = instanceForId(auxiliaryContainer.instanceId()); ServerNodeInstance instance = instanceForId(auxiliaryContainer.instanceId());
if (instance.isSubclassOf("QQuick3DNode")) {
if (!auxiliaryContainer.value().isNull()) if (!auxiliaryContainer.value().isNull())
instance.setPropertyVariant("visible", !auxiliaryContainer.value().toBool()); instance.setHideInEditor(auxiliaryContainer.value().toBool());
else else
instance.resetProperty("visible"); instance.setHideInEditor(false);
}
} }
} }
} }
@@ -1157,6 +1160,17 @@ ComponentCompletedCommand NodeInstanceServer::createComponentCompletedCommand(co
return ComponentCompletedCommand(idVector); return ComponentCompletedCommand(idVector);
} }
ChangeSelectionCommand NodeInstanceServer::createChangeSelectionCommand(const QList<ServerNodeInstance> &instanceList)
{
QVector<qint32> idVector;
for (const ServerNodeInstance &instance : instanceList) {
if (instance.instanceId() >= 0)
idVector.append(instance.instanceId());
}
return ChangeSelectionCommand(idVector);
}
ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const
{ {
QVector<PropertyValueContainer> valueVector; QVector<PropertyValueContainer> valueVector;

View File

@@ -68,6 +68,7 @@ class ComponentCompletedCommand;
class AddImportContainer; class AddImportContainer;
class MockupTypeContainer; class MockupTypeContainer;
class IdContainer; class IdContainer;
class ChangeSelectionCommand;
namespace Internal { namespace Internal {
class ChildrenChangeEventFilter; class ChildrenChangeEventFilter;
@@ -101,6 +102,7 @@ public:
void changeNodeSource(const ChangeNodeSourceCommand &command) override; void changeNodeSource(const ChangeNodeSourceCommand &command) override;
void token(const TokenCommand &command) override; void token(const TokenCommand &command) override;
void removeSharedMemory(const RemoveSharedMemoryCommand &command) override; void removeSharedMemory(const RemoveSharedMemoryCommand &command) override;
void changeSelection(const ChangeSelectionCommand &command) override;
ServerNodeInstance instanceForId(qint32 id) const; ServerNodeInstance instanceForId(qint32 id) const;
bool hasInstanceForId(qint32 id) const; bool hasInstanceForId(qint32 id) const;
@@ -170,6 +172,7 @@ protected:
InformationChangedCommand createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial = false) const; InformationChangedCommand createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial = false) const;
ChildrenChangedCommand createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const; ChildrenChangedCommand createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const;
ComponentCompletedCommand createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList); ComponentCompletedCommand createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList);
ChangeSelectionCommand createChangeSelectionCommand(const QList<ServerNodeInstance> &instanceList);
void addChangedProperty(const InstancePropertyPair &property); void addChangedProperty(const InstancePropertyPair &property);

View File

@@ -392,6 +392,10 @@ PropertyNameList ObjectNodeInstance::ignoredProperties() const
return PropertyNameList(); return PropertyNameList();
} }
void ObjectNodeInstance::setHideInEditor(bool)
{
}
QVariant ObjectNodeInstance::convertEnumToValue(const QVariant &value, const PropertyName &name) QVariant ObjectNodeInstance::convertEnumToValue(const QVariant &value, const PropertyName &name)
{ {
Q_ASSERT(value.canConvert<Enumeration>()); Q_ASSERT(value.canConvert<Enumeration>());

View File

@@ -193,6 +193,8 @@ public:
virtual PropertyNameList ignoredProperties() const; virtual PropertyNameList ignoredProperties() const;
void virtual setHideInEditor(bool b);
protected: protected:
explicit ObjectNodeInstance(QObject *object); explicit ObjectNodeInstance(QObject *object);
void doResetProperty(const PropertyName &propertyName); void doResetProperty(const PropertyName &propertyName);

View File

@@ -55,14 +55,18 @@
#include "createscenecommand.h" #include "createscenecommand.h"
#include "tokencommand.h" #include "tokencommand.h"
#include "removesharedmemorycommand.h" #include "removesharedmemorycommand.h"
#include "changeselectioncommand.h"
#include "dummycontextobject.h" #include "dummycontextobject.h"
#include "../editor3d/cameracontrolhelper.h"
#include <designersupportdelegate.h> #include <designersupportdelegate.h>
#include <QQmlProperty> #include <QQmlProperty>
#include <QOpenGLContext> #include <QOpenGLContext>
#include <QQuickView> #include <QQuickView>
#include <QQmlContext>
#include <QQmlEngine>
namespace QmlDesigner { namespace QmlDesigner {
@@ -73,8 +77,10 @@ static QVariant objectToVariant(QObject *object)
static QObject *createEditView3D(QQmlEngine *engine) static QObject *createEditView3D(QQmlEngine *engine)
{ {
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml")); QmlDesigner::Internal::CameraControlHelper *helper = new QmlDesigner::Internal::CameraControlHelper();
engine->rootContext()->setContextProperty("designStudioNativeCameraControlHelper", helper);
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"));
QWindow *window = qobject_cast<QWindow *>(component.create()); QWindow *window = qobject_cast<QWindow *>(component.create());
@@ -83,6 +89,7 @@ static QObject *createEditView3D(QQmlEngine *engine)
surfaceFormat.setVersion(4, 1); surfaceFormat.setVersion(4, 1);
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile); surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
window->setFormat(surfaceFormat); window->setFormat(surfaceFormat);
helper->setParent(window);
return window; return window;
} }
@@ -147,6 +154,12 @@ bool Qt5InformationNodeInstanceServer::isDirtyRecursiveForParentInstances(QQuick
return false; return false;
} }
/* This method allows changing the selection from the puppet */
void Qt5InformationNodeInstanceServer::selectInstance(const ServerNodeInstance &instance)
{
nodeInstanceClient()->selectionChanged(createChangeSelectionCommand({instance}));
}
QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport( QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport(
const QList<ServerNodeInstance> &instanceList) const const QList<ServerNodeInstance> &instanceList) const
{ {
@@ -358,4 +371,10 @@ void QmlDesigner::Qt5InformationNodeInstanceServer::removeSharedMemory(const Qml
ValuesChangedCommand::removeSharedMemorys(command.keyNumbers()); ValuesChangedCommand::removeSharedMemorys(command.keyNumbers());
} }
void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionCommand &command)
{
// keep track of selection.
qDebug() << Q_FUNC_INFO << command;
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -42,6 +42,7 @@ public:
void completeComponent(const CompleteComponentCommand &command) override; void completeComponent(const CompleteComponentCommand &command) override;
void token(const TokenCommand &command) override; void token(const TokenCommand &command) override;
void removeSharedMemory(const RemoveSharedMemoryCommand &command) override; void removeSharedMemory(const RemoveSharedMemoryCommand &command) override;
void changeSelection(const ChangeSelectionCommand &command) override;
protected: protected:
void collectItemChangesAndSendChangeCommands() override; void collectItemChangesAndSendChangeCommands() override;
@@ -49,6 +50,7 @@ protected:
void sendTokenBack(); void sendTokenBack();
bool isDirtyRecursiveForNonInstanceItems(QQuickItem *item) const; bool isDirtyRecursiveForNonInstanceItems(QQuickItem *item) const;
bool isDirtyRecursiveForParentInstances(QQuickItem *item) const; bool isDirtyRecursiveForParentInstances(QQuickItem *item) const;
void selectInstance(const ServerNodeInstance &instance);
private: private:
void setup3DEditView(const QList<ServerNodeInstance> &instanceList); void setup3DEditView(const QList<ServerNodeInstance> &instanceList);

View File

@@ -151,6 +151,11 @@ void Qt5TestNodeInstanceServer::clearScene(const ClearSceneCommand &command)
Qt5NodeInstanceServer::clearScene(command); Qt5NodeInstanceServer::clearScene(command);
} }
void Qt5TestNodeInstanceServer::changeSelection(const ChangeSelectionCommand &)
{
}
void Qt5TestNodeInstanceServer::removeInstances(const RemoveInstancesCommand &command) void Qt5TestNodeInstanceServer::removeInstances(const RemoveInstancesCommand &command)
{ {
ServerNodeInstance oldState = activeStateInstance(); ServerNodeInstance oldState = activeStateInstance();

View File

@@ -50,6 +50,7 @@ public:
void completeComponent(const CompleteComponentCommand &command) override; void completeComponent(const CompleteComponentCommand &command) override;
void changeNodeSource(const ChangeNodeSourceCommand &command) override; void changeNodeSource(const ChangeNodeSourceCommand &command) override;
void removeSharedMemory(const RemoveSharedMemoryCommand &command) override; void removeSharedMemory(const RemoveSharedMemoryCommand &command) override;
void changeSelection(const ChangeSelectionCommand &command) override;
using Qt5NodeInstanceServer::createInstances; using Qt5NodeInstanceServer::createInstances;

View File

@@ -0,0 +1,87 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** 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 "quick3dnodeinstance.h"
#include "qt5nodeinstanceserver.h"
#include <qmlprivategate.h>
#include <QDebug>
#include <QHash>
#include <QQmlExpression>
#include <QQmlProperty>
#include <cmath>
#ifdef QUICK3D_MODULE
#include <private/qquick3dnode_p.h>
#include <private/qquick3dnode_p_p.h>
#endif
namespace QmlDesigner {
namespace Internal {
Quick3DNodeInstance::Quick3DNodeInstance(QObject *node)
: ObjectNodeInstance(node)
{
}
Quick3DNodeInstance::~Quick3DNodeInstance()
{
}
Qt5NodeInstanceServer *Quick3DNodeInstance::qt5NodeInstanceServer() const
{
return qobject_cast<Qt5NodeInstanceServer *>(nodeInstanceServer());
}
QQuick3DNode *Quick3DNodeInstance::quick3DNode() const
{
#ifdef QUICK3D_MODULE
return qobject_cast<QQuick3DNode *>(object());
#else
return nullptr;
#endif
}
Quick3DNodeInstance::Pointer Quick3DNodeInstance::create(QObject *object)
{
Pointer instance(new Quick3DNodeInstance(object));
instance->populateResetHashes();
return instance;
}
void Quick3DNodeInstance::setHideInEditor(bool b)
{
#ifdef QUICK3D_MODULE
QQuick3DNodePrivate *privateNode = QQuick3DNodePrivate::get(quick3DNode());
if (privateNode)
privateNode->setIsHiddenInEditor(b);
#endif
}
} // namespace Internal
} // namespace QmlDesigner

View File

@@ -0,0 +1,57 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** 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 <QtGlobal>
#include "objectnodeinstance.h"
#include <designersupportdelegate.h>
QT_FORWARD_DECLARE_CLASS(QQuick3DNode)
namespace QmlDesigner {
namespace Internal {
class Quick3DNodeInstance : public ObjectNodeInstance
{
public:
using Pointer = QSharedPointer<Quick3DNodeInstance>;
~Quick3DNodeInstance() override;
static Pointer create(QObject *objectToBeWrapped);
void setHideInEditor(bool b) override;
protected:
explicit Quick3DNodeInstance(QObject *node);
private:
Qt5NodeInstanceServer *qt5NodeInstanceServer() const;
QQuick3DNode *quick3DNode() const;
};
} // namespace Internal
} // namespace QmlDesigner

View File

@@ -39,6 +39,7 @@
#include "qt3dpresentationnodeinstance.h" #include "qt3dpresentationnodeinstance.h"
#include "quickitemnodeinstance.h" #include "quickitemnodeinstance.h"
#include "quick3dnodeinstance.h"
#include "nodeinstanceserver.h" #include "nodeinstanceserver.h"
#include "instancecontainer.h" #include "instancecontainer.h"
@@ -170,6 +171,8 @@ Internal::ObjectNodeInstance::Pointer ServerNodeInstance::createInstance(QObject
instance = Internal::LayoutNodeInstance::create(objectToBeWrapped); instance = Internal::LayoutNodeInstance::create(objectToBeWrapped);
else if (isSubclassOf(objectToBeWrapped, "QQuickItem")) else if (isSubclassOf(objectToBeWrapped, "QQuickItem"))
instance = Internal::QuickItemNodeInstance::create(objectToBeWrapped); instance = Internal::QuickItemNodeInstance::create(objectToBeWrapped);
else if (isSubclassOf(objectToBeWrapped, "QQuick3DNode"))
instance = Internal::Quick3DNodeInstance::create(objectToBeWrapped);
else if (isSubclassOf(objectToBeWrapped, "QQmlComponent")) else if (isSubclassOf(objectToBeWrapped, "QQmlComponent"))
instance = Internal::ComponentNodeInstance::create(objectToBeWrapped); instance = Internal::ComponentNodeInstance::create(objectToBeWrapped);
else if (objectToBeWrapped->inherits("QQmlAnchorChanges")) else if (objectToBeWrapped->inherits("QQmlAnchorChanges"))
@@ -312,6 +315,11 @@ void ServerNodeInstance::setPropertyBinding(const PropertyName &name, const QStr
m_nodeInstance->setPropertyBinding(name, expression); m_nodeInstance->setPropertyBinding(name, expression);
} }
void ServerNodeInstance::setHideInEditor(bool b)
{
m_nodeInstance->setHideInEditor(b);
}
void ServerNodeInstance::resetProperty(const PropertyName &name) void ServerNodeInstance::resetProperty(const PropertyName &name)
{ {
m_nodeInstance->resetProperty(name); m_nodeInstance->resetProperty(name);

View File

@@ -172,6 +172,8 @@ private: // functions
void setPropertyBinding(const PropertyName &name, const QString &expression); void setPropertyBinding(const PropertyName &name, const QString &expression);
void setHideInEditor(bool b);
void resetProperty(const PropertyName &name); void resetProperty(const PropertyName &name);
void refreshProperty(const PropertyName &name); void refreshProperty(const PropertyName &name);

View File

@@ -5,6 +5,7 @@ CONFIG += c++11
DEFINES -= QT_CREATOR DEFINES -= QT_CREATOR
include (editor3d/editor3d.pri)
include (../instances/instances.pri) include (../instances/instances.pri)
include (instances/instances.pri) include (instances/instances.pri)
include (../commands/commands.pri) include (../commands/commands.pri)

View File

@@ -46,11 +46,30 @@ Item {
width: 96 width: 96
implicitHeight: spinBox.height implicitHeight: spinBox.height
onFocusChanged: transaction.end();
StudioControls.RealSpinBox { StudioControls.RealSpinBox {
id: spinBox id: spinBox
onDragStarted: hideCursor(); onDragStarted: {
onDragEnded: restoreCursor(); hideCursor();
transaction.start();
}
onDragEnded: {
restoreCursor();
transaction.end();
}
onRealValueModified: {
if (transaction.active())
commitValue();
}
function commitValue() {
if (spinBox.backendValue.value !== spinBox.realValue)
spinBox.backendValue.value = spinBox.realValue;
}
property variant backendValue property variant backendValue
property bool hasSlider: wrapper.sliderIndicatorVisible property bool hasSlider: wrapper.sliderIndicatorVisible
@@ -77,9 +96,6 @@ Item {
labelColor: spinBox.edit ? StudioTheme.Values.themeTextColor : colorLogic.textColor labelColor: spinBox.edit ? StudioTheme.Values.themeTextColor : colorLogic.textColor
onCompressedRealValueModified: { onCompressedRealValueModified: commitValue()
if (spinBox.backendValue.value !== spinBox.realValue)
spinBox.backendValue.value = spinBox.realValue;
}
} }
} }

View File

@@ -43,7 +43,6 @@
#include <QFontDatabase> #include <QFontDatabase>
#include <QFileInfo> #include <QFileInfo>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QLoggingCategory>
#include <QSettings> #include <QSettings>
#include <QStyle> #include <QStyle>
#include <QTextStream> #include <QTextStream>

View File

@@ -1766,7 +1766,7 @@ public:
{ return expression->firstSourceLocation(); } { return expression->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override SourceLocation lastSourceLocation() const override
{ return expression->lastSourceLocation(); } { return semicolonToken.isValid() ? semicolonToken : expression->lastSourceLocation(); }
// attributes // attributes
ExpressionNode *expression; ExpressionNode *expression;

View File

@@ -820,7 +820,7 @@ extern "C" HRESULT CALLBACK assign(CIDebugClient *client, PCSTR argsIn)
std::string errorMessage; std::string errorMessage;
bool success = false; bool success = false;
AssignEncoding enc = AssignPlainValue; bool encoded = false;
int token = 0; int token = 0;
do { do {
StringList tokens = commandTokens<StringList>(argsIn, &token); StringList tokens = commandTokens<StringList>(argsIn, &token);
@@ -830,10 +830,7 @@ extern "C" HRESULT CALLBACK assign(CIDebugClient *client, PCSTR argsIn)
} }
if (tokens.front() == "-h") { if (tokens.front() == "-h") {
enc = AssignHexEncoded; encoded = true;
tokens.pop_front();
} else if (tokens.front() == "-u") {
enc = AssignHexEncodedUtf16;
tokens.pop_front(); tokens.pop_front();
} }
@@ -864,7 +861,7 @@ extern "C" HRESULT CALLBACK assign(CIDebugClient *client, PCSTR argsIn)
SymbolGroup *symGroup = ExtensionContext::instance().symbolGroup(exc.symbols(), exc.threadId(), currentFrame, &errorMessage); SymbolGroup *symGroup = ExtensionContext::instance().symbolGroup(exc.symbols(), exc.threadId(), currentFrame, &errorMessage);
if (!symGroup) if (!symGroup)
break; break;
success = symGroup->assign(iname, enc, value, success = symGroup->assign(iname, encoded ? stringFromHex(value) : value,
SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()), SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()),
&errorMessage); &errorMessage);
} while (false); } while (false);

View File

@@ -33,6 +33,7 @@
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <codecvt>
#include <iomanip> #include <iomanip>
static const char whiteSpace[] = " \t\r\n"; static const char whiteSpace[] = " \t\r\n";
@@ -149,6 +150,11 @@ std::string wStringToString(const std::wstring &w)
return rc; return rc;
} }
std::wstring utf8ToUtf16(const std::string &s)
{
return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(s.data());
}
// Convert an ASCII hex digit to its value 'A'->10 // Convert an ASCII hex digit to its value 'A'->10
static inline unsigned hexDigit(char c) static inline unsigned hexDigit(char c)
{ {
@@ -210,6 +216,11 @@ std::string stringFromHex(const char *p, const char *end)
return rc; return rc;
} }
std::string stringFromHex(const std::string &hexEncoded)
{
return stringFromHex(hexEncoded.c_str(), hexEncoded.c_str() + hexEncoded.size());
}
// Helper for dumping memory // Helper for dumping memory
std::string dumpMemory(const unsigned char *p, size_t size, std::string dumpMemory(const unsigned char *p, size_t size,
bool wantQuotes) bool wantQuotes)

View File

@@ -167,6 +167,7 @@ inline std::ostream &operator<<(std::ostream &str, const gdbmiWStringFormat &wsf
} }
std::string wStringToString(const std::wstring &w); std::string wStringToString(const std::wstring &w);
std::wstring utf8ToUtf16(const std::string &s);
// Strings from raw data. // Strings from raw data.
std::wstring quotedWStringFromCharData(const unsigned char *data, size_t size, bool truncated = false); std::wstring quotedWStringFromCharData(const unsigned char *data, size_t size, bool truncated = false);
@@ -177,6 +178,7 @@ std::string dumpMemory(const unsigned char *data, size_t size, bool wantQuotes =
// String from hex "414A" -> "AJ". // String from hex "414A" -> "AJ".
std::string stringFromHex(const char *begin, const char *end); std::string stringFromHex(const char *begin, const char *end);
std::string stringFromHex(const std::string &hexEncoded);
// Decode hex to a memory area. // Decode hex to a memory area.
void decodeHex(const char *begin, const char *end, unsigned char *target); void decodeHex(const char *begin, const char *end, unsigned char *target);

View File

@@ -449,7 +449,6 @@ void SymbolGroup::markUninitialized(const std::vector<std::string> &uniniNodes)
} }
bool SymbolGroup::assign(const std::string &nodeName, bool SymbolGroup::assign(const std::string &nodeName,
int valueEncoding,
const std::string &value, const std::string &value,
const SymbolGroupValueContext &ctx, const SymbolGroupValueContext &ctx,
std::string *errorMessage) std::string *errorMessage)
@@ -468,9 +467,9 @@ bool SymbolGroup::assign(const std::string &nodeName,
int kt = node->dumperType(); int kt = node->dumperType();
if (kt < 0) if (kt < 0)
kt = knownType(node->type(), KnownTypeAutoStripPointer | KnownTypeHasClassPrefix); kt = knownType(node->type(), KnownTypeAutoStripPointer | KnownTypeHasClassPrefix);
return (kt & KT_Editable) ? // Edit complex types if (kt & KT_Editable)
assignType(node, kt, valueEncoding, value, ctx, errorMessage) : return assignType(node, kt, value, ctx, errorMessage);
node->assign(value, errorMessage); return node->assign(value, errorMessage);
} }
bool SymbolGroup::accept(SymbolGroupNodeVisitor &visitor) const bool SymbolGroup::accept(SymbolGroupNodeVisitor &visitor) const

View File

@@ -96,7 +96,6 @@ public:
// Assign a value by iname // Assign a value by iname
bool assign(const std::string &node, bool assign(const std::string &node,
int valueEncoding,
const std::string &value, const std::string &value,
const SymbolGroupValueContext &ctx, const SymbolGroupValueContext &ctx,
std::string *errorMessage); std::string *errorMessage);

View File

@@ -1432,10 +1432,11 @@ std::string SymbolGroupNode::msgAssignError(const std::string &nodeName,
} }
// Simple type // Simple type
bool SymbolGroupNode::assign(const std::string &value, std::string *errorMessage /* = 0 */) bool SymbolGroupNode::assign(const std::string &value,
std::string *errorMessage /* = 0 */)
{ {
const HRESULT hr = const HRESULT hr =
m_symbolGroup->debugSymbolGroup()->WriteSymbol(m_index, const_cast<char *>(value.c_str())); m_symbolGroup->debugSymbolGroup()->WriteSymbol(m_index, value.c_str());
if (FAILED(hr)) { if (FAILED(hr)) {
if (errorMessage) if (errorMessage)
*errorMessage = SymbolGroupNode::msgAssignError(name(), value, msgDebugEngineComFailed("WriteSymbol", hr)); *errorMessage = SymbolGroupNode::msgAssignError(name(), value, msgDebugEngineComFailed("WriteSymbol", hr));

View File

@@ -3309,101 +3309,6 @@ static inline std::vector<AbstractSymbolGroupNode *>
return rc; return rc;
} }
/* AssignmentStringData: Helper struct used for assigning values
* to string classes. Contains an (allocated) data array with size for use
* with IDebugDataSpaced::FillVirtual() + string length information and
* provides a conversion function decodeString() to create the array
* depending on the argument format (blow up ASCII to UTF16 or vice versa). */
struct AssignmentStringData
{
explicit AssignmentStringData(size_t dataLengthIn, size_t stringLengthIn);
static AssignmentStringData decodeString(const char *begin, const char *end,
int valueEncoding, bool toUtf16);
static inline AssignmentStringData decodeString(const std::string &value,
int valueEncoding, bool toUtf16)
{ return decodeString(value.c_str(), value.c_str() + value.size(),
valueEncoding, toUtf16); }
unsigned char *data;
size_t dataLength;
size_t stringLength;
};
AssignmentStringData::AssignmentStringData(size_t dataLengthIn, size_t stringLengthIn) :
data(new unsigned char[dataLengthIn]), dataLength(dataLengthIn),
stringLength(stringLengthIn)
{
if (dataLength)
memset(data, 0, dataLength);
}
AssignmentStringData AssignmentStringData::decodeString(const char *begin, const char *end,
int valueEncoding, bool toUtf16)
{
if (toUtf16) { // Target is UTF16 consisting of unsigned short characters.
switch (valueEncoding) {
// Hex encoded ASCII/2 digits per char: Decode to plain characters and
// recurse to expand them.
case AssignHexEncoded: {
const AssignmentStringData decoded = decodeString(begin, end, AssignHexEncoded, false);
const char *source = reinterpret_cast<const char*>(decoded.data);
const AssignmentStringData utf16 = decodeString(source, source + decoded.stringLength,
AssignPlainValue, true);
delete [] decoded.data;
return utf16;
}
// Hex encoded UTF16: 4 hex digits per character: Decode sequence.
case AssignHexEncodedUtf16: {
const size_t stringLength = (end - begin) / 4;
AssignmentStringData result(sizeof(unsigned short) *(stringLength + 1), stringLength);
decodeHex(begin, end, result.data);
return result;
}
default:
break;
}
// Convert plain ASCII data to UTF16 by expanding.
const size_t stringLength = end - begin;
AssignmentStringData result(sizeof(unsigned short) *(stringLength + 1), stringLength);
const unsigned char *source = reinterpret_cast<const unsigned char *>(begin);
unsigned short *target = reinterpret_cast<unsigned short *>(result.data);
std::copy(source, source + stringLength, target);
return result;
} // toUtf16
switch (valueEncoding) {
case AssignHexEncoded: { // '0A5A'..2 digits per character
const size_t stringLength = (end - begin) / 2;
AssignmentStringData result(stringLength + 1, stringLength);
decodeHex(begin, end, result.data);
return result;
}
// Condense UTF16 characters to ASCII: Decode and use only every 2nd character
// (little endian, first byte)
case AssignHexEncodedUtf16: {
const AssignmentStringData decoded = decodeString(begin, end, AssignHexEncoded, false);
const size_t stringLength = decoded.stringLength / 2;
const AssignmentStringData result(stringLength + 1, stringLength);
const unsigned char *sourceEnd = decoded.data + decoded.stringLength;
unsigned char *target = result.data;
for (const unsigned char *source = decoded.data; source < sourceEnd; source += 2)
*target++ = *source;
delete [] decoded.data;
return result;
}
break;
default:
break;
}
// Plain 0-terminated copy
const size_t stringLength = end - begin;
AssignmentStringData result(stringLength + 1, stringLength);
memcpy(result.data, begin, stringLength);
return result;
}
// Assignment helpers // Assignment helpers
static inline std::string msgAssignStringFailed(const std::string &value, int errorCode) static inline std::string msgAssignStringFailed(const std::string &value, int errorCode)
{ {
@@ -3417,8 +3322,9 @@ static inline std::string msgAssignStringFailed(const std::string &value, int er
* recurse (since 'd' might become invalid). This works for QString with UTF16 * recurse (since 'd' might become invalid). This works for QString with UTF16
* data and for QByteArray with ASCII data due to the similar member * data and for QByteArray with ASCII data due to the similar member
* names and both using a terminating '\0' w_char/byte. */ * names and both using a terminating '\0' w_char/byte. */
template <typename string>
static int assignQStringI(SymbolGroupNode *n, const char *className, static int assignQStringI(SymbolGroupNode *n, const char *className,
const AssignmentStringData &data, const string &data,
const SymbolGroupValueContext &ctx, const SymbolGroupValueContext &ctx,
bool doAlloc = true) bool doAlloc = true)
{ {
@@ -3431,7 +3337,7 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
const QtStringAddressData addressData = readQtStringAddressData(d, qtInfo); const QtStringAddressData addressData = readQtStringAddressData(d, qtInfo);
if (!addressData.address) if (!addressData.address)
return 9; return 9;
const bool needRealloc = addressData.allocated < data.stringLength; const bool needRealloc = addressData.allocated < data.size();
if (needRealloc) { if (needRealloc) {
if (!doAlloc) // Calling re-alloc failed somehow. if (!doAlloc) // Calling re-alloc failed somehow.
return 3; return 3;
@@ -3439,7 +3345,7 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
const std::string funcName const std::string funcName
= qtInfo.prependQtCoreModule(std::string(className) + "::resize"); = qtInfo.prependQtCoreModule(std::string(className) + "::resize");
callStr << funcName << '(' << std::hex << std::showbase callStr << funcName << '(' << std::hex << std::showbase
<< v.address() << ',' << data.stringLength << ')'; << v.address() << ',' << data.size() << ')';
std::wstring wOutput; std::wstring wOutput;
std::string errorMessage; std::string errorMessage;
return ExtensionContext::instance().call(callStr.str(), 0, &wOutput, &errorMessage) ? return ExtensionContext::instance().call(callStr.str(), 0, &wOutput, &errorMessage) ?
@@ -3447,8 +3353,8 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
} }
// Write data. // Write data.
if (!SymbolGroupValue::writeMemory(v.context().dataspaces, if (!SymbolGroupValue::writeMemory(v.context().dataspaces,
addressData.address, data.data, addressData.address, (const unsigned char *)(data.c_str()),
ULONG(data.dataLength))) ULONG(data.empty() ? 0 : sizeof(data.front()) * data.size())))
return 11; return 11;
// Correct size unless we re-allocated // Correct size unless we re-allocated
if (!needRealloc) { if (!needRealloc) {
@@ -3460,7 +3366,7 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
const SymbolGroupValue size = dV["size"]; const SymbolGroupValue size = dV["size"];
if (!size) if (!size)
return 16; return 16;
if (!size.node()->assign(toString(data.stringLength))) if (!size.node()->assign(toString(data.size())))
return 17; return 17;
} }
return 0; return 0;
@@ -3468,13 +3374,11 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
// QString assignment // QString assignment
static inline bool assignQString(SymbolGroupNode *n, static inline bool assignQString(SymbolGroupNode *n,
int valueEncoding, const std::string &value, const std::string &value,
const SymbolGroupValueContext &ctx, const SymbolGroupValueContext &ctx,
std::string *errorMessage) std::string *errorMessage)
{ {
const AssignmentStringData utf16 = AssignmentStringData::decodeString(value, valueEncoding, true); const int errorCode = assignQStringI(n, "QString", utf8ToUtf16(value), ctx);
const int errorCode = assignQStringI(n, "QString", utf16, ctx);
delete [] utf16.data;
if (errorCode) { if (errorCode) {
*errorMessage = msgAssignStringFailed(value, errorCode); *errorMessage = msgAssignStringFailed(value, errorCode);
return false; return false;
@@ -3484,13 +3388,11 @@ static inline bool assignQString(SymbolGroupNode *n,
// QByteArray assignment // QByteArray assignment
static inline bool assignQByteArray(SymbolGroupNode *n, static inline bool assignQByteArray(SymbolGroupNode *n,
int valueEncoding, const std::string &value, const std::string &value,
const SymbolGroupValueContext &ctx, const SymbolGroupValueContext &ctx,
std::string *errorMessage) std::string *errorMessage)
{ {
const AssignmentStringData data = AssignmentStringData::decodeString(value, valueEncoding, false); const int errorCode = assignQStringI(n, "QByteArray", value, ctx);
const int errorCode = assignQStringI(n, "QByteArray", data, ctx);
delete [] data.data;
if (errorCode) { if (errorCode) {
*errorMessage = msgAssignStringFailed(value, errorCode); *errorMessage = msgAssignStringFailed(value, errorCode);
return false; return false;
@@ -3499,8 +3401,9 @@ static inline bool assignQByteArray(SymbolGroupNode *n,
} }
// Helper to assign character data to std::string or std::wstring. // Helper to assign character data to std::string or std::wstring.
template <typename string>
static inline int assignStdStringI(SymbolGroupNode *n, int type, static inline int assignStdStringI(SymbolGroupNode *n, int type,
const AssignmentStringData &data, const string &data,
const SymbolGroupValueContext &ctx) const SymbolGroupValueContext &ctx)
{ {
/* We do not reallocate and just write to the allocated buffer /* We do not reallocate and just write to the allocated buffer
@@ -3527,7 +3430,7 @@ static inline int assignStdStringI(SymbolGroupNode *n, int type,
int reserved = base["_Myres"].intValue(); int reserved = base["_Myres"].intValue();
if (reserved < 0 || !size || !bx) if (reserved < 0 || !size || !bx)
return 42; return 42;
if (reserved <= (int)data.stringLength) if (reserved <= (int)data.size())
return 1; // Insufficient memory. return 1; // Insufficient memory.
// Copy data: 'Buf' array for small strings, else pointer 'Ptr'. // Copy data: 'Buf' array for small strings, else pointer 'Ptr'.
const int bufSize = type == KT_StdString ? 16 : 8; // see basic_string. const int bufSize = type == KT_StdString ? 16 : 8; // see basic_string.
@@ -3536,25 +3439,25 @@ static inline int assignStdStringI(SymbolGroupNode *n, int type,
if (!address) if (!address)
return 3; return 3;
if (!SymbolGroupValue::writeMemory(v.context().dataspaces, if (!SymbolGroupValue::writeMemory(v.context().dataspaces,
address, data.data, ULONG(data.dataLength))) address,
(const unsigned char *)(data.c_str()),
ULONG(data.empty() ? 0 : sizeof(data.front()) * data.size())))
return 7; return 7;
// Correct size // Correct size
if (!size.node()->assign(toString(data.stringLength))) if (!size.node()->assign(toString(data.size())))
return 13; return 13;
return 0; return 0;
} }
// assignment of std::string assign via ASCII, std::wstring via UTF16 // assignment of std::string assign via ASCII, std::wstring via UTF16
static inline bool assignStdString(SymbolGroupNode *n, static inline bool assignStdString(SymbolGroupNode *n,
int type, int valueEncoding, const std::string &value, int type, const std::string &value,
const SymbolGroupValueContext &ctx, const SymbolGroupValueContext &ctx,
std::string *errorMessage) std::string *errorMessage)
{ {
const bool toUtf16 = type == KT_StdWString; const int errorCode = type == KT_StdString
const AssignmentStringData data = AssignmentStringData::decodeString(value, valueEncoding, ? assignStdStringI(n, type, value, ctx)
toUtf16); : assignStdStringI(n, type, utf8ToUtf16(value), ctx);
const int errorCode = assignStdStringI(n, type, data, ctx);
delete [] data.data;
if (errorCode) { if (errorCode) {
*errorMessage = msgAssignStringFailed(value, errorCode); *errorMessage = msgAssignStringFailed(value, errorCode);
return false; return false;
@@ -3562,17 +3465,17 @@ static inline bool assignStdString(SymbolGroupNode *n,
return true; return true;
} }
bool assignType(SymbolGroupNode *n, int knownType, int valueEncoding, const std::string &value, bool assignType(SymbolGroupNode *n, int knownType, const std::string &value,
const SymbolGroupValueContext &ctx, std::string *errorMessage) const SymbolGroupValueContext &ctx, std::string *errorMessage)
{ {
switch (knownType) { switch (knownType) {
case KT_QString: case KT_QString:
return assignQString(n, valueEncoding, value, ctx, errorMessage); return assignQString(n, value, ctx, errorMessage);
case KT_QByteArray: case KT_QByteArray:
return assignQByteArray(n, valueEncoding, value, ctx, errorMessage); return assignQByteArray(n,value, ctx, errorMessage);
case KT_StdString: case KT_StdString:
case KT_StdWString: case KT_StdWString:
return assignStdString(n, knownType, valueEncoding, value, ctx, errorMessage); return assignStdString(n, knownType, value, ctx, errorMessage);
default: default:
break; break;
} }

View File

@@ -286,9 +286,8 @@ enum AssignEncoding
AssignHexEncodedUtf16 AssignHexEncodedUtf16
}; };
bool assignType(SymbolGroupNode *n, int knownType, int valueEncoding, const std::string &value, bool assignType(SymbolGroupNode *n, int knownType, const std::string &value,
const SymbolGroupValueContext &ctx, const SymbolGroupValueContext &ctx, std::string *errorMessage);
std::string *errorMessage);
// Non-container complex dumpers (QObjects/QVariants). // Non-container complex dumpers (QObjects/QVariants).
std::vector<AbstractSymbolGroupNode *> std::vector<AbstractSymbolGroupNode *>

View File

@@ -78,7 +78,7 @@ static FilePath findQmakeInDir(const FilePath &path)
if (path.isEmpty()) if (path.isEmpty())
return FilePath(); return FilePath();
const QString qmake = "qmake"; const QString qmake = HostOsInfo::withExecutableSuffix("qmake");
QDir dir(path.toString()); QDir dir(path.toString());
if (dir.exists(qmake)) { if (dir.exists(qmake)) {
const QString qmakePath = dir.absoluteFilePath(qmake); const QString qmakePath = dir.absoluteFilePath(qmake);

View File

@@ -925,6 +925,12 @@ bool FilePath::isChildOf(const QDir &dir) const
return isChildOf(FilePath::fromString(dir.absolutePath())); return isChildOf(FilePath::fromString(dir.absolutePath()));
} }
/// \returns whether FilePath startsWith \a s
bool FilePath::startsWith(const QString &s) const
{
return m_data.startsWith(s, HostOsInfo::fileNameCaseSensitivity());
}
/// \returns whether FilePath endsWith \a s /// \returns whether FilePath endsWith \a s
bool FilePath::endsWith(const QString &s) const bool FilePath::endsWith(const QString &s) const
{ {

View File

@@ -97,6 +97,7 @@ public:
bool isChildOf(const FilePath &s) const; bool isChildOf(const FilePath &s) const;
bool isChildOf(const QDir &dir) const; bool isChildOf(const QDir &dir) const;
bool startsWith(const QString &s) const;
bool endsWith(const QString &s) const; bool endsWith(const QString &s) const;
bool isLocal() const; bool isLocal() const;

View File

@@ -203,13 +203,15 @@ QList<TestConfiguration *> BoostTestTreeItem::getAllTestConfigurations() const
}); });
for (auto it = testsPerProjectfile.begin(), end = testsPerProjectfile.end(); it != end; ++it) { for (auto it = testsPerProjectfile.begin(), end = testsPerProjectfile.end(); it != end; ++it) {
for (const QString &target : qAsConst(it.value().internalTargets)) {
BoostTestConfiguration *config = new BoostTestConfiguration; BoostTestConfiguration *config = new BoostTestConfiguration;
config->setProject(project); config->setProject(project);
config->setProjectFile(it.key()); config->setProjectFile(it.key());
config->setTestCaseCount(it.value().testCases); config->setTestCaseCount(it.value().testCases);
config->setInternalTargets(it.value().internalTargets); config->setInternalTarget(target);
result.append(config); result.append(config);
} }
}
return result; return result;
} }
@@ -245,13 +247,15 @@ QList<TestConfiguration *> BoostTestTreeItem::getSelectedTestConfigurations() co
auto end = testCasesForProjectFile.cend(); auto end = testCasesForProjectFile.cend();
for (auto it = testCasesForProjectFile.cbegin(); it != end; ++it) { for (auto it = testCasesForProjectFile.cbegin(); it != end; ++it) {
for (const QString &target : it.value().internalTargets) {
BoostTestConfiguration *config = new BoostTestConfiguration; BoostTestConfiguration *config = new BoostTestConfiguration;
config->setProject(project); config->setProject(project);
config->setProjectFile(it.key()); config->setProjectFile(it.key());
config->setTestCases(it.value().testCases); config->setTestCases(it.value().testCases);
config->setInternalTargets(it.value().internalTargets); config->setInternalTarget(target);
result.append(config); result.append(config);
} }
}
return result; return result;
} }

View File

@@ -271,13 +271,15 @@ static QStringList splitFragments(const QStringList &fragments)
} }
RawProjectParts generateRawProjectParts(const PreprocessedData &input, RawProjectParts generateRawProjectParts(const PreprocessedData &input,
const FilePath &sourceDirectory) const FilePath &sourceDirectory,
const FilePath &buildDirectory)
{ {
RawProjectParts rpps; RawProjectParts rpps;
int counter = 0; int counter = 0;
for (const TargetDetails &t : input.targetDetails) { for (const TargetDetails &t : input.targetDetails) {
QDir sourceDir(sourceDirectory.toString()); QDir sourceDir(sourceDirectory.toString());
QDir buildDir(buildDirectory.toString());
bool needPostfix = t.compileGroups.size() > 1; bool needPostfix = t.compileGroups.size() > 1;
int count = 1; int count = 1;
@@ -321,16 +323,25 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input,
cxxProjectFlags.commandLineFlags = cProjectFlags.commandLineFlags; cxxProjectFlags.commandLineFlags = cProjectFlags.commandLineFlags;
rpp.setFlagsForCxx(cxxProjectFlags); rpp.setFlagsForCxx(cxxProjectFlags);
const QString precompiled_header FilePath precompiled_header
= findOrDefault(t.sources, [&ending](const SourceInfo &si) { = FilePath::fromString(findOrDefault(t.sources, [&ending](const SourceInfo &si) {
return si.path.endsWith(ending); return si.path.endsWith(ending);
}).path; }).path);
rpp.setFiles(transform<QList>(ci.sources, [&t, &sourceDir](const int si) { rpp.setFiles(transform<QList>(ci.sources, [&t, &sourceDir](const int si) {
return sourceDir.absoluteFilePath(t.sources[static_cast<size_t>(si)].path); return sourceDir.absoluteFilePath(t.sources[static_cast<size_t>(si)].path);
})); }));
if (!precompiled_header.isEmpty()) if (!precompiled_header.isEmpty()) {
rpp.setPreCompiledHeaders({precompiled_header}); if (precompiled_header.toFileInfo().isRelative()) {
const FilePath parentDir = FilePath::fromString(buildDir.absolutePath());
const QString dirName = buildDir.dirName();
if (precompiled_header.startsWith(dirName))
precompiled_header = FilePath::fromString(
precompiled_header.toString().mid(dirName.length() + 1));
precompiled_header = parentDir.pathAppended(precompiled_header.toString());
}
rpp.setPreCompiledHeaders({precompiled_header.toString()});
}
const bool isExecutable = t.type == "EXECUTABLE"; const bool isExecutable = t.type == "EXECUTABLE";
rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable
@@ -602,7 +613,7 @@ FileApiQtcData extractData(FileApiData &input,
result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory); result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory);
result.cmakeFiles = std::move(data.cmakeFiles); result.cmakeFiles = std::move(data.cmakeFiles);
result.projectParts = generateRawProjectParts(data, sourceDirectory); result.projectParts = generateRawProjectParts(data, sourceDirectory, buildDirectory);
auto pair = generateRootProjectNode(data, sourceDirectory, buildDirectory); auto pair = generateRootProjectNode(data, sourceDirectory, buildDirectory);
result.rootProjectNode = std::move(pair.first); result.rootProjectNode = std::move(pair.first);

View File

@@ -80,6 +80,12 @@ void registerDocumentation(const QStringList &files)
m_instance->registerDocumentation(files); m_instance->registerDocumentation(files);
} }
void unregisterDocumentation(const QStringList &fileNames)
{
if (checkInstance())
m_instance->unregisterDocumentation(fileNames);
}
QMap<QString, QUrl> linksForIdentifier(const QString &id) QMap<QString, QUrl> linksForIdentifier(const QString &id)
{ {
return checkInstance() ? m_instance->linksForIdentifier(id) : QMap<QString, QUrl>(); return checkInstance() ? m_instance->linksForIdentifier(id) : QMap<QString, QUrl>();

View File

@@ -61,6 +61,7 @@ enum HelpViewerLocation {
CORE_EXPORT QString documentationPath(); CORE_EXPORT QString documentationPath();
CORE_EXPORT void registerDocumentation(const QStringList &fileNames); CORE_EXPORT void registerDocumentation(const QStringList &fileNames);
CORE_EXPORT void unregisterDocumentation(const QStringList &fileNames);
CORE_EXPORT QMap<QString, QUrl> linksForIdentifier(const QString &id); CORE_EXPORT QMap<QString, QUrl> linksForIdentifier(const QString &id);
CORE_EXPORT QMap<QString, QUrl> linksForKeyword(const QString &id); CORE_EXPORT QMap<QString, QUrl> linksForKeyword(const QString &id);

View File

@@ -39,6 +39,7 @@ protected:
public: public:
virtual void registerDocumentation(const QStringList &fileNames) = 0; virtual void registerDocumentation(const QStringList &fileNames) = 0;
virtual void unregisterDocumentation(const QStringList &fileNames) = 0;
virtual QMap<QString, QUrl> linksForIdentifier(const QString &id) = 0; virtual QMap<QString, QUrl> linksForIdentifier(const QString &id) = 0;
virtual QMap<QString, QUrl> linksForKeyword(const QString &keyword) = 0; virtual QMap<QString, QUrl> linksForKeyword(const QString &keyword) = 0;
virtual QByteArray fileData(const QUrl &url) = 0; virtual QByteArray fileData(const QUrl &url) = 0;

View File

@@ -49,7 +49,6 @@ class Project;
namespace Cppcheck { namespace Cppcheck {
namespace Internal { namespace Internal {
class Diagnostic;
class CppcheckRunner; class CppcheckRunner;
class CppcheckTextMarkManager; class CppcheckTextMarkManager;
class CppcheckOptions; class CppcheckOptions;

View File

@@ -42,10 +42,6 @@ class IDocument;
class IEditor; class IEditor;
} }
namespace CppTools {
class ProjectInfo;
}
namespace Cppcheck { namespace Cppcheck {
namespace Internal { namespace Internal {

View File

@@ -140,8 +140,6 @@ QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
addPrecompiledHeaderOptions(usePrecompiledHeaders); addPrecompiledHeaderOptions(usePrecompiledHeaders);
addProjectConfigFileInclude(); addProjectConfigFileInclude();
addExtraCodeModelFlags();
addMsvcCompatibilityVersion(); addMsvcCompatibilityVersion();
addProjectMacros(); addProjectMacros();
undefineClangVersionMacrosForMsvc(); undefineClangVersionMacrosForMsvc();
@@ -727,7 +725,8 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
const Core::Id &toolChain = m_projectPart.toolchainType; const Core::Id &toolChain = m_projectPart.toolchainType;
bool containsDriverMode = false; bool containsDriverMode = false;
bool skipNext = false; bool skipNext = false;
for (const QString &option : m_projectPart.compilerFlags) { const QStringList allFlags = m_projectPart.compilerFlags + m_projectPart.extraCodeModelFlags;
for (const QString &option : allFlags) {
if (skipNext) { if (skipNext) {
skipNext = false; skipNext = false;
continue; continue;
@@ -752,6 +751,16 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
continue; continue;
} }
// As we always set the target explicitly, filter out target args.
if (!m_projectPart.toolChainTargetTriple.isEmpty()) {
if (option.startsWith("--target="))
continue;
if (option == "-target") {
skipNext = true;
continue;
}
}
if (option == includeUserPathOption || option == includeSystemPathOption if (option == includeUserPathOption || option == includeSystemPathOption
|| option == includeUserPathOptionWindows) { || option == includeUserPathOptionWindows) {
skipNext = true; skipNext = true;

View File

@@ -93,6 +93,9 @@ QVariant CtfStatisticsModel::data(const QModelIndex &index, int role) const
case Column::AvgDuration: case Column::AvgDuration:
case Column::MaxDuration: case Column::MaxDuration:
return Qt::AlignRight; return Qt::AlignRight;
default:
Q_UNREACHABLE();
return QVariant();
} }
case SortRole: case SortRole:
switch (index.column()) { switch (index.column()) {

View File

@@ -917,15 +917,6 @@ void CdbEngine::handleJumpToLineAddressResolution(const DebuggerResponse &respon
} }
} }
static inline bool isAsciiWord(const QString &s)
{
for (const QChar &c : s) {
if (!c.isLetterOrNumber() || c.toLatin1() == 0)
return false;
}
return true;
}
void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const QVariant &value) void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const QVariant &value)
{ {
if (debug) if (debug)
@@ -935,28 +926,8 @@ void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const Q
qWarning("Internal error: assignValueInDebugger: Invalid state or no stack frame."); qWarning("Internal error: assignValueInDebugger: Invalid state or no stack frame.");
return; return;
} }
QString cmd; runCommand({m_extensionCommandPrefix + "assign -h " + w->iname + '=' + toHex(value.toString()),
StringInputStream str(cmd); NoFlags});
switch (value.type()) {
case QVariant::String: {
// Convert qstring to Utf16 data not considering endianness for Windows.
const QString s = value.toString();
if (isAsciiWord(s)) {
str << m_extensionCommandPrefix << "assign \"" << w->iname << '=' << s << '"';
} else {
const QByteArray utf16(reinterpret_cast<const char *>(s.utf16()), 2 * s.size());
str << m_extensionCommandPrefix << "assign -u " << w->iname << '='
<< QString::fromLatin1(utf16.toHex());
}
}
break;
default:
str << m_extensionCommandPrefix << "assign " << w->iname << '='
<< value.toString();
break;
}
runCommand({cmd, NoFlags});
// Update all locals in case we change a union or something pointed to // Update all locals in case we change a union or something pointed to
// that affects other variables, too. // that affects other variables, too.
updateLocals(); updateLocals();

View File

@@ -442,6 +442,7 @@ public:
m_lookupRequests.clear(); m_lookupRequests.clear();
m_locationTimer.stop(); m_locationTimer.stop();
m_locationMark.reset(); m_locationMark.reset();
m_stackHandler.resetLocation();
m_disassemblerAgent.resetLocation(); m_disassemblerAgent.resetLocation();
m_toolTipManager.resetLocation(); m_toolTipManager.resetLocation();
} }

View File

@@ -870,6 +870,7 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(const QStringList &arguments)
engineManagerView->setSettings(ICore::settings(), "Debugger.SnapshotView"); engineManagerView->setSettings(ICore::settings(), "Debugger.SnapshotView");
engineManagerView->setIconSize(QSize(10, 10)); engineManagerView->setIconSize(QSize(10, 10));
engineManagerView->setModel(m_engineManager.model()); engineManagerView->setModel(m_engineManager.model());
engineManagerView->setSelectionMode(QAbstractItemView::SingleSelection);
auto engineManagerWindow = addSearch(engineManagerView); auto engineManagerWindow = addSearch(engineManagerView);
engineManagerWindow->setWindowTitle(tr("Debugger Perspectives")); engineManagerWindow->setWindowTitle(tr("Debugger Perspectives"));

View File

@@ -314,6 +314,11 @@ void StackHandler::scheduleResetLocation()
m_contentsValid = false; m_contentsValid = false;
} }
void StackHandler::resetLocation()
{
emit layoutChanged();
}
int StackHandler::stackRowCount() const int StackHandler::stackRowCount() const
{ {
// Only one "thread" for now. // Only one "thread" for now.

View File

@@ -112,6 +112,7 @@ public:
bool isContentsValid() const { return m_contentsValid; } bool isContentsValid() const { return m_contentsValid; }
bool operatesByInstruction() const; bool operatesByInstruction() const;
void scheduleResetLocation(); void scheduleResetLocation();
void resetLocation();
QIcon iconForRow(int row) const; QIcon iconForRow(int row) const;

View File

@@ -136,8 +136,20 @@ void HelpManager::registerDocumentation(const QStringList &files)
emit Core::HelpManager::Signals::instance()->documentationChanged(); emit Core::HelpManager::Signals::instance()->documentationChanged();
} }
}); });
ProgressManager::addTask(future, tr("Update Documentation"), ProgressManager::addTask(future, tr("Update Documentation"), kUpdateDocumentationTask);
kUpdateDocumentationTask); }
void HelpManager::unregisterDocumentation(const QStringList &fileNames)
{
if (fileNames.isEmpty())
return;
const auto getNamespaces = [](const QStringList &fileNames) {
QMutexLocker locker(&d->m_helpengineMutex);
return Utils::transform(fileNames, [](const QString &filePath) {
return d->m_helpEngine->namespaceName(filePath);
});
};
unregisterNamespaces(getNamespaces(fileNames));
} }
void HelpManager::registerDocumentationNow(QFutureInterface<bool> &futureInterface, void HelpManager::registerDocumentationNow(QFutureInterface<bool> &futureInterface,

View File

@@ -49,6 +49,7 @@ public:
static QString collectionFilePath(); static QString collectionFilePath();
void registerDocumentation(const QStringList &fileNames) override; void registerDocumentation(const QStringList &fileNames) override;
void unregisterDocumentation(const QStringList &fileNames) override;
static void unregisterNamespaces(const QStringList &nameSpaces); static void unregisterNamespaces(const QStringList &nameSpaces);

View File

@@ -1,11 +1,12 @@
add_qtc_plugin(McuSupport add_qtc_plugin(McuSupport
DEPENDS Qt5::Core DEPENDS Qt5::Core
PLUGIN_DEPENDS Core ProjectExplorer CMakeProjectManager PLUGIN_DEPENDS Core ProjectExplorer Debugger CMakeProjectManager
SOURCES SOURCES
mcusupport.qrc mcusupport.qrc
mcusupport_global.h mcusupport_global.h
mcusupportconstants.h mcusupportconstants.h
mcusupportdevice.cpp mcusupportdevice.h mcusupportdevice.cpp mcusupportdevice.h
mcusupportoptions.cpp mcusupportoptions.h
mcusupportoptionspage.cpp mcusupportoptionspage.h mcusupportoptionspage.cpp mcusupportoptionspage.h
mcusupportplugin.cpp mcusupportplugin.h mcusupportplugin.cpp mcusupportplugin.h
mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h mcusupportrunconfiguration.cpp mcusupportrunconfiguration.h

View File

@@ -8,12 +8,14 @@ HEADERS += \
mcusupport_global.h \ mcusupport_global.h \
mcusupportconstants.h \ mcusupportconstants.h \
mcusupportdevice.h \ mcusupportdevice.h \
mcusupportoptions.h \
mcusupportoptionspage.h \ mcusupportoptionspage.h \
mcusupportplugin.h \ mcusupportplugin.h \
mcusupportrunconfiguration.h mcusupportrunconfiguration.h
SOURCES += \ SOURCES += \
mcusupportdevice.cpp \ mcusupportdevice.cpp \
mcusupportoptions.cpp \
mcusupportoptionspage.cpp \ mcusupportoptionspage.cpp \
mcusupportplugin.cpp \ mcusupportplugin.cpp \
mcusupportrunconfiguration.cpp mcusupportrunconfiguration.cpp

View File

@@ -9,8 +9,8 @@ QtcPlugin {
Depends { name: "Core" } Depends { name: "Core" }
Depends { name: "ProjectExplorer" } Depends { name: "ProjectExplorer" }
Depends { name: "Debugger" }
Depends { name: "CMakeProjectManager" } Depends { name: "CMakeProjectManager" }
Depends { name: "QtSupport" }
files: [ files: [
"mcusupport.qrc", "mcusupport.qrc",
@@ -18,6 +18,8 @@ QtcPlugin {
"mcusupportconstants.h", "mcusupportconstants.h",
"mcusupportdevice.cpp", "mcusupportdevice.cpp",
"mcusupportdevice.h", "mcusupportdevice.h",
"mcusupportoptions.cpp",
"mcusupportoptions.h",
"mcusupportoptionspage.cpp", "mcusupportoptionspage.cpp",
"mcusupportoptionspage.h", "mcusupportoptionspage.h",
"mcusupportplugin.cpp", "mcusupportplugin.cpp",

View File

@@ -7,4 +7,5 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \ QTC_PLUGIN_DEPENDS += \
coreplugin \ coreplugin \
projectexplorer \ projectexplorer \
debugger \
cmakeprojectmanager cmakeprojectmanager

View File

@@ -0,0 +1,503 @@
/****************************************************************************
**
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** Contact: BlackBerry (qt@blackberry.com)
**
** 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 "mcusupportconstants.h"
#include "mcusupportoptions.h"
#include <coreplugin/icore.h>
#include <cmakeprojectmanager/cmakekitinformation.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggeritemmanager.h>
#include <debugger/debuggerkitinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/devicesupport/devicemanager.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <QDesktopServices>
#include <QDir>
#include <QFileInfo>
#include <QLabel>
#include <QToolButton>
#include <QVBoxLayout>
#include <QVariant>
namespace McuSupport {
namespace Internal {
PackageOptions::PackageOptions(const QString &label, const QString &defaultPath,
const QString &detectionPath, const QString &settingsKey)
: m_label(label)
, m_defaultPath(defaultPath)
, m_detectionPath(detectionPath)
, m_settingsKey(settingsKey)
{
QSettings *s = Core::ICore::settings();
s->beginGroup(Constants::SETTINGS_GROUP);
m_path = s->value(QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey,
m_defaultPath).toString();
s->endGroup();
}
QString PackageOptions::path() const
{
return QFileInfo(m_fileChooser->path() + m_relativePathModifier).absoluteFilePath();
}
QString PackageOptions::label() const
{
return m_label;
}
QString PackageOptions::detectionPath() const
{
return m_detectionPath;
}
QWidget *PackageOptions::widget()
{
if (m_widget)
return m_widget;
m_widget = new QWidget;
m_fileChooser = new Utils::PathChooser;
QObject::connect(m_fileChooser, &Utils::PathChooser::pathChanged,
[this](){
updateStatus();
emit changed();
});
auto layout = new QGridLayout(m_widget);
layout->setContentsMargins(0, 0, 0, 0);
m_statusIcon = new QLabel;
m_statusIcon->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding);
m_statusIcon->setAlignment(Qt::AlignTop);
m_statusLabel = new QLabel;
m_statusLabel->setWordWrap(true);
m_statusLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
if (!m_downloadUrl.isEmpty()) {
auto downLoadButton = new QToolButton;
downLoadButton->setIcon(Utils::Icons::DOWNLOAD.icon());
downLoadButton->setToolTip(tr("Download from \"%1\"").arg(m_downloadUrl));
QObject::connect(downLoadButton, &QToolButton::pressed, [this]{
QDesktopServices::openUrl(m_downloadUrl);
});
layout->addWidget(downLoadButton, 0, 2);
}
layout->addWidget(m_fileChooser, 0, 0, 1, 2);
layout->addWidget(m_statusIcon, 1, 0);
layout->addWidget(m_statusLabel, 1, 1, 1, -1);
m_fileChooser->setPath(m_path); // Triggers updateStatus() call
return m_widget;
}
PackageOptions::Status PackageOptions::status() const
{
return m_status;
}
void PackageOptions::setDownloadUrl(const QString &url)
{
m_downloadUrl = url;
}
void PackageOptions::setEnvironmentVariableName(const QString &name)
{
m_environmentVariableName = name;
}
QString PackageOptions::environmentVariableName() const
{
return m_environmentVariableName;
}
void PackageOptions::setAddToPath(bool addToPath)
{
m_addToPath = addToPath;
}
bool PackageOptions::addToPath() const
{
return m_addToPath;
}
void PackageOptions::writeToSettings() const
{
if (m_path.compare(m_defaultPath) == 0)
return;
QSettings *s = Core::ICore::settings();
s->beginGroup(Constants::SETTINGS_GROUP);
s->setValue(QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey, m_path);
s->endGroup();
}
void PackageOptions::setRelativePathModifier(const QString &path)
{
m_relativePathModifier = path;
}
void PackageOptions::updateStatus()
{
m_path = m_fileChooser->rawPath();
const bool validPath = m_fileChooser->isValid();
const Utils::FilePath detectionPath = Utils::FilePath::fromString(
m_fileChooser->path() + "/" + m_detectionPath);
const QString displayDetectionPath = Utils::FilePath::fromString(m_detectionPath).toUserOutput();
const bool validPackage = detectionPath.exists();
m_status = validPath ? (validPackage ? ValidPackage : ValidPathInvalidPackage) : InvalidPath;
static const QPixmap okIcon = Utils::Icons::OK.pixmap();
static const QPixmap notOkIcon = Utils::Icons::BROKEN.pixmap();
m_statusIcon->setPixmap(m_status == ValidPackage ? okIcon : notOkIcon);
QString statusText;
switch (m_status) {
case ValidPackage:
statusText = tr("Path is valid, \"%1\" was found.").arg(displayDetectionPath);
break;
case ValidPathInvalidPackage:
statusText = tr("Path exists, but does not contain \"%1\".").arg(displayDetectionPath);
break;
case InvalidPath:
statusText = tr("Path does not exist.");
break;
}
m_statusLabel->setText(statusText);
}
BoardOptions::BoardOptions(const QString &model, const QString &toolChainFileName,
const QVector<PackageOptions*> &packages)
: m_model(model)
, m_toolChainFile(toolChainFileName)
, m_packages(packages)
{
}
QString BoardOptions::model() const
{
return m_model;
}
QString BoardOptions::toolChainFile() const
{
return m_toolChainFile;
}
QVector<PackageOptions *> BoardOptions::packages() const
{
return m_packages;
}
static PackageOptions *createQulPackage()
{
auto result = new PackageOptions(
PackageOptions::tr("Qt MCU SDK"),
QDir::homePath(),
Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"),
"qulSdk");
result->setEnvironmentVariableName("Qul_DIR");
return result;
}
static PackageOptions *createArmGccPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles(x86)"))
+ "/GNU Tools ARM Embedded/"
: QString("%{Env:ARMGCC_DIR}");
auto result = new PackageOptions(
PackageOptions::tr("GNU Arm Embedded Toolchain"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"),
Constants::SETTINGS_KEY_PACKAGE_ARMGCC);
result->setDownloadUrl(
"https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads");
result->setEnvironmentVariableName("ARMGCC_DIR");
return result;
}
static PackageOptions *createStm32CubeFwF7SdkPackage()
{
auto result = new PackageOptions(
PackageOptions::tr("STM32Cube SDK"),
"%{Env:STM32Cube_FW_F7_SDK_PATH}",
"Drivers/STM32F7xx_HAL_Driver",
"stm32CubeFwF7Sdk");
result->setDownloadUrl(
"https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-mcu-packages/stm32cubef7.html");
result->setEnvironmentVariableName("STM32Cube_FW_F7_SDK_PATH");
return result;
}
static PackageOptions *createStm32CubeProgrammerPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles"))
+ "/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
: QDir::homePath();
auto result = new PackageOptions(
PackageOptions::tr("STM32CubeProgrammer"),
defaultPath,
QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "/bin/STM32_Programmer_CLI.exe"
: "/bin/STM32_Programmer.sh"),
"stm32CubeProgrammer");
result->setRelativePathModifier("/bin");
result->setDownloadUrl(
"https://www.st.com/en/development-tools/stm32cubeprog.html");
result->setAddToPath(true);
return result;
}
static PackageOptions *createEvkbImxrt1050SdkPackage()
{
auto result = new PackageOptions(
PackageOptions::tr("NXP EVKB-IMXRT1050 SDK"),
"%{Env:EVKB_IMXRT1050_SDK_PATH}",
"EVKB-IMXRT1050_manifest_v3_5.xml",
"evkbImxrt1050Sdk");
result->setDownloadUrl("https://mcuxpresso.nxp.com/en/welcome");
return result;
}
static PackageOptions *createSeggerJLinkPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles")) + "/SEGGER/JLink"
: QString("%{Env:SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH}");
auto result = new PackageOptions(
PackageOptions::tr("SEGGER JLink"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("JLink"),
"seggerJLink");
result->setDownloadUrl("https://www.segger.com/downloads/jlink");
return result;
}
McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent)
{
PackageOptions* qulPackage = createQulPackage();
PackageOptions* armGccPackage = createArmGccPackage();
PackageOptions* stm32CubeFwF7SdkPackage = createStm32CubeFwF7SdkPackage();
PackageOptions* stm32CubeProgrammerPackage = createStm32CubeProgrammerPackage();
PackageOptions* evkbImxrt1050SdkPackage = createEvkbImxrt1050SdkPackage();
PackageOptions* seggerJLinkPackage = createSeggerJLinkPackage();
toolchainPackage = armGccPackage;
auto stmPackages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
qulPackage};
auto nxpPackages = {armGccPackage, evkbImxrt1050SdkPackage, seggerJLinkPackage,
qulPackage};
packages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
evkbImxrt1050SdkPackage, seggerJLinkPackage, qulPackage};
boards.append(new BoardOptions(
"stm32f7508", "CMake/stm32f7508-discovery.cmake", stmPackages));
boards.append(new BoardOptions(
"stm32f769i", "CMake/stm32f769i-discovery.cmake", stmPackages));
boards.append(new BoardOptions(
"evkbimxrt1050", "CMake/evkbimxrt1050-toolchain.cmake", nxpPackages));
for (auto package : packages)
connect(package, &PackageOptions::changed, [this](){
emit changed();
});
}
McuSupportOptions::~McuSupportOptions()
{
qDeleteAll(packages);
packages.clear();
qDeleteAll(boards);
boards.clear();
}
QVector<BoardOptions *> McuSupportOptions::validBoards() const
{
return Utils::filtered(boards, [](BoardOptions *board){
return !Utils::anyOf(board->packages(), [](PackageOptions *package){
return package->status() != PackageOptions::ValidPackage;});
});
}
static ProjectExplorer::ToolChain* armGccToolchain(const Utils::FilePath &path, Core::Id language)
{
using namespace ProjectExplorer;
ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t){
return t->compilerCommand() == path && t->language() == language;
});
if (!toolChain) {
ToolChainFactory *gccFactory =
Utils::findOrDefault(ToolChainFactory::allToolChainFactories(), [](ToolChainFactory *f){
return f->supportedToolChainType() == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
});
if (gccFactory) {
const QList<ToolChain*> detected = gccFactory->detectForImport({path, language});
if (!detected.isEmpty()) {
toolChain = detected.first();
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("Arm GCC");
ToolChainManager::registerToolChain(toolChain);
}
}
}
return toolChain;
}
static void setKitProperties(ProjectExplorer::Kit *k, const BoardOptions* board)
{
using namespace ProjectExplorer;
k->setUnexpandedDisplayName("Qt MCU - " + board->model());
k->setValue(Constants::KIT_BOARD_MODEL_KEY, board->model());
k->setAutoDetected(false);
k->setIrrelevantAspects({
SysRootKitAspect::id(),
"QtSupport.QtInformation" // QtKitAspect::id()
});
}
static void setKitToolchains(ProjectExplorer::Kit *k, const QString &armGccPath)
{
using namespace ProjectExplorer;
const QString compileNameScheme = Utils::HostOsInfo::withExecutableSuffix(
armGccPath + "/bin/arm-none-eabi-%1");
ToolChain *cTc = armGccToolchain(
Utils::FilePath::fromUserInput(compileNameScheme.arg("gcc")),
ProjectExplorer::Constants::C_LANGUAGE_ID);
ToolChain *cxxTc = armGccToolchain(
Utils::FilePath::fromUserInput(compileNameScheme.arg("g++")),
ProjectExplorer::Constants::CXX_LANGUAGE_ID);
ToolChainKitAspect::setToolChain(k, cTc);
ToolChainKitAspect::setToolChain(k, cxxTc);
}
static void setKitDebugger(ProjectExplorer::Kit *k, const QString &armGccPath)
{
using namespace Debugger;
const Utils::FilePath command = Utils::FilePath::fromUserInput(
Utils::HostOsInfo::withExecutableSuffix(armGccPath + "/bin/arm-none-eabi-gdb-py"));
const DebuggerItem *debugger = DebuggerItemManager::findByCommand(command);
QVariant debuggerId;
if (!debugger) {
DebuggerItem newDebugger;
newDebugger.setCommand(command);
newDebugger.setUnexpandedDisplayName(
PackageOptions::tr("Arm GDB at %1").arg(command.toUserOutput()));
debuggerId = DebuggerItemManager::registerDebugger(newDebugger);
} else {
debuggerId = debugger->id();
}
DebuggerKitAspect::setDebugger(k, debuggerId);
}
static void setKitDevice(ProjectExplorer::Kit *k)
{
using namespace ProjectExplorer;
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE);
}
static void setKitEnvironment(ProjectExplorer::Kit *k, const BoardOptions* board)
{
using namespace ProjectExplorer;
Utils::EnvironmentItems changes;
QStringList pathAdditions;
for (auto package : board->packages()) {
if (package->addToPath())
pathAdditions.append(QDir::toNativeSeparators(package->path()));
if (!package->environmentVariableName().isEmpty())
changes.append({package->environmentVariableName(),
QDir::toNativeSeparators(package->path())});
}
if (!pathAdditions.isEmpty()) {
pathAdditions.append("${Path}");
changes.append({"Path", pathAdditions.join(Utils::HostOsInfo::pathListSeparator())});
}
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
}
static void setKitCMakeOptions(ProjectExplorer::Kit *k, const BoardOptions* board)
{
using namespace CMakeProjectManager;
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
config.append(CMakeConfigItem("CMAKE_TOOLCHAIN_FILE",
("%{CurrentBuild:Env:Qul_DIR}/" +
board->toolChainFile()).toUtf8()));
CMakeConfigurationKitAspect::setConfiguration(k, config);
}
ProjectExplorer::Kit *McuSupportOptions::kit(const BoardOptions* board)
{
using namespace ProjectExplorer;
Kit *kit = KitManager::kit([board](const Kit *k){
return board->model() == k->value(Constants::KIT_BOARD_MODEL_KEY).toString();
});
if (!kit) {
const QString armGccPath = toolchainPackage->path();
const auto init = [board, &armGccPath](Kit *k) {
KitGuard kitGuard(k);
setKitProperties(k, board);
setKitToolchains(k, armGccPath);
setKitDebugger(k, armGccPath);
setKitDevice(k);
setKitEnvironment(k, board);
setKitCMakeOptions(k, board);
k->setup();
k->fix();
};
kit = KitManager::registerKit(init);
}
return kit;
}
} // Internal
} // McuSupport

View File

@@ -0,0 +1,138 @@
/****************************************************************************
**
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** Contact: BlackBerry (qt@blackberry.com)
**
** 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 <QObject>
#include <QVector>
QT_FORWARD_DECLARE_CLASS(QWidget)
QT_FORWARD_DECLARE_CLASS(QLabel)
namespace Utils {
class PathChooser;
}
namespace ProjectExplorer {
class Kit;
}
namespace McuSupport {
namespace Internal {
class PackageOptions : public QObject
{
Q_OBJECT
public:
enum Status {
InvalidPath,
ValidPathInvalidPackage,
ValidPackage
};
PackageOptions(const QString &label, const QString &defaultPath, const QString &detectionPath,
const QString &settingsKey);
QString path() const;
QString label() const;
QString detectionPath() const;
Status status() const;
void setDownloadUrl(const QString &url);
void setEnvironmentVariableName(const QString &name);
void setAddToPath(bool addToPath);
bool addToPath() const;
void writeToSettings() const;
void setRelativePathModifier(const QString &path);
QWidget *widget();
QString environmentVariableName() const;
signals:
void changed();
private:
void updateStatus();
QWidget *m_widget = nullptr;
Utils::PathChooser *m_fileChooser = nullptr;
QLabel *m_statusIcon = nullptr;
QLabel *m_statusLabel = nullptr;
const QString m_label;
const QString m_defaultPath;
const QString m_detectionPath;
const QString m_settingsKey;
QString m_path;
QString m_relativePathModifier; // relative path to m_path to be returned by path()
QString m_downloadUrl;
QString m_environmentVariableName;
bool m_addToPath = false;
Status m_status = InvalidPath;
};
class BoardOptions : public QObject
{
Q_OBJECT
public:
BoardOptions(const QString &model, const QString &toolChainFile,
const QVector<PackageOptions *> &packages);
QString model() const;
QString toolChainFile() const;
QVector<PackageOptions *> packages() const;
private:
const QString m_model;
const QString m_toolChainFile;
const QVector<PackageOptions*> m_packages;
};
class McuSupportOptions : public QObject
{
Q_OBJECT
public:
McuSupportOptions(QObject *parent = nullptr);
~McuSupportOptions() override;
QVector<BoardOptions*> validBoards() const;
QVector<PackageOptions*> packages;
QVector<BoardOptions*> boards;
PackageOptions *toolchainPackage = nullptr;
ProjectExplorer::Kit *kit(const BoardOptions* board);
signals:
void changed();
};
} // namespace Internal
} // namespace McuSupport

View File

@@ -25,438 +25,24 @@
#include "mcusupportconstants.h" #include "mcusupportconstants.h"
#include "mcusupportoptionspage.h" #include "mcusupportoptionspage.h"
#include "mcusupportoptions.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cmakeprojectmanager/cmakekitinformation.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/devicesupport/devicemanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <QAction>
#include <QComboBox> #include <QComboBox>
#include <QDebug>
#include <QDesktopServices>
#include <QDir> #include <QDir>
#include <QFileInfo>
#include <QFormLayout> #include <QFormLayout>
#include <QGroupBox> #include <QGroupBox>
#include <QLabel> #include <QLabel>
#include <QSizePolicy>
#include <QToolButton>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QVariant>
namespace McuSupport { namespace McuSupport {
namespace Internal { namespace Internal {
class PackageOptions : public QObject
{
Q_OBJECT
public:
enum Status {
InvalidPath,
ValidPathInvalidPackage,
ValidPackage
};
PackageOptions(const QString &label, const QString &defaultPath, const QString &detectionPath,
const QString &settingsKey);
QString path() const;
QString label() const;
QString detectionPath() const;
Status status() const;
void setDownloadUrl(const QUrl &url);
void setEnvironmentVariableName(const QString &name);
void setAddToPath(bool addToPath);
bool addToPath() const;
void writeToSettings() const;
void setRelativePathModifier(const QString &path);
QWidget *widget();
QString environmentVariableName() const;
signals:
void changed();
private:
void updateStatus();
QWidget *m_widget = nullptr;
Utils::PathChooser *m_fileChooser = nullptr;
QLabel *m_statusIcon = nullptr;
QLabel *m_statusLabel = nullptr;
const QString m_label;
const QString m_defaultPath;
const QString m_detectionPath;
const QString m_settingsKey;
QString m_path;
QString m_relativePathModifier; // relative path to m_path to be returned by path()
QUrl m_downloadUrl;
QString m_environmentVariableName;
bool m_addToPath = false;
Status m_status = InvalidPath;
};
PackageOptions::PackageOptions(const QString &label, const QString &defaultPath,
const QString &detectionPath, const QString &settingsKey)
: m_label(label)
, m_defaultPath(defaultPath)
, m_detectionPath(detectionPath)
, m_settingsKey(settingsKey)
{
QSettings *s = Core::ICore::settings();
s->beginGroup(Constants::SETTINGS_GROUP);
m_path = s->value(QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey,
m_defaultPath).toString();
s->endGroup();
}
QString PackageOptions::path() const
{
return QFileInfo(m_fileChooser->path() + m_relativePathModifier).absoluteFilePath();
}
QString PackageOptions::label() const
{
return m_label;
}
QString PackageOptions::detectionPath() const
{
return m_detectionPath;
}
QWidget *PackageOptions::widget()
{
if (m_widget)
return m_widget;
m_widget = new QWidget;
m_fileChooser = new Utils::PathChooser;
QObject::connect(m_fileChooser, &Utils::PathChooser::pathChanged,
[this](){
updateStatus();
emit changed();
});
auto layout = new QGridLayout(m_widget);
layout->setContentsMargins(0, 0, 0, 0);
m_statusIcon = new QLabel;
m_statusIcon->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding);
m_statusIcon->setAlignment(Qt::AlignTop);
m_statusLabel = new QLabel;
m_statusLabel->setWordWrap(true);
m_statusLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
if (!m_downloadUrl.isEmpty()) {
auto downLoadButton = new QToolButton;
downLoadButton->setIcon(Utils::Icons::DOWNLOAD.icon());
downLoadButton->setToolTip(McuSupportOptionsPage::tr("Download from \"%1\"")
.arg(m_downloadUrl.toString()));
QObject::connect(downLoadButton, &QToolButton::pressed, [this]{
QDesktopServices::openUrl(m_downloadUrl);
});
layout->addWidget(downLoadButton, 0, 2);
}
layout->addWidget(m_fileChooser, 0, 0, 1, 2);
layout->addWidget(m_statusIcon, 1, 0);
layout->addWidget(m_statusLabel, 1, 1, 1, -1);
m_fileChooser->setPath(m_path); // Triggers updateStatus() call
return m_widget;
}
PackageOptions::Status PackageOptions::status() const
{
return m_status;
}
void PackageOptions::setDownloadUrl(const QUrl &url)
{
m_downloadUrl = url;
}
void PackageOptions::setEnvironmentVariableName(const QString &name)
{
m_environmentVariableName = name;
}
QString PackageOptions::environmentVariableName() const
{
return m_environmentVariableName;
}
void PackageOptions::setAddToPath(bool addToPath)
{
m_addToPath = addToPath;
}
bool PackageOptions::addToPath() const
{
return m_addToPath;
}
void PackageOptions::writeToSettings() const
{
if (m_path.compare(m_defaultPath) == 0)
return;
QSettings *s = Core::ICore::settings();
s->beginGroup(Constants::SETTINGS_GROUP);
s->setValue(QLatin1String(Constants::SETTINGS_KEY_PACKAGE_PREFIX) + m_settingsKey, m_path);
s->endGroup();
}
void PackageOptions::setRelativePathModifier(const QString &path)
{
m_relativePathModifier = path;
}
void PackageOptions::updateStatus()
{
m_path = m_fileChooser->rawPath();
const bool validPath = m_fileChooser->isValid();
const Utils::FilePath detectionPath = Utils::FilePath::fromString(
m_fileChooser->path() + "/" + m_detectionPath);
const QString displayDetectionPath = Utils::FilePath::fromString(m_detectionPath).toUserOutput();
const bool validPackage = detectionPath.exists();
m_status = validPath ? (validPackage ? ValidPackage : ValidPathInvalidPackage) : InvalidPath;
static const QPixmap okIcon = Utils::Icons::OK.pixmap();
static const QPixmap notOkIcon = Utils::Icons::BROKEN.pixmap();
m_statusIcon->setPixmap(m_status == ValidPackage ? okIcon : notOkIcon);
QString statusText;
switch (m_status) {
case ValidPackage:
statusText = McuSupportOptionsPage::tr(
"Path is valid, \"%1\" was found.").arg(displayDetectionPath);
break;
case ValidPathInvalidPackage:
statusText = McuSupportOptionsPage::tr(
"Path exists, but does not contain \"%1\".").arg(displayDetectionPath);
break;
case InvalidPath:
statusText = McuSupportOptionsPage::tr("Path does not exist.");
break;
}
m_statusLabel->setText(statusText);
}
class BoardOptions : public QObject
{
Q_OBJECT
public:
BoardOptions(const QString &model, const QString &toolChainFile,
const QVector<PackageOptions *> &packages);
QString model() const;
QString toolChainFile() const;
QVector<PackageOptions *> packages() const;
private:
const QString m_model;
const QString m_toolChainFile;
const QVector<PackageOptions*> m_packages;
};
BoardOptions::BoardOptions(const QString &model, const QString &toolChainFileName,
const QVector<PackageOptions*> &packages)
: m_model(model)
, m_toolChainFile(toolChainFileName)
, m_packages(packages)
{
}
QString BoardOptions::model() const
{
return m_model;
}
QString BoardOptions::toolChainFile() const
{
return m_toolChainFile;
}
QVector<PackageOptions *> BoardOptions::packages() const
{
return m_packages;
}
class McuSupportOptions : public QObject
{
Q_OBJECT
public:
McuSupportOptions(QObject *parent = nullptr);
~McuSupportOptions() override;
QVector<BoardOptions*> validBoards() const;
QVector<PackageOptions*> packages;
QVector<BoardOptions*> boards;
PackageOptions* toolchainPackage = nullptr;
signals:
void changed();
};
static PackageOptions* createQulPackage()
{
auto result = new PackageOptions(
McuSupportOptionsPage::tr("Qt MCU SDK"),
QDir::homePath(),
Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"),
"qulSdk");
result->setEnvironmentVariableName("Qul_DIR");
return result;
}
static PackageOptions* createArmGccPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles(x86)"))
+ "/GNU Tools ARM Embedded/"
: QString("%{Env:ARMGCC_DIR}");
auto result = new PackageOptions(
McuSupportOptionsPage::tr("GNU Arm Embedded Toolchain"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"),
Constants::SETTINGS_KEY_PACKAGE_ARMGCC);
result->setDownloadUrl(
QUrl::fromUserInput("https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads"));
result->setEnvironmentVariableName("ARMGCC_DIR");
return result;
}
static PackageOptions* createStm32CubeFwF7SdkPackage()
{
auto result = new PackageOptions(
McuSupportOptionsPage::tr("STM32Cube SDK"),
"%{Env:STM32Cube_FW_F7_SDK_PATH}",
"Drivers/STM32F7xx_HAL_Driver",
"stm32CubeFwF7Sdk");
result->setDownloadUrl(
QUrl::fromUserInput("https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-mcu-packages/stm32cubef7.html"));
result->setEnvironmentVariableName("STM32Cube_FW_F7_SDK_PATH");
return result;
}
static PackageOptions* createStm32CubeProgrammerPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles"))
+ "/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
: QDir::homePath();
auto result = new PackageOptions(
McuSupportOptionsPage::tr("STM32CubeProgrammer"),
defaultPath,
QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "/bin/STM32_Programmer_CLI.exe"
: "/bin/STM32_Programmer.sh"),
"stm32CubeProgrammer");
result->setRelativePathModifier("/bin");
result->setDownloadUrl(
QUrl::fromUserInput("https://www.st.com/en/development-tools/stm32cubeprog.html"));
result->setAddToPath(true);
return result;
}
static PackageOptions* createEvkbImxrt1050SdkPackage()
{
auto result = new PackageOptions(
McuSupportOptionsPage::tr("NXP EVKB-IMXRT1050 SDK"),
"%{Env:EVKB_IMXRT1050_SDK_PATH}",
"EVKB-IMXRT1050_manifest_v3_5.xml",
"evkbImxrt1050Sdk");
result->setDownloadUrl(
QUrl::fromUserInput("https://mcuxpresso.nxp.com/en/welcome"));
return result;
}
static PackageOptions* createSeggerJLinkPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles")) + "/SEGGER/JLink"
: QString("%{Env:SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH}");
auto result = new PackageOptions(
McuSupportOptionsPage::tr("SEGGER JLink"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("JLink"),
"seggerJLink");
result->setDownloadUrl(
QUrl::fromUserInput("https://www.segger.com/downloads/jlink"));
return result;
}
McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent)
{
PackageOptions* qulPackage = createQulPackage();
PackageOptions* armGccPackage = createArmGccPackage();
PackageOptions* stm32CubeFwF7SdkPackage = createStm32CubeFwF7SdkPackage();
PackageOptions* stm32CubeProgrammerPackage = createStm32CubeProgrammerPackage();
PackageOptions* evkbImxrt1050SdkPackage = createEvkbImxrt1050SdkPackage();
PackageOptions* seggerJLinkPackage = createSeggerJLinkPackage();
toolchainPackage = armGccPackage;
auto stmPackages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
qulPackage};
auto nxpPackages = {armGccPackage, evkbImxrt1050SdkPackage, seggerJLinkPackage,
qulPackage};
packages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
evkbImxrt1050SdkPackage, seggerJLinkPackage, qulPackage};
boards.append(new BoardOptions(
"stm32f7508", "CMake/stm32f7508-discovery.cmake", stmPackages));
boards.append(new BoardOptions(
"stm32f769i", "CMake/stm32f769i-discovery.cmake", stmPackages));
boards.append(new BoardOptions(
"evkbimxrt1050", "CMake/evkbimxrt1050-toolchain.cmake", nxpPackages));
for (auto package : packages)
connect(package, &PackageOptions::changed, [this](){
emit changed();
});
}
McuSupportOptions::~McuSupportOptions()
{
qDeleteAll(packages);
packages.clear();
qDeleteAll(boards);
boards.clear();
}
QVector<BoardOptions *> McuSupportOptions::validBoards() const
{
return Utils::filtered(boards, [](BoardOptions *board){
return !Utils::anyOf(board->packages(), [](PackageOptions *package){
return package->status() != PackageOptions::ValidPackage;});
});
}
class McuSupportOptionsWidget : public QWidget class McuSupportOptionsWidget : public QWidget
{ {
public: public:
@@ -559,7 +145,7 @@ McuSupportOptionsPage::McuSupportOptionsPage(QObject* parent)
setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY); setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY);
} }
QWidget* McuSupportOptionsPage::widget() QWidget *McuSupportOptionsPage::widget()
{ {
if (!m_options) if (!m_options)
m_options = new McuSupportOptions(this); m_options = new McuSupportOptions(this);
@@ -568,124 +154,6 @@ QWidget* McuSupportOptionsPage::widget()
return m_widget; return m_widget;
} }
static ProjectExplorer::ToolChain* armGccToolchain(const Utils::FilePath &path, Core::Id language)
{
using namespace ProjectExplorer;
ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t){
return t->compilerCommand() == path && t->language() == language;
});
if (!toolChain) {
ToolChainFactory *gccFactory =
Utils::findOrDefault(ToolChainFactory::allToolChainFactories(), [](ToolChainFactory *f){
return f->supportedToolChainType() == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID;
});
if (gccFactory) {
const QList<ToolChain*> detected = gccFactory->detectForImport({path, language});
if (!detected.isEmpty()) {
toolChain = detected.first();
toolChain->setDetection(ToolChain::ManualDetection);
toolChain->setDisplayName("Arm GCC");
ToolChainManager::registerToolChain(toolChain);
}
}
}
return toolChain;
}
static void setKitProperties(ProjectExplorer::Kit *k, const BoardOptions* board)
{
using namespace ProjectExplorer;
k->setUnexpandedDisplayName("Qt MCU - " + board->model());
k->setValue(Constants::KIT_BOARD_MODEL_KEY, board->model());
k->setAutoDetected(false);
k->setIrrelevantAspects({
SysRootKitAspect::id(),
"QtSupport.QtInformation" // QtKitAspect::id()
});
}
static void setKitToolchains(ProjectExplorer::Kit *k, const QString &armGccPath)
{
using namespace ProjectExplorer;
const QString compileNameScheme = Utils::HostOsInfo::withExecutableSuffix(
armGccPath + "/bin/arm-none-eabi-%1");
ToolChain *cTc = armGccToolchain(
Utils::FilePath::fromUserInput(compileNameScheme.arg("gcc")),
ProjectExplorer::Constants::C_LANGUAGE_ID);
ToolChain *cxxTc = armGccToolchain(
Utils::FilePath::fromUserInput(compileNameScheme.arg("g++")),
ProjectExplorer::Constants::CXX_LANGUAGE_ID);
ToolChainKitAspect::setToolChain(k, cTc);
ToolChainKitAspect::setToolChain(k, cxxTc);
}
static void setKitDevice(ProjectExplorer::Kit *k)
{
using namespace ProjectExplorer;
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE);
}
static void setKitEnvironment(ProjectExplorer::Kit *k, const BoardOptions* board)
{
using namespace ProjectExplorer;
Utils::EnvironmentItems changes;
QStringList pathAdditions;
for (auto package : board->packages()) {
if (package->addToPath())
pathAdditions.append(QDir::toNativeSeparators(package->path()));
if (!package->environmentVariableName().isEmpty())
changes.append({package->environmentVariableName(),
QDir::toNativeSeparators(package->path())});
}
if (!pathAdditions.isEmpty()) {
pathAdditions.append("${Path}");
changes.append({"Path", pathAdditions.join(Utils::HostOsInfo::pathListSeparator())});
}
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
}
static void setCMakeOptions(ProjectExplorer::Kit *k, const BoardOptions* board)
{
using namespace CMakeProjectManager;
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
config.append(CMakeConfigItem("CMAKE_TOOLCHAIN_FILE",
("%{CurrentBuild:Env:Qul_DIR}/" +
board->toolChainFile()).toUtf8()));
CMakeConfigurationKitAspect::setConfiguration(k, config);
}
static ProjectExplorer::Kit* boardKit(const BoardOptions* board, const QString &armGccPath)
{
using namespace ProjectExplorer;
Kit *kit = KitManager::kit([board](const Kit *k){
return board->model() == k->value(Constants::KIT_BOARD_MODEL_KEY).toString();
});
if (!kit) {
const auto init = [board, &armGccPath](Kit *k) {
KitGuard kitGuard(k);
setKitProperties(k, board);
setKitToolchains(k, armGccPath);
setKitDevice(k);
setKitEnvironment(k, board);
setCMakeOptions(k, board);
k->setup();
k->fix();
};
kit = KitManager::registerKit(init);
}
return kit;
}
void McuSupportOptionsPage::apply() void McuSupportOptionsPage::apply()
{ {
for (auto package : m_options->packages) for (auto package : m_options->packages)
@@ -697,9 +165,8 @@ void McuSupportOptionsPage::apply()
using namespace ProjectExplorer; using namespace ProjectExplorer;
for (auto board : validBoards) { for (auto board : validBoards)
Kit *kit = boardKit(board, m_options->toolchainPackage->path()); m_options->kit(board);
}
} }
void McuSupportOptionsPage::finish() void McuSupportOptionsPage::finish()
@@ -711,5 +178,3 @@ void McuSupportOptionsPage::finish()
} // Internal } // Internal
} // McuSupport } // McuSupport
#include "mcusupportoptionspage.moc"

View File

@@ -524,7 +524,9 @@ void Project::emitParsingStarted()
void Project::emitParsingFinished(bool success) void Project::emitParsingFinished(bool success)
{ {
QTC_ASSERT(d->m_isParsing, return); // Intentionally no return, as we currently get start - start - end - end
// sequences when switching qmake targets quickly.
QTC_CHECK(d->m_isParsing);
d->m_isParsing = false; d->m_isParsing = false;
d->m_hasParsingData = success; d->m_hasParsingData = success;

View File

@@ -674,7 +674,7 @@ TargetGroupItem::TargetGroupItem(const QString &displayName, Project *project)
QObject::connect(project, &Project::removedTarget, QObject::connect(project, &Project::removedTarget,
d.get(), &TargetGroupItemPrivate::handleTargetRemoved); d.get(), &TargetGroupItemPrivate::handleTargetRemoved);
QObject::connect(project, &Project::activeTargetChanged, QObject::connect(project, &Project::activeTargetChanged,
d.get(), &TargetGroupItemPrivate::handleTargetChanged, Qt::QueuedConnection); d.get(), &TargetGroupItemPrivate::handleTargetChanged);
} }
TargetGroupItem::~TargetGroupItem() = default; TargetGroupItem::~TargetGroupItem() = default;
@@ -748,8 +748,10 @@ TargetItem *TargetGroupItem::currentTargetItem() const
TargetItem *TargetGroupItem::targetItem(Target *target) const TargetItem *TargetGroupItem::targetItem(Target *target) const
{ {
if (target) if (target) {
return findFirstLevelChild([target](TargetItem *item) { return item->target() == target; }); Id needle = target->id(); // Unconfigured project have no active target.
return findFirstLevelChild([needle](TargetItem *item) { return item->m_kitId == needle; });
}
return nullptr; return nullptr;
} }

View File

@@ -738,9 +738,8 @@ void QbsProject::updateDocuments(const std::set<QString> &files)
const FilePath buildDir = FilePath::fromString(m_projectData.buildDirectory()); const FilePath buildDir = FilePath::fromString(m_projectData.buildDirectory());
const QVector<FilePath> nonBuildDirFilePaths = filtered(filePaths, const QVector<FilePath> nonBuildDirFilePaths = filtered(filePaths,
[buildDir](const FilePath &p) { [buildDir](const FilePath &p) {
return p.isChildOf(buildDir); return !p.isChildOf(buildDir);
}); });
setExtraProjectFiles(nonBuildDirFilePaths); setExtraProjectFiles(nonBuildDirFilePaths);
} }

View File

@@ -197,12 +197,12 @@ Project::RestoreResult QmakeProject::fromMap(const QVariantMap &map, QString *er
if (m_activeTarget) { if (m_activeTarget) {
connect(m_activeTarget, &Target::activeBuildConfigurationChanged, connect(m_activeTarget, &Target::activeBuildConfigurationChanged,
this, &QmakeProject::scheduleAsyncUpdateLater); this, &QmakeProject::scheduleAsyncUpdateLater);
scheduleAsyncUpdate(QmakeProFile::ParseNow);
} }
connect(this, &Project::activeTargetChanged, connect(this, &Project::activeTargetChanged,
this, &QmakeProject::activeTargetWasChanged); this, &QmakeProject::activeTargetWasChanged);
scheduleAsyncUpdate(QmakeProFile::ParseNow);
return RestoreResult::Ok; return RestoreResult::Ok;
} }
@@ -707,7 +707,8 @@ QmakeProFileNode *QmakeProject::rootProjectNode() const
void QmakeProject::activeTargetWasChanged() void QmakeProject::activeTargetWasChanged()
{ {
if (m_activeTarget) { const bool hadActiveTarget = m_activeTarget;
if (hadActiveTarget) {
disconnect(m_activeTarget, &Target::activeBuildConfigurationChanged, disconnect(m_activeTarget, &Target::activeBuildConfigurationChanged,
this, &QmakeProject::scheduleAsyncUpdateLater); this, &QmakeProject::scheduleAsyncUpdateLater);
} }
@@ -721,7 +722,7 @@ void QmakeProject::activeTargetWasChanged()
connect(m_activeTarget, &Target::activeBuildConfigurationChanged, connect(m_activeTarget, &Target::activeBuildConfigurationChanged,
this, &QmakeProject::scheduleAsyncUpdateLater); this, &QmakeProject::scheduleAsyncUpdateLater);
scheduleAsyncUpdate(); scheduleAsyncUpdate(hadActiveTarget ? QmakeProFile::ParseLater : QmakeProFile::ParseNow);
} }
static void notifyChangedHelper(const FilePath &fileName, QmakeProFile *file) static void notifyChangedHelper(const FilePath &fileName, QmakeProFile *file)

View File

@@ -138,6 +138,7 @@ extend_qtc_plugin(QmlDesigner
synchronizecommand.cpp synchronizecommand.h synchronizecommand.cpp synchronizecommand.h
tokencommand.cpp tokencommand.h tokencommand.cpp tokencommand.h
valueschangedcommand.cpp valueschangedcommand.h valueschangedcommand.cpp valueschangedcommand.h
changeselectioncommand.cpp changeselectioncommand.h
) )
extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner

View File

@@ -127,6 +127,8 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
#else #else
Q_UNUSED(inputFiles) Q_UNUSED(inputFiles)
Q_UNUSED(importPath) Q_UNUSED(importPath)
Q_UNUSED(options)
Q_UNUSED(extToImportOptionsMap)
addError(tr("Importing 3D assets requires building against Qt Quick 3D module.")); addError(tr("Importing 3D assets requires building against Qt Quick 3D module."));
notifyFinished(); notifyFinished();
#endif #endif
@@ -173,6 +175,7 @@ bool ItemLibraryAssetImporter::isQuick3DAsset(const QString &fileName) const
} }
return quick3DExt.contains(QFileInfo(fileName).suffix()); return quick3DExt.contains(QFileInfo(fileName).suffix());
#else #else
Q_UNUSED(fileName)
return false; return false;
#endif #endif
} }
@@ -182,6 +185,7 @@ QVariantMap ItemLibraryAssetImporter::supportedOptions(const QString &modelFile)
#ifdef IMPORT_QUICK3D_ASSETS #ifdef IMPORT_QUICK3D_ASSETS
return m_quick3DAssetImporter->getOptionsForFile(modelFile); return m_quick3DAssetImporter->getOptionsForFile(modelFile);
#else #else
Q_UNUSED(modelFile)
return {}; return {};
#endif #endif
} }

View File

@@ -41,7 +41,7 @@ void PropertyEditorTransaction::start()
if (m_rewriterTransaction.isValid()) if (m_rewriterTransaction.isValid())
m_rewriterTransaction.commit(); m_rewriterTransaction.commit();
m_rewriterTransaction = m_propertyEditor->beginRewriterTransaction(QByteArrayLiteral("PropertyEditorTransaction::start")); m_rewriterTransaction = m_propertyEditor->beginRewriterTransaction(QByteArrayLiteral("PropertyEditorTransaction::start"));
m_timerId = startTimer(4000); m_timerId = startTimer(10000);
} }
void PropertyEditorTransaction::end() void PropertyEditorTransaction::end()
@@ -52,6 +52,11 @@ void PropertyEditorTransaction::end()
} }
} }
bool PropertyEditorTransaction::active() const
{
return m_rewriterTransaction.isValid();
}
void PropertyEditorTransaction::timerEvent(QTimerEvent *timerEvent) void PropertyEditorTransaction::timerEvent(QTimerEvent *timerEvent)
{ {
if (timerEvent->timerId() != m_timerId) if (timerEvent->timerId() != m_timerId)

View File

@@ -38,6 +38,8 @@ public:
Q_INVOKABLE void start(); Q_INVOKABLE void start();
Q_INVOKABLE void end(); Q_INVOKABLE void end();
Q_INVOKABLE bool active() const;
protected: protected:
void timerEvent(QTimerEvent *event) override; void timerEvent(QTimerEvent *event) override;

View File

@@ -64,6 +64,7 @@ class ChangeValuesCommand;
class ChangeBindingsCommand; class ChangeBindingsCommand;
class ChangeIdsCommand; class ChangeIdsCommand;
class RemoveInstancesCommand; class RemoveInstancesCommand;
class ChangeSelectionCommand;
class RemovePropertiesCommand; class RemovePropertiesCommand;
class CompleteComponentCommand; class CompleteComponentCommand;
class InformationContainer; class InformationContainer;
@@ -119,6 +120,7 @@ public:
void updatePosition(const QList<VariantProperty>& propertyList); void updatePosition(const QList<VariantProperty>& propertyList);
void valuesChanged(const ValuesChangedCommand &command) override; void valuesChanged(const ValuesChangedCommand &command) override;
void valuesModified(const ValuesModifiedCommand &command) override;
void pixmapChanged(const PixmapChangedCommand &command) override; void pixmapChanged(const PixmapChangedCommand &command) override;
void informationChanged(const InformationChangedCommand &command) override; void informationChanged(const InformationChangedCommand &command) override;
void childrenChanged(const ChildrenChangedCommand &command) override; void childrenChanged(const ChildrenChangedCommand &command) override;
@@ -134,6 +136,11 @@ public:
void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector); void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector);
void selectionChanged(const ChangeSelectionCommand &command) override;
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
const QList<ModelNode> &lastSelectedNodeList) override;
protected: protected:
void timerEvent(QTimerEvent *event) override; void timerEvent(QTimerEvent *event) override;
@@ -173,6 +180,7 @@ private: // functions
ChangeBindingsCommand createChangeBindingCommand(const QList<BindingProperty> &propertyList) const; ChangeBindingsCommand createChangeBindingCommand(const QList<BindingProperty> &propertyList) const;
ChangeIdsCommand createChangeIdsCommand(const QList<NodeInstance> &instanceList) const; ChangeIdsCommand createChangeIdsCommand(const QList<NodeInstance> &instanceList) const;
RemoveInstancesCommand createRemoveInstancesCommand(const QList<ModelNode> &nodeList) const; RemoveInstancesCommand createRemoveInstancesCommand(const QList<ModelNode> &nodeList) const;
ChangeSelectionCommand createChangeSelectionCommand(const QList<ModelNode> &nodeList) const;
RemoveInstancesCommand createRemoveInstancesCommand(const ModelNode &node) const; RemoveInstancesCommand createRemoveInstancesCommand(const ModelNode &node) const;
RemovePropertiesCommand createRemovePropertiesCommand(const QList<AbstractProperty> &propertyList) const; RemovePropertiesCommand createRemovePropertiesCommand(const QList<AbstractProperty> &propertyList) const;
RemoveSharedMemoryCommand createRemoveSharedMemoryCommand(const QString &sharedMemoryTypeName, quint32 keyNumber); RemoveSharedMemoryCommand createRemoveSharedMemoryCommand(const QString &sharedMemoryTypeName, quint32 keyNumber);

View File

@@ -41,6 +41,7 @@
#include <changestatecommand.h> #include <changestatecommand.h>
#include <completecomponentcommand.h> #include <completecomponentcommand.h>
#include <changenodesourcecommand.h> #include <changenodesourcecommand.h>
#include <changeselectioncommand.h>
#include <informationchangedcommand.h> #include <informationchangedcommand.h>
#include <pixmapchangedcommand.h> #include <pixmapchangedcommand.h>
@@ -270,6 +271,7 @@ void NodeInstanceServerProxy::dispatchCommand(const QVariant &command, PuppetStr
{ {
static const int informationChangedCommandType = QMetaType::type("InformationChangedCommand"); static const int informationChangedCommandType = QMetaType::type("InformationChangedCommand");
static const int valuesChangedCommandType = QMetaType::type("ValuesChangedCommand"); static const int valuesChangedCommandType = QMetaType::type("ValuesChangedCommand");
static const int valuesModifiedCommandType = QMetaType::type("ValuesModifiedCommand");
static const int pixmapChangedCommandType = QMetaType::type("PixmapChangedCommand"); static const int pixmapChangedCommandType = QMetaType::type("PixmapChangedCommand");
static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand"); static const int childrenChangedCommandType = QMetaType::type("ChildrenChangedCommand");
static const int statePreviewImageChangedCommandType = QMetaType::type("StatePreviewImageChangedCommand"); static const int statePreviewImageChangedCommandType = QMetaType::type("StatePreviewImageChangedCommand");
@@ -278,6 +280,7 @@ void NodeInstanceServerProxy::dispatchCommand(const QVariant &command, PuppetStr
static const int tokenCommandType = QMetaType::type("TokenCommand"); static const int tokenCommandType = QMetaType::type("TokenCommand");
static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand"); static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
static const int puppetAliveCommandType = QMetaType::type("PuppetAliveCommand"); static const int puppetAliveCommandType = QMetaType::type("PuppetAliveCommand");
static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand");
if (m_destructing) if (m_destructing)
return; return;
@@ -287,6 +290,8 @@ void NodeInstanceServerProxy::dispatchCommand(const QVariant &command, PuppetStr
nodeInstanceClient()->informationChanged(command.value<InformationChangedCommand>()); nodeInstanceClient()->informationChanged(command.value<InformationChangedCommand>());
} else if (command.userType() == valuesChangedCommandType) { } else if (command.userType() == valuesChangedCommandType) {
nodeInstanceClient()->valuesChanged(command.value<ValuesChangedCommand>()); nodeInstanceClient()->valuesChanged(command.value<ValuesChangedCommand>());
} else if (command.userType() == valuesModifiedCommandType) {
nodeInstanceClient()->valuesModified(command.value<ValuesModifiedCommand>());
} else if (command.userType() == pixmapChangedCommandType) { } else if (command.userType() == pixmapChangedCommandType) {
nodeInstanceClient()->pixmapChanged(command.value<PixmapChangedCommand>()); nodeInstanceClient()->pixmapChanged(command.value<PixmapChangedCommand>());
} else if (command.userType() == childrenChangedCommandType) { } else if (command.userType() == childrenChangedCommandType) {
@@ -299,6 +304,8 @@ void NodeInstanceServerProxy::dispatchCommand(const QVariant &command, PuppetStr
nodeInstanceClient()->token(command.value<TokenCommand>()); nodeInstanceClient()->token(command.value<TokenCommand>());
} else if (command.userType() == debugOutputCommandType) { } else if (command.userType() == debugOutputCommandType) {
nodeInstanceClient()->debugOutput(command.value<DebugOutputCommand>()); nodeInstanceClient()->debugOutput(command.value<DebugOutputCommand>());
} else if (command.userType() == changeSelectionCommandType) {
nodeInstanceClient()->selectionChanged(command.value<ChangeSelectionCommand>());
} else if (command.userType() == puppetAliveCommandType) { } else if (command.userType() == puppetAliveCommandType) {
puppetAlive(puppetStreamType); puppetAlive(puppetStreamType);
} else if (command.userType() == synchronizeCommandType) { } else if (command.userType() == synchronizeCommandType) {
@@ -645,6 +652,11 @@ void NodeInstanceServerProxy::removeInstances(const RemoveInstancesCommand &comm
writeCommand(QVariant::fromValue(command)); writeCommand(QVariant::fromValue(command));
} }
void NodeInstanceServerProxy::changeSelection(const ChangeSelectionCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceServerProxy::removeProperties(const RemovePropertiesCommand &command) void NodeInstanceServerProxy::removeProperties(const RemovePropertiesCommand &command)
{ {
writeCommand(QVariant::fromValue(command)); writeCommand(QVariant::fromValue(command));

View File

@@ -71,6 +71,7 @@ public:
void createScene(const CreateSceneCommand &command) override; void createScene(const CreateSceneCommand &command) override;
void clearScene(const ClearSceneCommand &command) override; void clearScene(const ClearSceneCommand &command) override;
void removeInstances(const RemoveInstancesCommand &command) override; void removeInstances(const RemoveInstancesCommand &command) override;
void changeSelection(const ChangeSelectionCommand &command) override;
void removeProperties(const RemovePropertiesCommand &command) override; void removeProperties(const RemovePropertiesCommand &command) override;
void changePropertyBindings(const ChangeBindingsCommand &command) override; void changePropertyBindings(const ChangeBindingsCommand &command) override;
void changePropertyValues(const ChangeValuesCommand &command) override; void changePropertyValues(const ChangeValuesCommand &command) override;

View File

@@ -51,6 +51,7 @@
#include "changeauxiliarycommand.h" #include "changeauxiliarycommand.h"
#include "changebindingscommand.h" #include "changebindingscommand.h"
#include "changeidscommand.h" #include "changeidscommand.h"
#include "changeselectioncommand.h"
#include "changenodesourcecommand.h" #include "changenodesourcecommand.h"
#include "removeinstancescommand.h" #include "removeinstancescommand.h"
#include "removepropertiescommand.h" #include "removepropertiescommand.h"
@@ -1109,6 +1110,21 @@ RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const QLis
return RemoveInstancesCommand(idList); return RemoveInstancesCommand(idList);
} }
ChangeSelectionCommand NodeInstanceView::createChangeSelectionCommand(const QList<ModelNode> &nodeList) const
{
QVector<qint32> idList;
foreach (const ModelNode &node, nodeList) {
if (node.isValid() && hasInstanceForModelNode(node)) {
NodeInstance instance = instanceForModelNode(node);
if (instance.instanceId() >= 0)
idList.append(instance.instanceId());
}
}
return ChangeSelectionCommand(idList);
}
RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const ModelNode &node) const RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const ModelNode &node) const
{ {
QVector<qint32> idList; QVector<qint32> idList;
@@ -1174,6 +1190,20 @@ void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command)
emitInstancePropertyChange(valuePropertyChangeList); emitInstancePropertyChange(valuePropertyChangeList);
} }
void NodeInstanceView::valuesModified(const ValuesModifiedCommand &command)
{
if (!model())
return;
for (const PropertyValueContainer &container : command.valueChanges()) {
if (hasInstanceForId(container.instanceId())) {
NodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid())
instance.modelNode().variantProperty(container.name()).setValue(container.value());
}
}
}
void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command) void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
{ {
if (!model()) if (!model())
@@ -1364,6 +1394,20 @@ void NodeInstanceView::sendToken(const QString &token, int number, const QVector
nodeInstanceServer()->token(TokenCommand(token, number, instanceIdVector)); nodeInstanceServer()->token(TokenCommand(token, number, instanceIdVector));
} }
void NodeInstanceView::selectionChanged(const ChangeSelectionCommand &command)
{
foreach (const qint32 &instanceId, command.instanceIds()) {
if (hasModelNodeForInternalId(instanceId))
selectModelNode(modelNodeForInternalId(instanceId));
}
}
void NodeInstanceView::selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
const QList<ModelNode> & /*lastSelectedNodeList*/)
{
nodeInstanceServer()->changeSelection(createChangeSelectionCommand(selectedNodeList));
}
void NodeInstanceView::timerEvent(QTimerEvent *event) void NodeInstanceView::timerEvent(QTimerEvent *event)
{ {
if (m_restartProcessTimerId == event->timerId()) if (m_restartProcessTimerId == event->timerId())

View File

@@ -464,14 +464,11 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
#ifndef QMLDESIGNER_TEST #ifndef QMLDESIGNER_TEST
view = QmlDesignerPlugin::instance()->viewManager().nodeInstanceView(); view = QmlDesignerPlugin::instance()->viewManager().nodeInstanceView();
view->emitCustomNotification("PuppetStatus", {}, {QVariant(m_qrcMapping)}); view->emitCustomNotification("PuppetStatus", {}, {QVariant(m_qrcMapping)});
#endif
QStringList importPaths = m_model->importPaths();
QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick3D", "1.0"); QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick3D", "1.0");
bool view3DEnabled = false; bool view3DEnabled = false;
if (view && m_model->hasImport(import, true, true)) { if (m_model->hasImport(import, true, true)) {
if (view->rootModelNode().hasAuxiliaryData("3d-view")) if (view->rootModelNode().hasAuxiliaryData("3d-view"))
view3DEnabled = view->rootModelNode().auxiliaryData("3d-view").toBool(); view3DEnabled = view->rootModelNode().auxiliaryData("3d-view").toBool();
else else
@@ -480,6 +477,9 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
if (view3DEnabled) if (view3DEnabled)
environment.set("QMLDESIGNER_QUICK3D_MODE", "true"); environment.set("QMLDESIGNER_QUICK3D_MODE", "true");
#endif
QStringList importPaths = m_model->importPaths();
/* For the fallback puppet we have to remove the path to the original qtbase plugins to avoid conflics */ /* For the fallback puppet we have to remove the path to the original qtbase plugins to avoid conflics */
if (m_availablePuppetType == FallbackPuppet) if (m_availablePuppetType == FallbackPuppet)

View File

@@ -1464,6 +1464,10 @@ void ModelPrivate::changeSelectedNodes(const QList<InternalNode::Pointer> &newSe
Q_ASSERT(view != nullptr); Q_ASSERT(view != nullptr);
view->selectedNodesChanged(toModelNodeList(newSelectedNodeList, view.data()), toModelNodeList(oldSelectedNodeList, view.data())); view->selectedNodesChanged(toModelNodeList(newSelectedNodeList, view.data()), toModelNodeList(oldSelectedNodeList, view.data()));
} }
if (nodeInstanceView())
nodeInstanceView()->selectedNodesChanged(toModelNodeList(newSelectedNodeList, nodeInstanceView()),
toModelNodeList(oldSelectedNodeList, nodeInstanceView()));
} }
QList<InternalNode::Pointer> ModelPrivate::selectedNodes() const QList<InternalNode::Pointer> ModelPrivate::selectedNodes() const

View File

@@ -424,6 +424,7 @@ void DocumentManager::findPathToIsoProFile(bool *iconResourceFileAlreadyExists,
if (!iconQrcFileNode) { if (!iconQrcFileNode) {
// The QRC file that we want doesn't exist or is not listed under RESOURCES in the .pro. // The QRC file that we want doesn't exist or is not listed under RESOURCES in the .pro.
if (project)
*resourceFilePath = project->projectDirectory().toString() + "/" + isoIconsQrcFile; *resourceFilePath = project->projectDirectory().toString() + "/" + isoIconsQrcFile;
// We assume that the .pro containing the QML file is an acceptable place to add the .qrc file. // We assume that the .pro containing the QML file is an acceptable place to add the .qrc file.

View File

@@ -167,6 +167,8 @@ Project {
"commands/tokencommand.h", "commands/tokencommand.h",
"commands/valueschangedcommand.cpp", "commands/valueschangedcommand.cpp",
"commands/valueschangedcommand.h", "commands/valueschangedcommand.h",
"commands/changeselectioncommand.cpp",
"commands/changeselectioncommand.h",
"container/addimportcontainer.cpp", "container/addimportcontainer.cpp",
"container/addimportcontainer.h", "container/addimportcontainer.h",
"container/idcontainer.cpp", "container/idcontainer.cpp",

View File

@@ -77,7 +77,10 @@ QnxDeployQtLibrariesDialog::QnxDeployQtLibrariesDialog(const IDevice::ConstPtr &
connect(m_uploadService, &AbstractRemoteLinuxDeployService::errorMessage, connect(m_uploadService, &AbstractRemoteLinuxDeployService::errorMessage,
m_ui->deployLogWindow, &QPlainTextEdit::appendPlainText); m_ui->deployLogWindow, &QPlainTextEdit::appendPlainText);
connect(m_uploadService, &AbstractRemoteLinuxDeployService::warningMessage, connect(m_uploadService, &AbstractRemoteLinuxDeployService::warningMessage,
m_ui->deployLogWindow, &QPlainTextEdit::appendPlainText); this, [this](const QString &message) {
if (!message.contains("stat:"))
m_ui->deployLogWindow->appendPlainText(message);
});
connect(m_uploadService, &AbstractRemoteLinuxDeployService::stdOutData, connect(m_uploadService, &AbstractRemoteLinuxDeployService::stdOutData,
m_ui->deployLogWindow, &QPlainTextEdit::appendPlainText); m_ui->deployLogWindow, &QPlainTextEdit::appendPlainText);
connect(m_uploadService, &AbstractRemoteLinuxDeployService::stdErrData, connect(m_uploadService, &AbstractRemoteLinuxDeployService::stdErrData,

View File

@@ -45,13 +45,13 @@
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QDebug>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QLoggingCategory>
#include <QSettings> #include <QSettings>
#include <QStandardPaths> #include <QStandardPaths>
#include <QTextStream>
#include <QStringList> #include <QStringList>
#include <QTextStream>
#include <QTimer> #include <QTimer>
using namespace Utils; using namespace Utils;
@@ -65,7 +65,8 @@ const char QTVERSION_TYPE_KEY[] = "QtVersion.Type";
const char QTVERSION_FILE_VERSION_KEY[] = "Version"; const char QTVERSION_FILE_VERSION_KEY[] = "Version";
const char QTVERSION_FILENAME[] = "/qtversion.xml"; const char QTVERSION_FILENAME[] = "/qtversion.xml";
static QMap<int, BaseQtVersion *> m_versions; using VersionMap = QMap<int, BaseQtVersion *>;
static VersionMap m_versions;
static int m_idcount = 0; static int m_idcount = 0;
// managed by QtProjectManagerPlugin // managed by QtProjectManagerPlugin
static QtVersionManager *m_instance = nullptr; static QtVersionManager *m_instance = nullptr;
@@ -73,7 +74,7 @@ static FileSystemWatcher *m_configFileWatcher = nullptr;
static QTimer *m_fileWatcherTimer = nullptr; static QTimer *m_fileWatcherTimer = nullptr;
static PersistentSettingsWriter *m_writer = nullptr; static PersistentSettingsWriter *m_writer = nullptr;
enum { debug = 0 }; static Q_LOGGING_CATEGORY(log, "qtc.qt.versions", QtWarningMsg);
static FilePath globalSettingsFileName() static FilePath globalSettingsFileName()
{ {
@@ -94,8 +95,9 @@ bool qtVersionNumberCompare(BaseQtVersion *a, BaseQtVersion *b)
static bool restoreQtVersions(); static bool restoreQtVersions();
static void findSystemQt(); static void findSystemQt();
static void saveQtVersions(); static void saveQtVersions();
static void updateDocumentation(); static void updateDocumentation(const QList<BaseQtVersion *> &added,
const QList<BaseQtVersion *> &removed = {},
const QList<BaseQtVersion *> &allNew = {});
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// QtVersionManager // QtVersionManager
@@ -143,7 +145,7 @@ void QtVersionManager::triggerQtVersionRestore()
FileSystemWatcher::WatchModifiedDate); FileSystemWatcher::WatchModifiedDate);
} // exists } // exists
updateDocumentation(); updateDocumentation(m_versions.values());
} }
bool QtVersionManager::isLoaded() bool QtVersionManager::isLoaded()
@@ -172,24 +174,24 @@ QtVersionManager *QtVersionManager::instance()
static bool restoreQtVersions() static bool restoreQtVersions()
{ {
QTC_ASSERT(!m_writer, return false); QTC_ASSERT(!m_writer, return false);
m_writer = new PersistentSettingsWriter(settingsFileName(QLatin1String(QTVERSION_FILENAME)), m_writer = new PersistentSettingsWriter(settingsFileName(QTVERSION_FILENAME),
QLatin1String("QtCreatorQtVersions")); "QtCreatorQtVersions");
const QList<QtVersionFactory *> factories = QtVersionFactory::allQtVersionFactories(); const QList<QtVersionFactory *> factories = QtVersionFactory::allQtVersionFactories();
PersistentSettingsReader reader; PersistentSettingsReader reader;
FilePath filename = settingsFileName(QLatin1String(QTVERSION_FILENAME)); const FilePath filename = settingsFileName(QTVERSION_FILENAME);
if (!reader.load(filename)) if (!reader.load(filename))
return false; return false;
QVariantMap data = reader.restoreValues(); QVariantMap data = reader.restoreValues();
// Check version: // Check version:
int version = data.value(QLatin1String(QTVERSION_FILE_VERSION_KEY), 0).toInt(); const int version = data.value(QTVERSION_FILE_VERSION_KEY, 0).toInt();
if (version < 1) if (version < 1)
return false; return false;
const QString keyPrefix = QLatin1String(QTVERSION_DATA_KEY); const QString keyPrefix(QTVERSION_DATA_KEY);
const QVariantMap::ConstIterator dcend = data.constEnd(); const QVariantMap::ConstIterator dcend = data.constEnd();
for (QVariantMap::ConstIterator it = data.constBegin(); it != dcend; ++it) { for (QVariantMap::ConstIterator it = data.constBegin(); it != dcend; ++it) {
const QString &key = it.key(); const QString &key = it.key();
@@ -201,7 +203,7 @@ static bool restoreQtVersions()
continue; continue;
const QVariantMap qtversionMap = it.value().toMap(); const QVariantMap qtversionMap = it.value().toMap();
const QString type = qtversionMap.value(QLatin1String(QTVERSION_TYPE_KEY)).toString(); const QString type = qtversionMap.value(QTVERSION_TYPE_KEY).toString();
bool restored = false; bool restored = false;
for (QtVersionFactory *f : factories) { for (QtVersionFactory *f : factories) {
@@ -251,19 +253,19 @@ void QtVersionManager::updateFromInstaller(bool emitSignal)
if (reader.load(path)) if (reader.load(path))
data = reader.restoreValues(); data = reader.restoreValues();
if (debug) { if (log().isDebugEnabled()) {
qDebug()<< "======= Existing Qt versions ======="; qCDebug(log) << "======= Existing Qt versions =======";
foreach (BaseQtVersion *version, m_versions) { for (BaseQtVersion *version : qAsConst(m_versions)) {
qDebug() << version->qmakeCommand().toString() << "id:"<<version->uniqueId(); qCDebug(log) << version->qmakeCommand().toString() << "id:"<<version->uniqueId();
qDebug() << " autodetection source:"<< version->autodetectionSource(); qCDebug(log) << " autodetection source:"<< version->autodetectionSource();
qDebug() << ""; qCDebug(log) << "";
} }
qDebug()<< "======= Adding sdk versions ======="; qCDebug(log)<< "======= Adding sdk versions =======";
} }
QStringList sdkVersions; QStringList sdkVersions;
const QString keyPrefix = QLatin1String(QTVERSION_DATA_KEY); const QString keyPrefix(QTVERSION_DATA_KEY);
const QVariantMap::ConstIterator dcend = data.constEnd(); const QVariantMap::ConstIterator dcend = data.constEnd();
for (QVariantMap::ConstIterator it = data.constBegin(); it != dcend; ++it) { for (QVariantMap::ConstIterator it = data.constBegin(); it != dcend; ++it) {
const QString &key = it.key(); const QString &key = it.key();
@@ -275,30 +277,29 @@ void QtVersionManager::updateFromInstaller(bool emitSignal)
continue; continue;
QVariantMap qtversionMap = it.value().toMap(); QVariantMap qtversionMap = it.value().toMap();
const QString type = qtversionMap.value(QLatin1String(QTVERSION_TYPE_KEY)).toString(); const QString type = qtversionMap.value(QTVERSION_TYPE_KEY).toString();
const QString autoDetectionSource = qtversionMap.value(QLatin1String("autodetectionSource")).toString(); const QString autoDetectionSource = qtversionMap.value("autodetectionSource").toString();
sdkVersions << autoDetectionSource; sdkVersions << autoDetectionSource;
int id = -1; // see BaseQtVersion::fromMap() int id = -1; // see BaseQtVersion::fromMap()
QtVersionFactory *factory = nullptr; QtVersionFactory *factory = nullptr;
foreach (QtVersionFactory *f, factories) { for (QtVersionFactory *f : factories) {
if (f->canRestore(type)) if (f->canRestore(type))
factory = f; factory = f;
} }
if (!factory) { if (!factory) {
if (debug) qCDebug(log, "Warning: Unable to find factory for type '%s'", qPrintable(type));
qDebug("Warning: Unable to find factory for type '%s'", qPrintable(type));
continue; continue;
} }
// First try to find a existing Qt version to update // First try to find a existing Qt version to update
bool restored = false; bool restored = false;
foreach (BaseQtVersion *v, m_versions) { const VersionMap versionsCopy = m_versions; // m_versions is modified in loop
for (BaseQtVersion *v : versionsCopy) {
if (v->autodetectionSource() == autoDetectionSource) { if (v->autodetectionSource() == autoDetectionSource) {
id = v->uniqueId(); id = v->uniqueId();
if (debug) qCDebug(log) << " Qt version found with same autodetection source" << autoDetectionSource << " => Migrating id:" << id;
qDebug() << " Qt version found with same autodetection source" << autoDetectionSource << " => Migrating id:" << id;
m_versions.remove(id); m_versions.remove(id);
qtversionMap[QLatin1String(Constants::QTVERSIONID)] = id; qtversionMap[Constants::QTVERSIONID] = id;
qtversionMap[QLatin1String(Constants::QTVERSIONNAME)] = v->unexpandedDisplayName(); qtversionMap[Constants::QTVERSIONNAME] = v->unexpandedDisplayName();
delete v; delete v;
if (BaseQtVersion *qtv = factory->restore(type, qtversionMap)) { if (BaseQtVersion *qtv = factory->restore(type, qtversionMap)) {
@@ -314,8 +315,7 @@ void QtVersionManager::updateFromInstaller(bool emitSignal)
} }
// Create a new qtversion // Create a new qtversion
if (!restored) { // didn't replace any existing versions if (!restored) { // didn't replace any existing versions
if (debug) qCDebug(log) << " No Qt version found matching" << autoDetectionSource << " => Creating new version";
qDebug() << " No Qt version found matching" << autoDetectionSource << " => Creating new version";
if (BaseQtVersion *qtv = factory->restore(type, qtversionMap)) { if (BaseQtVersion *qtv = factory->restore(type, qtversionMap)) {
Q_ASSERT(qtv->isAutodetected()); Q_ASSERT(qtv->isAutodetected());
m_versions.insert(qtv->uniqueId(), qtv); m_versions.insert(qtv->uniqueId(), qtv);
@@ -323,37 +323,37 @@ void QtVersionManager::updateFromInstaller(bool emitSignal)
restored = true; restored = true;
} }
} }
if (!restored) if (!restored) {
if (debug) qCDebug(log, "Warning: Unable to update qtversion '%s' from sdk installer.",
qDebug("Warning: Unable to update qtversion '%s' from sdk installer.",
qPrintable(autoDetectionSource)); qPrintable(autoDetectionSource));
} }
}
if (debug) { if (log().isDebugEnabled()) {
qDebug() << "======= Before removing outdated sdk versions ======="; qCDebug(log) << "======= Before removing outdated sdk versions =======";
foreach (BaseQtVersion *version, m_versions) { for (BaseQtVersion *version : qAsConst(m_versions)) {
qDebug() << version->qmakeCommand().toString() << "id:"<<version->uniqueId(); qCDebug(log) << version->qmakeCommand().toString() << "id:"<<version->uniqueId();
qDebug() << " autodetection source:"<< version->autodetectionSource(); qCDebug(log) << " autodetection source:"<< version->autodetectionSource();
qDebug() << ""; qCDebug(log) << "";
} }
} }
foreach (BaseQtVersion *qtVersion, m_versions) { const VersionMap versionsCopy = m_versions; // m_versions is modified in loop
if (qtVersion->autodetectionSource().startsWith(QLatin1String("SDK."))) { for (BaseQtVersion *qtVersion : versionsCopy) {
if (qtVersion->autodetectionSource().startsWith("SDK.")) {
if (!sdkVersions.contains(qtVersion->autodetectionSource())) { if (!sdkVersions.contains(qtVersion->autodetectionSource())) {
if (debug) qCDebug(log) << " removing version"<<qtVersion->autodetectionSource();
qDebug() << " removing version"<<qtVersion->autodetectionSource();
m_versions.remove(qtVersion->uniqueId()); m_versions.remove(qtVersion->uniqueId());
removed << qtVersion->uniqueId(); removed << qtVersion->uniqueId();
} }
} }
} }
if (debug) { if (log().isDebugEnabled()) {
qDebug()<< "======= End result ======="; qCDebug(log)<< "======= End result =======";
foreach (BaseQtVersion *version, m_versions) { for (BaseQtVersion *version : qAsConst(m_versions)) {
qDebug() << version->qmakeCommand().toString() << "id:"<<version->uniqueId(); qCDebug(log) << version->qmakeCommand().toString() << "id:" << version->uniqueId();
qDebug() << " autodetection source:"<< version->autodetectionSource(); qCDebug(log) << " autodetection source:"<< version->autodetectionSource();
qDebug() << ""; qCDebug(log) << "";
} }
} }
if (emitSignal) if (emitSignal)
@@ -366,17 +366,16 @@ static void saveQtVersions()
return; return;
QVariantMap data; QVariantMap data;
data.insert(QLatin1String(QTVERSION_FILE_VERSION_KEY), 1); data.insert(QTVERSION_FILE_VERSION_KEY, 1);
int count = 0; int count = 0;
foreach (BaseQtVersion *qtv, m_versions) { for (BaseQtVersion *qtv : qAsConst(m_versions)) {
QVariantMap tmp = qtv->toMap(); QVariantMap tmp = qtv->toMap();
if (tmp.isEmpty()) if (tmp.isEmpty())
continue; continue;
tmp.insert(QLatin1String(QTVERSION_TYPE_KEY), qtv->type()); tmp.insert(QTVERSION_TYPE_KEY, qtv->type());
data.insert(QString::fromLatin1(QTVERSION_DATA_KEY) + QString::number(count), tmp); data.insert(QString::fromLatin1(QTVERSION_DATA_KEY) + QString::number(count), tmp);
++count; ++count;
} }
m_writer->save(data, Core::ICore::mainWindow()); m_writer->save(data, Core::ICore::mainWindow());
} }
@@ -394,10 +393,10 @@ static QList<QByteArray> runQtChooser(const QString &qtchooser, const QStringLis
// Asks qtchooser for the qmake path of a given version // Asks qtchooser for the qmake path of a given version
static QString qmakePath(const QString &qtchooser, const QString &version) static QString qmakePath(const QString &qtchooser, const QString &version)
{ {
QList<QByteArray> outputs = runQtChooser(qtchooser, QStringList() const QList<QByteArray> outputs = runQtChooser(qtchooser,
<< QStringLiteral("-qt=%1").arg(version) {QStringLiteral("-qt=%1").arg(version),
<< QStringLiteral("-print-env")); QStringLiteral("-print-env")});
foreach (const QByteArray &output, outputs) { for (const QByteArray &output : outputs) {
if (output.startsWith("QTTOOLDIR=\"")) { if (output.startsWith("QTTOOLDIR=\"")) {
QByteArray withoutVarName = output.mid(11); // remove QTTOOLDIR=" QByteArray withoutVarName = output.mid(11); // remove QTTOOLDIR="
withoutVarName.chop(1); // remove trailing quote withoutVarName.chop(1); // remove trailing quote
@@ -414,9 +413,9 @@ static FilePathList gatherQmakePathsFromQtChooser()
if (qtchooser.isEmpty()) if (qtchooser.isEmpty())
return FilePathList(); return FilePathList();
QList<QByteArray> versions = runQtChooser(qtchooser, QStringList("-l")); const QList<QByteArray> versions = runQtChooser(qtchooser, QStringList("-l"));
QSet<FilePath> foundQMakes; QSet<FilePath> foundQMakes;
foreach (const QByteArray &version, versions) { for (const QByteArray &version : versions) {
FilePath possibleQMake = FilePath::fromString( FilePath possibleQMake = FilePath::fromString(
qmakePath(qtchooser, QString::fromLocal8Bit(version))); qmakePath(qtchooser, QString::fromLocal8Bit(version)));
if (!possibleQMake.isEmpty()) if (!possibleQMake.isEmpty())
@@ -432,9 +431,11 @@ static void findSystemQt()
systemQMakes.append(gatherQmakePathsFromQtChooser()); systemQMakes.append(gatherQmakePathsFromQtChooser());
foreach (const FilePath &qmakePath, Utils::filteredUnique(systemQMakes)) { const FilePathList uniqueSystemQmakes = Utils::filteredUnique(systemQMakes);
BaseQtVersion *version for (const FilePath &qmakePath : uniqueSystemQmakes) {
= QtVersionFactory::createQtVersionFromQMakePath(qmakePath, false, QLatin1String("PATH")); BaseQtVersion *version = QtVersionFactory::createQtVersionFromQMakePath(qmakePath,
false,
"PATH");
if (version) if (version)
m_versions.insert(version->uniqueId(), version); m_versions.insert(version->uniqueId(), version);
} }
@@ -463,20 +464,37 @@ void QtVersionManager::removeVersion(BaseQtVersion *version)
delete version; delete version;
} }
static void updateDocumentation() static QStringList documentationFiles(BaseQtVersion *v)
{ {
QStringList files; QStringList files;
foreach (BaseQtVersion *v, m_versions) {
const QStringList docPaths = QStringList( const QStringList docPaths = QStringList(
{v->docsPath().toString() + QChar('/'), v->docsPath().toString() + "/qch/"}); {v->docsPath().toString() + QChar('/'), v->docsPath().toString() + "/qch/"});
foreach (const QString &docPath, docPaths) { for (const QString &docPath : docPaths) {
const QDir versionHelpDir(docPath); const QDir versionHelpDir(docPath);
foreach (const QString &helpFile, for (const QString &helpFile : versionHelpDir.entryList(QStringList("*.qch"), QDir::Files))
versionHelpDir.entryList(QStringList("*.qch"), QDir::Files)) files.append(docPath + helpFile);
files << docPath + helpFile;
} }
} return files;
Core::HelpManager::registerDocumentation(files); }
static QStringList documentationFiles(const QList<BaseQtVersion *> &vs)
{
QStringList files;
for (BaseQtVersion *v : vs)
files += documentationFiles(v);
return files;
}
static void updateDocumentation(const QList<BaseQtVersion *> &added,
const QList<BaseQtVersion *> &removed,
const QList<BaseQtVersion *> &allNew)
{
const QStringList docsOfAll = documentationFiles(allNew);
const QStringList docsToRemove = Utils::filtered(documentationFiles(removed),
[&docsOfAll](const QString &f) {
return !docsOfAll.contains(f);
});
Core::HelpManager::unregisterDocumentation(docsToRemove);
Core::HelpManager::registerDocumentation(documentationFiles(added));
} }
int QtVersionManager::getUniqueId() int QtVersionManager::getUniqueId()
@@ -490,7 +508,6 @@ QList<BaseQtVersion *> QtVersionManager::versions(const BaseQtVersion::Predicate
QTC_ASSERT(isLoaded(), return versions); QTC_ASSERT(isLoaded(), return versions);
if (predicate) if (predicate)
return Utils::filtered(m_versions.values(), predicate); return Utils::filtered(m_versions.values(), predicate);
else
return m_versions.values(); return m_versions.values();
} }
@@ -504,7 +521,7 @@ QList<BaseQtVersion *> QtVersionManager::sortVersions(const QList<BaseQtVersion
BaseQtVersion *QtVersionManager::version(int id) BaseQtVersion *QtVersionManager::version(int id)
{ {
QTC_ASSERT(isLoaded(), return nullptr); QTC_ASSERT(isLoaded(), return nullptr);
QMap<int, BaseQtVersion *>::const_iterator it = m_versions.constFind(id); VersionMap::const_iterator it = m_versions.constFind(id);
if (it == m_versions.constEnd()) if (it == m_versions.constEnd())
return nullptr; return nullptr;
return it.value(); return it.value();
@@ -521,22 +538,22 @@ static bool equals(BaseQtVersion *a, BaseQtVersion *b)
return a->equals(b); return a->equals(b);
} }
void QtVersionManager::setNewQtVersions(QList<BaseQtVersion *> newVersions) void QtVersionManager::setNewQtVersions(const QList<BaseQtVersion *> &newVersions)
{ {
// We want to preserve the same order as in the settings dialog // We want to preserve the same order as in the settings dialog
// so we sort a copy // so we sort a copy
QList<BaseQtVersion *> sortedNewVersions = newVersions; QList<BaseQtVersion *> sortedNewVersions = newVersions;
Utils::sort(sortedNewVersions, &BaseQtVersion::uniqueId); Utils::sort(sortedNewVersions, &BaseQtVersion::uniqueId);
QList<int> addedVersions; QList<BaseQtVersion *> addedVersions;
QList<int> removedVersions; QList<BaseQtVersion *> removedVersions;
QList<int> changedVersions; QList<std::pair<BaseQtVersion *, BaseQtVersion *>> changedVersions;
// So we trying to find the minimal set of changed versions, // So we trying to find the minimal set of changed versions,
// iterate over both sorted list // iterate over both sorted list
// newVersions and oldVersions iterator // newVersions and oldVersions iterator
QList<BaseQtVersion *>::const_iterator nit, nend; QList<BaseQtVersion *>::const_iterator nit, nend;
QMap<int, BaseQtVersion *>::const_iterator oit, oend; VersionMap::const_iterator oit, oend;
nit = sortedNewVersions.constBegin(); nit = sortedNewVersions.constBegin();
nend = sortedNewVersions.constEnd(); nend = sortedNewVersions.constEnd();
oit = m_versions.constBegin(); oit = m_versions.constBegin();
@@ -546,41 +563,54 @@ void QtVersionManager::setNewQtVersions(QList<BaseQtVersion *> newVersions)
int nid = (*nit)->uniqueId(); int nid = (*nit)->uniqueId();
int oid = (*oit)->uniqueId(); int oid = (*oit)->uniqueId();
if (nid < oid) { if (nid < oid) {
addedVersions.push_back(nid); addedVersions.push_back(*nit);
++nit; ++nit;
} else if (oid < nid) { } else if (oid < nid) {
removedVersions.push_back(oid); removedVersions.push_back(*oit);
++oit; ++oit;
} else { } else {
if (!equals(*oit, *nit)) if (!equals(*oit, *nit))
changedVersions.push_back(oid); changedVersions.push_back({*oit, *nit});
++oit; ++oit;
++nit; ++nit;
} }
} }
while (nit != nend) { while (nit != nend) {
addedVersions.push_back((*nit)->uniqueId()); addedVersions.push_back(*nit);
++nit; ++nit;
} }
while (oit != oend) { while (oit != oend) {
removedVersions.push_back((*oit)->uniqueId()); removedVersions.push_back(*oit);
++oit; ++oit;
} }
if (!changedVersions.isEmpty() || !addedVersions.isEmpty() || !removedVersions.isEmpty()) {
const QList<BaseQtVersion *> changedOldVersions
= Utils::transform(changedVersions, &std::pair<BaseQtVersion *, BaseQtVersion *>::first);
const QList<BaseQtVersion *> changedNewVersions
= Utils::transform(changedVersions,
&std::pair<BaseQtVersion *, BaseQtVersion *>::second);
updateDocumentation(addedVersions + changedNewVersions,
removedVersions + changedOldVersions,
sortedNewVersions);
}
const QList<int> addedIds = Utils::transform(addedVersions, &BaseQtVersion::uniqueId);
const QList<int> removedIds = Utils::transform(removedVersions, &BaseQtVersion::uniqueId);
const QList<int> changedIds = Utils::transform(changedVersions,
[](std::pair<BaseQtVersion *, BaseQtVersion *> v) {
return v.first->uniqueId();
});
qDeleteAll(m_versions); qDeleteAll(m_versions);
m_versions.clear(); m_versions = Utils::transform<VersionMap>(sortedNewVersions, [](BaseQtVersion *v) {
foreach (BaseQtVersion *v, sortedNewVersions) return std::make_pair(v->uniqueId(), v);
m_versions.insert(v->uniqueId(), v); });
if (!changedVersions.isEmpty() || !addedVersions.isEmpty() || !removedVersions.isEmpty())
updateDocumentation();
saveQtVersions(); saveQtVersions();
if (!changedVersions.isEmpty() || !addedVersions.isEmpty() || !removedVersions.isEmpty()) if (!changedVersions.isEmpty() || !addedVersions.isEmpty() || !removedVersions.isEmpty())
emit m_instance->qtVersionsChanged(addedVersions, removedVersions, changedVersions); emit m_instance->qtVersionsChanged(addedIds, removedIds, changedIds);
} }
} // namespace QtVersion } // namespace QtVersion

View File

@@ -73,7 +73,7 @@ private:
void triggerQtVersionRestore(); void triggerQtVersionRestore();
// Used by QtOptionsPage // Used by QtOptionsPage
static void setNewQtVersions(QList<BaseQtVersion *> newVersions); static void setNewQtVersions(const QList<BaseQtVersion *> &newVersions);
// Used by QtVersion // Used by QtVersion
static int getUniqueId(); static int getUniqueId();
}; };

View File

@@ -91,7 +91,7 @@ static ProjectExplorer::Abi toolChainAbi()
}; };
} }
void WebAssemblyToolChain::addToEnvironment(Utils::Environment &env) const static void addEmscriptenToEnvironment(Utils::Environment &env)
{ {
const CompilerConfiguration configuration = compilerConfiguration(); const CompilerConfiguration configuration = compilerConfiguration();
@@ -113,6 +113,25 @@ void WebAssemblyToolChain::addToEnvironment(Utils::Environment &env) const
env.set("EMSCRIPTEN", configuration.emScripten.toUserOutput()); env.set("EMSCRIPTEN", configuration.emScripten.toUserOutput());
} }
static void addRegisteredMinGWToEnvironment(Utils::Environment &env)
{
using namespace ProjectExplorer;
const ToolChain *toolChain = ToolChainManager::toolChain([](const ToolChain *t){
return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID;
});
if (toolChain) {
const QString mingwPath = toolChain->compilerCommand().parentDir().toUserOutput();
env.appendOrSetPath(mingwPath);
}
}
void WebAssemblyToolChain::addToEnvironment(Utils::Environment &env) const
{
addEmscriptenToEnvironment(env);
if (Utils::HostOsInfo::isWindowsHost())
addRegisteredMinGWToEnvironment(env);
}
WebAssemblyToolChain::WebAssemblyToolChain() : WebAssemblyToolChain::WebAssemblyToolChain() :
ClangToolChain(Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID) ClangToolChain(Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID)
{ {

View File

@@ -32,16 +32,7 @@
#if defined __cplusplus #if defined __cplusplus
#include <QEvent> #include <QtGui>
#include <QTimer> #include <QtWidgets>
#include <QApplication>
#include <QBitmap>
#include <QCursor>
#include <QImage>
#include <QLayout>
#include <QPainter>
#include <QPixmap>
#include <QStyle>
#include <QWidget>
#endif #endif

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