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}"
RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}"
QT_SKIP_TRANSLATION "${skip_translation}"
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
${_arg_PROPERTIES}
)
append_extra_translations("${name}" "${_arg_EXTRA_TRANSLATIONS}")

View File

@@ -1,9 +1,9 @@
#BINARY_ARTIFACTS_BRANCH = master
#PROJECT_USER_FILE_EXTENSION = .user
set(IDE_VERSION "4.10.82") # The IDE version.
set(IDE_VERSION_COMPAT "4.10.82") # The IDE Compatibility version.
set(IDE_VERSION_DISPLAY "4.11.0-beta1") # The IDE display version.
set(IDE_VERSION "4.10.83") # The IDE version.
set(IDE_VERSION_COMPAT "4.10.83") # The IDE Compatibility 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_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/
**
** This file is part of the Qt Creator documentation.
@@ -28,7 +28,7 @@
\contentspage index.html
\previouspage creator-developing-generic-linux.html
\page creator-developing-ios.html
\nextpage creator-developing-qnx.html
\nextpage creator-developing-mcu.html
\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
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}
You can connect QNX devices to the development PC to deploy, run and

View File

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

View File

@@ -133,6 +133,13 @@
code for a QApplication or create one that contains an
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
\li Libraries

View File

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

View File

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

View File

@@ -4,16 +4,16 @@ import qbs.FileInfo
import "qtc.js" as HelperFunctions
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_minor: '10'
property string ide_version_release: '82'
property string ide_version_release: '83'
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.'
+ ide_version_release
property string ide_compat_version_major: '4'
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 + '.'
+ ide_compat_version_minor + '.' + ide_compat_version_release

View File

@@ -1,8 +1,8 @@
QTCREATOR_VERSION = 4.10.82
QTCREATOR_COMPAT_VERSION = 4.10.82
QTCREATOR_DISPLAY_VERSION = 4.11.0-beta1
QTCREATOR_VERSION = 4.10.83
QTCREATOR_COMPAT_VERSION = 4.10.83
QTCREATOR_DISPLAY_VERSION = 4.11.0-beta2
QTCREATOR_COPYRIGHT_YEAR = 2019
BINARY_ARTIFACTS_BRANCH = master
BINARY_ARTIFACTS_BRANCH = 4.11
IDE_DISPLAY_NAME = Qt Creator
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/removesharedmemorycommand.h
HEADERS += $$PWD/puppetalivecommand.h
HEADERS += $$PWD/changeselectioncommand.h
SOURCES += $$PWD/synchronizecommand.cpp
SOURCES += $$PWD/debugoutputcommand.cpp
@@ -53,3 +54,4 @@ SOURCES += $$PWD/pixmapchangedcommand.cpp
SOURCES += $$PWD/changeauxiliarycommand.cpp
SOURCES += $$PWD/removesharedmemorycommand.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;
}

View File

@@ -42,7 +42,7 @@ public:
ValuesChangedCommand();
explicit ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector);
QVector<PropertyValueContainer> valueChanges() const;
const QVector<PropertyValueContainer> valueChanges() const;
quint32 keyNumber() const;
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);
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
Q_DECLARE_METATYPE(QmlDesigner::ValuesModifiedCommand)
Q_DECLARE_METATYPE(QmlDesigner::ValuesChangedCommand)

View File

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

View File

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

View File

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

View File

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

View File

@@ -49,6 +49,7 @@ class CompleteComponentCommand;
class ChangeNodeSourceCommand;
class TokenCommand;
class RemoveSharedMemoryCommand;
class ChangeSelectionCommand;
class NodeInstanceServerInterface : public QObject
{
@@ -77,6 +78,7 @@ public:
virtual void changeNodeSource(const ChangeNodeSourceCommand &command) = 0;
virtual void token(const TokenCommand &command) = 0;
virtual void removeSharedMemory(const RemoveSharedMemoryCommand &command) = 0;
virtual void changeSelection(const ChangeSelectionCommand &command) = 0;
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 QtQuick3D 1.0
import QtQuick3D.Helpers 1.0
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
Window {
id: viewWindow
width: 1024
height: 768
visible: true
title: "3D"
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 {
color: "black"
id: sceneBg
color: "#FFFFFF"
anchors.fill: parent
}
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
focus: true
View3D {
id: view
id: editView
anchors.fill: parent
enableWireframeMode: true
camera: camera01
camera: editCamera
AxisHelper {
id: axisGrid
enableXZGrid: true
enableAxisLines: false
}
Light {
id: directionalLight
visible: checkBox.checked
id: pointLight
visible: showEditLight
position: editCamera.position
lightType: Light.Point
}
Camera {
id: camera01
z: slider.value
id: editCamera
y: 200
z: -300
clipFar: 100000
projectionMode: usePerspective ? Camera.Perspective : Camera.Orthographic
}
Component.onCompleted: {
directionalLight.setParentItem(view.scene)
camera01.setParentItem(view.scene)
pointLight.setParentItem(editView.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/
qtHaveModule(quick3d) {
QT *= quick3d-private
DEFINES *= QUICK3D_MODULE
}
HEADERS += $$PWD/qt5nodeinstanceserver.h
HEADERS += $$PWD/qt5testnodeinstanceserver.h
HEADERS += $$PWD/qt5informationnodeinstanceserver.h
@@ -23,6 +28,7 @@ HEADERS += $$PWD/anchorchangesnodeinstance.h
HEADERS += $$PWD/positionernodeinstance.h
HEADERS += $$PWD/layoutnodeinstance.h
HEADERS += $$PWD/qt3dpresentationnodeinstance.h
HEADERS += $$PWD/quick3dnodeinstance.h
SOURCES += $$PWD/qt5nodeinstanceserver.cpp
SOURCES += $$PWD/qt5testnodeinstanceserver.cpp
@@ -47,3 +53,4 @@ SOURCES += $$PWD/anchorchangesnodeinstance.cpp
SOURCES += $$PWD/positionernodeinstance.cpp
SOURCES += $$PWD/layoutnodeinstance.cpp
SOURCES += $$PWD/qt3dpresentationnodeinstance.cpp
SOURCES += $$PWD/quick3dnodeinstance.cpp

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -50,6 +50,7 @@ public:
void completeComponent(const CompleteComponentCommand &command) override;
void changeNodeSource(const ChangeNodeSourceCommand &command) override;
void removeSharedMemory(const RemoveSharedMemoryCommand &command) override;
void changeSelection(const ChangeSelectionCommand &command) override;
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 "quickitemnodeinstance.h"
#include "quick3dnodeinstance.h"
#include "nodeinstanceserver.h"
#include "instancecontainer.h"
@@ -170,6 +171,8 @@ Internal::ObjectNodeInstance::Pointer ServerNodeInstance::createInstance(QObject
instance = Internal::LayoutNodeInstance::create(objectToBeWrapped);
else if (isSubclassOf(objectToBeWrapped, "QQuickItem"))
instance = Internal::QuickItemNodeInstance::create(objectToBeWrapped);
else if (isSubclassOf(objectToBeWrapped, "QQuick3DNode"))
instance = Internal::Quick3DNodeInstance::create(objectToBeWrapped);
else if (isSubclassOf(objectToBeWrapped, "QQmlComponent"))
instance = Internal::ComponentNodeInstance::create(objectToBeWrapped);
else if (objectToBeWrapped->inherits("QQmlAnchorChanges"))
@@ -312,6 +315,11 @@ void ServerNodeInstance::setPropertyBinding(const PropertyName &name, const QStr
m_nodeInstance->setPropertyBinding(name, expression);
}
void ServerNodeInstance::setHideInEditor(bool b)
{
m_nodeInstance->setHideInEditor(b);
}
void ServerNodeInstance::resetProperty(const PropertyName &name)
{
m_nodeInstance->resetProperty(name);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -33,6 +33,7 @@
#include <cstring>
#include <iostream>
#include <sstream>
#include <codecvt>
#include <iomanip>
static const char whiteSpace[] = " \t\r\n";
@@ -149,6 +150,11 @@ std::string wStringToString(const std::wstring &w)
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
static inline unsigned hexDigit(char c)
{
@@ -210,6 +216,11 @@ std::string stringFromHex(const char *p, const char *end)
return rc;
}
std::string stringFromHex(const std::string &hexEncoded)
{
return stringFromHex(hexEncoded.c_str(), hexEncoded.c_str() + hexEncoded.size());
}
// Helper for dumping memory
std::string dumpMemory(const unsigned char *p, size_t size,
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::wstring utf8ToUtf16(const std::string &s);
// Strings from raw data.
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".
std::string stringFromHex(const char *begin, const char *end);
std::string stringFromHex(const std::string &hexEncoded);
// Decode hex to a memory area.
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,
int valueEncoding,
const std::string &value,
const SymbolGroupValueContext &ctx,
std::string *errorMessage)
@@ -468,9 +467,9 @@ bool SymbolGroup::assign(const std::string &nodeName,
int kt = node->dumperType();
if (kt < 0)
kt = knownType(node->type(), KnownTypeAutoStripPointer | KnownTypeHasClassPrefix);
return (kt & KT_Editable) ? // Edit complex types
assignType(node, kt, valueEncoding, value, ctx, errorMessage) :
node->assign(value, errorMessage);
if (kt & KT_Editable)
return assignType(node, kt, value, ctx, errorMessage);
return node->assign(value, errorMessage);
}
bool SymbolGroup::accept(SymbolGroupNodeVisitor &visitor) const

View File

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

View File

@@ -1432,10 +1432,11 @@ std::string SymbolGroupNode::msgAssignError(const std::string &nodeName,
}
// 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 =
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 (errorMessage)
*errorMessage = SymbolGroupNode::msgAssignError(name(), value, msgDebugEngineComFailed("WriteSymbol", hr));

View File

@@ -3309,101 +3309,6 @@ static inline std::vector<AbstractSymbolGroupNode *>
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
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
* data and for QByteArray with ASCII data due to the similar member
* names and both using a terminating '\0' w_char/byte. */
template <typename string>
static int assignQStringI(SymbolGroupNode *n, const char *className,
const AssignmentStringData &data,
const string &data,
const SymbolGroupValueContext &ctx,
bool doAlloc = true)
{
@@ -3431,7 +3337,7 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
const QtStringAddressData addressData = readQtStringAddressData(d, qtInfo);
if (!addressData.address)
return 9;
const bool needRealloc = addressData.allocated < data.stringLength;
const bool needRealloc = addressData.allocated < data.size();
if (needRealloc) {
if (!doAlloc) // Calling re-alloc failed somehow.
return 3;
@@ -3439,7 +3345,7 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
const std::string funcName
= qtInfo.prependQtCoreModule(std::string(className) + "::resize");
callStr << funcName << '(' << std::hex << std::showbase
<< v.address() << ',' << data.stringLength << ')';
<< v.address() << ',' << data.size() << ')';
std::wstring wOutput;
std::string errorMessage;
return ExtensionContext::instance().call(callStr.str(), 0, &wOutput, &errorMessage) ?
@@ -3447,8 +3353,8 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
}
// Write data.
if (!SymbolGroupValue::writeMemory(v.context().dataspaces,
addressData.address, data.data,
ULONG(data.dataLength)))
addressData.address, (const unsigned char *)(data.c_str()),
ULONG(data.empty() ? 0 : sizeof(data.front()) * data.size())))
return 11;
// Correct size unless we re-allocated
if (!needRealloc) {
@@ -3460,7 +3366,7 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
const SymbolGroupValue size = dV["size"];
if (!size)
return 16;
if (!size.node()->assign(toString(data.stringLength)))
if (!size.node()->assign(toString(data.size())))
return 17;
}
return 0;
@@ -3468,13 +3374,11 @@ static int assignQStringI(SymbolGroupNode *n, const char *className,
// QString assignment
static inline bool assignQString(SymbolGroupNode *n,
int valueEncoding, const std::string &value,
const std::string &value,
const SymbolGroupValueContext &ctx,
std::string *errorMessage)
{
const AssignmentStringData utf16 = AssignmentStringData::decodeString(value, valueEncoding, true);
const int errorCode = assignQStringI(n, "QString", utf16, ctx);
delete [] utf16.data;
const int errorCode = assignQStringI(n, "QString", utf8ToUtf16(value), ctx);
if (errorCode) {
*errorMessage = msgAssignStringFailed(value, errorCode);
return false;
@@ -3484,13 +3388,11 @@ static inline bool assignQString(SymbolGroupNode *n,
// QByteArray assignment
static inline bool assignQByteArray(SymbolGroupNode *n,
int valueEncoding, const std::string &value,
const std::string &value,
const SymbolGroupValueContext &ctx,
std::string *errorMessage)
{
const AssignmentStringData data = AssignmentStringData::decodeString(value, valueEncoding, false);
const int errorCode = assignQStringI(n, "QByteArray", data, ctx);
delete [] data.data;
const int errorCode = assignQStringI(n, "QByteArray", value, ctx);
if (errorCode) {
*errorMessage = msgAssignStringFailed(value, errorCode);
return false;
@@ -3499,8 +3401,9 @@ static inline bool assignQByteArray(SymbolGroupNode *n,
}
// Helper to assign character data to std::string or std::wstring.
template <typename string>
static inline int assignStdStringI(SymbolGroupNode *n, int type,
const AssignmentStringData &data,
const string &data,
const SymbolGroupValueContext &ctx)
{
/* 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();
if (reserved < 0 || !size || !bx)
return 42;
if (reserved <= (int)data.stringLength)
if (reserved <= (int)data.size())
return 1; // Insufficient memory.
// Copy data: 'Buf' array for small strings, else pointer 'Ptr'.
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)
return 3;
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;
// Correct size
if (!size.node()->assign(toString(data.stringLength)))
if (!size.node()->assign(toString(data.size())))
return 13;
return 0;
}
// assignment of std::string assign via ASCII, std::wstring via UTF16
static inline bool assignStdString(SymbolGroupNode *n,
int type, int valueEncoding, const std::string &value,
int type, const std::string &value,
const SymbolGroupValueContext &ctx,
std::string *errorMessage)
{
const bool toUtf16 = type == KT_StdWString;
const AssignmentStringData data = AssignmentStringData::decodeString(value, valueEncoding,
toUtf16);
const int errorCode = assignStdStringI(n, type, data, ctx);
delete [] data.data;
const int errorCode = type == KT_StdString
? assignStdStringI(n, type, value, ctx)
: assignStdStringI(n, type, utf8ToUtf16(value), ctx);
if (errorCode) {
*errorMessage = msgAssignStringFailed(value, errorCode);
return false;
@@ -3562,17 +3465,17 @@ static inline bool assignStdString(SymbolGroupNode *n,
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)
{
switch (knownType) {
case KT_QString:
return assignQString(n, valueEncoding, value, ctx, errorMessage);
return assignQString(n, value, ctx, errorMessage);
case KT_QByteArray:
return assignQByteArray(n, valueEncoding, value, ctx, errorMessage);
return assignQByteArray(n,value, ctx, errorMessage);
case KT_StdString:
case KT_StdWString:
return assignStdString(n, knownType, valueEncoding, value, ctx, errorMessage);
return assignStdString(n, knownType, value, ctx, errorMessage);
default:
break;
}

View File

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

View File

@@ -78,7 +78,7 @@ static FilePath findQmakeInDir(const FilePath &path)
if (path.isEmpty())
return FilePath();
const QString qmake = "qmake";
const QString qmake = HostOsInfo::withExecutableSuffix("qmake");
QDir dir(path.toString());
if (dir.exists(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()));
}
/// \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
bool FilePath::endsWith(const QString &s) const
{

View File

@@ -97,6 +97,7 @@ public:
bool isChildOf(const FilePath &s) const;
bool isChildOf(const QDir &dir) const;
bool startsWith(const QString &s) const;
bool endsWith(const QString &s) 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 (const QString &target : qAsConst(it.value().internalTargets)) {
BoostTestConfiguration *config = new BoostTestConfiguration;
config->setProject(project);
config->setProjectFile(it.key());
config->setTestCaseCount(it.value().testCases);
config->setInternalTargets(it.value().internalTargets);
config->setInternalTarget(target);
result.append(config);
}
}
return result;
}
@@ -245,13 +247,15 @@ QList<TestConfiguration *> BoostTestTreeItem::getSelectedTestConfigurations() co
auto end = testCasesForProjectFile.cend();
for (auto it = testCasesForProjectFile.cbegin(); it != end; ++it) {
for (const QString &target : it.value().internalTargets) {
BoostTestConfiguration *config = new BoostTestConfiguration;
config->setProject(project);
config->setProjectFile(it.key());
config->setTestCases(it.value().testCases);
config->setInternalTargets(it.value().internalTargets);
config->setInternalTarget(target);
result.append(config);
}
}
return result;
}

View File

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

View File

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

View File

@@ -61,6 +61,7 @@ enum HelpViewerLocation {
CORE_EXPORT QString documentationPath();
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> linksForKeyword(const QString &id);

View File

@@ -39,6 +39,7 @@ protected:
public:
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> linksForKeyword(const QString &keyword) = 0;
virtual QByteArray fileData(const QUrl &url) = 0;

View File

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

View File

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

View File

@@ -140,8 +140,6 @@ QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
addPrecompiledHeaderOptions(usePrecompiledHeaders);
addProjectConfigFileInclude();
addExtraCodeModelFlags();
addMsvcCompatibilityVersion();
addProjectMacros();
undefineClangVersionMacrosForMsvc();
@@ -727,7 +725,8 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
const Core::Id &toolChain = m_projectPart.toolchainType;
bool containsDriverMode = 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) {
skipNext = false;
continue;
@@ -752,6 +751,16 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
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
|| option == includeUserPathOptionWindows) {
skipNext = true;

View File

@@ -93,6 +93,9 @@ QVariant CtfStatisticsModel::data(const QModelIndex &index, int role) const
case Column::AvgDuration:
case Column::MaxDuration:
return Qt::AlignRight;
default:
Q_UNREACHABLE();
return QVariant();
}
case SortRole:
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)
{
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.");
return;
}
QString cmd;
StringInputStream str(cmd);
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});
runCommand({m_extensionCommandPrefix + "assign -h " + w->iname + '=' + toHex(value.toString()),
NoFlags});
// Update all locals in case we change a union or something pointed to
// that affects other variables, too.
updateLocals();

View File

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

View File

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

View File

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

View File

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

View File

@@ -136,8 +136,20 @@ void HelpManager::registerDocumentation(const QStringList &files)
emit Core::HelpManager::Signals::instance()->documentationChanged();
}
});
ProgressManager::addTask(future, tr("Update Documentation"),
kUpdateDocumentationTask);
ProgressManager::addTask(future, tr("Update Documentation"), 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,

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,4 +7,5 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \
coreplugin \
projectexplorer \
debugger \
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 "mcusupportoptionspage.h"
#include "mcusupportoptions.h"
#include <coreplugin/icore.h>
#include <cmakeprojectmanager/cmakekitinformation.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 <QAction>
#include <QComboBox>
#include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QFileInfo>
#include <QFormLayout>
#include <QGroupBox>
#include <QLabel>
#include <QSizePolicy>
#include <QToolButton>
#include <QVBoxLayout>
#include <QVariant>
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 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
{
public:
@@ -559,7 +145,7 @@ McuSupportOptionsPage::McuSupportOptionsPage(QObject* parent)
setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY);
}
QWidget* McuSupportOptionsPage::widget()
QWidget *McuSupportOptionsPage::widget()
{
if (!m_options)
m_options = new McuSupportOptions(this);
@@ -568,124 +154,6 @@ QWidget* McuSupportOptionsPage::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()
{
for (auto package : m_options->packages)
@@ -697,9 +165,8 @@ void McuSupportOptionsPage::apply()
using namespace ProjectExplorer;
for (auto board : validBoards) {
Kit *kit = boardKit(board, m_options->toolchainPackage->path());
}
for (auto board : validBoards)
m_options->kit(board);
}
void McuSupportOptionsPage::finish()
@@ -711,5 +178,3 @@ void McuSupportOptionsPage::finish()
} // Internal
} // McuSupport
#include "mcusupportoptionspage.moc"

View File

@@ -524,7 +524,9 @@ void Project::emitParsingStarted()
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_hasParsingData = success;

View File

@@ -674,7 +674,7 @@ TargetGroupItem::TargetGroupItem(const QString &displayName, Project *project)
QObject::connect(project, &Project::removedTarget,
d.get(), &TargetGroupItemPrivate::handleTargetRemoved);
QObject::connect(project, &Project::activeTargetChanged,
d.get(), &TargetGroupItemPrivate::handleTargetChanged, Qt::QueuedConnection);
d.get(), &TargetGroupItemPrivate::handleTargetChanged);
}
TargetGroupItem::~TargetGroupItem() = default;
@@ -748,8 +748,10 @@ TargetItem *TargetGroupItem::currentTargetItem() const
TargetItem *TargetGroupItem::targetItem(Target *target) const
{
if (target)
return findFirstLevelChild([target](TargetItem *item) { return item->target() == target; });
if (target) {
Id needle = target->id(); // Unconfigured project have no active target.
return findFirstLevelChild([needle](TargetItem *item) { return item->m_kitId == needle; });
}
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 QVector<FilePath> nonBuildDirFilePaths = filtered(filePaths,
[buildDir](const FilePath &p) {
return p.isChildOf(buildDir);
return !p.isChildOf(buildDir);
});
setExtraProjectFiles(nonBuildDirFilePaths);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -51,6 +51,7 @@
#include "changeauxiliarycommand.h"
#include "changebindingscommand.h"
#include "changeidscommand.h"
#include "changeselectioncommand.h"
#include "changenodesourcecommand.h"
#include "removeinstancescommand.h"
#include "removepropertiescommand.h"
@@ -1109,6 +1110,21 @@ RemoveInstancesCommand NodeInstanceView::createRemoveInstancesCommand(const QLis
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
{
QVector<qint32> idList;
@@ -1174,6 +1190,20 @@ void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command)
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)
{
if (!model())
@@ -1364,6 +1394,20 @@ void NodeInstanceView::sendToken(const QString &token, int number, const QVector
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)
{
if (m_restartProcessTimerId == event->timerId())

View File

@@ -464,14 +464,11 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
#ifndef QMLDESIGNER_TEST
view = QmlDesignerPlugin::instance()->viewManager().nodeInstanceView();
view->emitCustomNotification("PuppetStatus", {}, {QVariant(m_qrcMapping)});
#endif
QStringList importPaths = m_model->importPaths();
QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick3D", "1.0");
bool view3DEnabled = false;
if (view && m_model->hasImport(import, true, true)) {
if (m_model->hasImport(import, true, true)) {
if (view->rootModelNode().hasAuxiliaryData("3d-view"))
view3DEnabled = view->rootModelNode().auxiliaryData("3d-view").toBool();
else
@@ -480,6 +477,9 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
if (view3DEnabled)
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 */
if (m_availablePuppetType == FallbackPuppet)

View File

@@ -1464,6 +1464,10 @@ void ModelPrivate::changeSelectedNodes(const QList<InternalNode::Pointer> &newSe
Q_ASSERT(view != nullptr);
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

View File

@@ -424,6 +424,7 @@ void DocumentManager::findPathToIsoProFile(bool *iconResourceFileAlreadyExists,
if (!iconQrcFileNode) {
// 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;
// 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/valueschangedcommand.cpp",
"commands/valueschangedcommand.h",
"commands/changeselectioncommand.cpp",
"commands/changeselectioncommand.h",
"container/addimportcontainer.cpp",
"container/addimportcontainer.h",
"container/idcontainer.cpp",

View File

@@ -77,7 +77,10 @@ QnxDeployQtLibrariesDialog::QnxDeployQtLibrariesDialog(const IDevice::ConstPtr &
connect(m_uploadService, &AbstractRemoteLinuxDeployService::errorMessage,
m_ui->deployLogWindow, &QPlainTextEdit::appendPlainText);
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,
m_ui->deployLogWindow, &QPlainTextEdit::appendPlainText);
connect(m_uploadService, &AbstractRemoteLinuxDeployService::stdErrData,

View File

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

View File

@@ -73,7 +73,7 @@ private:
void triggerQtVersionRestore();
// Used by QtOptionsPage
static void setNewQtVersions(QList<BaseQtVersion *> newVersions);
static void setNewQtVersions(const QList<BaseQtVersion *> &newVersions);
// Used by QtVersion
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();
@@ -113,6 +113,25 @@ void WebAssemblyToolChain::addToEnvironment(Utils::Environment &env) const
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() :
ClangToolChain(Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID)
{

View File

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

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